Add a microtask abstraction
authoryoav@yoav.ws <yoav@yoav.ws@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Mar 2015 01:04:40 +0000 (01:04 +0000)
committeryoav@yoav.ws <yoav@yoav.ws@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Mar 2015 01:04:40 +0000 (01:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=137496

Reviewed by Sam Weinig.

Source/WebCore:

This patch adds a microtask abstraction: https://html.spec.whatwg.org/multipage/webappapis.html#microtask
That abstraction is required in order to enable async loading of images,
which is in turn required to enable support for the picture element, as well as
to make sure that the order of properties set on HTMLImageElement has no implications.

* WebCore.vcxproj/WebCore.vcxproj: Add MicroTask.{h,cpp} to the project.
* WebCore.vcxproj/WebCoreTestSupport.vcxproj: Add MicroTaskTest.{h,cpp} to the project.
* WebCore.vcxproj/WebCore.vcxproj.filters: Add MicroTask.{h,cpp} to the project.
* WebCore.vcxproj/WebCoreTestSupport.vcxproj.filters: Add MicroTaskTest.{h,cpp} to the project.
* WebCore.xcodeproj/project.pbxproj: Add MicroTask{,Test}.{h,cpp} to the project.
* dom/Document.h: Add WEBCORE_EXPORT to addConsoleMessage, so it can be used in MicroTaskTest that's in WebCoreTestSupport..
* dom/MicroTask.h: Add a MicroTask interface class. Add a MicroTaskQueue singleton.
(WebCore::MicroTask::~MicroTask):
(WebCore::MicroTask::run): Run the microtask.
* dom/MicroTask.cpp: Implement the MicroTaskQueue singleton.
(WebCore::MicroTaskQueue::singleton): Get a singleton instance of MicroTaskQueue.
(WebCore::MicroTaskQueue::queueMicroTask): Add a microtask to the queue.
(WebCore::MicroTaskQueue::runMicroTasks): Run all the microtasks in the queue and clear it.
* dom/ScriptRunner.cpp: Trigger running of all microtasks in queue.
(WebCore::ScriptRunner::timerFired):
* html/parser/HTMLScriptRunner.cpp: Trigger running of all microtasks in queue.
(WebCore::HTMLScriptRunner::executePendingScriptAndDispatchEvent):
(WebCore::HTMLScriptRunner::executeScriptsWaitingForParsing):
(WebCore::HTMLScriptRunner::runScript):
* testing/Internals.cpp: Add a method to queue a test microtask.
(WebCore::Internals::queueMicroTask):
* testing/Internals.h: Add a method to queue a test microtask.
(WebCore::Internals::queueMicroTask):
* testing/Internals.idl: Expose test microtask queueing to test JS.
* testing/MicroTaskTest.cpp: Add a test class that implements a microtask and prints to the console when it runs.
(WebCore::MicroTaskTest::run): Run the microtask
(WebCore::MicroTaskTest::create): Create a test microtask.
* testing/MicroTaskTest.h: Add a test class that implements a microtask.
(WebCore::MicroTaskTest::run):
(WebCore::MicroTaskTest::create):

LayoutTests:

Adding a test for microtask abstraction.

* fast/dom/microtask-detach.html: Added.
* fast/dom/microtask-detach-expected.txt: Added.
* fast/dom/microtask-inorder.html: Added.
* fast/dom/microtask-inorder-expected.txt: Added.
* fast/dom/microtask-reverse.html: Added.
* fast/dom/microtask-reverse-expected.txt: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@180911 268f45cc-cd09-0410-ab3c-d52691b4dbfc

24 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/microtask-detach-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/microtask-detach.html [new file with mode: 0644]
LayoutTests/fast/dom/microtask-inorder-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/microtask-inorder.html [new file with mode: 0644]
LayoutTests/fast/dom/microtask-reverse-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/microtask-reverse.html [new file with mode: 0644]
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
Source/WebCore/WebCore.vcxproj/WebCoreTestSupport.vcxproj
Source/WebCore/WebCore.vcxproj/WebCoreTestSupport.vcxproj.filters
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/Document.h
Source/WebCore/dom/MicroTask.cpp [new file with mode: 0644]
Source/WebCore/dom/MicroTask.h [new file with mode: 0644]
Source/WebCore/dom/ScriptRunner.cpp
Source/WebCore/html/parser/HTMLScriptRunner.cpp
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebCore/testing/MicroTaskTest.cpp [new file with mode: 0644]
Source/WebCore/testing/MicroTaskTest.h [new file with mode: 0644]

index f639cdb..53868d1 100644 (file)
@@ -1,3 +1,19 @@
+2015-03-02   Yoav Weiss  <yoav@yoav.ws>
+
+        Add a microtask abstraction
+        https://bugs.webkit.org/show_bug.cgi?id=137496
+
+        Reviewed by Sam Weinig.
+
+        Adding a test for microtask abstraction.
+
+        * fast/dom/microtask-detach.html: Added.
+        * fast/dom/microtask-detach-expected.txt: Added.
+        * fast/dom/microtask-inorder.html: Added.
+        * fast/dom/microtask-inorder-expected.txt: Added.
+        * fast/dom/microtask-reverse.html: Added.
+        * fast/dom/microtask-reverse-expected.txt: Added.
+
 2015-03-02  Myles C. Maxfield  <mmaxfield@apple.com>
 
         Last gardening after r177774
diff --git a/LayoutTests/fast/dom/microtask-detach-expected.txt b/LayoutTests/fast/dom/microtask-detach-expected.txt
new file mode 100644 (file)
index 0000000..28cd295
--- /dev/null
@@ -0,0 +1,9 @@
+CONSOLE MESSAGE: line 31: Finished queueing tests.
+CONSOLE MESSAGE: MicroTask #1 has run.
+CONSOLE MESSAGE: MicroTask #0 has run.
+
+
+--------
+Frame: 'frame1'
+--------
+
diff --git a/LayoutTests/fast/dom/microtask-detach.html b/LayoutTests/fast/dom/microtask-detach.html
new file mode 100644 (file)
index 0000000..8977732
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpChildFramesAsText();
+    testRunner.waitUntilDone();
+}
+</script>
+<body>
+<iframe id="frame1"></iframe>
+<iframe id="frame2"></iframe>
+<script>
+
+(function() {
+    var iframe1 = document.querySelector("#frame1").contentWindow;
+    var iframe2Node = document.querySelector("#frame2");
+    var iframe2 = iframe2Node.contentWindow;
+
+    if(iframe2.internals)
+        iframe2.internals.queueMicroTask(2);
+    if(iframe1.internals)
+        iframe1.internals.queueMicroTask(1);
+    if(window.internals)
+        internals.queueMicroTask(0);
+    document.body.removeChild(iframe2Node);
+}());
+
+if (window.GCController)
+    GCController.collect();
+
+console.log("Finished queueing tests.");
+requestAnimationFrame(function() {
+    if (window.testRunner)
+        testRunner.notifyDone();
+});
+</script>
+</body>
diff --git a/LayoutTests/fast/dom/microtask-inorder-expected.txt b/LayoutTests/fast/dom/microtask-inorder-expected.txt
new file mode 100644 (file)
index 0000000..0380b94
--- /dev/null
@@ -0,0 +1,15 @@
+CONSOLE MESSAGE: line 23: Finished queueing tests.
+CONSOLE MESSAGE: MicroTask #2 has run.
+CONSOLE MESSAGE: MicroTask #1 has run.
+CONSOLE MESSAGE: MicroTask #0 has run.
+
+--------
+Frame: 'frame1'
+--------
+
+
+--------
+Frame: 'frame2'
+--------
+
diff --git a/LayoutTests/fast/dom/microtask-inorder.html b/LayoutTests/fast/dom/microtask-inorder.html
new file mode 100644 (file)
index 0000000..79c8e2f
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpChildFramesAsText();
+    testRunner.waitUntilDone();
+}
+</script>
+<iframe id="frame1"></iframe>
+<iframe id="frame2"></iframe>
+<script>
+
+var iframe1 = document.querySelector("#frame1").contentWindow;
+var iframe2 = document.querySelector("#frame2").contentWindow;
+
+if(iframe2.internals)
+    iframe2.internals.queueMicroTask(2);
+if(iframe1.internals)
+    iframe1.internals.queueMicroTask(1);
+if(window.internals)
+    internals.queueMicroTask(0);
+
+console.log("Finished queueing tests.");
+requestAnimationFrame(function() {
+    if (window.testRunner)
+        testRunner.notifyDone();
+});
+</script>
diff --git a/LayoutTests/fast/dom/microtask-reverse-expected.txt b/LayoutTests/fast/dom/microtask-reverse-expected.txt
new file mode 100644 (file)
index 0000000..2ec88bb
--- /dev/null
@@ -0,0 +1,15 @@
+CONSOLE MESSAGE: line 23: Finished queueing tests.
+CONSOLE MESSAGE: MicroTask #0 has run.
+CONSOLE MESSAGE: MicroTask #1 has run.
+CONSOLE MESSAGE: MicroTask #2 has run.
+
+--------
+Frame: 'frame1'
+--------
+
+
+--------
+Frame: 'frame2'
+--------
+
diff --git a/LayoutTests/fast/dom/microtask-reverse.html b/LayoutTests/fast/dom/microtask-reverse.html
new file mode 100644 (file)
index 0000000..b1b4e77
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpChildFramesAsText();
+    testRunner.waitUntilDone();
+}
+</script>
+<iframe id="frame1"></iframe>
+<iframe id="frame2"></iframe>
+<script>
+
+var iframe1 = document.querySelector("#frame1").contentWindow;
+var iframe2 = document.querySelector("#frame2").contentWindow;
+
+if(window.internals)
+    internals.queueMicroTask(0);
+if(iframe1.internals)
+    iframe1.internals.queueMicroTask(1);
+if(iframe2.internals)
+    iframe2.internals.queueMicroTask(2);
+
+console.log("Finished queueing tests.");
+requestAnimationFrame(function() {
+    if (window.testRunner)
+        testRunner.notifyDone();
+});
+</script>
index 32898c7..753464b 100644 (file)
@@ -1370,6 +1370,7 @@ set(WebCore_SOURCES
     dom/MessageEvent.cpp
     dom/MessagePort.cpp
     dom/MessagePortChannel.cpp
+    dom/MicroTask.cpp
     dom/MouseEvent.cpp
     dom/MouseRelatedEvent.cpp
     dom/MutationEvent.cpp
@@ -3154,6 +3155,7 @@ set(WebCoreTestSupport_SOURCES
     testing/InternalSettings.cpp
     testing/Internals.cpp
 
+    testing/MicroTaskTest.cpp
     testing/MockPageOverlayClient.cpp
 
     testing/js/WebCoreTestSupport.cpp
index 2e9efce..a638c06 100644 (file)
@@ -1,3 +1,46 @@
+2015-03-02  Yoav Weiss  <yoav@yoav.ws>
+
+        Add a microtask abstraction
+        https://bugs.webkit.org/show_bug.cgi?id=137496
+
+        Reviewed by Sam Weinig.
+
+        This patch adds a microtask abstraction: https://html.spec.whatwg.org/multipage/webappapis.html#microtask
+        That abstraction is required in order to enable async loading of images,
+        which is in turn required to enable support for the picture element, as well as
+        to make sure that the order of properties set on HTMLImageElement has no implications.
+
+        * WebCore.vcxproj/WebCore.vcxproj: Add MicroTask.{h,cpp} to the project.
+        * WebCore.vcxproj/WebCoreTestSupport.vcxproj: Add MicroTaskTest.{h,cpp} to the project.
+        * WebCore.vcxproj/WebCore.vcxproj.filters: Add MicroTask.{h,cpp} to the project.
+        * WebCore.vcxproj/WebCoreTestSupport.vcxproj.filters: Add MicroTaskTest.{h,cpp} to the project.
+        * WebCore.xcodeproj/project.pbxproj: Add MicroTask{,Test}.{h,cpp} to the project.
+        * dom/Document.h: Add WEBCORE_EXPORT to addConsoleMessage, so it can be used in MicroTaskTest that's in WebCoreTestSupport..
+        * dom/MicroTask.h: Add a MicroTask interface class. Add a MicroTaskQueue singleton.
+        (WebCore::MicroTask::~MicroTask):
+        (WebCore::MicroTask::run): Run the microtask.
+        * dom/MicroTask.cpp: Implement the MicroTaskQueue singleton.
+        (WebCore::MicroTaskQueue::singleton): Get a singleton instance of MicroTaskQueue.
+        (WebCore::MicroTaskQueue::queueMicroTask): Add a microtask to the queue.
+        (WebCore::MicroTaskQueue::runMicroTasks): Run all the microtasks in the queue and clear it.
+        * dom/ScriptRunner.cpp: Trigger running of all microtasks in queue.
+        (WebCore::ScriptRunner::timerFired):
+        * html/parser/HTMLScriptRunner.cpp: Trigger running of all microtasks in queue.
+        (WebCore::HTMLScriptRunner::executePendingScriptAndDispatchEvent):
+        (WebCore::HTMLScriptRunner::executeScriptsWaitingForParsing):
+        (WebCore::HTMLScriptRunner::runScript):
+        * testing/Internals.cpp: Add a method to queue a test microtask.
+        (WebCore::Internals::queueMicroTask):
+        * testing/Internals.h: Add a method to queue a test microtask.
+        (WebCore::Internals::queueMicroTask):
+        * testing/Internals.idl: Expose test microtask queueing to test JS.
+        * testing/MicroTaskTest.cpp: Add a test class that implements a microtask and prints to the console when it runs.
+        (WebCore::MicroTaskTest::run): Run the microtask
+        (WebCore::MicroTaskTest::create): Create a test microtask.
+        * testing/MicroTaskTest.h: Add a test class that implements a microtask.
+        (WebCore::MicroTaskTest::run):
+        (WebCore::MicroTaskTest::create):
+
 2015-03-02  Jeremy Jones  <jeremyj@apple.com>
 
         RenderVideo should not paint the video frame when video is fullscreen.
index 0442bf3..310dbb7 100644 (file)
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="..\dom\MicroTask.cpp" />
     <ClCompile Include="..\dom\MouseEvent.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
     <ClInclude Include="..\dom\MessageEvent.h" />
     <ClInclude Include="..\dom\MessagePort.h" />
     <ClInclude Include="..\dom\MessagePortChannel.h" />
+    <ClInclude Include="..\dom\MicroTask.h" />
     <ClInclude Include="..\dom\MouseEvent.h" />
     <ClInclude Include="..\dom\MouseRelatedEvent.h" />
     <ClInclude Include="..\dom\MutationEvent.h" />
   <ImportGroup Label="ExtensionTargets">
     <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
index 834ef16..b91f08f 100644 (file)
     <ClCompile Include="..\dom\MessagePortChannel.cpp">
       <Filter>dom</Filter>
     </ClCompile>
+    <ClCompile Include="..\dom\MicroTask.cpp">
+      <Filter>dom</Filter>
+    </ClCompile>
     <ClCompile Include="..\dom\MouseEvent.cpp">
       <Filter>dom</Filter>
     </ClCompile>
     <ClInclude Include="..\dom\MessagePortChannel.h">
       <Filter>dom</Filter>
     </ClInclude>
+    <ClInclude Include="..\dom\MicroTask.h">
+      <Filter>dom</Filter>
+    </ClInclude>
     <ClInclude Include="..\dom\MouseEvent.h">
       <Filter>dom</Filter>
     </ClInclude>
       <Filter>platform\win</Filter>
     </MASM>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index 2f81639..433eaf2 100644 (file)
       <ForcedIncludeFiles Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">
       </ForcedIncludeFiles>
     </ClCompile>
+    <ClCompile Include="..\testing\MicroTaskTest.cpp" />
     <ClCompile Include="..\testing\MockPageOverlayClient.cpp" />
     <ClCompile Include="..\testing\InternalSettings.cpp" />
     <ClCompile Include="..\testing\js\WebCoreTestSupport.cpp" />
     <ClInclude Include="..\testing\js\WebCoreTestSupportPrefix.h" />
     <ClInclude Include="..\testing\MallocStatistics.h" />
     <ClInclude Include="..\testing\MemoryInfo.h" />
+    <ClInclude Include="..\testing\MicroTaskTest.h" />
     <ClInclude Include="..\testing\MockCDM.h" />
     <ClInclude Include="..\testing\MockPageOverlayClient.h" />
     <ClInclude Include="..\testing\TypeConversions.h" />
index 64886a8..42ca728 100644 (file)
@@ -39,6 +39,9 @@
     <ClCompile Include="..\testing\js\WebCoreTestSupport.cpp">
       <Filter>testing</Filter>
     </ClCompile>
+    <ClCompile Include="..\testing\MicroTaskTest.cpp">
+      <Filter>testing</Filter>
+    </ClCompile>
     <ClCompile Include="..\testing\MockCDM.cpp">
       <Filter>testing</Filter>
     </ClCompile>
@@ -90,6 +93,9 @@
       <Filter>testing</Filter>
     </ClInclude>
     <ClInclude Include="..\config.h" />
+    <ClInclude Include="..\testing\MicroTaskTest.h">
+      <Filter>testing</Filter>
+    </ClInclude>
     <ClInclude Include="..\testing\MockCDM.h">
       <Filter>testing</Filter>
     </ClInclude>
       <Filter>testing</Filter>
     </ClInclude>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index 4cdebc5..ced8c49 100644 (file)
                536D5A23193E8E0C00CE4CAB /* ParsingUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 536D5A22193E8E0C00CE4CAB /* ParsingUtilities.h */; };
                536D5A25193F40FC00CE4CAB /* SourceSizeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 536D5A24193F40FC00CE4CAB /* SourceSizeList.cpp */; };
                536D5A27193F410B00CE4CAB /* SourceSizeList.h in Headers */ = {isa = PBXBuildFile; fileRef = 536D5A26193F410B00CE4CAB /* SourceSizeList.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               53B895AF19DC7ED9009CAA93 /* MicroTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 53B895AD19DC7C37009CAA93 /* MicroTask.h */; settings = {ATTRIBUTES = (Public, ); }; };
                53C8298D13D8D92700DE2DEB /* RenderFlexibleBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53C8298B13D8D92700DE2DEB /* RenderFlexibleBox.cpp */; };
                53C8298E13D8D92700DE2DEB /* RenderFlexibleBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 53C8298C13D8D92700DE2DEB /* RenderFlexibleBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
                53E29E5E167A8A1900586D3D /* InternalSettingsGenerated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53E29E5C167A8A1900586D3D /* InternalSettingsGenerated.cpp */; };
                CA3BF67E10D99BAE00E6CE53 /* ScrollAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CAE9F90F146441F000C245B0 /* CSSAspectRatioValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CAE9F90D146441F000C245B0 /* CSSAspectRatioValue.cpp */; };
                CAE9F910146441F000C245B0 /* CSSAspectRatioValue.h in Headers */ = {isa = PBXBuildFile; fileRef = CAE9F90E146441F000C245B0 /* CSSAspectRatioValue.h */; };
