OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef HTMLParserReentryPermit_h | |
6 #define HTMLParserReentryPermit_h | |
7 | |
8 #include "base/macros.h" | |
9 #include "platform/heap/Handle.h" | |
10 | |
11 namespace blink { | |
12 | |
13 // The HTML spec for parsing controls reentering the parser from | |
14 // script with the "parser pause flag" and "script nesting level." | |
15 // | |
16 // The parser pause flag puts a brake on whether the tokenizer will | |
17 // produce more tokens. When the parser is paused, nested invocations | |
18 // of the tokenizer unwind. | |
19 // | |
20 // The script nesting level is incremented and decremented any time | |
21 // the parser causes script to run. The script nesting level: | |
22 // | |
23 // - May prevent document.open from blowing away the document. | |
24 // | |
25 // - Governs whether a script element becomes the "pending | |
26 // parsing-blocking script." The pending parsing-blocking script in | |
27 // turn affects whether document.write reenters the parser. | |
28 // | |
29 // Clearing the parser pause flag is simple: Whenever the script | |
30 // nesting level hits zero, the parser pause flag is cleared. However | |
31 // setting the parser pause flag is subtle. | |
32 // | |
33 // Processing a typical script end tag, or running a chain of pending | |
34 // parser-blocking scripts after that, does not set the parser pause | |
35 // flag. However recursively parsing end script tags, or running | |
36 // custom element constructors, does set the parser pause flag. | |
37 class HTMLParserReentryPermit final : public GarbageCollected<HTMLParserReentryP ermit> { | |
kouhei (in TOK)
2016/08/15 02:10:31
I really appreciate this refactoring!
I slightly p
| |
38 public: | |
39 HTMLParserReentryPermit() | |
40 : m_scriptNestingLevel(0) | |
41 , m_parserPauseFlag(false) {} | |
42 | |
43 // TODO(dominicc): platform/heap/BlinkGCAPIReference.md says this type | |
44 // should not be traced, but compilation errors result unless it is. | |
45 DEFINE_INLINE_TRACE() {} | |
46 | |
47 unsigned scriptNestingLevel() const { return m_scriptNestingLevel; } | |
48 bool parserPauseFlag() const { return m_parserPauseFlag; } | |
49 void pause() | |
50 { | |
51 CHECK(m_scriptNestingLevel); | |
52 m_parserPauseFlag = true; | |
53 } | |
54 | |
55 class ScriptNestingLevelIncrementer final { | |
56 STACK_ALLOCATED(); | |
57 public: | |
58 explicit ScriptNestingLevelIncrementer(HTMLParserReentryPermit* permit) | |
59 : m_permit(permit) | |
60 { | |
61 m_permit->m_scriptNestingLevel++; | |
62 } | |
63 | |
64 ScriptNestingLevelIncrementer(ScriptNestingLevelIncrementer&&) | |
65 = default; | |
66 | |
67 ~ScriptNestingLevelIncrementer() | |
68 { | |
69 m_permit->m_scriptNestingLevel--; | |
70 if (!m_permit->m_scriptNestingLevel) | |
71 m_permit->m_parserPauseFlag = false; | |
72 } | |
73 | |
74 private: | |
75 UntracedMember<HTMLParserReentryPermit> m_permit; | |
76 | |
77 DISALLOW_COPY_AND_ASSIGN(ScriptNestingLevelIncrementer); | |
78 }; | |
79 | |
80 ScriptNestingLevelIncrementer incrementScriptNestingLevel() | |
81 { | |
82 return ScriptNestingLevelIncrementer(this); | |
83 } | |
84 | |
85 private: | |
86 // https://html.spec.whatwg.org/#script-nesting-level | |
87 unsigned m_scriptNestingLevel; | |
88 | |
89 // https://html.spec.whatwg.org/#parser-pause-flag | |
90 bool m_parserPauseFlag; | |
91 | |
92 DISALLOW_COPY_AND_ASSIGN(HTMLParserReentryPermit); | |
93 }; | |
94 | |
95 } // namespace blink | |
96 | |
97 #endif // HTMLParserReentryPermit_h | |
OLD | NEW |