summaryrefslogtreecommitdiffstats
path: root/dom/xslt/xslt/txStylesheetCompiler.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/xslt/xslt/txStylesheetCompiler.h')
-rw-r--r--dom/xslt/xslt/txStylesheetCompiler.h234
1 files changed, 234 insertions, 0 deletions
diff --git a/dom/xslt/xslt/txStylesheetCompiler.h b/dom/xslt/xslt/txStylesheetCompiler.h
new file mode 100644
index 0000000000..759219ced6
--- /dev/null
+++ b/dom/xslt/xslt/txStylesheetCompiler.h
@@ -0,0 +1,234 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef TRANSFRMX_TXSTYLESHEETCOMPILER_H
+#define TRANSFRMX_TXSTYLESHEETCOMPILER_H
+
+#include "mozilla/Attributes.h"
+#include "mozilla/UniquePtr.h"
+#include "txStack.h"
+#include "txXSLTPatterns.h"
+#include "txExpr.h"
+#include "txIXPathContext.h"
+#include "txStylesheet.h"
+#include "nsTArray.h"
+
+extern bool TX_XSLTFunctionAvailable(nsAtom* aName, int32_t aNameSpaceID);
+
+class txHandlerTable;
+class txElementContext;
+class txInstructionContainer;
+class txInstruction;
+class txNamespaceMap;
+class txToplevelItem;
+class txPushNewContext;
+class txStylesheetCompiler;
+
+class txElementContext : public txObject {
+ public:
+ explicit txElementContext(const nsAString& aBaseURI);
+ txElementContext(const txElementContext& aOther);
+
+ bool mPreserveWhitespace;
+ bool mForwardsCompatibleParsing;
+ nsString mBaseURI;
+ RefPtr<txNamespaceMap> mMappings;
+ nsTArray<int32_t> mInstructionNamespaces;
+ int32_t mDepth;
+};
+
+using mozilla::dom::ReferrerPolicy;
+
+class txACompileObserver {
+ public:
+ NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
+
+ virtual nsresult loadURI(const nsAString& aUri, const nsAString& aReferrerUri,
+ ReferrerPolicy aReferrerPolicy,
+ txStylesheetCompiler* aCompiler) = 0;
+ virtual void onDoneCompiling(txStylesheetCompiler* aCompiler,
+ nsresult aResult,
+ const char16_t* aErrorText = nullptr,
+ const char16_t* aParam = nullptr) = 0;
+};
+
+#define TX_DECL_ACOMPILEOBSERVER \
+ nsresult loadURI(const nsAString& aUri, const nsAString& aReferrerUri, \
+ ReferrerPolicy aReferrerPolicy, \
+ txStylesheetCompiler* aCompiler) override; \
+ void onDoneCompiling(txStylesheetCompiler* aCompiler, nsresult aResult, \
+ const char16_t* aErrorText = nullptr, \
+ const char16_t* aParam = nullptr) override;
+
+class txInScopeVariable {
+ public:
+ explicit txInScopeVariable(const txExpandedName& aName)
+ : mName(aName), mLevel(1) {}
+ txExpandedName mName;
+ int32_t mLevel;
+};
+
+class txStylesheetCompilerState : public txIParseContext {
+ public:
+ explicit txStylesheetCompilerState(txACompileObserver* aObserver);
+ ~txStylesheetCompilerState();
+
+ nsresult init(const nsAString& aStylesheetURI, ReferrerPolicy aReferrerPolicy,
+ txStylesheet* aStylesheet, txListIterator* aInsertPosition);
+
+ // Embedded stylesheets state
+ bool handleEmbeddedSheet() { return mEmbedStatus == eInEmbed; }
+ void doneEmbedding() { mEmbedStatus = eHasEmbed; }
+
+ // Stack functions
+ enum enumStackType {
+ eElementHandler,
+ eHandlerTable,
+ eVariableItem,
+ eCopy,
+ eInstruction,
+ ePushNewContext,
+ eConditionalGoto,
+ eCheckParam,
+ ePushNullTemplateRule
+ };
+ void pushHandlerTable(txHandlerTable* aTable);
+ void popHandlerTable();
+ void pushSorter(txPushNewContext* aSorter);
+ void popSorter();
+ void pushChooseGotoList();
+ void popChooseGotoList();
+ void pushObject(txObject* aObject);
+ txObject* popObject();
+ void pushPtr(void* aPtr, enumStackType aType);
+ void* popPtr(enumStackType aType);
+
+ // stylesheet functions
+ void addToplevelItem(txToplevelItem* aItem);
+ nsresult openInstructionContainer(txInstructionContainer* aContainer);
+ void closeInstructionContainer();
+ txInstruction* addInstruction(
+ mozilla::UniquePtr<txInstruction>&& aInstruction);
+ template <class T>
+ T* addInstruction(mozilla::UniquePtr<T> aInstruction) {
+ return static_cast<T*>(addInstruction(
+ mozilla::UniquePtr<txInstruction>(std::move(aInstruction))));
+ }
+ nsresult loadIncludedStylesheet(const nsAString& aURI);
+ nsresult loadImportedStylesheet(const nsAString& aURI,
+ txStylesheet::ImportFrame* aFrame);
+
+ // misc
+ void addGotoTarget(txInstruction** aTargetPointer);
+ void addVariable(const txExpandedName& aName);
+
+ // txIParseContext
+ nsresult resolveNamespacePrefix(nsAtom* aPrefix, int32_t& aID) override;
+ nsresult resolveFunctionCall(nsAtom* aName, int32_t aID,
+ FunctionCall** aFunction) override;
+ bool caseInsensitiveNameTests() override;
+
+ /**
+ * Should the stylesheet be parsed in forwards compatible parsing mode.
+ */
+ bool fcp() { return mElementContext->mForwardsCompatibleParsing; }
+
+ void SetErrorOffset(uint32_t aOffset) override;
+
+ bool allowed(Allowed aAllowed) override { return !(mDisAllowed & aAllowed); }
+
+ bool ignoreError(nsresult aResult) {
+ // Some errors shouldn't be ignored even in forwards compatible parsing
+ // mode.
+ return aResult != NS_ERROR_XSLT_CALL_TO_KEY_NOT_ALLOWED && fcp();
+ }
+
+ RefPtr<txStylesheet> mStylesheet;
+ txHandlerTable* mHandlerTable;
+ mozilla::UniquePtr<txElementContext> mElementContext;
+ txPushNewContext* mSorter;
+ mozilla::UniquePtr<txList> mChooseGotoList;
+ bool mDOE;
+ bool mSearchingForFallback;
+ uint16_t mDisAllowed;
+
+ protected:
+ RefPtr<txACompileObserver> mObserver;
+ nsTArray<txInScopeVariable> mInScopeVariables;
+ nsTArray<txStylesheetCompiler*> mChildCompilerList;
+ // embed info, target information is the ID
+ nsString mTarget;
+ enum { eNoEmbed, eNeedEmbed, eInEmbed, eHasEmbed } mEmbedStatus;
+ nsString mStylesheetURI;
+ bool mIsTopCompiler;
+ bool mDoneWithThisStylesheet;
+ txStack mObjectStack;
+ txStack mOtherStack;
+ nsTArray<enumStackType> mTypeStack;
+
+ private:
+ mozilla::UniquePtr<txInstruction>* mNextInstrPtr;
+ txListIterator mToplevelIterator;
+ nsTArray<txInstruction**> mGotoTargetPointers;
+ ReferrerPolicy mReferrerPolicy;
+};
+
+struct txStylesheetAttr {
+ int32_t mNamespaceID;
+ RefPtr<nsAtom> mLocalName;
+ RefPtr<nsAtom> mPrefix;
+ nsString mValue;
+};
+
+class txStylesheetCompiler final : private txStylesheetCompilerState,
+ public txACompileObserver {
+ public:
+ friend class txStylesheetCompilerState;
+ friend bool TX_XSLTFunctionAvailable(nsAtom* aName, int32_t aNameSpaceID);
+ txStylesheetCompiler(const nsAString& aStylesheetURI,
+ ReferrerPolicy aReferrerPolicy,
+ txACompileObserver* aObserver);
+ txStylesheetCompiler(const nsAString& aStylesheetURI,
+ txStylesheet* aStylesheet,
+ txListIterator* aInsertPosition,
+ ReferrerPolicy aReferrerPolicy,
+ txACompileObserver* aObserver);
+
+ void setBaseURI(const nsString& aBaseURI);
+
+ nsresult startElement(int32_t aNamespaceID, nsAtom* aLocalName,
+ nsAtom* aPrefix, txStylesheetAttr* aAttributes,
+ int32_t aAttrCount);
+ nsresult startElement(const char16_t* aName, const char16_t** aAtts,
+ int32_t aAttrCount);
+ nsresult endElement();
+ nsresult characters(const nsAString& aStr);
+ nsresult doneLoading();
+
+ void cancel(nsresult aError, const char16_t* aErrorText = nullptr,
+ const char16_t* aParam = nullptr);
+
+ txStylesheet* getStylesheet();
+
+ TX_DECL_ACOMPILEOBSERVER
+ NS_INLINE_DECL_REFCOUNTING(txStylesheetCompiler, override)
+
+ private:
+ // Private destructor, to discourage deletion outside of Release():
+ ~txStylesheetCompiler() = default;
+
+ nsresult startElementInternal(int32_t aNamespaceID, nsAtom* aLocalName,
+ nsAtom* aPrefix, txStylesheetAttr* aAttributes,
+ int32_t aAttrCount);
+
+ nsresult flushCharacters();
+ nsresult ensureNewElementContext();
+ nsresult maybeDoneCompiling();
+
+ nsString mCharacters;
+ nsresult mStatus;
+};
+
+#endif