+               CB8CF0181A9358D4000D510B /* MicroTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB8CF0151A934B43000D510B /* MicroTask.cpp */; };
+               CB8CF01D1A95DE42000D510B /* MicroTaskTest.h in Headers */ = {isa = PBXBuildFile; fileRef = CB8CF01C1A95DE42000D510B /* MicroTaskTest.h */; };
+               CB8CF01F1A95DE59000D510B /* MicroTaskTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB8CF01E1A95DE59000D510B /* MicroTaskTest.cpp */; };
                CCC2B51415F613060048CDD6 /* DeviceClient.h in Headers */ = {isa = PBXBuildFile; fileRef = CCC2B51015F613060048CDD6 /* DeviceClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CCC2B51515F613060048CDD6 /* DeviceController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CCC2B51115F613060048CDD6 /* DeviceController.cpp */; };
                CCC2B51615F613060048CDD6 /* DeviceController.h in Headers */ = {isa = PBXBuildFile; fileRef = CCC2B51215F613060048CDD6 /* DeviceController.h */; settings = {ATTRIBUTES = (Private, ); }; };
                536D5A22193E8E0C00CE4CAB /* ParsingUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParsingUtilities.h; path = parser/ParsingUtilities.h; sourceTree = "<group>"; };
                536D5A24193F40FC00CE4CAB /* SourceSizeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceSizeList.cpp; sourceTree = "<group>"; };
                536D5A26193F410B00CE4CAB /* SourceSizeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceSizeList.h; sourceTree = "<group>"; };
+               53B895AD19DC7C37009CAA93 /* MicroTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MicroTask.h; sourceTree = "<group>"; };
                53C8298B13D8D92700DE2DEB /* RenderFlexibleBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderFlexibleBox.cpp; sourceTree = "<group>"; };
                53C8298C13D8D92700DE2DEB /* RenderFlexibleBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderFlexibleBox.h; sourceTree = "<group>"; };
                53E29E5C167A8A1900586D3D /* InternalSettingsGenerated.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InternalSettingsGenerated.cpp; sourceTree = "<group>"; };
                CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollAnimator.h; sourceTree = "<group>"; };
                CAE9F90D146441F000C245B0 /* CSSAspectRatioValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSAspectRatioValue.cpp; sourceTree = "<group>"; };
                CAE9F90E146441F000C245B0 /* CSSAspectRatioValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSAspectRatioValue.h; sourceTree = "<group>"; };
+               CB8CF0151A934B43000D510B /* MicroTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MicroTask.cpp; sourceTree = "<group>"; };
+               CB8CF01C1A95DE42000D510B /* MicroTaskTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MicroTaskTest.h; sourceTree = "<group>"; };
+               CB8CF01E1A95DE59000D510B /* MicroTaskTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MicroTaskTest.cpp; sourceTree = "<group>"; };
                CCC2B51015F613060048CDD6 /* DeviceClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceClient.h; sourceTree = "<group>"; };
                CCC2B51115F613060048CDD6 /* DeviceController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeviceController.cpp; sourceTree = "<group>"; };
                CCC2B51215F613060048CDD6 /* DeviceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceController.h; sourceTree = "<group>"; };
                                A7BF7EDD14C9175A0014489D /* InternalSettings.h */,
                                A7BF7EDE14C9175A0014489D /* InternalSettings.idl */,
                                A7BE7EDD14C9175A0014489D /* MallocStatistics.h */,
