diff -r 000000000000 -r 6474c204b198 content/xul/document/src/nsXULContentSink.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/xul/document/src/nsXULContentSink.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,151 @@ +/* -*- 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 "nsAutoPtr.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 : public nsIXMLContentSink, + public nsIExpatSink +{ +public: + XULContentSinkImpl(); + virtual ~XULContentSinkImpl(); + + // nsISupports + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_NSIEXPATSINK + + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(XULContentSinkImpl, nsIXMLContentSink) + + // nsIContentSink + NS_IMETHOD WillParse(void) MOZ_OVERRIDE { return NS_OK; } + NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) MOZ_OVERRIDE; + NS_IMETHOD DidBuildModel(bool aTerminated) MOZ_OVERRIDE; + NS_IMETHOD WillInterrupt(void) MOZ_OVERRIDE; + NS_IMETHOD WillResume(void) MOZ_OVERRIDE; + NS_IMETHOD SetParser(nsParserBase* aParser) MOZ_OVERRIDE; + virtual void FlushPendingNotifications(mozFlushType aType) MOZ_OVERRIDE { } + NS_IMETHOD SetDocumentCharset(nsACString& aCharset) MOZ_OVERRIDE; + virtual nsISupports *GetTarget() MOZ_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: + // 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, + nsINodeInfo *aNodeInfo); + + nsresult OpenTag(const char16_t** aAttributes, + const uint32_t aAttrLen, + const uint32_t aLineNumber, + nsINodeInfo *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); + + + nsRefPtr mNodeInfoManager; + + nsresult NormalizeAttributeString(const char16_t *aExpatName, + nsAttrName &aName); + nsresult CreateElement(nsINodeInfo *aNodeInfo, + nsXULPrototypeElement** aResult); + + + public: + enum State { eInProlog, eInDocumentElement, eInScript, eInEpilog }; + protected: + + State mState; + + // content stack management + class ContextStack { + protected: + struct Entry { + nsRefPtr 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(nsRefPtr& aNode); + nsresult GetTopChildren(nsPrototypeArray** aChildren); + + void Clear(); + + void Traverse(nsCycleCollectionTraversalCallback& aCallback); + }; + + friend class ContextStack; + ContextStack mContextStack; + + nsWeakPtr mDocument; // [OWNER] + nsCOMPtr mDocumentURL; // [OWNER] + + nsRefPtr mPrototype; // [OWNER] + + // We use regular pointer b/c of funky exports on nsIParser: + nsParserBase* mParser; // [OWNER] + nsCOMPtr mSecMan; +}; + +#endif /* nsXULContentSink_h__ */