diff options
Diffstat (limited to 'dom/xul/nsXULContentSink.h')
-rw-r--r-- | dom/xul/nsXULContentSink.h | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/dom/xul/nsXULContentSink.h b/dom/xul/nsXULContentSink.h new file mode 100644 index 000000000..ff38cad60 --- /dev/null +++ b/dom/xul/nsXULContentSink.h @@ -0,0 +1,150 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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 nsXULContentSink_h__ +#define nsXULContentSink_h__ + +#include "mozilla/Attributes.h" +#include "nsIExpatSink.h" +#include "nsIXMLContentSink.h" +#include "nsNodeInfoManager.h" +#include "nsWeakPtr.h" +#include "nsXULElement.h" +#include "nsIDTD.h" + +class nsIDocument; +class nsIScriptSecurityManager; +class nsAttrName; +class nsXULPrototypeDocument; +class nsXULPrototypeElement; +class nsXULPrototypeNode; + +class XULContentSinkImpl final : public nsIXMLContentSink, + public nsIExpatSink +{ +public: + XULContentSinkImpl(); + + // nsISupports + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_NSIEXPATSINK + + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(XULContentSinkImpl, nsIXMLContentSink) + + // nsIContentSink + NS_IMETHOD WillParse(void) override { return NS_OK; } + NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override; + NS_IMETHOD DidBuildModel(bool aTerminated) override; + NS_IMETHOD WillInterrupt(void) override; + NS_IMETHOD WillResume(void) override; + NS_IMETHOD SetParser(nsParserBase* aParser) override; + virtual void FlushPendingNotifications(mozFlushType aType) override { } + NS_IMETHOD SetDocumentCharset(nsACString& aCharset) override; + virtual nsISupports *GetTarget() override; + + /** + * Initialize the content sink, giving it an nsIDocument object + * with which to communicate with the outside world, and an + * nsXULPrototypeDocument to build. + */ + nsresult Init(nsIDocument* aDocument, nsXULPrototypeDocument* aPrototype); + +protected: + virtual ~XULContentSinkImpl(); + + // pseudo-constants + char16_t* mText; + int32_t mTextLength; + int32_t mTextSize; + bool mConstrainSize; + + nsresult AddAttributes(const char16_t** aAttributes, + const uint32_t aAttrLen, + nsXULPrototypeElement* aElement); + + nsresult OpenRoot(const char16_t** aAttributes, + const uint32_t aAttrLen, + mozilla::dom::NodeInfo *aNodeInfo); + + nsresult OpenTag(const char16_t** aAttributes, + const uint32_t aAttrLen, + const uint32_t aLineNumber, + mozilla::dom::NodeInfo *aNodeInfo); + + // If OpenScript returns NS_OK and after it returns our state is eInScript, + // that means that we created a prototype script and stuck it on + // mContextStack. If NS_OK is returned but the state is still + // eInDocumentElement then we didn't create a prototype script (e.g. the + // script had an unknown type), and the caller should create a prototype + // element. + nsresult OpenScript(const char16_t** aAttributes, + const uint32_t aLineNumber); + + static bool IsDataInBuffer(char16_t* aBuffer, int32_t aLength); + + // Text management + nsresult FlushText(bool aCreateTextNode = true); + nsresult AddText(const char16_t* aText, int32_t aLength); + + + RefPtr<nsNodeInfoManager> mNodeInfoManager; + + nsresult NormalizeAttributeString(const char16_t *aExpatName, + nsAttrName &aName); + nsresult CreateElement(mozilla::dom::NodeInfo *aNodeInfo, + nsXULPrototypeElement** aResult); + + + public: + enum State { eInProlog, eInDocumentElement, eInScript, eInEpilog }; + protected: + + State mState; + + // content stack management + class ContextStack { + protected: + struct Entry { + RefPtr<nsXULPrototypeNode> mNode; + // a LOT of nodes have children; preallocate for 8 + nsPrototypeArray mChildren; + State mState; + Entry* mNext; + Entry() : mChildren(8) {} + }; + + Entry* mTop; + int32_t mDepth; + + public: + ContextStack(); + ~ContextStack(); + + int32_t Depth() { return mDepth; } + + nsresult Push(nsXULPrototypeNode* aNode, State aState); + nsresult Pop(State* aState); + + nsresult GetTopNode(RefPtr<nsXULPrototypeNode>& aNode); + nsresult GetTopChildren(nsPrototypeArray** aChildren); + + void Clear(); + + void Traverse(nsCycleCollectionTraversalCallback& aCallback); + }; + + friend class ContextStack; + ContextStack mContextStack; + + nsWeakPtr mDocument; // [OWNER] + nsCOMPtr<nsIURI> mDocumentURL; // [OWNER] + + RefPtr<nsXULPrototypeDocument> mPrototype; // [OWNER] + + RefPtr<nsParserBase> mParser; + nsCOMPtr<nsIScriptSecurityManager> mSecMan; +}; + +#endif /* nsXULContentSink_h__ */ |