Bug 1811871 - Check collapsed attribute rather than computed opacity value to tell...
[gecko.git] / dom / prototype / PrototypeDocumentContentSink.h
blobc4735ed52c98e80d2c6f405ede358de2e9bc53e8
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_PrototypeDocumentContentSink_h__
8 #define mozilla_dom_PrototypeDocumentContentSink_h__
10 #include "mozilla/Attributes.h"
11 #include "nsIContentSink.h"
12 #include "nsTArray.h"
13 #include "nsCOMPtr.h"
14 #include "nsCRT.h"
15 #include "nsCycleCollectionNoteChild.h"
16 #include "nsCycleCollectionParticipant.h"
17 #include "nsIDTD.h"
18 #include "mozilla/dom/FromParser.h"
19 #include "nsXULPrototypeDocument.h"
20 #include "nsIStreamLoader.h"
21 #include "nsIScriptContext.h"
22 #include "nsICSSLoaderObserver.h"
23 #include "mozilla/Logging.h"
24 #include "js/experimental/JSStencil.h"
25 #include "mozilla/RefPtr.h"
27 class nsIURI;
28 class nsIChannel;
29 class nsIContent;
30 class nsIParser;
31 class nsTextNode;
32 class nsINode;
33 class nsXULPrototypeElement;
34 class nsXULPrototypePI;
35 class nsXULPrototypeScript;
37 namespace mozilla::dom {
38 class Element;
39 class ScriptLoader;
40 class Document;
41 class XMLStylesheetProcessingInstruction;
42 } // namespace mozilla::dom
44 nsresult NS_NewPrototypeDocumentContentSink(nsIContentSink** aResult,
45 mozilla::dom::Document* aDoc,
46 nsIURI* aURI,
47 nsISupports* aContainer,
48 nsIChannel* aChannel);
50 namespace mozilla::dom {
52 class PrototypeDocumentContentSink final : public nsIStreamLoaderObserver,
53 public nsIContentSink,
54 public nsICSSLoaderObserver,
55 public nsIOffThreadScriptReceiver {
56 public:
57 PrototypeDocumentContentSink();
59 nsresult Init(Document* aDoc, nsIURI* aURL, nsISupports* aContainer,
60 nsIChannel* aChannel);
62 // nsISupports
63 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
64 NS_DECL_NSISTREAMLOADEROBSERVER
66 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(PrototypeDocumentContentSink,
67 nsIContentSink)
69 // nsIContentSink
70 NS_IMETHOD WillParse(void) override { return NS_OK; };
71 NS_IMETHOD WillInterrupt(void) override { return NS_OK; };
72 void WillResume() override{};
73 NS_IMETHOD SetParser(nsParserBase* aParser) override;
74 virtual void InitialTranslationCompleted() override;
75 virtual void FlushPendingNotifications(FlushType aType) override{};
76 virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override;
77 virtual nsISupports* GetTarget() override;
78 virtual bool IsScriptExecuting() override;
79 virtual void ContinueInterruptedParsingAsync() override;
81 // nsICSSLoaderObserver
82 NS_IMETHOD StyleSheetLoaded(StyleSheet* aSheet, bool aWasDeferred,
83 nsresult aStatus) override;
85 // nsIOffThreadScriptReceiver
86 NS_IMETHOD OnScriptCompileComplete(JS::Stencil* aStencil,
87 nsresult aStatus) override;
89 nsresult OnPrototypeLoadDone(nsXULPrototypeDocument* aPrototype);
91 protected:
92 virtual ~PrototypeDocumentContentSink();
94 static LazyLogModule gLog;
96 nsIParser* GetParser();
98 void ContinueInterruptedParsingIfEnabled();
99 void StartLayout();
101 virtual nsresult AddAttributes(nsXULPrototypeElement* aPrototype,
102 Element* aElement);
104 RefPtr<nsParserBase> mParser;
105 nsCOMPtr<nsIURI> mDocumentURI;
106 RefPtr<Document> mDocument;
107 RefPtr<ScriptLoader> mScriptLoader;
109 PrototypeDocumentContentSink* mNextSrcLoadWaiter; // [OWNER] but not COMPtr
112 * The prototype-script of the current transcluded script that is being
113 * loaded. For document.write('<script src="nestedwrite.js"><\/script>')
114 * to work, these need to be in a stack element type, and we need to hold
115 * the top of stack here.
117 nsXULPrototypeScript* mCurrentScriptProto;
120 * Whether the current transcluded script is being compiled off thread.
121 * The load event is blocked while this is in progress.
123 bool mOffThreadCompiling;
126 * If the current transcluded script is being compiled off thread, the
127 * source for that script.
129 Utf8Unit* mOffThreadCompileStringBuf;
130 size_t mOffThreadCompileStringLength;
133 * Wether the prototype document is still be traversed to create the DOM.
134 * Layout will not be started until false.
136 bool mStillWalking;
139 * Number of style sheets still loading. Layout will not start until zero.
141 uint32_t mPendingSheets;
144 * Context stack, which maintains the state of the Builder and allows
145 * it to be interrupted.
147 class ContextStack {
148 protected:
149 struct Entry {
150 nsXULPrototypeElement* mPrototype;
151 nsIContent* mElement;
152 int32_t mIndex;
153 Entry* mNext;
156 Entry* mTop;
157 int32_t mDepth;
159 public:
160 ContextStack();
161 ~ContextStack();
163 int32_t Depth() { return mDepth; }
165 nsresult Push(nsXULPrototypeElement* aPrototype, nsIContent* aElement);
166 nsresult Pop();
167 nsresult Peek(nsXULPrototypeElement** aPrototype, nsIContent** aElement,
168 int32_t* aIndex);
170 nsresult SetTopIndex(int32_t aIndex);
172 void Traverse(nsCycleCollectionTraversalCallback& aCallback,
173 const char* aName, uint32_t aFlags = 0);
174 void Clear();
176 // Cycle collector helpers for ContextStack.
177 friend void ImplCycleCollectionUnlink(
178 PrototypeDocumentContentSink::ContextStack& aField) {
179 aField.Clear();
182 friend void ImplCycleCollectionTraverse(
183 nsCycleCollectionTraversalCallback& aCallback,
184 PrototypeDocumentContentSink::ContextStack& aField, const char* aName,
185 uint32_t aFlags = 0) {
186 aField.Traverse(aCallback, aName, aFlags);
190 friend class ContextStack;
191 ContextStack mContextStack;
194 * The current prototype that we are walking to construct the
195 * content model.
197 RefPtr<nsXULPrototypeDocument> mCurrentPrototype;
198 nsresult CreateAndInsertPI(const nsXULPrototypePI* aProtoPI);
199 nsresult ExecuteScript(nsXULPrototypeScript* aScript);
200 nsresult LoadScript(nsXULPrototypeScript* aScriptProto, bool* aBlock);
203 * A wrapper around ResumeWalkInternal to report walking errors.
205 nsresult ResumeWalk();
208 * Resume (or initiate) an interrupted (or newly prepared)
209 * prototype walk.
211 nsresult ResumeWalkInternal();
214 * Called at the end of ResumeWalk(), from StyleSheetLoaded(),
215 * and from DocumentL10n.
216 * If walking, stylesheets and l10n are not blocking, it
217 * will trigger `DoneWalking()`.
219 nsresult MaybeDoneWalking();
222 * Called from `MaybeDoneWalking()`.
223 * Expects that both the prototype document walk is complete and
224 * all referenced stylesheets finished loading.
226 nsresult DoneWalking();
229 * Create a delegate content model element from a prototype.
230 * Note that the resulting content node is not bound to any tree
232 nsresult CreateElementFromPrototype(nsXULPrototypeElement* aPrototype,
233 Element** aResult, nsIContent* aParent);
235 * Prepare to walk the current prototype.
237 nsresult PrepareToWalk();
239 * Creates a processing instruction based on aProtoPI and inserts
240 * it to the DOM.
242 nsresult CreateAndInsertPI(const nsXULPrototypePI* aProtoPI, nsINode* aParent,
243 nsINode* aBeforeThis);
246 * Inserts the passed <?xml-stylesheet ?> PI at the specified
247 * index. Loads and applies the associated stylesheet
248 * asynchronously.
249 * The prototype document walk can happen before the stylesheets
250 * are loaded, but the final steps in the load process (see
251 * DoneWalking()) are not run before all the stylesheets are done
252 * loading.
254 nsresult InsertXMLStylesheetPI(const nsXULPrototypePI* aProtoPI,
255 nsINode* aParent, nsINode* aBeforeThis,
256 XMLStylesheetProcessingInstruction* aPINode);
257 void CloseElement(Element* aElement, bool aHadChildren);
260 } // namespace mozilla::dom
262 #endif // mozilla_dom_PrototypeDocumentContentSink_h__