+                               CB8CF01E1A95DE59000D510B /* MicroTaskTest.cpp */,
+                               CB8CF01C1A95DE42000D510B /* MicroTaskTest.h */,
                                A7BE7EDE14C9175A0014489D /* MallocStatistics.idl */,
                                CD5393CB175DCCE600C07123 /* MemoryInfo.h */,
                                CD5393CC175DCCE600C07123 /* MemoryInfo.idl */,
                                E1ADECBD0E76ACF1004A1A5E /* MessagePort.h */,
                                E1ADECC60E76AD1F004A1A5E /* MessagePort.idl */,
                                41BF700A0FE86F49005E8DEC /* MessagePortChannel.h */,
+                               53B895AD19DC7C37009CAA93 /* MicroTask.h */,
+                               CB8CF0151A934B43000D510B /* MicroTask.cpp */,
                                85031B2F0A44EFC700F992E0 /* MouseEvent.cpp */,
                                85031B300A44EFC700F992E0 /* MouseEvent.h */,
                                141B94E509EC4223000E9413 /* MouseEvent.idl */,
                                53ED3FDF167A88E7006762E6 /* JSInternalSettingsGenerated.h in Headers */,
                                A740B59514C935AB00A77FA4 /* JSMallocStatistics.h in Headers */,
                                CD5393D4175E018600C07123 /* JSMemoryInfo.h in Headers */,
