Changeset 60275 in webkit
- Timestamp:
- May 27, 2010 12:14:02 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 17 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r60269 r60275 1 2010-05-26 Eric Seidel <eric@webkit.org> 2 3 Reviewed by Adam Barth. 4 5 Update our expectations now that we're handling external scripts. 6 7 * html5lib/webkit-runner-expected-html5.txt: 8 1 9 2010-05-26 Tony Chang <tony@chromium.org> 2 10 -
trunk/LayoutTests/html5lib/webkit-runner-expected-html5.txt
r60172 r60275 1 CONSOLE MESSAGE: line 1: SyntaxError: Parse error2 CONSOLE MESSAGE: line 1: SyntaxError: Parse error3 CONSOLE MESSAGE: line 1: ReferenceError: Can't find variable: a4 CONSOLE MESSAGE: line 1: SyntaxError: Parse error5 CONSOLE MESSAGE: line 1: SyntaxError: Parse error6 CONSOLE MESSAGE: line 1: SyntaxError: Parse error7 CONSOLE MESSAGE: line 1: SyntaxError: Parse error8 CONSOLE MESSAGE: line 1: ReferenceError: Can't find variable: a9 CONSOLE MESSAGE: line 1: SyntaxError: Parse error10 CONSOLE MESSAGE: line 1: SyntaxError: Parse error11 1 CONSOLE MESSAGE: line 1: SyntaxError: Parse error 12 2 CONSOLE MESSAGE: line 1: SyntaxError: Parse error 13 3 CONSOLE MESSAGE: line 2: PASS 14 4 CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ 5 CONSOLE MESSAGE: line 1: SyntaxError: Parse error 6 CONSOLE MESSAGE: line 1: SyntaxError: Parse error 15 7 Content-Type: text/plain 16 8 resources/tests1.dat: 25, 29, 30, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 50, 51, 52, 53, 54, 57, 59, 78, 79, 80, 81, 82, 87, 90, 91, 92, 96, 98, 101, 104, 106, 109, 113 -
trunk/WebCore/Android.mk
r60228 r60275 250 250 html/HTML5Tokenizer.cpp \ 251 251 html/HTML5TreeBuilder.cpp \ 252 html/HTML5ScriptRunner.cpp \ 252 253 html/HTMLAllCollection.cpp \ 253 254 html/HTMLCollection.cpp \ -
trunk/WebCore/CMakeLists.txt
r60240 r60275 904 904 html/HTML5Tokenizer.cpp 905 905 html/HTML5TreeBuilder.cpp 906 html/HTML5ScriptRunner.cpp 906 907 html/HTMLAllCollection.cpp 907 908 html/HTMLAnchorElement.cpp -
trunk/WebCore/ChangeLog
r60274 r60275 1 2010-05-26 Eric Seidel <eric@webkit.org> 2 3 Reviewed by Adam Barth. 4 5 Teach the HTML5 parser how to handle external scripts 6 https://bugs.webkit.org/show_bug.cgi?id=39716 7 8 Make it possible for the HTML5Tokenizer to run external scripts. 9 I created a new class HTML5ScriptRunner to hold all of the 10 script-logic which is scattered throughout the old HTMLTokenizer. 11 12 The design is for the HTML5Tokenizer (the "controller") to hold 13 the Lexer, TreeBuilder and ScriptRunner. The Lexer returns back 14 to the controller, which passes tokens to the TreeBuilder. When the 15 treebuilder encounters a </script> tag it pauses itself and returns 16 back to the controller which calls the ScriptRunner. The TreeBuilder 17 is un-paused when the HTML5Tokenizer calls takeScriptToProcess(). 18 19 The ScriptRunner attempts to process the passed script, and additionally 20 any blocked scripts it can. It returns to the controller indicating if 21 parsing should continue. If not, callbacks when external scripts load 22 or when stylesheets are finished parsing will cause the controller to 23 kick off script execution and parsing again at a later point. 24 25 * WebCore.xcodeproj/project.pbxproj: 26 - Add HTML5ScriptRunner.* 27 * bindings/js/CachedScriptSourceProvider.h: 28 - Add missing include discovered while building. 29 * dom/ScriptElement.cpp: 30 (WebCore::ScriptElement::finishParsingChildren): 31 - Remove previous hack for inline <script> execution. 32 * dom/ScriptElement.h: 33 - Explain the HTML5 spec names for m_evaluated and m_createdByParser. 34 * html/HTML5ScriptRunner.cpp: Added. 35 (WebCore::HTML5ScriptRunner::HTML5ScriptRunner): 36 - The HTML5Tokenizer is passed to the HTML5ScriptRunner as a 37 CachedResourceClient. The HTML5ScriptRunner will register the 38 HTML5Tokenizer for notifyFinished callbacks when the scripts load. 39 The HTML5Tokenizer is expected to call the HTML5ScriptRunner to 40 execute any loaded scripts at that point. 41 (WebCore::HTML5ScriptRunner::~HTML5ScriptRunner): 42 (WebCore::HTML5ScriptRunner::frame): Helper method. 43 (WebCore::createScriptLoadEvent): Helper method. 44 (WebCore::createScriptErrorEvent): Helper method. 45 (WebCore::HTML5ScriptRunner::sourceFromPendingScript): 46 - Helper method for dealing with both inline and external script types. 47 (WebCore::HTML5ScriptRunner::isPendingScriptReady): 48 - Helper for dealing with both inline and external scripts. 49 (WebCore::HTML5ScriptRunner::executePendingScript): 50 - Execute one script. Both external and inline scripts 51 can become m_parsingBlockingScript if they can't be executed 52 immediately after parsing. 53 (WebCore::HTML5ScriptRunner::execute): 54 - Takes a script element from the tree builder and tries 55 to process it. 56 (WebCore::HTML5ScriptRunner::executeParsingBlockingScripts): 57 - Runs the current parsing blocking script if ready. 58 - Running a script could add another parsing blocking script 59 so we loop until there is no ready-to-run parsing blocking script. 60 (WebCore::HTML5ScriptRunner::executeScriptsWaitingForLoad): 61 - Called by HTML5Tokenizer when a script loads. 62 (WebCore::HTML5ScriptRunner::executeScriptsWaitingForStylesheets): 63 - Called by HTML5Tokenizer when stylesheets complete. 64 (WebCore::HTML5ScriptRunner::requestScript): 65 - Transcription of the HTML5 spec. 66 (WebCore::HTML5ScriptRunner::runScript): 67 - Transcription of the HTML5 spec. 68 * html/HTML5ScriptRunner.h: Added. 69 - New class to handle script loading and execution for the HTML5 parser. 70 * html/HTML5Tokenizer.cpp: 71 (WebCore::HTML5Tokenizer::HTML5Tokenizer): 72 - Create a HTML5ScriptRunner and pass it "this" as the CachedResourceClient. 73 (WebCore::HTML5Tokenizer::pumpLexer): 74 - When the parser is paused, try to run scripts. 75 (WebCore::HTML5Tokenizer::write): 76 - Only pump the lexer when the parser is not paused. 77 (WebCore::HTML5Tokenizer::end): 78 - finish() tells us that we've reached EOF, not end() 79 - Only pump the lexer when the parser is not paused. 80 (WebCore::HTML5Tokenizer::finish): 81 - Mark EOF, and end() if we're not waiting on scripts. 82 (WebCore::HTML5Tokenizer::isWaitingForScripts): 83 - isPaused() seems to mean isPausedForExternalScripts(). 84 (WebCore::HTML5Tokenizer::resumeParsingAfterScriptExecution): 85 (WebCore::HTML5Tokenizer::notifyFinished): 86 (WebCore::HTML5Tokenizer::executeScriptsWaitingForStylesheets): 87 * html/HTML5Tokenizer.h: 88 * html/HTML5TreeBuilder.cpp: 89 (WebCore::HTML5TreeBuilder::HTML5TreeBuilder): 90 - Add an m_isPaused flag. 91 (WebCore::HTML5TreeBuilder::handleScriptStartTag): 92 (WebCore::HTML5TreeBuilder::handleScriptEndTag): 93 (WebCore::HTML5TreeBuilder::takeScriptToProcess): 94 - Acknowledge that the caller has received the script element. 95 It is the caller's responsibility to execute the script if necessary 96 and re-pause the tree builder if necessary. 97 (WebCore::HTML5TreeBuilder::passTokenToLegacyParser): 98 - Save off the current script tag so that it can be passed to 99 the HTML5ScriptRunner when we're paused. 100 * html/HTML5TreeBuilder.h: 101 (WebCore::HTML5TreeBuilder::setPaused): 102 (WebCore::HTML5TreeBuilder::isPaused): 103 1 104 2010-05-26 Adam Barth <abarth@webkit.org> 2 105 -
trunk/WebCore/GNUmakefile.am
r60270 r60275 1090 1090 WebCore/html/HTML5TreeBuilder.cpp \ 1091 1091 WebCore/html/HTML5TreeBuilder.h \ 1092 WebCore/html/HTML5ScriptRunner.cpp \ 1093 WebCore/html/HTML5ScriptRunner.h \ 1092 1094 WebCore/html/HTMLAllCollection.cpp \ 1093 1095 WebCore/html/HTMLAllCollection.h \ -
trunk/WebCore/WebCore.gypi
r60241 r60275 1475 1475 'html/HTML5TreeBuilder.cpp', 1476 1476 'html/HTML5TreeBuilder.h', 1477 'html/HTML5ScriptRunner.cpp', 1478 'html/HTML5ScriptRunner.h', 1477 1479 'html/HTMLAllCollection.cpp', 1478 1480 'html/HTMLAllCollection.h', -
trunk/WebCore/WebCore.pro
r60240 r60275 612 612 html/HTML5Tokenizer.cpp \ 613 613 html/HTML5TreeBuilder.cpp \ 614 html/HTML5ScriptRunner.cpp \ 614 615 html/HTMLAllCollection.cpp \ 615 616 html/HTMLAnchorElement.cpp \ -
trunk/WebCore/WebCore.vcproj/WebCore.vcproj
r60241 r60275 30958 30958 </File> 30959 30959 <File 30960 RelativePath="..\html\HTML5ScriptRunner.cpp" 30961 > 30962 </File> 30963 <File 30964 RelativePath="..\html\HTML5ScriptRunner.h" 30965 > 30966 </File> 30967 <File 30960 30968 RelativePath="..\html\HTMLAllCollection.cpp" 30961 30969 > -
trunk/WebCore/WebCore.xcodeproj/project.pbxproj
r60240 r60275 2917 2917 A833C80D0A2CF25600D57664 /* XMLNames.h in Headers */ = {isa = PBXBuildFile; fileRef = A833C80B0A2CF25600D57664 /* XMLNames.h */; }; 2918 2918 A833C8520A2CF52800D57664 /* SVGElementFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 656581E609D1508D000E61D7 /* SVGElementFactory.cpp */; }; 2919 A83B3AF011ADEFF500458809 /* HTML5ScriptRunner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A83B3AEE11ADEFF500458809 /* HTML5ScriptRunner.cpp */; }; 2920 A83B3AF111ADEFF500458809 /* HTML5ScriptRunner.h in Headers */ = {isa = PBXBuildFile; fileRef = A83B3AEF11ADEFF500458809 /* HTML5ScriptRunner.h */; }; 2919 2921 A83B78FC0CCAFF15000B0825 /* JSSVGFontFaceUriElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A83B78F20CCAFF15000B0825 /* JSSVGFontFaceUriElement.h */; }; 2920 2922 A83B78FD0CCAFF15000B0825 /* JSSVGFontFaceUriElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A83B78F30CCAFF15000B0825 /* JSSVGFontFaceUriElement.cpp */; }; … … 8358 8360 A833C80A0A2CF25600D57664 /* XMLNames.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XMLNames.cpp; sourceTree = "<group>"; }; 8359 8361 A833C80B0A2CF25600D57664 /* XMLNames.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XMLNames.h; sourceTree = "<group>"; }; 8362 A83B3AEE11ADEFF500458809 /* HTML5ScriptRunner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTML5ScriptRunner.cpp; sourceTree = "<group>"; }; 8363 A83B3AEF11ADEFF500458809 /* HTML5ScriptRunner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTML5ScriptRunner.h; sourceTree = "<group>"; }; 8360 8364 A83B78F20CCAFF15000B0825 /* JSSVGFontFaceUriElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSVGFontFaceUriElement.h; sourceTree = "<group>"; }; 8361 8365 A83B78F30CCAFF15000B0825 /* JSSVGFontFaceUriElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSVGFontFaceUriElement.cpp; sourceTree = "<group>"; }; … … 13327 13331 isa = PBXGroup; 13328 13332 children = ( 13329 49484FAE102CF01E00187DD3 /* canvas */,13330 13333 2EAFAF0B10E2AF2D007ED3D6 /* Blob.cpp */, 13331 13334 2EAFAF0C10E2AF2D007ED3D6 /* Blob.h */, 13332 13335 2EAFAF0D10E2AF2D007ED3D6 /* Blob.idl */, 13336 49484FAE102CF01E00187DD3 /* canvas */, 13333 13337 93C441ED0F813A1A00C1A634 /* CollectionCache.cpp */, 13334 13338 93C441EE0F813A1A00C1A634 /* CollectionCache.h */, … … 13371 13375 97E8B35411A23CE200169409 /* HTML5Lexer.cpp */, 13372 13376 97E8B35511A23CE200169409 /* HTML5Lexer.h */, 13377 A83B3AEE11ADEFF500458809 /* HTML5ScriptRunner.cpp */, 13378 A83B3AEF11ADEFF500458809 /* HTML5ScriptRunner.h */, 13373 13379 97E8B3C211A2890800169409 /* HTML5Token.h */, 13374 13380 A871038811A2947000DBD50E /* HTML5Tokenizer.cpp */, … … 19364 19370 B6693EEE11AD63E6003F2770 /* IDBObjectStoreRequest.h in Headers */, 19365 19371 B6693EF311AD6486003F2770 /* JSIDBObjectStoreRequest.h in Headers */, 19372 A83B3AF111ADEFF500458809 /* HTML5ScriptRunner.h in Headers */, 19366 19373 ); 19367 19374 runOnlyForDeploymentPostprocessing = 0; … … 21658 21665 B6693EF211AD6486003F2770 /* JSIDBObjectStoreRequest.cpp in Sources */, 21659 21666 B627FB2D11AD743500E97B72 /* IDBDatabaseImpl.cpp in Sources */, 21667 A83B3AF011ADEFF500458809 /* HTML5ScriptRunner.cpp in Sources */, 21660 21668 ); 21661 21669 runOnlyForDeploymentPostprocessing = 0; -
trunk/WebCore/bindings/js/CachedScriptSourceProvider.h
r57738 r60275 30 30 #include "CachedResourceHandle.h" 31 31 #include "CachedScript.h" 32 #include "JSDOMBinding.h" // for stringToUString 32 33 #include "ScriptSourceProvider.h" 33 34 #include <parser/SourceCode.h> -
trunk/WebCore/dom/ScriptElement.cpp
r59778 r60275 98 98 if (sourceUrl.isEmpty() && data.scriptContent().isEmpty()) 99 99 data.setCreatedByParser(false); 100 // HTML5 Requires that we execute scripts from the parser, not from101 // HTMLTokenizer like we currently do.102 // FIXME: It may not be safe to execute scripts from here if103 // HTMLParser::popOneBlockCommon is not reentrant.104 else if (useHTML5Parser(data.element()->document())) {105 // This is currently an incomplete implementation, see:106 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-incdata107 data.evaluateScript(ScriptSourceCode(data.scriptContent(), data.element()->document()->url())); // FIXME: Provide a real starting line number here108 }109 100 } 110 101 -
trunk/WebCore/dom/ScriptElement.h
r55414 r60275 95 95 Element* m_element; 96 96 CachedResourceHandle<CachedScript> m_cachedScript; 97 bool m_createdByParser; 97 bool m_createdByParser; // HTML5: "parser-inserted" 98 98 bool m_requested; 99 bool m_evaluated; 99 bool m_evaluated; // HTML5: "already started" 100 100 bool m_firedLoad; 101 101 }; -
trunk/WebCore/html/HTML5ScriptRunner.h
r60274 r60275 24 24 */ 25 25 26 #ifndef HTML5 Tokenizer_h27 #define HTML5 Tokenizer_h26 #ifndef HTML5ScriptRunner_h 27 #define HTML5ScriptRunner_h 28 28 29 29 #include "CachedResourceClient.h" 30 #include "HTML5Token.h" 31 #include "SegmentedString.h" 32 #include "Tokenizer.h" 33 #include <wtf/OwnPtr.h> 30 #include "CachedResourceHandle.h" 31 #include <wtf/Noncopyable.h> 32 #include <wtf/PassRefPtr.h> 34 33 35 34 namespace WebCore { 36 35 37 class HTMLDocument; 38 class HTML5TreeBuilder; 39 class HTML5Lexer; 36 class CachedResourceClient; 37 class CachedScript; 38 class Document; 39 class Element; 40 class Frame; 41 class ScriptSourceCode; 40 42 41 // FIXME: This is the wrong layer to hook in the new HTML 5 Lexer, 42 // however HTMLTokenizer is too large and too fragile of a class to hack into. 43 // Eventually we should split all of the HTML lexer logic out from HTMLTokenizer 44 // and then share non-lexer-specific tokenizer logic between HTML5 and the 45 // legacy WebKit HTML lexer. 43 class HTML5ScriptRunner : public Noncopyable { 44 public: 45 HTML5ScriptRunner(Document*, CachedResourceClient*); 46 ~HTML5ScriptRunner(); 46 47 47 // FIXME: This class is far from complete. 48 class HTML5Tokenizer : public Tokenizer, public CachedResourceClient { 49 public: 50 HTML5Tokenizer(HTMLDocument*, bool reportErrors); 51 virtual ~HTML5Tokenizer(); 52 53 virtual void begin(); 54 virtual void write(const SegmentedString&, bool appendData); 55 virtual void end(); 56 virtual void finish(); 57 virtual bool isWaitingForScripts() const; 48 // Processes the passed in script and any pending scripts if possible. 49 bool execute(PassRefPtr<Element> scriptToProcess); 50 // Processes any pending scripts. 51 bool executeScriptsWaitingForLoad(CachedResource*); 58 52 59 53 private: 60 void pumpLexer(); 54 struct PendingScript { 55 RefPtr<Element> element; 56 CachedResourceHandle<CachedScript> cachedScript; 57 // HTML5 has an isReady parameter, however isReady ends up equivalent to 58 // m_document->haveStylesheetsLoaded() && cachedScript->isLoaded() 59 }; 61 60 62 SegmentedString m_source;61 Frame* frame() const; 63 62 64 // We hold m_token here because it might be partially complete.65 HTML5Token m_token;63 bool executeParsingBlockingScripts(); 64 void executePendingScript(); 66 65 67 OwnPtr<HTML5Lexer> m_lexer; 68 OwnPtr<HTML5TreeBuilder> m_treeBuilder; 66 void requestScript(Element*); 67 void runScript(Element*); 68 69 bool isPendingScriptReady(const PendingScript&); 70 ScriptSourceCode sourceFromPendingScript(const PendingScript&, bool& errorOccurred); 71 72 Document* m_document; 73 CachedResourceClient* m_loadNotifier; 74 PendingScript m_parsingBlockingScript; 75 unsigned m_scriptNestingLevel; 69 76 }; 70 77 -
trunk/WebCore/html/HTML5Tokenizer.cpp
r60257 r60275 27 27 #include "HTML5Tokenizer.h" 28 28 29 #include "Element.h" 29 30 #include "HTML5Lexer.h" 31 #include "HTML5ScriptRunner.h" 32 #include "HTML5Token.h" 30 33 #include "HTML5TreeBuilder.h" 34 #include "HTMLDocument.h" 31 35 #include "Node.h" 32 36 #include "NotImplemented.h" … … 37 41 : Tokenizer() 38 42 , m_lexer(new HTML5Lexer) 43 , m_scriptRunner(new HTML5ScriptRunner(document, this)) 39 44 , m_treeBuilder(new HTML5TreeBuilder(m_lexer.get(), document, reportErrors)) 40 45 { … … 52 57 void HTML5Tokenizer::pumpLexer() 53 58 { 59 ASSERT(!m_treeBuilder->isPaused()); 54 60 while (m_lexer->nextToken(m_source, m_token)) { 55 61 m_treeBuilder->constructTreeFromToken(m_token); 56 62 m_token.clear(); 63 64 if (!m_treeBuilder->isPaused()) 65 continue; 66 67 // The parser will pause itself when waiting on a script to load or run. 68 // ScriptRunner executes scripts at the right times and handles reentrancy. 69 bool shouldContinueParsing = m_scriptRunner->execute(m_treeBuilder->takeScriptToProcess()); 70 if (!shouldContinueParsing) { 71 // ASSERT(m_source.isEmpty() || m_treeBuilder->isPaused()); 72 // FIXME: the script runner should either make this call or return a special 73 // value to indicate we should pause. 74 m_treeBuilder->setPaused(true); 75 return; 76 } 57 77 } 58 78 } … … 60 80 void HTML5Tokenizer::write(const SegmentedString& source, bool) 61 81 { 82 // FIXME: This does not yet correctly handle reentrant writes. 62 83 m_source.append(source); 63 pumpLexer(); 84 if (!m_treeBuilder->isPaused()) 85 pumpLexer(); 64 86 } 65 87 66 88 void HTML5Tokenizer::end() 67 89 { 68 m_source.close();69 pumpLexer();90 if (!m_treeBuilder->isPaused()) 91 pumpLexer(); 70 92 m_treeBuilder->finished(); 71 93 } … … 73 95 void HTML5Tokenizer::finish() 74 96 { 75 end(); 97 // finish() indicates we will not receive any more data. If we are waiting on 98 // an external script to load, we can't finish parsing quite yet. 99 m_source.close(); 100 if (!m_treeBuilder->isPaused()) 101 end(); 76 102 } 77 103 78 104 bool HTML5Tokenizer::isWaitingForScripts() const 79 105 { 80 notImplemented(); 81 return false; 106 return m_treeBuilder->isPaused(); 107 } 108 109 void HTML5Tokenizer::resumeParsingAfterScriptExecution() 110 { 111 ASSERT(!m_treeBuilder->isPaused()); 112 // FIXME: This is the wrong write in the case of document.write re-entry. 113 pumpLexer(); 114 if (m_source.isEmpty() && m_source.isClosed()) 115 end(); // The document already finished parsing we were just waiting on scripts when finished() was called. 116 } 117 118 void HTML5Tokenizer::notifyFinished(CachedResource* cachedResource) 119 { 120 bool shouldContinueParsing = m_scriptRunner->executeScriptsWaitingForLoad(cachedResource); 121 if (shouldContinueParsing) { 122 m_treeBuilder->setPaused(false); 123 resumeParsingAfterScriptExecution(); 124 } 125 } 126 127 void HTML5Tokenizer::executeScriptsWaitingForStylesheets() 128 { 129 // FIXME: We can't block for stylesheets yet, because that causes us to re-enter 130 // the parser from executeScriptsWaitingForStylesheets when parsing style tags. 82 131 } 83 132 -
trunk/WebCore/html/HTML5Tokenizer.h
r60257 r60275 35 35 namespace WebCore { 36 36 37 class HTML5Lexer; 38 class HTML5ScriptRunner; 39 class HTML5TreeBuilder; 37 40 class HTMLDocument; 38 class HTML5TreeBuilder;39 class HTML5Lexer;40 41 41 // FIXME: This is the wrong layer to hook in the new HTML 5 Lexer, 42 // however HTMLTokenizer is too large and too fragile of a class to hack into. 43 // Eventually we should split all of the HTML lexer logic out from HTMLTokenizer 44 // and then share non-lexer-specific tokenizer logic between HTML5 and the 45 // legacy WebKit HTML lexer. 46 47 // FIXME: This class is far from complete. 48 class HTML5Tokenizer : public Tokenizer, public CachedResourceClient { 42 // FIXME: The whole Tokenizer class system should be renamed "Parser" 43 // or "ParserController" as the job of this class is to drive parsing process 44 // but it does not itself Tokenize. 45 class HTML5Tokenizer : public Tokenizer, CachedResourceClient { 49 46 public: 50 47 HTML5Tokenizer(HTMLDocument*, bool reportErrors); … … 56 53 virtual void finish(); 57 54 virtual bool isWaitingForScripts() const; 55 virtual void executeScriptsWaitingForStylesheets(); 56 57 // CachedResourceClient 58 virtual void notifyFinished(CachedResource*); 58 59 59 60 private: 60 61 void pumpLexer(); 62 void resumeParsingAfterScriptExecution(); 61 63 62 64 SegmentedString m_source; … … 66 68 67 69 OwnPtr<HTML5Lexer> m_lexer; 70 OwnPtr<HTML5ScriptRunner> m_scriptRunner; 68 71 OwnPtr<HTML5TreeBuilder> m_treeBuilder; 69 72 }; -
trunk/WebCore/html/HTML5TreeBuilder.cpp
r60137 r60275 27 27 #include "HTML5TreeBuilder.h" 28 28 29 #include " Attribute.h"29 #include "Element.h" 30 30 #include "HTML5Lexer.h" 31 31 #include "HTML5Token.h" … … 44 44 : m_document(document) 45 45 , m_reportErrors(reportErrors) 46 , m_isPaused(false) 46 47 , m_lexer(lexer) 47 48 , m_legacyHTMLParser(new HTMLParser(document, reportErrors)) … … 94 95 } 95 96 97 void HTML5TreeBuilder::handleScriptStartTag() 98 { 99 notImplemented(); // The HTML frgment case? 100 m_lexer->setState(HTML5Lexer::ScriptDataState); 101 notImplemented(); // Save insertion mode. 102 } 103 104 void HTML5TreeBuilder::handleScriptEndTag(Element* scriptElement) 105 { 106 ASSERT(!m_scriptToProcess); // Caller never called takeScriptToProcess! 107 notImplemented(); // Save insertion mode and insertion point? 108 109 // Pause ourselves so that parsing stops until the script can be processed by the caller. 110 m_isPaused = true; 111 m_scriptToProcess = scriptElement; 112 } 113 114 PassRefPtr<Element> HTML5TreeBuilder::takeScriptToProcess() 115 { 116 // Unpause ourselves, callers may pause us again when processing the script. 117 // The HTML5 spec is written as though scripts are executed inside the tree 118 // builder. We pause the parser to exit the tree builder, and then resume 119 // before running scripts. 120 m_isPaused = false; 121 return m_scriptToProcess.release(); 122 } 123 96 124 PassRefPtr<Node> HTML5TreeBuilder::passTokenToLegacyParser(HTML5Token& token) 97 125 { 126 if (token.type() == HTML5Token::DOCTYPE) { 127 DoctypeToken doctypeToken; 128 doctypeToken.m_name.append(token.name().characters(), token.name().length()); 129 doctypeToken.m_publicID = token.publicIdentifier(); 130 doctypeToken.m_systemID = token.systemIdentifier(); 131 132 m_legacyHTMLParser->parseDoctypeToken(&doctypeToken); 133 return 0; 134 } 135 136 // For now, we translate into an old-style token for testing. 137 Token oldStyleToken; 138 convertToOldStyle(token, oldStyleToken); 139 140 RefPtr<Node> result = m_legacyHTMLParser->parseToken(&oldStyleToken); 98 141 if (token.type() == HTML5Token::StartTag) { 99 142 // This work is supposed to be done by the parser, but 100 143 // when using the old parser for we have to do this manually. 101 if (token.name() == scriptTag) 102 m_lexer->setState(HTML5Lexer::ScriptDataState); 103 else if (token.name() == textareaTag || token.name() == titleTag) 144 if (token.name() == scriptTag) { 145 handleScriptStartTag(); 146 m_lastScriptElement = static_pointer_cast<Element>(result); 147 } else if (token.name() == textareaTag || token.name() == titleTag) 104 148 m_lexer->setState(HTML5Lexer::RCDATAState); 105 149 else if (token.name() == styleTag || token.name() == iframeTag … … 110 154 m_lexer->setState(HTML5Lexer::PLAINTEXTState); 111 155 } 112 113 if (token.type() == HTML5Token::DOCTYPE) { 114 DoctypeToken doctypeToken; 115 doctypeToken.m_name.append(token.name().characters(), token.name().length()); 116 doctypeToken.m_publicID = token.publicIdentifier(); 117 doctypeToken.m_systemID = token.systemIdentifier(); 118 119 m_legacyHTMLParser->parseDoctypeToken(&doctypeToken); 120 return 0; 121 } 122 123 // For now, we translate into an old-style token for testing. 124 Token oldStyleToken; 125 convertToOldStyle(token, oldStyleToken); 126 127 return m_legacyHTMLParser->parseToken(&oldStyleToken); 156 if (token.type() == HTML5Token::EndTag) { 157 if (token.name() == scriptTag) { 158 if (m_lastScriptElement) { 159 handleScriptEndTag(m_lastScriptElement.get()); 160 m_lastScriptElement = 0; 161 } 162 } 163 } 164 return result.release(); 128 165 } 129 166 -
trunk/WebCore/html/HTML5TreeBuilder.h
r60095 r60275 30 30 #include <wtf/OwnPtr.h> 31 31 #include <wtf/PassRefPtr.h> 32 #include <wtf/RefPtr.h> 32 33 #include <wtf/unicode/Unicode.h> 33 34 34 35 namespace WebCore { 35 36 class Document; 37 class Element; 38 class Frame; 36 39 class HTML5Lexer; 37 40 class HTML5Token; … … 45 48 ~HTML5TreeBuilder(); 46 49 50 void setPaused(bool paused) { m_isPaused = paused; } 51 bool isPaused() { return m_isPaused; } 52 47 53 // The token really should be passed as a const& since it's never modified. 48 54 PassRefPtr<Node> constructTreeFromToken(HTML5Token&); 55 // Must be called when parser is paused before calling the parser again. 56 PassRefPtr<Element> takeScriptToProcess(); 57 58 // Done, close any open tags, etc. 49 59 void finished(); 50 60 … … 52 62 PassRefPtr<Node> passTokenToLegacyParser(HTML5Token&); 53 63 PassRefPtr<Node> processToken(HTML5Token&, UChar currentCharacter = 0); 64 65 void handleScriptStartTag(); 66 void handleScriptEndTag(Element*); 54 67 55 // We could grab m_document off the lexer if we wanted to save space. 56 Document* m_document; 68 Document* m_document; // This is only used by the m_legacyParser for now. 57 69 bool m_reportErrors; 70 bool m_isPaused; 58 71 // HTML5 spec requires that we be able to change the state of the lexer 59 72 // from within parser actions. … … 62 75 // We're re-using logic from the old HTMLParser while this class is being written. 63 76 OwnPtr<HTMLParser> m_legacyHTMLParser; 77 RefPtr<Element> m_lastScriptElement; // FIXME: This is a hack for <script> support. 78 RefPtr<Element> m_scriptToProcess; // Set to a <script> tag which needs processing. 64 79 }; 65 80
Note: See TracChangeset
for help on using the changeset viewer.