Changeset 205652 in webkit
- Timestamp:
- Sep 8, 2016 10:49:43 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 5 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r205579 r205652 1 2016-09-08 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 ScriptRunner should be driven by PendingScript rather than ScriptElement 4 https://bugs.webkit.org/show_bug.cgi?id=161726 5 6 Reviewed by Ryosuke Niwa. 7 8 * js/dom/document-write-in-error-event-expected.txt: Added. 9 * js/dom/document-write-in-error-event.html: Added. 10 * js/dom/document-write-in-load-event-expected.txt: Added. 11 * js/dom/document-write-in-load-event.html: Added. 12 * js/dom/script-tests/dummy.js: Added. 13 1 14 2016-09-07 Simon Fraser <simon.fraser@apple.com> 2 15 -
trunk/Source/WebCore/ChangeLog
r205650 r205652 1 2016-09-08 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 ScriptRunner should be driven by PendingScript rather than ScriptElement 4 https://bugs.webkit.org/show_bug.cgi?id=161726 5 6 Reviewed by Ryosuke Niwa. 7 8 ScriptRunner is driven by ScriptElement::notifyFinished. While ScriptRunner is driven by this, 9 HTMLScriptRunner does not use it. Instead, HTMLScriptRunner uses PendingScriptClient. As a result, 10 ScriptElement::notifyFinished is used only when the script is annotated with "defer" or "async" 11 while all the external script will load the LoadableScript. It is confusing. 12 This patch removes ScriptElement::notifyFinished and use PendingScript's observability 13 in ScriptRunner instead. 14 15 This patch also fixes the behavior about ignore-destructive-writes counter[1]. When dispatching 16 the load and error events, this ignore-destructive-writes counter should not be incremeneted by 17 this execution. The added tests ensure this behavior. 18 19 [1]: https://html.spec.whatwg.org/multipage/scripting.html#execute-the-script-block 20 21 * dom/ScriptElement.cpp: Drop LoadableScriptClient interface. 22 (WebCore::ScriptElement::prepareScript): Do not use addClient. ScriptRunner use PendingScript::{setClient,clearClient} instead. 23 (WebCore::ScriptElement::executeScriptForScriptRunner): IgnoreDestructiveWriteCountIncrementer will be done in ScriptElement::executeScript. 24 So no need to do it here, that's duplicated. 25 (WebCore::ScriptElement::~ScriptElement): Deleted. ScriptElement does not use addClient/removeClient. 26 (WebCore::ScriptElement::stopLoadRequest): Deleted. 27 (WebCore::ScriptElement::executeScriptForHTMLScriptRunner): Deleted. executeScriptForHTMLScriptRunner and executeScriptForScriptRunner are 28 merged into executeScriptForRunner. 29 (WebCore::ScriptElement::notifyFinished): Deleted. 30 * dom/ScriptElement.h: 31 (WebCore::ScriptElement::~ScriptElement): 32 (WebCore::ScriptElement::willExecuteInOrder): Used in ScriptRunner to determine whether the script is async or defer. 33 (WebCore::ScriptElement::willExecuteWhenDocumentFinishedParsing): Deleted. 34 * dom/ScriptRunner.cpp: 35 (WebCore::ScriptRunner::~ScriptRunner): HashSet's iterator will return `const PendingScript&`. 36 Another option is using HashSet<RefPtr<PendingScript>>. Here, we use a little bit weired const_cast. 37 (WebCore::ScriptRunner::queueScriptForExecution): Use PendingScript::setClient to wait loading. 38 (WebCore::ScriptRunner::notifyFinished): Notify the script ready here. 39 (WebCore::ScriptRunner::timerFired): Use executeScriptForScriptRunner. 40 (WebCore::ScriptRunner::notifyScriptReady): Deleted. 41 * dom/ScriptRunner.h: 42 * html/parser/HTMLScriptRunner.cpp: 43 (WebCore::HTMLScriptRunner::executePendingScriptAndDispatchEvent): Use executeScriptForScriptRunner. 44 1 45 2016-09-08 Alex Christensen <achristensen@webkit.org> 2 46 -
trunk/Source/WebCore/dom/ScriptElement.cpp
r205581 r205652 76 76 } 77 77 78 ScriptElement::~ScriptElement()79 {80 stopLoadRequest();81 }82 83 78 bool ScriptElement::shouldCallFinishedInsertingSubtree(ContainerNode& insertionPoint) 84 79 { … … 246 241 m_willExecuteInOrder = true; 247 242 document.scriptRunner()->queueScriptForExecution(this, *m_loadableScript, ScriptRunner::IN_ORDER_EXECUTION); 248 m_loadableScript->addClient(*this);249 243 } else if (hasSourceAttribute()) { 250 244 ASSERT(m_loadableScript); 251 245 m_element.document().scriptRunner()->queueScriptForExecution(this, *m_loadableScript, ScriptRunner::ASYNC_EXECUTION); 252 m_loadableScript->addClient(*this);253 246 } else { 254 247 // Reset line numbering for nested writes. … … 337 330 } 338 331 339 void ScriptElement::stopLoadRequest()340 {341 if (m_loadableScript) {342 if (!m_willBeParserExecuted)343 m_loadableScript->removeClient(*this);344 m_loadableScript = nullptr;345 }346 }347 348 332 void ScriptElement::executeScriptAndDispatchEvent(LoadableScript& loadableScript) 349 333 { … … 359 343 } 360 344 361 void ScriptElement::executeScriptForScriptRunner(LoadableScript& loadableScript) 362 { 363 ASSERT(!m_willBeParserExecuted); 364 executeScriptAndDispatchEvent(loadableScript); 365 loadableScript.removeClient(*this); 366 } 367 368 void ScriptElement::executeScriptForHTMLScriptRunner(PendingScript& pendingScript) 369 { 370 IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer(&m_element.document()); 345 void ScriptElement::executeScriptForScriptRunner(PendingScript& pendingScript) 346 { 371 347 if (auto* loadableScript = pendingScript.loadableScript()) 372 348 executeScriptAndDispatchEvent(*loadableScript); … … 378 354 } 379 355 380 void ScriptElement::notifyFinished(LoadableScript&)381 {382 ASSERT(!m_willBeParserExecuted);383 384 // LoadableScript possibly invokes this notifyFinished() more than385 // once because ScriptElement doesn't unsubscribe itself from386 // LoadableScript here and does it in execute() instead.387 // We use m_loadableScript to check if this function is already called.388 if (!m_loadableScript)389 return;390 391 if (m_willExecuteInOrder)392 m_element.document().scriptRunner()->notifyScriptReady(this, ScriptRunner::IN_ORDER_EXECUTION);393 else394 m_element.document().scriptRunner()->notifyScriptReady(this, ScriptRunner::ASYNC_EXECUTION);395 396 m_loadableScript = nullptr;397 }398 399 356 bool ScriptElement::ignoresLoadRequest() const 400 357 { -
trunk/Source/WebCore/dom/ScriptElement.h
r205581 r205652 39 39 class ScriptSourceCode; 40 40 41 class ScriptElement : private LoadableScriptClient{41 class ScriptElement { 42 42 public: 43 virtual ~ScriptElement() ;43 virtual ~ScriptElement() { } 44 44 45 45 Element& element() { return m_element; } … … 53 53 void executeScript(const ScriptSourceCode&); 54 54 55 void executeScriptForScriptRunner(LoadableScript&); 56 void executeScriptForHTMLScriptRunner(PendingScript&); 55 void executeScriptForScriptRunner(PendingScript&); 57 56 58 57 // XML parser calls these … … 64 63 bool readyToBeParserExecuted() const { return m_readyToBeParserExecuted; } 65 64 bool willExecuteWhenDocumentFinishedParsing() const { return m_willExecuteWhenDocumentFinishedParsing; } 65 bool willExecuteInOrder() const { return m_willExecuteInOrder; } 66 66 LoadableScript* loadableScript() { return m_loadableScript.get(); } 67 67 … … 93 93 94 94 bool requestClassicScript(const String& sourceURL); 95 void stopLoadRequest();96 97 void notifyFinished(LoadableScript&) override;98 95 99 96 virtual String sourceAttributeValue() const = 0; -
trunk/Source/WebCore/dom/ScriptRunner.cpp
r205581 r205652 41 41 ScriptRunner::~ScriptRunner() 42 42 { 43 for (size_t i = 0; i < m_scriptsToExecuteSoon.size(); ++i) 43 for (auto& pendingScript : m_scriptsToExecuteSoon) { 44 UNUSED_PARAM(pendingScript); 44 45 m_document.decrementLoadEventDelayCount(); 45 for (size_t i = 0; i < m_scriptsToExecuteInOrder.size(); ++i) 46 } 47 for (auto& pendingScript : m_scriptsToExecuteInOrder) { 48 if (pendingScript->watchingForLoad()) 49 pendingScript->clearClient(); 46 50 m_document.decrementLoadEventDelayCount(); 47 for (unsigned i = 0; i < m_pendingAsyncScripts.size(); ++i) 51 } 52 for (auto& pendingScript : m_pendingAsyncScripts) { 53 if (pendingScript->watchingForLoad()) 54 const_cast<PendingScript&>(pendingScript.get()).clearClient(); 48 55 m_document.decrementLoadEventDelayCount(); 56 } 49 57 } 50 58 … … 58 66 m_document.incrementLoadEventDelayCount(); 59 67 68 Ref<PendingScript> pendingScript = PendingScript::create(element, loadableScript); 60 69 switch (executionType) { 61 70 case ASYNC_EXECUTION: 62 m_pendingAsyncScripts.add( scriptElement, PendingScript::create(element, loadableScript));71 m_pendingAsyncScripts.add(pendingScript.copyRef()); 63 72 break; 64 73 65 74 case IN_ORDER_EXECUTION: 66 m_scriptsToExecuteInOrder.append( PendingScript::create(element, loadableScript));75 m_scriptsToExecuteInOrder.append(pendingScript.copyRef()); 67 76 break; 68 77 } 78 pendingScript->setClient(this); 69 79 } 70 80 … … 80 90 } 81 91 82 void ScriptRunner::notify ScriptReady(ScriptElement* scriptElement, ExecutionType executionType)92 void ScriptRunner::notifyFinished(PendingScript& pendingScript) 83 93 { 84 switch (executionType) { 85 case ASYNC_EXECUTION: 86 ASSERT(m_pendingAsyncScripts.contains(scriptElement)); 87 m_scriptsToExecuteSoon.append(m_pendingAsyncScripts.take(scriptElement)->ptr()); 88 break; 89 90 case IN_ORDER_EXECUTION: 94 auto* scriptElement = toScriptElementIfPossible(&pendingScript.element()); 95 ASSERT(scriptElement); 96 if (scriptElement->willExecuteInOrder()) 91 97 ASSERT(!m_scriptsToExecuteInOrder.isEmpty()); 92 break; 98 else { 99 ASSERT(m_pendingAsyncScripts.contains(pendingScript)); 100 m_scriptsToExecuteSoon.append(m_pendingAsyncScripts.take(pendingScript)->ptr()); 93 101 } 102 pendingScript.clearClient(); 94 103 m_timer.startOneShot(0); 95 104 } … … 117 126 ASSERT(scriptElement); 118 127 ASSERT(script->needsLoading()); 119 scriptElement->executeScriptForScriptRunner(*script ->loadableScript());128 scriptElement->executeScriptForScriptRunner(*script); 120 129 m_document.decrementLoadEventDelayCount(); 121 130 } -
trunk/Source/WebCore/dom/ScriptRunner.h
r205581 r205652 26 26 #pragma once 27 27 28 #include "PendingScriptClient.h" 28 29 #include "Timer.h" 29 #include <wtf/Hash Map.h>30 #include <wtf/HashSet.h> 30 31 #include <wtf/Noncopyable.h> 31 32 #include <wtf/Vector.h> … … 38 39 class LoadableScript; 39 40 40 class ScriptRunner {41 class ScriptRunner : private PendingScriptClient { 41 42 WTF_MAKE_NONCOPYABLE(ScriptRunner); WTF_MAKE_FAST_ALLOCATED; 42 43 public: … … 54 55 void timerFired(); 55 56 57 void notifyFinished(PendingScript&) override; 58 56 59 Document& m_document; 57 60 Vector<Ref<PendingScript>> m_scriptsToExecuteInOrder; 58 61 Vector<RefPtr<PendingScript>> m_scriptsToExecuteSoon; // http://www.whatwg.org/specs/web-apps/current-work/#set-of-scripts-that-will-execute-as-soon-as-possible 59 Hash Map<ScriptElement*,Ref<PendingScript>> m_pendingAsyncScripts;62 HashSet<Ref<PendingScript>> m_pendingAsyncScripts; 60 63 Timer m_timer; 61 64 }; -
trunk/Source/WebCore/html/parser/HTMLScriptRunner.cpp
r205581 r205652 122 122 if (auto* scriptElement = toScriptElementIfPossible(&pendingScript->element())) { 123 123 NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel); 124 scriptElement->executeScriptFor HTMLScriptRunner(*pendingScript);124 scriptElement->executeScriptForScriptRunner(*pendingScript); 125 125 } 126 126 ASSERT(!isExecutingScript());
Note: See TracChangeset
for help on using the changeset viewer.