+                               CB8CF01D1A95DE42000D510B /* MicroTaskTest.h in Headers */,
                                EBF5121D1696496C0056BD25 /* JSTypeConversions.h in Headers */,
                                CDC26B41160A8CCE0026757B /* MockCDM.h in Headers */,
                                2D97F04819DD4140001EE9C3 /* MockPageOverlayClient.h in Headers */,
                                53C8298E13D8D92700DE2DEB /* RenderFlexibleBox.h in Headers */,
                                508CCA4F13CF106B003151F3 /* RenderFlowThread.h in Headers */,
                                A871DED30A1530C700B12A68 /* RenderFrame.h in Headers */,
+                               53B895AF19DC7ED9009CAA93 /* MicroTask.h in Headers */,
                                0FD3080F117CF7E700A791F7 /* RenderFrameBase.h in Headers */,
                                A871DED10A1530C700B12A68 /* RenderFrameSet.h in Headers */,
                                CDEA7C841276230400B846DD /* RenderFullScreen.h in Headers */,
                                53E29E5E167A8A1900586D3D /* InternalSettingsGenerated.cpp in Sources */,
                                417DA71D13735DFA007C57FB /* JSInternals.cpp in Sources */,
                                A740B5A714C935AF00A77FA4 /* JSInternalSettings.cpp in Sources */,
