diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp')
-rw-r--r-- | src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp | 89 |
1 files changed, 63 insertions, 26 deletions
diff --git a/src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp b/src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp index 9d8136b..d0f3965 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp @@ -167,10 +167,12 @@ HTMLTokenizer::HTMLTokenizer(HTMLDocument* doc, bool reportErrors) , m_requestingScript(false) , m_hasScriptsWaitingForStylesheets(false) , m_timer(this, &HTMLTokenizer::timerFired) + , m_externalScriptsTimer(this, &HTMLTokenizer::executeExternalScriptsTimerFired) , m_doc(doc) , m_parser(new HTMLParser(doc, reportErrors)) , m_inWrite(false) , m_fragment(false) + , m_scriptingPermission(FragmentScriptingAllowed) { begin(); } @@ -186,15 +188,17 @@ HTMLTokenizer::HTMLTokenizer(HTMLViewSourceDocument* doc) , m_requestingScript(false) , m_hasScriptsWaitingForStylesheets(false) , m_timer(this, &HTMLTokenizer::timerFired) + , m_externalScriptsTimer(this, &HTMLTokenizer::executeExternalScriptsTimerFired) , m_doc(doc) , m_parser(0) , m_inWrite(false) , m_fragment(false) + , m_scriptingPermission(FragmentScriptingAllowed) { begin(); } -HTMLTokenizer::HTMLTokenizer(DocumentFragment* frag) +HTMLTokenizer::HTMLTokenizer(DocumentFragment* frag, FragmentScriptingPermission scriptingPermission) : m_buffer(0) , m_scriptCode(0) , m_scriptCodeSize(0) @@ -204,10 +208,12 @@ HTMLTokenizer::HTMLTokenizer(DocumentFragment* frag) , m_requestingScript(false) , m_hasScriptsWaitingForStylesheets(false) , m_timer(this, &HTMLTokenizer::timerFired) + , m_externalScriptsTimer(this, &HTMLTokenizer::executeExternalScriptsTimerFired) , m_doc(frag->document()) - , m_parser(new HTMLParser(frag)) + , m_parser(new HTMLParser(frag, scriptingPermission)) , m_inWrite(false) , m_fragment(true) + , m_scriptingPermission(scriptingPermission) { begin(); } @@ -232,6 +238,8 @@ void HTMLTokenizer::reset() m_scriptCodeSize = m_scriptCodeCapacity = m_scriptCodeResync = 0; m_timer.stop(); + m_externalScriptsTimer.stop(); + m_state.setAllowYield(false); m_state.setForceSynchronous(false); @@ -463,6 +471,13 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state) state = processListing(SegmentedString(m_scriptCode, m_scriptCodeSize), state); RefPtr<Node> node = processToken(); + + if (node && m_scriptingPermission == FragmentScriptingNotAllowed) { + ExceptionCode ec; + node->remove(ec); + node = 0; + } + String scriptString = node ? node->textContent() : ""; m_currentToken.tagName = scriptTag.localName(); m_currentToken.beginTag = false; @@ -552,12 +567,6 @@ HTMLTokenizer::State HTMLTokenizer::scriptExecution(const ScriptSourceCode& sour return state; m_executingScript++; -#if ENABLE(INSPECTOR) - InspectorTimelineAgent* timelineAgent = m_doc->inspectorTimelineAgent(); - if (timelineAgent) - timelineAgent->willEvaluateScriptTag(sourceCode.url().isNull() ? String() : sourceCode.url().string(), sourceCode.startLine()); -#endif - SegmentedString* savedPrependingSrc = m_currentPrependingSrc; SegmentedString prependingSrc; m_currentPrependingSrc = &prependingSrc; @@ -615,11 +624,6 @@ HTMLTokenizer::State HTMLTokenizer::scriptExecution(const ScriptSourceCode& sour m_currentPrependingSrc = savedPrependingSrc; -#if ENABLE(INSPECTOR) - if (timelineAgent) - timelineAgent->didEvaluateScriptTag(); -#endif - return state; } @@ -1507,7 +1511,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString& src, State state) m_scriptTagSrcAttrValue = String(); m_scriptTagCharsetAttrValue = String(); if (m_currentToken.attrs && !m_fragment) { - if (m_doc->frame() && m_doc->frame()->script()->isEnabled()) { + if (m_doc->frame() && m_doc->frame()->script()->canExecuteScripts(NotAboutToExecuteScript)) { if ((a = m_currentToken.attrs->getAttributeItem(srcAttr))) m_scriptTagSrcAttrValue = m_doc->completeURL(deprecatedParseURL(a->value())).string(); } @@ -1615,8 +1619,7 @@ inline bool HTMLTokenizer::continueProcessing(int& processedCount, double startT m_timer.startOneShot(0); #ifdef INSTRUMENT_LAYOUT_SCHEDULING if (currentTime() - startTime > m_tokenizerTimeDelay) - printf("Deferring processing of data because %dms elapsed away from event loop.\n", - int(m_tokenizerTimeDelay * 1000)); + printf("Deferring processing of data because 500ms elapsed away from event loop.\n"); #endif return false; } @@ -1678,9 +1681,8 @@ void HTMLTokenizer::write(const SegmentedString& str, bool appendData) double startTime = currentTime(); #if ENABLE(INSPECTOR) - InspectorTimelineAgent* timelineAgent = m_doc->inspectorTimelineAgent(); - if (timelineAgent) - timelineAgent->willWriteHTML(); + if (InspectorTimelineAgent* timelineAgent = m_doc->inspectorTimelineAgent()) + timelineAgent->willWriteHTML(source.length(), m_lineNumber); #endif Frame* frame = m_doc->frame(); @@ -1805,8 +1807,8 @@ void HTMLTokenizer::write(const SegmentedString& str, bool appendData) #endif #if ENABLE(INSPECTOR) - if (timelineAgent) - timelineAgent->didWriteHTML(); + if (InspectorTimelineAgent* timelineAgent = m_doc->inspectorTimelineAgent()) + timelineAgent->didWriteHTML(m_lineNumber); #endif m_inWrite = wasInWrite; @@ -1816,8 +1818,8 @@ void HTMLTokenizer::write(const SegmentedString& str, bool appendData) if (m_noMoreData && !m_inWrite && !state.loadingExtScript() && !m_executingScript && !m_timer.isActive()) end(); // this actually causes us to be deleted - // After parsing, go ahead and dispatch image beforeload/load events. - ImageLoader::dispatchPendingEvents(); + // After parsing, go ahead and dispatch image beforeload events. + ImageLoader::dispatchPendingBeforeLoadEvents(); } void HTMLTokenizer::stopParsing() @@ -1919,7 +1921,7 @@ void HTMLTokenizer::finish() PassRefPtr<Node> HTMLTokenizer::processToken() { ScriptController* scriptController = (!m_fragment && m_doc->frame()) ? m_doc->frame()->script() : 0; - if (scriptController && scriptController->isEnabled()) + if (scriptController && scriptController->canExecuteScripts(NotAboutToExecuteScript)) // FIXME: Why isn't this m_currentScriptTagStartLineNumber? I suspect this is wrong. scriptController->setEventHandlerLineNumber(m_currentTagStartLineNumber + 1); // Script line numbers are 1 based. if (m_dest > m_buffer) { @@ -2020,6 +2022,11 @@ void HTMLTokenizer::executeScriptsWaitingForStylesheets() void HTMLTokenizer::notifyFinished(CachedResource*) { + executeExternalScriptsIfReady(); +} + +void HTMLTokenizer::executeExternalScriptsIfReady() +{ #ifdef INSTRUMENT_LAYOUT_SCHEDULING if (!m_doc->ownerElement()) printf("script loaded at %d\n", m_doc->elapsedTime()); @@ -2034,7 +2041,12 @@ void HTMLTokenizer::notifyFinished(CachedResource*) return; bool finished = false; + + double startTime = currentTime(); while (!finished && m_pendingScripts.first()->isLoaded()) { + if (!continueExecutingExternalScripts(startTime)) + break; + CachedScript* cs = m_pendingScripts.first().get(); m_pendingScripts.removeFirst(); ASSERT(cache()->disabled() || cs->accessCount() > 0); @@ -2094,6 +2106,31 @@ void HTMLTokenizer::notifyFinished(CachedResource*) } } +void HTMLTokenizer::executeExternalScriptsTimerFired(Timer<HTMLTokenizer>*) +{ + if (m_doc->view() && m_doc->view()->layoutPending() && !m_doc->minimumLayoutDelay()) { + // Restart the timer and do layout first. + m_externalScriptsTimer.startOneShot(0); + return; + } + + // Continue executing external scripts. + executeExternalScriptsIfReady(); +} + +bool HTMLTokenizer::continueExecutingExternalScripts(double startTime) +{ + if (m_externalScriptsTimer.isActive()) + return false; + + if (currentTime() - startTime > m_tokenizerTimeDelay) { + // Schedule the timer to keep processing as soon as possible. + m_externalScriptsTimer.startOneShot(0); + return false; + } + return true; +} + bool HTMLTokenizer::isWaitingForScripts() const { return m_state.loadingExtScript(); @@ -2104,9 +2141,9 @@ void HTMLTokenizer::setSrc(const SegmentedString& source) m_src = source; } -void parseHTMLDocumentFragment(const String& source, DocumentFragment* fragment) +void parseHTMLDocumentFragment(const String& source, DocumentFragment* fragment, FragmentScriptingPermission scriptingPermission) { - HTMLTokenizer tok(fragment); + HTMLTokenizer tok(fragment, scriptingPermission); tok.setForceSynchronous(true); tok.write(source, true); tok.finish(); |