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