+                               CB8CF01F1A95DE59000D510B /* MicroTaskTest.cpp in Sources */,
                                53ED3FDE167A88E7006762E6 /* JSInternalSettingsGenerated.cpp in Sources */,
                                A740B59714C935AF00A77FA4 /* JSMallocStatistics.cpp in Sources */,
                                CD5393D3175E018600C07123 /* JSMemoryInfo.cpp in Sources */,
                                B2227A900D00BF220071B782 /* SVGPolygonElement.cpp in Sources */,
                                B2227A930D00BF220071B782 /* SVGPolylineElement.cpp in Sources */,
                                B2227A960D00BF220071B782 /* SVGPreserveAspectRatio.cpp in Sources */,
+                               CB8CF0181A9358D4000D510B /* MicroTask.cpp in Sources */,
                                B543B85717EB758F003BE93A /* SVGPropertyInfo.cpp in Sources */,
                                B2227A990D00BF220071B782 /* SVGRadialGradientElement.cpp in Sources */,
                                B2227A9D0D00BF220071B782 /* SVGRectElement.cpp in Sources */,
index 15444a6..3f11319 100644 (file)
@@ -1262,7 +1262,7 @@ public:
     void addDisabledFieldsetElement() { m_disabledFieldsetElementsCount++; }
     void removeDisabledFieldsetElement() { ASSERT(m_disabledFieldsetElementsCount); m_disabledFieldsetElementsCount--; }
 
