nsXULContentSink.h (4483B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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 nsXULContentSink_h__ 7 #define nsXULContentSink_h__ 8 9 #include "mozilla/WeakPtr.h" 10 #include "nsIExpatSink.h" 11 #include "nsIWeakReferenceUtils.h" 12 #include "nsIXMLContentSink.h" 13 #include "nsNodeInfoManager.h" 14 #include "nsXULElement.h" 15 16 class nsIScriptSecurityManager; 17 class nsAttrName; 18 class nsXULPrototypeDocument; 19 class nsXULPrototypeElement; 20 class nsXULPrototypeNode; 21 22 class XULContentSinkImpl final : public nsIXMLContentSink, public nsIExpatSink { 23 public: 24 XULContentSinkImpl(); 25 26 // nsISupports 27 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 28 NS_DECL_NSIEXPATSINK 29 30 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(XULContentSinkImpl, 31 nsIXMLContentSink) 32 33 // nsIContentSink 34 NS_IMETHOD WillParse(void) override { return NS_OK; } 35 NS_IMETHOD DidBuildModel(bool aTerminated) override; 36 NS_IMETHOD WillInterrupt(void) override; 37 void WillResume() override; 38 NS_IMETHOD SetParser(nsParserBase* aParser) override; 39 virtual void FlushPendingNotifications(mozilla::FlushType aType) override {} 40 virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override; 41 virtual nsISupports* GetTarget() override; 42 43 /** 44 * Initialize the content sink, giving it a document with which to communicate 45 * with the outside world, and an nsXULPrototypeDocument to build. 46 */ 47 nsresult Init(mozilla::dom::Document* aDocument, 48 nsXULPrototypeDocument* aPrototype); 49 50 protected: 51 virtual ~XULContentSinkImpl(); 52 53 // pseudo-constants 54 char16_t* mText; 55 int32_t mTextLength; 56 int32_t mTextSize; 57 bool mConstrainSize; 58 59 nsresult AddAttributes(const char16_t** aAttributes, const uint32_t aAttrLen, 60 nsXULPrototypeElement* aElement); 61 62 nsresult OpenRoot(const char16_t** aAttributes, const uint32_t aAttrLen, 63 mozilla::dom::NodeInfo* aNodeInfo); 64 65 nsresult OpenTag(const char16_t** aAttributes, const uint32_t aAttrLen, 66 const uint32_t aLineNumber, 67 mozilla::dom::NodeInfo* aNodeInfo); 68 69 // If OpenScript returns NS_OK and after it returns our state is eInScript, 70 // that means that we created a prototype script and stuck it on 71 // mContextStack. If NS_OK is returned but the state is still 72 // eInDocumentElement then we didn't create a prototype script (e.g. the 73 // script had an unknown type), and the caller should create a prototype 74 // element. 75 nsresult OpenScript(const char16_t** aAttributes, const uint32_t aLineNumber); 76 77 static bool IsDataInBuffer(char16_t* aBuffer, int32_t aLength); 78 79 // Text management 80 nsresult FlushText(bool aCreateTextNode = true); 81 nsresult AddText(const char16_t* aText, int32_t aLength); 82 83 RefPtr<nsNodeInfoManager> mNodeInfoManager; 84 85 nsresult NormalizeAttributeString(const char16_t* aExpatName, 86 nsAttrName& aName); 87 88 public: 89 enum State { eInProlog, eInDocumentElement, eInScript, eInEpilog }; 90 91 protected: 92 State mState; 93 94 // content stack management 95 class ContextStack { 96 protected: 97 struct Entry { 98 RefPtr<nsXULPrototypeNode> mNode; 99 // a LOT of nodes have children; preallocate for 8 100 nsPrototypeArray mChildren; 101 State mState; 102 Entry* mNext; 103 Entry(RefPtr<nsXULPrototypeNode>&& aNode, State aState, Entry* aNext) 104 : mNode(std::move(aNode)), 105 mChildren(8), 106 mState(aState), 107 mNext(aNext) {} 108 }; 109 110 Entry* mTop; 111 int32_t mDepth; 112 113 public: 114 ContextStack(); 115 ~ContextStack(); 116 117 int32_t Depth() { return mDepth; } 118 119 void Push(RefPtr<nsXULPrototypeNode>&& aNode, State aState); 120 nsresult Pop(State* aState); 121 122 nsresult GetTopNode(RefPtr<nsXULPrototypeNode>& aNode); 123 nsresult GetTopChildren(nsPrototypeArray** aChildren); 124 125 void Clear(); 126 127 void Traverse(nsCycleCollectionTraversalCallback& aCallback); 128 }; 129 130 friend class ContextStack; 131 ContextStack mContextStack; 132 133 mozilla::WeakPtr<mozilla::dom::Document> mDocument; 134 nsCOMPtr<nsIURI> mDocumentURL; // [OWNER] 135 136 RefPtr<nsXULPrototypeDocument> mPrototype; // [OWNER] 137 138 RefPtr<nsParserBase> mParser; 139 nsCOMPtr<nsIScriptSecurityManager> mSecMan; 140 }; 141 142 #endif /* nsXULContentSink_h__ */