[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
tonyg at chromium.org
tonyg at chromium.org
Wed Dec 22 12:56:43 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit ea72ae98d32b055a702d692809704a69f107e3cd
Author: tonyg at chromium.org <tonyg at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Thu Sep 2 15:45:43 2010 +0000
2010-09-01 Tony Gentilcore <tonyg at chromium.org>
Reviewed by Adam Barth.
Support <script defer> as specified by HTML5
https://bugs.webkit.org/show_bug.cgi?id=40934
* fast/dom/HTMLScriptElement/defer-double-defer-write-expected.txt: Added.
* fast/dom/HTMLScriptElement/defer-double-defer-write.html: Added. Tests that a write of a deferred script from a deferred script will execute when the document is closed. The explicit close is necessary because this is a script created parser.
* fast/dom/HTMLScriptElement/defer-double-write-expected.txt: Added.
* fast/dom/HTMLScriptElement/defer-double-write.html: Added. Tests that a script block written from a deferred script will write into the new document.
* fast/dom/HTMLScriptElement/defer-inline-script-expected.txt: Added.
* fast/dom/HTMLScriptElement/defer-inline-script.html: Added. Tests that inline scripts are not deferred. This is consistent with HTML5 and inconsistent with IE.
* fast/dom/HTMLScriptElement/defer-onbeforeload-expected.txt: Added.
* fast/dom/HTMLScriptElement/defer-onbeforeload.html: Added. Tests that the beforeload event is fired immediately and is cancellable.
* fast/dom/HTMLScriptElement/defer-script-invalid-url-expected.txt: Added.
* fast/dom/HTMLScriptElement/defer-script-invalid-url.html: Added. Tests that deferred scripts with invalid URLs are ignored and that subsequent deferred scripts will be run.
* fast/dom/HTMLScriptElement/defer-write-expected.txt: Added.
* fast/dom/HTMLScriptElement/defer-write.html: Added. Tests that a basic write from a deferred script blows away the document.
* fast/dom/HTMLScriptElement/resources/defer.js: Added.
* fast/dom/HTMLScriptElement/resources/external.js: Added.
* fast/dom/HTMLScriptElement/resources/shouldnotexecute.js: Added.
* fast/dom/HTMLScriptElement/shouldnotexecute.js: Added.
* fast/dom/HTMLScriptElement/two-defer-writes-expected.txt: Added.
* fast/dom/HTMLScriptElement/two-defer-writes.html: Added. Tests that when a document.write from the first deferred script blows away the document, subsequent deferred scripts are not executed.
* http/tests/misc/resources/defer-script.js: Added.
* http/tests/misc/resources/external-script.js: Added.
* http/tests/misc/resources/script-debug-body-background.js: Added.
* http/tests/misc/resources/script-write-slow-stylesheet.js: Added.
* http/tests/misc/resources/slow-defer-script.cgi: Added.
* http/tests/misc/resources/slow-stylesheet.cgi: Added.
* http/tests/misc/script-defer-after-slow-stylesheet-expected.txt: Added.
* http/tests/misc/script-defer-after-slow-stylesheet.html: Added. Tests that deferred scripts respect blocking stylesheets.
* http/tests/misc/script-defer-expected.txt: Added.
* http/tests/misc/script-defer.html: Added. Tests basic ordering of deferred scripts.
2010-09-01 Tony Gentilcore <tonyg at chromium.org>
Reviewed by Adam Barth.
Support <script defer> as specified by HTML5
https://bugs.webkit.org/show_bug.cgi?id=40934
Tests: fast/dom/HTMLScriptElement/defer-double-defer-write.html
fast/dom/HTMLScriptElement/defer-double-write.html
fast/dom/HTMLScriptElement/defer-inline-script.html
fast/dom/HTMLScriptElement/defer-onbeforeload.html
fast/dom/HTMLScriptElement/defer-script-invalid-url.html
fast/dom/HTMLScriptElement/defer-write.html
fast/dom/HTMLScriptElement/two-defer-writes.html
http/tests/misc/script-defer-after-slow-stylesheet.html
http/tests/misc/script-defer.html
* dom/Document.cpp:
(WebCore::Document::open): Allow implicit open for writes() while executing deferred scripts.
* dom/DocumentParser.cpp:
(WebCore::DocumentParser::DocumentParser):
(WebCore::DocumentParser::startParsing):
(WebCore::DocumentParser::prepareToStopParsing): If called when stopped or detached, it shouldn't reset to stopping.
(WebCore::DocumentParser::stopParsing):
(WebCore::DocumentParser::detach):
* dom/DocumentParser.h:
(WebCore::DocumentParser::isParsing):
(WebCore::DocumentParser::isActive):
(WebCore::DocumentParser::isStopping):
(WebCore::DocumentParser::isDetached):
* dom/RawDataDocumentParser.h:
(WebCore::RawDataDocumentParser::finish):
* dom/XMLDocumentParser.cpp:
(WebCore::XMLDocumentParser::append):
(WebCore::XMLDocumentParser::exitText):
* dom/XMLDocumentParserLibxml2.cpp:
(WebCore::XMLDocumentParser::doWrite):
(WebCore::XMLDocumentParser::startElementNs):
(WebCore::XMLDocumentParser::endElementNs):
(WebCore::XMLDocumentParser::characters):
(WebCore::XMLDocumentParser::error):
(WebCore::XMLDocumentParser::processingInstruction):
(WebCore::XMLDocumentParser::cdataBlock):
(WebCore::XMLDocumentParser::comment):
(WebCore::XMLDocumentParser::internalSubset):
(WebCore::XMLDocumentParser::initializeParserContext):
(WebCore::XMLDocumentParser::doEnd):
* html/parser/HTMLDocumentParser.cpp:
(WebCore::HTMLDocumentParser::prepareToStopParsing):
(WebCore::HTMLDocumentParser::pumpTokenizerIfPossible):
(WebCore::HTMLDocumentParser::pumpTokenizer):
(WebCore::HTMLDocumentParser::insert):
(WebCore::HTMLDocumentParser::append):
(WebCore::HTMLDocumentParser::end):
(WebCore::HTMLDocumentParser::attemptToEnd):
(WebCore::HTMLDocumentParser::endIfDelayed):
(WebCore::HTMLDocumentParser::notifyFinished):
* html/parser/HTMLDocumentParser.h:
* html/parser/HTMLScriptRunner.cpp:
(WebCore::HTMLScriptRunner::~HTMLScriptRunner):
(WebCore::HTMLScriptRunner::executeParsingBlockingScript):
(WebCore::HTMLScriptRunner::executePendingScriptAndDispatchEvent):
(WebCore::HTMLScriptRunner::executeScriptsWaitingForParsing):
(WebCore::HTMLScriptRunner::requestDeferredScript):
(WebCore::HTMLScriptRunner::runScript):
* html/parser/HTMLScriptRunner.h:
* loader/ImageDocument.cpp:
(WebCore::ImageDocumentParser::finish):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@66670 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index d91a054..2a8bda1 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,39 @@
+2010-09-01 Tony Gentilcore <tonyg at chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Support <script defer> as specified by HTML5
+ https://bugs.webkit.org/show_bug.cgi?id=40934
+
+ * fast/dom/HTMLScriptElement/defer-double-defer-write-expected.txt: Added.
+ * fast/dom/HTMLScriptElement/defer-double-defer-write.html: Added. Tests that a write of a deferred script from a deferred script will execute when the document is closed. The explicit close is necessary because this is a script created parser.
+ * fast/dom/HTMLScriptElement/defer-double-write-expected.txt: Added.
+ * fast/dom/HTMLScriptElement/defer-double-write.html: Added. Tests that a script block written from a deferred script will write into the new document.
+ * fast/dom/HTMLScriptElement/defer-inline-script-expected.txt: Added.
+ * fast/dom/HTMLScriptElement/defer-inline-script.html: Added. Tests that inline scripts are not deferred. This is consistent with HTML5 and inconsistent with IE.
+ * fast/dom/HTMLScriptElement/defer-onbeforeload-expected.txt: Added.
+ * fast/dom/HTMLScriptElement/defer-onbeforeload.html: Added. Tests that the beforeload event is fired immediately and is cancellable.
+ * fast/dom/HTMLScriptElement/defer-script-invalid-url-expected.txt: Added.
+ * fast/dom/HTMLScriptElement/defer-script-invalid-url.html: Added. Tests that deferred scripts with invalid URLs are ignored and that subsequent deferred scripts will be run.
+ * fast/dom/HTMLScriptElement/defer-write-expected.txt: Added.
+ * fast/dom/HTMLScriptElement/defer-write.html: Added. Tests that a basic write from a deferred script blows away the document.
+ * fast/dom/HTMLScriptElement/resources/defer.js: Added.
+ * fast/dom/HTMLScriptElement/resources/external.js: Added.
+ * fast/dom/HTMLScriptElement/resources/shouldnotexecute.js: Added.
+ * fast/dom/HTMLScriptElement/shouldnotexecute.js: Added.
+ * fast/dom/HTMLScriptElement/two-defer-writes-expected.txt: Added.
+ * fast/dom/HTMLScriptElement/two-defer-writes.html: Added. Tests that when a document.write from the first deferred script blows away the document, subsequent deferred scripts are not executed.
+ * http/tests/misc/resources/defer-script.js: Added.
+ * http/tests/misc/resources/external-script.js: Added.
+ * http/tests/misc/resources/script-debug-body-background.js: Added.
+ * http/tests/misc/resources/script-write-slow-stylesheet.js: Added.
+ * http/tests/misc/resources/slow-defer-script.cgi: Added.
+ * http/tests/misc/resources/slow-stylesheet.cgi: Added.
+ * http/tests/misc/script-defer-after-slow-stylesheet-expected.txt: Added.
+ * http/tests/misc/script-defer-after-slow-stylesheet.html: Added. Tests that deferred scripts respect blocking stylesheets.
+ * http/tests/misc/script-defer-expected.txt: Added.
+ * http/tests/misc/script-defer.html: Added. Tests basic ordering of deferred scripts.
+
2010-09-02 Andrey Kosyakov <caseq at chromium.org>
Reviewed by Yury Semikhatsky.
diff --git a/LayoutTests/editing/selection/5136696-expected.txt b/LayoutTests/fast/dom/HTMLScriptElement/defer-double-defer-write-expected.txt
old mode 100644
new mode 100755
similarity index 100%
copy from LayoutTests/editing/selection/5136696-expected.txt
copy to LayoutTests/fast/dom/HTMLScriptElement/defer-double-defer-write-expected.txt
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/defer-double-defer-write.html b/LayoutTests/fast/dom/HTMLScriptElement/defer-double-defer-write.html
new file mode 100644
index 0000000..0412050
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/defer-double-defer-write.html
@@ -0,0 +1,6 @@
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+</script>
+FAIL
+<script defer src="data:text/javascript,document.write('FAIL'); document.write('<script defer src=\'data:text/javascript,document.write("PASS");\'></script>'); document.close();"></script>
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/defer-double-write-expected.txt b/LayoutTests/fast/dom/HTMLScriptElement/defer-double-write-expected.txt
new file mode 100755
index 0000000..8d04f96
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/defer-double-write-expected.txt
@@ -0,0 +1 @@
+1 2
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/defer-double-write.html b/LayoutTests/fast/dom/HTMLScriptElement/defer-double-write.html
new file mode 100644
index 0000000..e55e1d3
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/defer-double-write.html
@@ -0,0 +1,6 @@
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+</script>
+FAIL
+<script defer src="data:text/javascript,document.writeln(1); document.write('<script src=\'data:text/javascript,document.writeln(2)\'></script>');"></script>
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/defer-inline-script-expected.txt b/LayoutTests/fast/dom/HTMLScriptElement/defer-inline-script-expected.txt
new file mode 100755
index 0000000..beaaad8
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/defer-inline-script-expected.txt
@@ -0,0 +1,4 @@
+Checks that inline scripts are not deferred.
+1
+2
+
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/defer-inline-script.html b/LayoutTests/fast/dom/HTMLScriptElement/defer-inline-script.html
new file mode 100644
index 0000000..a15c201
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/defer-inline-script.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+Checks that inline scripts are not deferred.
+<div id="console"></div>
+<script src="data:text/javascript,debug(2);" defer></script>
+<script defer>
+ debug(1);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload-expected.txt b/LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload-expected.txt
new file mode 100644
index 0000000..2eb56c9
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload-expected.txt
@@ -0,0 +1,7 @@
+Checks that deferred scripts fire onbeforeload immediately and that it is cancellable.
+cancelled onbeforeload defer
+onbeforeload defer
+onbeforeload external
+external
+defer
+
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload.html b/LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload.html
new file mode 100644
index 0000000..a22b184
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+Checks that deferred scripts fire onbeforeload immediately and that it is cancellable.
+<div id="console"></div>
+<script src="resources/shouldnotexecute.js" onbeforeload="debug('cancelled onbeforeload defer'); return false;" defer></script>
+<script src="resources/defer.js" onbeforeload="debug('onbeforeload defer'); return true;" defer></script>
+<script src="resources/external.js" onbeforeload="debug('onbeforeload external'); return true;"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/defer-script-invalid-url-expected.txt b/LayoutTests/fast/dom/HTMLScriptElement/defer-script-invalid-url-expected.txt
new file mode 100644
index 0000000..045af1d
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/defer-script-invalid-url-expected.txt
@@ -0,0 +1,3 @@
+Checks that deferred scripts with invalid URLs are ignored and subsequent deferred scripts executed.
+defer
+
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/defer-script-invalid-url.html b/LayoutTests/fast/dom/HTMLScriptElement/defer-script-invalid-url.html
new file mode 100644
index 0000000..bf6cee4
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/defer-script-invalid-url.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+Checks that deferred scripts with invalid URLs are ignored and subsequent deferred scripts executed.
+<div id="console"></div>
+<script src="http://localhost:999999/" defer></script>
+<script src="resources/defer.js" defer></script>
+</body>
+</html>
diff --git a/LayoutTests/editing/selection/5136696-expected.txt b/LayoutTests/fast/dom/HTMLScriptElement/defer-write-expected.txt
similarity index 100%
copy from LayoutTests/editing/selection/5136696-expected.txt
copy to LayoutTests/fast/dom/HTMLScriptElement/defer-write-expected.txt
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/defer-write.html b/LayoutTests/fast/dom/HTMLScriptElement/defer-write.html
new file mode 100644
index 0000000..0c0bbff
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/defer-write.html
@@ -0,0 +1,6 @@
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+</script>
+FAIL
+<script defer src="data:text/javascript,document.write('PASS');"></script>
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/resources/defer.js b/LayoutTests/fast/dom/HTMLScriptElement/resources/defer.js
new file mode 100644
index 0000000..fc67db4
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/resources/defer.js
@@ -0,0 +1 @@
+debug("defer");
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/resources/external.js b/LayoutTests/fast/dom/HTMLScriptElement/resources/external.js
new file mode 100644
index 0000000..fbad465
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/resources/external.js
@@ -0,0 +1 @@
+debug("external");
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/resources/shouldnotexecute.js b/LayoutTests/fast/dom/HTMLScriptElement/resources/shouldnotexecute.js
new file mode 100644
index 0000000..c0d6954
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/resources/shouldnotexecute.js
@@ -0,0 +1 @@
+debug("FAIL");
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/shouldnotexecute.js b/LayoutTests/fast/dom/HTMLScriptElement/shouldnotexecute.js
new file mode 100644
index 0000000..fc67db4
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/shouldnotexecute.js
@@ -0,0 +1 @@
+debug("defer");
diff --git a/LayoutTests/editing/selection/5136696-expected.txt b/LayoutTests/fast/dom/HTMLScriptElement/two-defer-writes-expected.txt
similarity index 100%
copy from LayoutTests/editing/selection/5136696-expected.txt
copy to LayoutTests/fast/dom/HTMLScriptElement/two-defer-writes-expected.txt
diff --git a/LayoutTests/fast/dom/HTMLScriptElement/two-defer-writes.html b/LayoutTests/fast/dom/HTMLScriptElement/two-defer-writes.html
new file mode 100644
index 0000000..4b0d378
--- /dev/null
+++ b/LayoutTests/fast/dom/HTMLScriptElement/two-defer-writes.html
@@ -0,0 +1,7 @@
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+</script>
+FAIL
+<script defer src="data:text/javascript,document.write('PASS');"></script>
+<script defer src="data:text/javascript,document.write('FAIL');"></script>
diff --git a/LayoutTests/http/tests/misc/resources/defer-script.js b/LayoutTests/http/tests/misc/resources/defer-script.js
new file mode 100644
index 0000000..fc67db4
--- /dev/null
+++ b/LayoutTests/http/tests/misc/resources/defer-script.js
@@ -0,0 +1 @@
+debug("defer");
diff --git a/LayoutTests/http/tests/misc/resources/external-script.js b/LayoutTests/http/tests/misc/resources/external-script.js
new file mode 100644
index 0000000..fbad465
--- /dev/null
+++ b/LayoutTests/http/tests/misc/resources/external-script.js
@@ -0,0 +1 @@
+debug("external");
diff --git a/LayoutTests/http/tests/misc/resources/script-debug-body-background.js b/LayoutTests/http/tests/misc/resources/script-debug-body-background.js
new file mode 100644
index 0000000..6fbe7a1
--- /dev/null
+++ b/LayoutTests/http/tests/misc/resources/script-debug-body-background.js
@@ -0,0 +1 @@
+shouldBeEqualToString("getComputedStyle(document.body)['background-color']", "rgb(255, 0, 0)");
diff --git a/LayoutTests/http/tests/misc/resources/script-write-slow-stylesheet.js b/LayoutTests/http/tests/misc/resources/script-write-slow-stylesheet.js
new file mode 100644
index 0000000..ed11eb5
--- /dev/null
+++ b/LayoutTests/http/tests/misc/resources/script-write-slow-stylesheet.js
@@ -0,0 +1 @@
+document.write('<link rel="stylesheet" href="http://127.0.0.1:8000/misc/resources/slow-stylesheet.cgi">');
diff --git a/LayoutTests/http/tests/misc/resources/slow-defer-script.cgi b/LayoutTests/http/tests/misc/resources/slow-defer-script.cgi
new file mode 100755
index 0000000..a98d3d5
--- /dev/null
+++ b/LayoutTests/http/tests/misc/resources/slow-defer-script.cgi
@@ -0,0 +1,5 @@
+#!/usr/bin/perl -w
+
+print "Content-type: text/javascript\n\n";
+sleep(0.5);
+print "debug('slowDefer');\n";
diff --git a/LayoutTests/http/tests/misc/resources/slow-stylesheet.cgi b/LayoutTests/http/tests/misc/resources/slow-stylesheet.cgi
new file mode 100755
index 0000000..fcddca4
--- /dev/null
+++ b/LayoutTests/http/tests/misc/resources/slow-stylesheet.cgi
@@ -0,0 +1,5 @@
+#!/usr/bin/perl -w
+
+print "Content-type: text/css\n\n";
+sleep(0.5);
+print "body { background-color: #FF0000 }\n";
diff --git a/LayoutTests/http/tests/misc/script-defer-after-slow-stylesheet-expected.txt b/LayoutTests/http/tests/misc/script-defer-after-slow-stylesheet-expected.txt
new file mode 100644
index 0000000..5245763
--- /dev/null
+++ b/LayoutTests/http/tests/misc/script-defer-after-slow-stylesheet-expected.txt
@@ -0,0 +1,10 @@
+This tests that an inline slow stylesheet executes before deferred scripts.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS getComputedStyle(document.body)['background-color'] is "rgb(255, 0, 0)"
+DOMContentLoaded
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/misc/script-defer-after-slow-stylesheet.html b/LayoutTests/http/tests/misc/script-defer-after-slow-stylesheet.html
new file mode 100644
index 0000000..06ec849
--- /dev/null
+++ b/LayoutTests/http/tests/misc/script-defer-after-slow-stylesheet.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<link rel="stylesheet" href="../../js-test-resources/js-test-style.css">
+<script src="../../js-test-resources/js-test-pre.js"></script>
+</head>
+<body>
+<dvi id="description"></div>
+<div id="console"></div>
+<script type="text/javascript">
+description('This tests that an inline slow stylesheet executes before deferred scripts.');
+
+var jsTestIsAsync = true;
+
+document.addEventListener("DOMContentLoaded", function() {
+ debug('DOMContentLoaded');
+
+ finishJSTest();
+}, false);
+</script>
+
+<script src="http://127.0.0.1:8000/misc/resources/script-debug-body-background.
+js" defer="defer"></script>
+<link rel="stylesheet" href="http://127.0.0.1:8000/misc/resources/slow-styleshe
+et.cgi">
+<script>
+var successfullyParsed = true;
+</script>
+<script src="../../js-test-resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/misc/script-defer-expected.txt b/LayoutTests/http/tests/misc/script-defer-expected.txt
new file mode 100644
index 0000000..bfcaa6e
--- /dev/null
+++ b/LayoutTests/http/tests/misc/script-defer-expected.txt
@@ -0,0 +1,8 @@
+This tests for proper execution order of scripts with the defer attribute https://bugs.webkit.org/show_bug.cgi?id=20710.
+external
+inline
+slowDefer
+defer
+DOMContentLoaded
+load
+
diff --git a/LayoutTests/http/tests/misc/script-defer.html b/LayoutTests/http/tests/misc/script-defer.html
new file mode 100644
index 0000000..95cf8b3
--- /dev/null
+++ b/LayoutTests/http/tests/misc/script-defer.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<link rel="stylesheet" href="../../js-test-resources/js-test-style.css">
+<script src="../../js-test-resources/js-test-pre.js"></script>
+</head>
+<body onload="debug('load')">
+This tests for proper execution order of scripts with the defer attribute <a href="https://bugs.webkit.org/show_bug.cgi?id=20710">https://bugs.webkit.org/show_bug.cgi?id=20710</a>.
+<div id="console"></div>
+
+<script type="text/javascript">
+document.addEventListener("DOMContentLoaded", function() {
+ debug('DOMContentLoaded');
+}, false);
+</script>
+<script src="http://127.0.0.1:8000/misc/resources/slow-defer-script.cgi" defer="DEFER"></script>
+<script src="http://127.0.0.1:8000/misc/resources/defer-script.js" defer="DEFER"></script>
+<script src="http://127.0.0.1:8000/misc/resources/external-script.js"></script>
+<script>
+debug("inline");
+</script>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index ccb2831..454d91a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,72 @@
+2010-09-01 Tony Gentilcore <tonyg at chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Support <script defer> as specified by HTML5
+ https://bugs.webkit.org/show_bug.cgi?id=40934
+
+ Tests: fast/dom/HTMLScriptElement/defer-double-defer-write.html
+ fast/dom/HTMLScriptElement/defer-double-write.html
+ fast/dom/HTMLScriptElement/defer-inline-script.html
+ fast/dom/HTMLScriptElement/defer-onbeforeload.html
+ fast/dom/HTMLScriptElement/defer-script-invalid-url.html
+ fast/dom/HTMLScriptElement/defer-write.html
+ fast/dom/HTMLScriptElement/two-defer-writes.html
+ http/tests/misc/script-defer-after-slow-stylesheet.html
+ http/tests/misc/script-defer.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::open): Allow implicit open for writes() while executing deferred scripts.
+ * dom/DocumentParser.cpp:
+ (WebCore::DocumentParser::DocumentParser):
+ (WebCore::DocumentParser::startParsing):
+ (WebCore::DocumentParser::prepareToStopParsing): If called when stopped or detached, it shouldn't reset to stopping.
+ (WebCore::DocumentParser::stopParsing):
+ (WebCore::DocumentParser::detach):
+ * dom/DocumentParser.h:
+ (WebCore::DocumentParser::isParsing):
+ (WebCore::DocumentParser::isActive):
+ (WebCore::DocumentParser::isStopping):
+ (WebCore::DocumentParser::isDetached):
+ * dom/RawDataDocumentParser.h:
+ (WebCore::RawDataDocumentParser::finish):
+ * dom/XMLDocumentParser.cpp:
+ (WebCore::XMLDocumentParser::append):
+ (WebCore::XMLDocumentParser::exitText):
+ * dom/XMLDocumentParserLibxml2.cpp:
+ (WebCore::XMLDocumentParser::doWrite):
+ (WebCore::XMLDocumentParser::startElementNs):
+ (WebCore::XMLDocumentParser::endElementNs):
+ (WebCore::XMLDocumentParser::characters):
+ (WebCore::XMLDocumentParser::error):
+ (WebCore::XMLDocumentParser::processingInstruction):
+ (WebCore::XMLDocumentParser::cdataBlock):
+ (WebCore::XMLDocumentParser::comment):
+ (WebCore::XMLDocumentParser::internalSubset):
+ (WebCore::XMLDocumentParser::initializeParserContext):
+ (WebCore::XMLDocumentParser::doEnd):
+ * html/parser/HTMLDocumentParser.cpp:
+ (WebCore::HTMLDocumentParser::prepareToStopParsing):
+ (WebCore::HTMLDocumentParser::pumpTokenizerIfPossible):
+ (WebCore::HTMLDocumentParser::pumpTokenizer):
+ (WebCore::HTMLDocumentParser::insert):
+ (WebCore::HTMLDocumentParser::append):
+ (WebCore::HTMLDocumentParser::end):
+ (WebCore::HTMLDocumentParser::attemptToEnd):
+ (WebCore::HTMLDocumentParser::endIfDelayed):
+ (WebCore::HTMLDocumentParser::notifyFinished):
+ * html/parser/HTMLDocumentParser.h:
+ * html/parser/HTMLScriptRunner.cpp:
+ (WebCore::HTMLScriptRunner::~HTMLScriptRunner):
+ (WebCore::HTMLScriptRunner::executeParsingBlockingScript):
+ (WebCore::HTMLScriptRunner::executePendingScriptAndDispatchEvent):
+ (WebCore::HTMLScriptRunner::executeScriptsWaitingForParsing):
+ (WebCore::HTMLScriptRunner::requestDeferredScript):
+ (WebCore::HTMLScriptRunner::runScript):
+ * html/parser/HTMLScriptRunner.h:
+ * loader/ImageDocument.cpp:
+ (WebCore::ImageDocumentParser::finish):
+
2010-09-02 Andrey Kosyakov <caseq at chromium.org>
Reviewed by Yury Semikhatsky.
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index 741f98a..dbf447d 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -1823,7 +1823,7 @@ void Document::open(Document* ownerDocument)
if (m_frame) {
ScriptableDocumentParser* parser = scriptableDocumentParser();
- if (m_frame->loader()->isLoadingMainResource() || (parser && parser->isExecutingScript()))
+ if (m_frame->loader()->isLoadingMainResource() || (parser && parser->isParsing() && parser->isExecutingScript()))
return;
if (m_frame->loader()->state() == FrameStateProvisional)
diff --git a/WebCore/dom/DocumentParser.cpp b/WebCore/dom/DocumentParser.cpp
index cc4c61b..639860a 100644
--- a/WebCore/dom/DocumentParser.cpp
+++ b/WebCore/dom/DocumentParser.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
DocumentParser::DocumentParser(Document* document)
- : m_parserStopped(false)
+ : m_state(ParsingState)
, m_document(document)
{
ASSERT(document);
@@ -45,8 +45,25 @@ DocumentParser::~DocumentParser()
ASSERT(!m_document);
}
+void DocumentParser::startParsing()
+{
+ m_state = ParsingState;
+}
+
+void DocumentParser::prepareToStopParsing()
+{
+ if (m_state == ParsingState)
+ m_state = StoppingState;
+}
+
+void DocumentParser::stopParsing()
+{
+ m_state = StoppedState;
+}
+
void DocumentParser::detach()
{
+ m_state = DetachedState;
m_document = 0;
}
diff --git a/WebCore/dom/DocumentParser.h b/WebCore/dom/DocumentParser.h
index 3c28856..7cc9e7b 100644
--- a/WebCore/dom/DocumentParser.h
+++ b/WebCore/dom/DocumentParser.h
@@ -57,12 +57,29 @@ public:
// FIXME: processingData() is only used by DocumentLoader::isLoadingInAPISense
// and is very unclear as to what it actually means. The LegacyHTMLDocumentParser
- // used to implements it.
+ // used to implement it.
virtual bool processingData() const { return false; }
// document() will return 0 after detach() is called.
Document* document() const { ASSERT(m_document); return m_document; }
- bool isDetached() const { return !m_document; }
+
+ bool isParsing() const { return m_state == ParsingState; }
+ bool isStopping() const { return m_state == StoppingState; }
+ bool isStopped() const { return m_state >= StoppedState; }
+ bool isDetached() const { return m_state == DetachedState; }
+
+ // FIXME: Is this necessary? Does XMLDocumentParserLibxml2 really need to set this?
+ virtual void startParsing();
+
+ // prepareToStop() is used when the EOF token is encountered and parsing is to be
+ // stopped normally.
+ virtual void prepareToStopParsing();
+
+ // stopParsing() is used when a load is canceled/stopped.
+ // stopParsing() is currently different from detach(), but shouldn't be.
+ // It should NOT be ok to call any methods on DocumentParser after either
+ // detach() or stopParsing() but right now only detach() will ASSERT.
+ virtual void stopParsing();
// Document is expected to detach the parser before releasing its ref.
// After detach, m_document is cleared. The parser will unwind its
@@ -71,22 +88,18 @@ public:
// detach is called.
virtual void detach();
- // stopParsing() is used when a load is canceled/stopped.
- // stopParsing() is currently different from detach(), but shouldn't be.
- // It should NOT be ok to call any methods on DocumentParser after either
- // detach() or stopParsing() but right now only detach() will ASSERT.
- virtual void stopParsing() { m_parserStopped = true; }
-
protected:
DocumentParser(Document*);
- // The parser has buffers, so parsing may continue even after
- // it stops receiving data. We use m_parserStopped to stop the parser
- // even when it has buffered data.
- // FIXME: m_document = 0 could be changed to mean "parser stopped".
- bool m_parserStopped;
-
private:
+ enum ParserState {
+ ParsingState,
+ StoppingState,
+ StoppedState,
+ DetachedState
+ };
+ ParserState m_state;
+
// Every DocumentParser needs a pointer back to the document.
// m_document will be 0 after the parser is stopped.
Document* m_document;
diff --git a/WebCore/dom/RawDataDocumentParser.h b/WebCore/dom/RawDataDocumentParser.h
index 093ddaf..9ca36f4 100644
--- a/WebCore/dom/RawDataDocumentParser.h
+++ b/WebCore/dom/RawDataDocumentParser.h
@@ -39,7 +39,7 @@ protected:
virtual void finish()
{
- if (!m_parserStopped && !isDetached())
+ if (!isStopped())
document()->finishedParsing();
}
diff --git a/WebCore/dom/XMLDocumentParser.cpp b/WebCore/dom/XMLDocumentParser.cpp
index 4b76472..5fb8b54 100644
--- a/WebCore/dom/XMLDocumentParser.cpp
+++ b/WebCore/dom/XMLDocumentParser.cpp
@@ -132,7 +132,7 @@ void XMLDocumentParser::append(const SegmentedString& s)
if (m_sawXSLTransform || !m_sawFirstElement)
m_originalSourceForTransform += parseString;
- if (isDetached() || m_parserStopped || m_sawXSLTransform)
+ if (isStopped() || m_sawXSLTransform)
return;
if (m_parserPaused) {
@@ -190,7 +190,7 @@ static inline String toString(const xmlChar* str, unsigned len)
void XMLDocumentParser::exitText()
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (!m_currentNode || !m_currentNode->isTextNode())
diff --git a/WebCore/dom/XMLDocumentParserLibxml2.cpp b/WebCore/dom/XMLDocumentParserLibxml2.cpp
index db94c50..d99ab4b 100644
--- a/WebCore/dom/XMLDocumentParserLibxml2.cpp
+++ b/WebCore/dom/XMLDocumentParserLibxml2.cpp
@@ -660,7 +660,7 @@ void XMLDocumentParser::doWrite(const String& parseString)
// JavaScript (which may be run under the xmlParseChunk callstack) may
// cause the parser to be stopped or detached.
- if (isDetached() || m_parserStopped)
+ if (isStopped())
return;
}
@@ -733,7 +733,7 @@ static inline void handleElementAttributes(Element* newElement, const xmlChar**
void XMLDocumentParser::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xmlPrefix, const xmlChar* xmlURI, int nb_namespaces,
const xmlChar** libxmlNamespaces, int nb_attributes, int nb_defaulted, const xmlChar** libxmlAttributes)
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_parserPaused) {
@@ -822,7 +822,7 @@ void XMLDocumentParser::startElementNs(const xmlChar* xmlLocalName, const xmlCha
void XMLDocumentParser::endElementNs()
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_parserPaused) {
@@ -906,7 +906,7 @@ void XMLDocumentParser::endElementNs()
void XMLDocumentParser::characters(const xmlChar* s, int len)
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_parserPaused) {
@@ -921,7 +921,7 @@ void XMLDocumentParser::characters(const xmlChar* s, int len)
void XMLDocumentParser::error(ErrorType type, const char* message, va_list args)
{
- if (m_parserStopped)
+ if (isStopped())
return;
#if COMPILER(MSVC) || COMPILER(RVCT)
@@ -945,7 +945,7 @@ void XMLDocumentParser::error(ErrorType type, const char* message, va_list args)
void XMLDocumentParser::processingInstruction(const xmlChar* target, const xmlChar* data)
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_parserPaused) {
@@ -979,7 +979,7 @@ void XMLDocumentParser::processingInstruction(const xmlChar* target, const xmlCh
void XMLDocumentParser::cdataBlock(const xmlChar* s, int len)
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_parserPaused) {
@@ -997,7 +997,7 @@ void XMLDocumentParser::cdataBlock(const xmlChar* s, int len)
void XMLDocumentParser::comment(const xmlChar* s)
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_parserPaused) {
@@ -1034,7 +1034,7 @@ void XMLDocumentParser::endDocument()
void XMLDocumentParser::internalSubset(const xmlChar* name, const xmlChar* externalID, const xmlChar* systemID)
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_parserPaused) {
@@ -1294,7 +1294,7 @@ void XMLDocumentParser::initializeParserContext(const char* chunk)
sax.ignorableWhitespace = ignorableWhitespaceHandler;
sax.entityDecl = xmlSAX2EntityDecl;
sax.initialized = XML_SAX2_MAGIC;
- m_parserStopped = false;
+ DocumentParser::startParsing();
m_sawError = false;
m_sawXSLTransform = false;
m_sawFirstElement = false;
@@ -1318,11 +1318,11 @@ void XMLDocumentParser::doEnd()
document()->setParsing(false); // Make the doc think it's done, so it will apply xsl sheets.
document()->styleSelectorChanged(RecalcStyleImmediately);
document()->setParsing(true);
- m_parserStopped = true;
+ DocumentParser::stopParsing();
}
#endif
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_context) {
diff --git a/WebCore/dom/XMLDocumentParserQt.cpp b/WebCore/dom/XMLDocumentParserQt.cpp
index dfd6fb1..c1f59ac 100644
--- a/WebCore/dom/XMLDocumentParserQt.cpp
+++ b/WebCore/dom/XMLDocumentParserQt.cpp
@@ -199,7 +199,7 @@ void XMLDocumentParser::doWrite(const String& parseString)
void XMLDocumentParser::initializeParserContext(const char*)
{
- m_parserStopped = false;
+ DocumentParser::startParsing();
m_sawError = false;
m_sawXSLTransform = false;
m_sawFirstElement = false;
@@ -213,7 +213,7 @@ void XMLDocumentParser::doEnd()
document()->setParsing(false); // Make the doc think it's done, so it will apply xsl sheets.
document()->styleSelectorChanged(RecalcStyleImmediately);
document()->setParsing(true);
- m_parserStopped = true;
+ DocumentParser::stopParsing();
}
#endif
@@ -350,7 +350,7 @@ static inline void handleElementAttributes(Element* newElement, const QXmlStream
void XMLDocumentParser::parse()
{
- while (!m_parserStopped && !m_parserPaused && !m_stream.atEnd()) {
+ while (!isStopped() && !m_parserPaused && !m_stream.atEnd()) {
m_stream.readNext();
switch (m_stream.tokenType()) {
case QXmlStreamReader::StartDocument: {
diff --git a/WebCore/html/parser/HTMLDocumentParser.cpp b/WebCore/html/parser/HTMLDocumentParser.cpp
index 207bd3e..975fcb8 100644
--- a/WebCore/html/parser/HTMLDocumentParser.cpp
+++ b/WebCore/html/parser/HTMLDocumentParser.cpp
@@ -142,6 +142,28 @@ void HTMLDocumentParser::stopParsing()
m_parserScheduler.clear(); // Deleting the scheduler will clear any timers.
}
+// This kicks off "Once the user agent stops parsing" as described by:
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end
+void HTMLDocumentParser::prepareToStopParsing()
+{
+ ASSERT(!hasInsertionPoint());
+
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtr<HTMLDocumentParser> protect(this);
+
+ // FIXME: Set the current document readiness to "interactive".
+
+ // NOTE: This pump should only ever emit buffered character tokens,
+ // so ForceSynchronous vs. AllowYield should be meaningless.
+ pumpTokenizerIfPossible(ForceSynchronous);
+
+ DocumentParser::prepareToStopParsing();
+ if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing())
+ return;
+ end();
+}
+
bool HTMLDocumentParser::processingData() const
{
return isScheduledForResume() || inWrite();
@@ -149,7 +171,7 @@ bool HTMLDocumentParser::processingData() const
void HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode)
{
- if (m_parserStopped || m_treeBuilder->isPaused())
+ if (isStopped() || m_treeBuilder->isPaused())
return;
// Once a resume is scheduled, HTMLParserScheduler controls when we next pump.
@@ -193,8 +215,7 @@ bool HTMLDocumentParser::runScriptsForPausedTreeBuilder()
void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
{
- ASSERT(!isDetached());
- ASSERT(!m_parserStopped);
+ ASSERT(!isStopped());
ASSERT(!m_treeBuilder->isPaused());
ASSERT(!isScheduledForResume());
// ASSERT that this object is both attached to the Document and protected.
@@ -214,7 +235,7 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
m_token.clear();
// JavaScript may have stopped or detached the parser.
- if (isDetached() || m_parserStopped)
+ if (isStopped())
return;
// The parser will pause itself when waiting on a script to load or run.
@@ -226,7 +247,7 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
m_treeBuilder->setPaused(!shouldContinueParsing);
// JavaScript may have stopped or detached the parser.
- if (isDetached() || m_parserStopped)
+ if (isStopped())
return;
if (!shouldContinueParsing)
@@ -275,7 +296,7 @@ bool HTMLDocumentParser::hasInsertionPoint()
void HTMLDocumentParser::insert(const SegmentedString& source)
{
- if (m_parserStopped)
+ if (isStopped())
return;
// pumpTokenizer can cause this parser to be detached from the Document,
@@ -296,7 +317,7 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
void HTMLDocumentParser::append(const SegmentedString& source)
{
- if (m_parserStopped)
+ if (isStopped())
return;
// pumpTokenizer can cause this parser to be detached from the Document,
@@ -328,14 +349,6 @@ void HTMLDocumentParser::end()
ASSERT(!isDetached());
ASSERT(!isScheduledForResume());
- // pumpTokenizer can cause this parser to be detached from the Document,
- // but we need to ensure it isn't deleted yet.
- RefPtr<HTMLDocumentParser> protect(this);
-
- // NOTE: This pump should only ever emit buffered character tokens,
- // so ForceSynchronous vs. AllowYield should be meaningless.
- pumpTokenizerIfPossible(ForceSynchronous);
-
// Informs the the rest of WebCore that parsing is really finished (and deletes this).
m_treeBuilder->finished();
}
@@ -349,7 +362,7 @@ void HTMLDocumentParser::attemptToEnd()
m_endWasDelayed = true;
return;
}
- end();
+ prepareToStopParsing();
}
void HTMLDocumentParser::endIfDelayed()
@@ -362,7 +375,7 @@ void HTMLDocumentParser::endIfDelayed()
return;
m_endWasDelayed = false;
- end();
+ prepareToStopParsing();
}
void HTMLDocumentParser::finish()
@@ -447,6 +460,11 @@ bool HTMLDocumentParser::shouldLoadExternalScriptFromSrc(const AtomicString& src
void HTMLDocumentParser::notifyFinished(CachedResource* cachedResource)
{
+ if (isStopping()) {
+ prepareToStopParsing();
+ return;
+ }
+
// pumpTokenizer can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
RefPtr<HTMLDocumentParser> protect(this);
diff --git a/WebCore/html/parser/HTMLDocumentParser.h b/WebCore/html/parser/HTMLDocumentParser.h
index da21a2b..a32b439 100644
--- a/WebCore/html/parser/HTMLDocumentParser.h
+++ b/WebCore/html/parser/HTMLDocumentParser.h
@@ -81,6 +81,7 @@ private:
virtual void append(const SegmentedString&);
virtual bool finishWasCalled();
virtual bool processingData() const;
+ virtual void prepareToStopParsing();
virtual void stopParsing();
virtual bool isWaitingForScripts() const;
virtual bool isExecutingScript() const;
diff --git a/WebCore/html/parser/HTMLScriptRunner.cpp b/WebCore/html/parser/HTMLScriptRunner.cpp
index 6d470a0..764bf01 100644
--- a/WebCore/html/parser/HTMLScriptRunner.cpp
+++ b/WebCore/html/parser/HTMLScriptRunner.cpp
@@ -75,6 +75,12 @@ HTMLScriptRunner::~HTMLScriptRunner()
// FIXME: Should we be passed a "done loading/parsing" callback sooner than destruction?
if (m_parsingBlockingScript.cachedScript() && m_parsingBlockingScript.watchingForLoad())
stopWatchingForLoad(m_parsingBlockingScript);
+
+ while (!m_scriptsToExecuteAfterParsing.isEmpty()) {
+ PendingScript pendingScript = m_scriptsToExecuteAfterParsing.takeFirst();
+ if (pendingScript.cachedScript() && pendingScript.watchingForLoad())
+ stopWatchingForLoad(pendingScript);
+ }
}
void HTMLScriptRunner::detach()
@@ -129,10 +135,6 @@ void HTMLScriptRunner::executeParsingBlockingScript()
ASSERT(m_document->haveStylesheetsLoaded());
ASSERT(isPendingScriptReady(m_parsingBlockingScript));
- // Stop watching loads before executeScript to prevent recursion if the script reloads itself.
- if (m_parsingBlockingScript.cachedScript() && m_parsingBlockingScript.watchingForLoad())
- stopWatchingForLoad(m_parsingBlockingScript);
-
InsertionPointRecord insertionPointRecord(m_host->inputStream());
executePendingScriptAndDispatchEvent(m_parsingBlockingScript);
}
@@ -142,6 +144,10 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi
bool errorOccurred = false;
ScriptSourceCode sourceCode = sourceFromPendingScript(pendingScript, errorOccurred);
+ // Stop watching loads before executeScript to prevent recursion if the script reloads itself.
+ if (pendingScript.cachedScript() && pendingScript.watchingForLoad())
+ stopWatchingForLoad(pendingScript);
+
// Clear the pending script before possible rentrancy from executeScript()
RefPtr<Element> scriptElement = pendingScript.releaseElementAndClear();
{
@@ -238,6 +244,24 @@ bool HTMLScriptRunner::executeScriptsWaitingForStylesheets()
return executeParsingBlockingScripts();
}
+bool HTMLScriptRunner::executeScriptsWaitingForParsing()
+{
+ while (!m_scriptsToExecuteAfterParsing.isEmpty()) {
+ ASSERT(!m_scriptNestingLevel);
+ ASSERT(!haveParsingBlockingScript());
+ ASSERT(m_scriptsToExecuteAfterParsing.first().cachedScript());
+ if (!m_scriptsToExecuteAfterParsing.first().cachedScript()->isLoaded()) {
+ watchForLoad(m_scriptsToExecuteAfterParsing.first());
+ return false;
+ }
+ PendingScript first = m_scriptsToExecuteAfterParsing.takeFirst();
+ executePendingScriptAndDispatchEvent(first);
+ if (!m_document)
+ return false;
+ }
+ return true;
+}
+
void HTMLScriptRunner::requestParsingBlockingScript(Element* element)
{
if (!requestPendingScript(m_parsingBlockingScript, element))
@@ -252,6 +276,16 @@ void HTMLScriptRunner::requestParsingBlockingScript(Element* element)
watchForLoad(m_parsingBlockingScript);
}
+void HTMLScriptRunner::requestDeferredScript(Element* element)
+{
+ PendingScript pendingScript;
+ if (!requestPendingScript(pendingScript, element))
+ return;
+
+ ASSERT(pendingScript.cachedScript());
+ m_scriptsToExecuteAfterParsing.append(pendingScript);
+}
+
bool HTMLScriptRunner::requestPendingScript(PendingScript& pendingScript, Element* script) const
{
ASSERT(!pendingScript.element());
@@ -287,8 +321,11 @@ void HTMLScriptRunner::runScript(Element* script, int startingLineNumber)
notImplemented(); // event for support
if (script->hasAttribute(srcAttr)) {
- // FIXME: Handle defer and async
- requestParsingBlockingScript(script);
+ // FIXME: Handle async.
+ if (script->hasAttribute(deferAttr))
+ requestDeferredScript(script);
+ else
+ requestParsingBlockingScript(script);
} else {
// FIXME: We do not block inline <script> tags on stylesheets to match the
// old parser for now. When we do, the ASSERT below should be added.
diff --git a/WebCore/html/parser/HTMLScriptRunner.h b/WebCore/html/parser/HTMLScriptRunner.h
index ead9289..47c96fd 100644
--- a/WebCore/html/parser/HTMLScriptRunner.h
+++ b/WebCore/html/parser/HTMLScriptRunner.h
@@ -27,6 +27,7 @@
#define HTMLScriptRunner_h
#include "PendingScript.h"
+#include <wtf/Deque.h>
#include <wtf/Noncopyable.h>
#include <wtf/PassRefPtr.h>
@@ -56,6 +57,7 @@ public:
bool executeScriptsWaitingForLoad(CachedResource*);
bool hasScriptsWaitingForStylesheets() const { return m_hasScriptsWaitingForStylesheets; }
bool executeScriptsWaitingForStylesheets();
+ bool executeScriptsWaitingForParsing();
bool isExecutingScript() const { return !!m_scriptNestingLevel; }
@@ -71,6 +73,7 @@ private:
bool executeParsingBlockingScripts();
void requestParsingBlockingScript(Element*);
+ void requestDeferredScript(Element*);
bool requestPendingScript(PendingScript&, Element*) const;
void runScript(Element*, int startingLineNumber);
@@ -84,6 +87,7 @@ private:
Document* m_document;
HTMLScriptRunnerHost* m_host;
PendingScript m_parsingBlockingScript;
+ Deque<PendingScript> m_scriptsToExecuteAfterParsing; // http://www.whatwg.org/specs/web-apps/current-work/#list-of-scripts-that-will-execute-when-the-document-has-finished-parsing
unsigned m_scriptNestingLevel;
// We only want stylesheet loads to trigger script execution if script
diff --git a/WebCore/loader/ImageDocument.cpp b/WebCore/loader/ImageDocument.cpp
index 702ed9d..cc3c85c 100644
--- a/WebCore/loader/ImageDocument.cpp
+++ b/WebCore/loader/ImageDocument.cpp
@@ -138,7 +138,7 @@ void ImageDocumentParser::appendBytes(DocumentWriter*, const char*, int, bool)
void ImageDocumentParser::finish()
{
- if (!m_parserStopped && document()->imageElement()) {
+ if (!isStopped() && document()->imageElement()) {
CachedImage* cachedImage = document()->cachedImage();
RefPtr<SharedBuffer> data = document()->frame()->loader()->documentLoader()->mainResourceData();
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list