-    virtual void addConsoleMessage(MessageSource, MessageLevel, const String& message, unsigned long requestIdentifier = 0) override final;
+    WEBCORE_EXPORT virtual void addConsoleMessage(MessageSource, MessageLevel, const String& message, unsigned long requestIdentifier = 0) override final;
 
     WEBCORE_EXPORT virtual SecurityOrigin* topOrigin() const override final;
 
@@ -1288,6 +1288,7 @@ public:
     bool isPlayingAudio() const { return m_isPlayingAudio; }
     WEBCORE_EXPORT void updateIsPlayingAudio();
     void pageMutedStateDidChange();
+    WeakPtr<Document> createWeakPtr() { return m_weakFactory.createWeakPtr(); }
 
 protected:
     enum ConstructionFlags { Synthesized = 1, NonRenderedPlaceholder = 1 << 1 };
diff --git a/Source/WebCore/dom/MicroTask.cpp b/Source/WebCore/dom/MicroTask.cpp
new file mode 100644 (file)
index 0000000..c786e35
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 Yoav Weiss (yoav@yoav.ws)
+ * Copyright (C) 2015 Akamai Technologies Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "MicroTask.h"
+
+#include "Document.h"
+#include <wtf/text/StringBuilder.h>
+
+namespace WebCore {
+
+MicroTaskQueue& MicroTaskQueue::singleton()
+{
+    ASSERT(isMainThread());
+    static NeverDestroyed<MicroTaskQueue> queue;
+    return queue;
+}
+
+void MicroTaskQueue::queueMicroTask(std::unique_ptr<MicroTask> task)
+{
+    ASSERT(isMainThread());
+    m_microTaskQueue.append(WTF::move(task));
+}
+
+void MicroTaskQueue::runMicroTasks()
+{
+    ASSERT(isMainThread());
+    for (auto& task : m_microTaskQueue)
+        task->run();
+    m_microTaskQueue.clear();
+}
+
+} // namespace WebCore
+
diff --git a/Source/WebCore/dom/MicroTask.h b/Source/WebCore/dom/MicroTask.h
new file mode 100644 (file)
index 0000000..6ec40f1
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 Yoav Weiss (yoav@yoav.ws)
+ * Copyright (C) 2015 Akamai Technologies Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MicroTask_h
+#define MicroTask_h
+
+#include <wtf/NeverDestroyed.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+
+namespace WebCore {
+
+class MicroTask : public RefCounted<MicroTask> {
+public:
+    virtual void run() = 0;
+    virtual ~MicroTask() { }
+};
+
+class MicroTaskQueue {
+    friend NeverDestroyed<MicroTaskQueue>;
+
+public:
+    WEBCORE_EXPORT static MicroTaskQueue& singleton();
+    ~MicroTaskQueue() { }
+
+    WEBCORE_EXPORT void queueMicroTask(std::unique_ptr<MicroTask>);
+
+    void runMicroTasks();
+
+private:
+    MicroTaskQueue() { }
+    Vector<std::unique_ptr<MicroTask>> m_microTaskQueue;
+};
+
+} // namespace WebCore
+
+#endif // MicroTask_h
index ed94da3..c46b78e 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "CachedScript.h"
 #include "Element.h"
