Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef TRANSFRMX_TXSTYLESHEETCOMPILER_H
7 : #define TRANSFRMX_TXSTYLESHEETCOMPILER_H
8 :
9 : #include "mozilla/Attributes.h"
10 : #include "txStack.h"
11 : #include "txXSLTPatterns.h"
12 : #include "txExpr.h"
13 : #include "txIXPathContext.h"
14 : #include "nsAutoPtr.h"
15 : #include "txStylesheet.h"
16 : #include "nsTArray.h"
17 : #include "mozilla/net/ReferrerPolicy.h"
18 :
19 : extern bool
20 : TX_XSLTFunctionAvailable(nsIAtom* aName, int32_t aNameSpaceID);
21 :
22 : class txHandlerTable;
23 : class txElementContext;
24 : class txInstructionContainer;
25 : class txInstruction;
26 : class txNamespaceMap;
27 : class txToplevelItem;
28 : class txPushNewContext;
29 : class txStylesheetCompiler;
30 : class txInScopeVariable;
31 :
32 0 : class txElementContext : public txObject
33 : {
34 : public:
35 : explicit txElementContext(const nsAString& aBaseURI);
36 : txElementContext(const txElementContext& aOther);
37 :
38 : bool mPreserveWhitespace;
39 : bool mForwardsCompatibleParsing;
40 : nsString mBaseURI;
41 : RefPtr<txNamespaceMap> mMappings;
42 : nsTArray<int32_t> mInstructionNamespaces;
43 : int32_t mDepth;
44 : };
45 :
46 0 : class txACompileObserver
47 : {
48 : public:
49 : NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
50 :
51 : virtual nsresult loadURI(const nsAString& aUri,
52 : const nsAString& aReferrerUri,
53 : mozilla::net::ReferrerPolicy aReferrerPolicy,
54 : txStylesheetCompiler* aCompiler) = 0;
55 : virtual void onDoneCompiling(txStylesheetCompiler* aCompiler,
56 : nsresult aResult,
57 : const char16_t *aErrorText = nullptr,
58 : const char16_t *aParam = nullptr) = 0;
59 : };
60 :
61 : #define TX_DECL_ACOMPILEOBSERVER \
62 : nsresult loadURI(const nsAString& aUri, const nsAString& aReferrerUri, \
63 : mozilla::net::ReferrerPolicy aReferrerPolicy, \
64 : txStylesheetCompiler* aCompiler); \
65 : void onDoneCompiling(txStylesheetCompiler* aCompiler, nsresult aResult, \
66 : const char16_t *aErrorText = nullptr, \
67 : const char16_t *aParam = nullptr);
68 :
69 : class txStylesheetCompilerState : public txIParseContext
70 : {
71 : public:
72 : explicit txStylesheetCompilerState(txACompileObserver* aObserver);
73 : ~txStylesheetCompilerState();
74 :
75 : nsresult init(const nsAString& aStylesheetURI,
76 : mozilla::net::ReferrerPolicy aReferrerPolicy,
77 : txStylesheet* aStylesheet, txListIterator* aInsertPosition);
78 :
79 : // Embedded stylesheets state
80 0 : bool handleEmbeddedSheet()
81 : {
82 0 : return mEmbedStatus == eInEmbed;
83 : }
84 0 : void doneEmbedding()
85 : {
86 0 : mEmbedStatus = eHasEmbed;
87 0 : }
88 :
89 : // Stack functions
90 : enum enumStackType
91 : {
92 : eElementHandler,
93 : eHandlerTable,
94 : eVariableItem,
95 : eCopy,
96 : eInstruction,
97 : ePushNewContext,
98 : eConditionalGoto,
99 : eCheckParam,
100 : ePushNullTemplateRule
101 : };
102 : nsresult pushHandlerTable(txHandlerTable* aTable);
103 : void popHandlerTable();
104 : nsresult pushSorter(txPushNewContext* aSorter);
105 : void popSorter();
106 : nsresult pushChooseGotoList();
107 : void popChooseGotoList();
108 : nsresult pushObject(txObject* aObject);
109 : txObject* popObject();
110 : nsresult pushPtr(void* aPtr, enumStackType aType);
111 : void* popPtr(enumStackType aType);
112 :
113 : // stylesheet functions
114 : nsresult addToplevelItem(txToplevelItem* aItem);
115 : nsresult openInstructionContainer(txInstructionContainer* aContainer);
116 : void closeInstructionContainer();
117 : nsresult addInstruction(nsAutoPtr<txInstruction>&& aInstruction);
118 : nsresult loadIncludedStylesheet(const nsAString& aURI);
119 : nsresult loadImportedStylesheet(const nsAString& aURI,
120 : txStylesheet::ImportFrame* aFrame);
121 :
122 : // misc
123 : nsresult addGotoTarget(txInstruction** aTargetPointer);
124 : nsresult addVariable(const txExpandedName& aName);
125 :
126 : // txIParseContext
127 : nsresult resolveNamespacePrefix(nsIAtom* aPrefix, int32_t& aID) override;
128 : nsresult resolveFunctionCall(nsIAtom* aName, int32_t aID,
129 : FunctionCall** aFunction) override;
130 : bool caseInsensitiveNameTests() override;
131 :
132 : /**
133 : * Should the stylesheet be parsed in forwards compatible parsing mode.
134 : */
135 0 : bool fcp()
136 : {
137 0 : return mElementContext->mForwardsCompatibleParsing;
138 : }
139 :
140 : void SetErrorOffset(uint32_t aOffset) override;
141 :
142 0 : bool allowed(Allowed aAllowed) override
143 : {
144 0 : return !(mDisAllowed & aAllowed);
145 : }
146 :
147 0 : bool ignoreError(nsresult aResult)
148 : {
149 : // Some errors shouldn't be ignored even in forwards compatible parsing
150 : // mode.
151 0 : return aResult != NS_ERROR_XSLT_CALL_TO_KEY_NOT_ALLOWED &&
152 0 : fcp();
153 : }
154 :
155 : static void shutdown();
156 :
157 :
158 : RefPtr<txStylesheet> mStylesheet;
159 : txHandlerTable* mHandlerTable;
160 : nsAutoPtr<txElementContext> mElementContext;
161 : txPushNewContext* mSorter;
162 : nsAutoPtr<txList> mChooseGotoList;
163 : bool mDOE;
164 : bool mSearchingForFallback;
165 : uint16_t mDisAllowed;
166 :
167 : protected:
168 : RefPtr<txACompileObserver> mObserver;
169 : nsTArray<txInScopeVariable*> mInScopeVariables;
170 : nsTArray<txStylesheetCompiler*> mChildCompilerList;
171 : // embed info, target information is the ID
172 : nsString mTarget;
173 : enum
174 : {
175 : eNoEmbed,
176 : eNeedEmbed,
177 : eInEmbed,
178 : eHasEmbed
179 : } mEmbedStatus;
180 : nsString mStylesheetURI;
181 : bool mIsTopCompiler;
182 : bool mDoneWithThisStylesheet;
183 : txStack mObjectStack;
184 : txStack mOtherStack;
185 : nsTArray<enumStackType> mTypeStack;
186 :
187 : private:
188 : txInstruction** mNextInstrPtr;
189 : txListIterator mToplevelIterator;
190 : nsTArray<txInstruction**> mGotoTargetPointers;
191 : mozilla::net::ReferrerPolicy mReferrerPolicy;
192 : };
193 :
194 0 : struct txStylesheetAttr
195 : {
196 : int32_t mNamespaceID;
197 : nsCOMPtr<nsIAtom> mLocalName;
198 : nsCOMPtr<nsIAtom> mPrefix;
199 : nsString mValue;
200 : };
201 :
202 : class txStylesheetCompiler final : private txStylesheetCompilerState,
203 : public txACompileObserver
204 : {
205 : public:
206 : friend class txStylesheetCompilerState;
207 : friend bool TX_XSLTFunctionAvailable(nsIAtom* aName,
208 : int32_t aNameSpaceID);
209 : txStylesheetCompiler(const nsAString& aStylesheetURI,
210 : mozilla::net::ReferrerPolicy aReferrerPolicy,
211 : txACompileObserver* aObserver);
212 : txStylesheetCompiler(const nsAString& aStylesheetURI,
213 : txStylesheet* aStylesheet,
214 : txListIterator* aInsertPosition,
215 : mozilla::net::ReferrerPolicy aReferrerPolicy,
216 : txACompileObserver* aObserver);
217 :
218 : void setBaseURI(const nsString& aBaseURI);
219 :
220 : nsresult startElement(int32_t aNamespaceID, nsIAtom* aLocalName,
221 : nsIAtom* aPrefix, txStylesheetAttr* aAttributes,
222 : int32_t aAttrCount);
223 : nsresult startElement(const char16_t *aName,
224 : const char16_t **aAtts,
225 : int32_t aAttrCount);
226 : nsresult endElement();
227 : nsresult characters(const nsAString& aStr);
228 : nsresult doneLoading();
229 :
230 : void cancel(nsresult aError, const char16_t *aErrorText = nullptr,
231 : const char16_t *aParam = nullptr);
232 :
233 : txStylesheet* getStylesheet();
234 :
235 : TX_DECL_ACOMPILEOBSERVER
236 0 : NS_INLINE_DECL_REFCOUNTING(txStylesheetCompiler)
237 :
238 : private:
239 : // Private destructor, to discourage deletion outside of Release():
240 0 : ~txStylesheetCompiler()
241 0 : {
242 0 : }
243 :
244 : nsresult startElementInternal(int32_t aNamespaceID, nsIAtom* aLocalName,
245 : nsIAtom* aPrefix,
246 : txStylesheetAttr* aAttributes,
247 : int32_t aAttrCount);
248 :
249 : nsresult flushCharacters();
250 : nsresult ensureNewElementContext();
251 : nsresult maybeDoneCompiling();
252 :
253 : nsString mCharacters;
254 : nsresult mStatus;
255 : };
256 :
257 0 : class txInScopeVariable {
258 : public:
259 0 : explicit txInScopeVariable(const txExpandedName& aName) : mName(aName), mLevel(1)
260 : {
261 0 : }
262 : txExpandedName mName;
263 : int32_t mLevel;
264 : };
265 :
266 : #endif
|