Backed out changeset 6a14206eb5a9 (bug 1299271) for causing python taskgraph-tests...
[gecko.git] / parser / html / nsHtml5TreeBuilderHSupplement.h
blob3fc1609e5abca74da1dbd74c51f9bdc3120391f3
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #define NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH 512
6 private:
7 using Encoding = mozilla::Encoding;
8 template <typename T>
9 using NotNull = mozilla::NotNull<T>;
11 nsHtml5OplessBuilder* mBuilder;
12 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
13 // If mBuilder is not null, the tree op machinery is not in use and
14 // the fields below aren't in use, either.
15 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
16 nsHtml5Highlighter* mViewSource;
17 mozilla::ImportScanner mImportScanner;
18 nsTArray<nsHtml5TreeOperation> mOpQueue;
19 nsTArray<nsHtml5SpeculativeLoad> mSpeculativeLoadQueue;
20 nsAHtml5TreeOpSink* mOpSink;
21 mozilla::UniquePtr<nsIContent*[]> mHandles;
22 int32_t mHandlesUsed;
23 nsTArray<mozilla::UniquePtr<nsIContent*[]>> mOldHandles;
24 nsHtml5TreeOpStage* mSpeculativeLoadStage;
25 nsresult mBroken;
26 // Controls whether the current HTML script goes through the more complex
27 // path that accommodates the possibility of the script becoming a
28 // parser-blocking script and the possibility of the script inserting
29 // content into this parse using document.write (as it is observable from
30 // the Web).
32 // Notably, in some cases scripts that do NOT NEED the more complex path
33 // BREAK the parse if they incorrectly go onto the complex path as their
34 // other handling doesn't necessarily take care of the responsibilities
35 // associated with the more complex path. See comments in
36 // `nsHtml5TreeBuilder::createElement` in the CppSupplement for details.
37 bool mCurrentHtmlScriptCannotDocumentWriteOrBlock;
38 bool mPreventScriptExecution;
39 /**
40 * Whether to actually generate speculative load operations that actually
41 * represent speculative loads as opposed to other operations traveling
42 * in the same queue. True for normal loads and false for XHR, plain text,
43 * and View Source. Needed, because we can't just null-check
44 * mSpeculativeLoadStage, since it is used for transferring encoding
45 * information even in the XHR/plain text/View Source cases.
47 bool mGenerateSpeculativeLoads;
49 bool mHasSeenImportMap;
50 #ifdef DEBUG
51 bool mActive;
52 #endif
54 // DocumentModeHandler
55 /**
56 * Tree builder uses this to report quirkiness of the document
58 void documentMode(nsHtml5DocumentMode m);
60 nsIContentHandle* getDocumentFragmentForTemplate(nsIContentHandle* aTemplate);
62 nsIContentHandle* getFormPointerForContext(nsIContentHandle* aContext);
64 /**
65 * Using nsIContent** instead of nsIContent* is the parser deals with DOM
66 * nodes in a way that works off the main thread. Non-main-thread code
67 * can't refcount or otherwise touch nsIContent objects in any way.
68 * Yet, the off-the-main-thread code needs to have a way to hold onto a
69 * particular node and repeatedly operate on the same node.
71 * The way this works is that the off-the-main-thread code has an
72 * nsIContent** for each DOM node and a given nsIContent** is only ever
73 * actually dereferenced into an actual nsIContent* on the main thread.
74 * When the off-the-main-thread code requests a new node, it gets an
75 * nsIContent** immediately and a tree op is enqueued for later allocating
76 * an actual nsIContent object and writing a pointer to it into the memory
77 * location pointed to by the nsIContent**.
79 * Since tree ops are in a queue, the node creating tree op will always
80 * run before tree ops that try to further operate on the node that the
81 * nsIContent** is a handle to.
83 * On-the-main-thread parts of the parser use nsIContent* instead of
84 * nsIContent**. Since both cases share the same parser core, the parser
85 * core casts both to nsIContentHandle*.
87 nsIContentHandle* AllocateContentHandle();
89 void accumulateCharactersForced(const char16_t* aBuf, int32_t aStart,
90 int32_t aLength) {
91 accumulateCharacters(aBuf, aStart, aLength);
94 void MarkAsBrokenAndRequestSuspensionWithBuilder(nsresult aRv) {
95 mBuilder->MarkAsBroken(aRv);
96 requestSuspension();
99 void MarkAsBrokenAndRequestSuspensionWithoutBuilder(nsresult aRv) {
100 MarkAsBroken(aRv);
101 requestSuspension();
104 void MarkAsBrokenFromPortability(nsresult aRv);
106 public:
107 explicit nsHtml5TreeBuilder(nsHtml5OplessBuilder* aBuilder);
109 nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink, nsHtml5TreeOpStage* aStage,
110 bool aGenerateSpeculativeLoads);
112 ~nsHtml5TreeBuilder();
114 bool WantsLineAndColumn() {
115 // Perhaps just checking mBuilder would be sufficient.
116 // For createContextualFragment, we have non-null mBuilder and
117 // false for mPreventScriptExecution. However, do the line and
118 // column that get attached to script elements make any sense
119 // anyway in that case?
120 return !(mBuilder && mPreventScriptExecution);
123 void StartPlainTextViewSource(const nsAutoString& aTitle);
125 void StartPlainText();
127 void StartPlainTextBody();
129 bool HasScriptThatMayDocumentWriteOrBlock();
131 void SetOpSink(nsAHtml5TreeOpSink* aOpSink) { mOpSink = aOpSink; }
133 void ClearOps() { mOpQueue.Clear(); }
136 * Flushes tree ops.
137 * @return Ok(true) if there were ops to flush, Ok(false)
138 * if there were no ops to flush and Err() on OOM.
140 mozilla::Result<bool, nsresult> Flush(bool aDiscretionary = false);
142 void FlushLoads();
145 * Sets the document charset via the speculation queue.
147 * @param aCommitEncodingSpeculation true iff the main thread should
148 * treat the first speculation as an
149 * encoding speculation.
151 void SetDocumentCharset(NotNull<const Encoding*> aEncoding,
152 nsCharsetSource aCharsetSource,
153 bool aCommitEncodingSpeculation);
156 * Updates the charset source via the op queue.
158 void UpdateCharsetSource(nsCharsetSource aCharsetSource);
160 void StreamEnded();
162 void NeedsCharsetSwitchTo(NotNull<const Encoding*> aEncoding, int32_t aSource,
163 int32_t aLineNumber);
165 void MaybeComplainAboutCharset(const char* aMsgId, bool aError,
166 int32_t aLineNumber);
168 void TryToEnableEncodingMenu();
170 void AddSnapshotToScript(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine);
172 void DropHandles();
174 void SetPreventScriptExecution(bool aPrevent) {
175 mPreventScriptExecution = aPrevent;
178 bool HasBuilder() { return mBuilder; }
181 * Makes sure the buffers are large enough to be able to tokenize aLength
182 * UTF-16 code units before having to make the buffers larger.
184 * @param aLength the number of UTF-16 code units to be tokenized before the
185 * next call to this method.
186 * @return true if successful; false if out of memory
188 bool EnsureBufferSpace(int32_t aLength);
190 void EnableViewSource(nsHtml5Highlighter* aHighlighter);
192 void errDeepTree();
194 void errStrayStartTag(nsAtom* aName);
196 void errStrayEndTag(nsAtom* aName);
198 void errUnclosedElements(int32_t aIndex, nsAtom* aName);
200 void errUnclosedElementsImplied(int32_t aIndex, nsAtom* aName);
202 void errUnclosedElementsCell(int32_t aIndex);
204 void errStrayDoctype();
206 void errAlmostStandardsDoctype();
208 void errQuirkyDoctype();
210 void errNonSpaceInTrailer();
212 void errNonSpaceAfterFrameset();
214 void errNonSpaceInFrameset();
216 void errNonSpaceAfterBody();
218 void errNonSpaceInColgroupInFragment();
220 void errNonSpaceInNoscriptInHead();
222 void errFooBetweenHeadAndBody(nsAtom* aName);
224 void errStartTagWithoutDoctype();
226 void errNoSelectInTableScope();
228 void errStartSelectWhereEndSelectExpected();
230 void errStartTagWithSelectOpen(nsAtom* aName);
232 void errBadStartTagInNoscriptInHead(nsAtom* aName);
234 void errImage();
236 void errIsindex();
238 void errFooSeenWhenFooOpen(nsAtom* aName);
240 void errHeadingWhenHeadingOpen();
242 void errFramesetStart();
244 void errNoCellToClose();
246 void errStartTagInTable(nsAtom* aName);
248 void errFormWhenFormOpen();
250 void errTableSeenWhileTableOpen();
252 void errStartTagInTableBody(nsAtom* aName);
254 void errEndTagSeenWithoutDoctype();
256 void errEndTagAfterBody();
258 void errEndTagSeenWithSelectOpen(nsAtom* aName);
260 void errGarbageInColgroup();
262 void errEndTagBr();
264 void errNoElementToCloseButEndTagSeen(nsAtom* aName);
266 void errHtmlStartTagInForeignContext(nsAtom* aName);
268 void errNoTableRowToClose();
270 void errNonSpaceInTable();
272 void errUnclosedChildrenInRuby();
274 void errStartTagSeenWithoutRuby(nsAtom* aName);
276 void errSelfClosing();
278 void errNoCheckUnclosedElementsOnStack();
280 void errEndTagDidNotMatchCurrentOpenElement(nsAtom* aName, nsAtom* aOther);
282 void errEndTagViolatesNestingRules(nsAtom* aName);
284 void errEndWithUnclosedElements(nsAtom* aName);
286 void errListUnclosedStartTags(int32_t aIgnored);
288 void MarkAsBroken(nsresult aRv);
291 * Checks if this parser is broken. Returns a non-NS_OK (i.e. non-0)
292 * value if broken.
294 nsresult IsBroken() { return mBroken; }