+#include "MicroTask.h"
 #include "PendingScript.h"
 #include "ScriptElement.h"
 
@@ -116,6 +117,7 @@ void ScriptRunner::timerFired()
         toScriptElementIfPossible(element.get())->execute(cachedScript);
         m_document.decrementLoadEventDelayCount();
     }
+    MicroTaskQueue::singleton().runMicroTasks();
 }
 
 }
index 41e725f..27dd673 100644 (file)
@@ -36,6 +36,7 @@
 #include "HTMLNames.h"
 #include "HTMLScriptRunnerHost.h"
 #include "IgnoreDestructiveWriteCountIncrementer.h"
+#include "MicroTask.h"
 #include "MutationObserver.h"
 #include "NestingLevelIncrementer.h"
 #include "NotImplemented.h"
@@ -129,8 +130,10 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi
     if (pendingScript.cachedScript() && pendingScript.watchingForLoad())
         stopWatchingForLoad(pendingScript);
 
-    if (!isExecutingScript())
+    if (!isExecutingScript()) {
         MutationObserver::deliverAllMutations();
+        MicroTaskQueue::singleton().runMicroTasks();
+    }
 
     // Clear the pending script before possible rentrancy from executeScript()
     RefPtr<Element> element = pendingScript.releaseElementAndClear();
@@ -231,6 +234,8 @@ bool HTMLScriptRunner::executeScriptsWaitingForParsing()
         if (!m_document)
             return false;
     }
+    if (!isExecutingScript())
+        MicroTaskQueue::singleton().runMicroTasks();
     return true;
 }
 
@@ -293,8 +298,10 @@ void HTMLScriptRunner::runScript(Element* script, const TextPosition& scriptStar
         // every script element, even if it's not ready to execute yet. There's
         // unfortuantely no obvious way to tell if prepareScript is going to
         // execute the script from out here.
-        if (!isExecutingScript())
+        if (!isExecutingScript()) {
             MutationObserver::deliverAllMutations();
+            MicroTaskQueue::singleton().runMicroTasks();
+        }
 
         InsertionPointRecord insertionPointRecord(m_host.inputStream());
         NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel);
index da6e709..5716f84 100644 (file)
@@ -79,6 +79,8 @@
 #include "MediaSessionManager.h"
 #include "MemoryCache.h"
 #include "MemoryInfo.h"
+#include "MicroTask.h"
+#include "MicroTaskTest.h"
 #include "MockPageOverlayClient.h"
 #include "Page.h"
 #include "PageCache.h"
@@ -2532,4 +2534,10 @@ RefPtr<File> Internals::createFile(const String& path)
     return File::create(url.fileSystemPath());
 }
 
+void Internals::queueMicroTask(int testNumber)
+{
+    if (contextDocument())
+        MicroTaskQueue::singleton().queueMicroTask(MicroTaskTest::create(contextDocument()->createWeakPtr(), testNumber));
+}
+
 }
index 1b9b8d7..c878f59 100644 (file)
@@ -366,6 +366,7 @@ public:
     bool isPagePlayingAudio();
 
     RefPtr<File> createFile(const String&);
+    void queueMicroTask(int);
 
 private:
     explicit Internals(Document*);
index 497725c..406a92b 100644 (file)
@@ -322,4 +322,5 @@ enum PageOverlayType {
     boolean isPagePlayingAudio();
     
     File createFile(DOMString url);
+    void queueMicroTask(long testNumber);
 };
diff --git a/Source/WebCore/testing/MicroTaskTest.cpp b/Source/WebCore/testing/MicroTaskTest.cpp
new file mode 100644 (file)
index 0000000..413f2fd
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 Akamai Technologies Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "MicroTaskTest.h"
+
+#include "Document.h"
+
+namespace WebCore {
+
+void MicroTaskTest::run()
+{
+    StringBuilder message;
+    message.append("MicroTask #");
+    message.append(String::number(m_testNumber));
+    message.append(" has run.");
+    if (m_document)
+        m_document->addConsoleMessage(MessageSource::JS, MessageLevel::Debug, message.toString());
+}
+
+std::unique_ptr<MicroTaskTest> MicroTaskTest::create(WeakPtr<Document> document, int testNumber)
+{
+    return std::unique_ptr<MicroTaskTest>(new MicroTaskTest(document, testNumber));
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/testing/MicroTaskTest.h b/Source/WebCore/testing/MicroTaskTest.h
new file mode 100644 (file)
index 0000000..a7422e8
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Akamai Technologies Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef MicroTaskTest_h
+#define MicroTaskTest_h
+
+#include "MicroTask.h"
+#include <wtf/WeakPtr.h>
+
+namespace WebCore {
+
+class Document;
+
+class MicroTaskTest : public MicroTask {
+public:
+    virtual void run() override;
+    WEBCORE_TESTSUPPORT_EXPORT static std::unique_ptr<MicroTaskTest> create(WeakPtr<Document>, int testNumber);
+
+private:
+    MicroTaskTest(WeakPtr<Document> document, int testNumber)
+        : m_document(document)
+        , m_testNumber(testNumber)
+    {
+    }
+
+    WeakPtr<Document> m_document;
+    int m_testNumber;
+};
+
+} // namespace WebCore
+
+#endif