[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
abarth at webkit.org
abarth at webkit.org
Wed Dec 22 11:26:56 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 8a828c10648d10b4018fa70aef6ef112b2b4032e
Author: abarth at webkit.org <abarth at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Jul 23 22:14:02 2010 +0000
2010-07-23 Adam Barth <abarth at webkit.org>
Reviewed by Eric Seidel.
HTML5 Parser: document.write in a asynchronous script which is specified to load before page finish blows away document
https://bugs.webkit.org/show_bug.cgi?id=42365
* http/tests/misc/write-from-dom-script-expected.txt: Added.
* http/tests/misc/write-from-dom-script.html: Added.
- Test the scenario where a script added to the DOM asynchronously
while the nesting level is >0. It's supposed to have its calls to
document.write blocked.
* http/tests/misc/write-while-waiting.html:
- Writes are only prevented from scripts that are added to the DOM.
Scripts that run via setTimeout do not have their writes blocked.
2010-07-23 Adam Barth <abarth at webkit.org>
Reviewed by Eric Seidel.
HTML5 Parser: document.write in a asynchronous script which is specified to load before page finish blows away document
https://bugs.webkit.org/show_bug.cgi?id=42365
This patch implements the changes Ian made to HTML5 to address these
issues. Let's try it and see how well it works.
Test: http/tests/misc/write-from-dom-script.html
* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::write):
* dom/Document.h:
(WebCore::Document::writeDisabled):
(WebCore::Document::setWriteDisabled):
* dom/DocumentParser.h:
(WebCore::DocumentParser::hasInsertionPoint):
* dom/ScriptElement.cpp:
(WebCore::ScriptElement::insertedIntoDocument):
(WebCore::ScriptElementData::ScriptElementData):
(WebCore::ScriptElementData::evaluateScript):
* dom/ScriptElement.h:
(WebCore::ScriptElementData::writeDisabled):
(WebCore::ScriptElementData::setWriteDisabled):
* html/HTMLDocumentParser.cpp:
(WebCore::HTMLDocumentParser::hasInsertionPoint):
(WebCore::HTMLDocumentParser::insert):
* html/HTMLDocumentParser.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@63998 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 3f5ee14..ea6fcab 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,19 @@
+2010-07-23 Adam Barth <abarth at webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ HTML5 Parser: document.write in a asynchronous script which is specified to load before page finish blows away document
+ https://bugs.webkit.org/show_bug.cgi?id=42365
+
+ * http/tests/misc/write-from-dom-script-expected.txt: Added.
+ * http/tests/misc/write-from-dom-script.html: Added.
+ - Test the scenario where a script added to the DOM asynchronously
+ while the nesting level is >0. It's supposed to have its calls to
+ document.write blocked.
+ * http/tests/misc/write-while-waiting.html:
+ - Writes are only prevented from scripts that are added to the DOM.
+ Scripts that run via setTimeout do not have their writes blocked.
+
2010-07-23 Shinichiro Hamaji <hamaji at chromium.org>
Unreviewed. Land the expectation for win.
diff --git a/LayoutTests/editing/selection/5136696-expected.txt b/LayoutTests/http/tests/misc/write-from-dom-script-expected.txt
similarity index 100%
copy from LayoutTests/editing/selection/5136696-expected.txt
copy to LayoutTests/http/tests/misc/write-from-dom-script-expected.txt
diff --git a/LayoutTests/http/tests/misc/write-from-dom-script.html b/LayoutTests/http/tests/misc/write-from-dom-script.html
new file mode 100644
index 0000000..68afa27
--- /dev/null
+++ b/LayoutTests/http/tests/misc/write-from-dom-script.html
@@ -0,0 +1,21 @@
+<html>
+<body>
+PASS
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+window.scriptDidReallyRun = false;
+
+var script = document.createElement("script");
+script.src = "data:text/javascript,document.write('FAIL');document.close();" +
+ "window.scriptDidReally = true;";
+document.body.appendChild(script);
+</script>
+<script src="resources/script-slow1.pl"></script>
+<script>
+if (!window.scriptDidReallyRun)
+ alert("FAIL! The script didn't really run. :(");
+<script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/misc/write-while-waiting.html b/LayoutTests/http/tests/misc/write-while-waiting.html
index 4bf390f..0c715d8 100644
--- a/LayoutTests/http/tests/misc/write-while-waiting.html
+++ b/LayoutTests/http/tests/misc/write-while-waiting.html
@@ -1,11 +1,11 @@
<html>
<body>
-PASS
+FAIL
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
-setTimeout("document.write('FAIL');document.close();", 100);
+setTimeout("document.write('PASS');document.close();", 100);
</script>
<script src="resources/script-slow1.pl"></script>
</body>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 6cdde9c..35a1981 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,35 @@
+2010-07-23 Adam Barth <abarth at webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ HTML5 Parser: document.write in a asynchronous script which is specified to load before page finish blows away document
+ https://bugs.webkit.org/show_bug.cgi?id=42365
+
+ This patch implements the changes Ian made to HTML5 to address these
+ issues. Let's try it and see how well it works.
+
+ Test: http/tests/misc/write-from-dom-script.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::Document):
+ (WebCore::Document::write):
+ * dom/Document.h:
+ (WebCore::Document::writeDisabled):
+ (WebCore::Document::setWriteDisabled):
+ * dom/DocumentParser.h:
+ (WebCore::DocumentParser::hasInsertionPoint):
+ * dom/ScriptElement.cpp:
+ (WebCore::ScriptElement::insertedIntoDocument):
+ (WebCore::ScriptElementData::ScriptElementData):
+ (WebCore::ScriptElementData::evaluateScript):
+ * dom/ScriptElement.h:
+ (WebCore::ScriptElementData::writeDisabled):
+ (WebCore::ScriptElementData::setWriteDisabled):
+ * html/HTMLDocumentParser.cpp:
+ (WebCore::HTMLDocumentParser::hasInsertionPoint):
+ (WebCore::HTMLDocumentParser::insert):
+ * html/HTMLDocumentParser.h:
+
2010-07-23 Patrick Gansterer <paroga at paroga.com>
Reviewed by Adam Roben.
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index 9c747d3..1c0e57c 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -363,6 +363,7 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
, m_frameElementsShouldIgnoreScrolling(false)
, m_containsValidityStyleRules(false)
, m_updateFocusAppearanceRestoresSelection(false)
+ , m_writeDisabled(false)
, m_title("")
, m_rawTitle("")
, m_titleSetExplicitly(false)
@@ -2016,7 +2017,13 @@ void Document::write(const SegmentedString& text, Document* ownerDocument)
printf("Beginning a document.write at %d\n", elapsedTime());
#endif
- if (!m_parser)
+ // If the insertion point is undefined and the Document has the
+ // "write-neutralised" flag set, then abort these steps.
+ bool hasInsertionPoint = m_parser && m_parser->hasInsertionPoint();
+ if (!hasInsertionPoint && writeDisabled())
+ return;
+
+ if (!hasInsertionPoint)
open(ownerDocument);
ASSERT(m_parser);
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index 078cb53..ee46f53 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -1002,6 +1002,9 @@ public:
const QualifiedName& idAttributeName() const { return m_idAttributeName; }
+ bool writeDisabled() const { return m_writeDisabled; }
+ void setWriteDisabled(bool flag) { m_writeDisabled = flag; }
+
protected:
Document(Frame*, const KURL&, bool isXHTML, bool isHTML);
@@ -1155,6 +1158,9 @@ private:
bool m_containsValidityStyleRules;
bool m_updateFocusAppearanceRestoresSelection;
+ // http://www.whatwg.org/specs/web-apps/current-work/#write-neutralised
+ bool m_writeDisabled;
+
String m_title;
String m_rawTitle;
bool m_titleSetExplicitly;
diff --git a/WebCore/dom/DocumentParser.h b/WebCore/dom/DocumentParser.h
index 7e47a87..a3545b6 100644
--- a/WebCore/dom/DocumentParser.h
+++ b/WebCore/dom/DocumentParser.h
@@ -40,6 +40,9 @@ public:
virtual ScriptableDocumentParser* asScriptableDocumentParser() { return 0; }
+ // http://www.whatwg.org/specs/web-apps/current-work/#insertion-point
+ virtual bool hasInsertionPoint() { return true; }
+
// insert is used by document.write
virtual void insert(const SegmentedString&) = 0;
diff --git a/WebCore/dom/ScriptElement.cpp b/WebCore/dom/ScriptElement.cpp
index 518aead..dab8f8c 100644
--- a/WebCore/dom/ScriptElement.cpp
+++ b/WebCore/dom/ScriptElement.cpp
@@ -27,6 +27,7 @@
#include "CachedScript.h"
#include "DocLoader.h"
#include "Document.h"
+#include "DocumentParser.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "HTMLNames.h"
@@ -53,6 +54,16 @@ void ScriptElement::insertedIntoDocument(ScriptElementData& data, const String&
if (data.createdByParser())
return;
+ // http://www.whatwg.org/specs/web-apps/current-work/#script
+
+ // If the element's Document has an active parser, and the parser's script
+ // nesting level is non-zero, but this script element does not have the
+ // "parser-inserted" flag set, the user agent must set the element's
+ // "write-neutralised" flag.
+ DocumentParser* parser = data.element()->document()->parser();
+ if (parser && parser->hasInsertionPoint())
+ data.setWriteDisabled(true);
+
if (!sourceUrl.isEmpty()) {
data.requestScript(sourceUrl);
return;
@@ -84,13 +95,6 @@ void ScriptElement::childrenChanged(ScriptElementData& data)
data.evaluateScript(ScriptSourceCode(data.scriptContent(), element->document()->url())); // FIXME: Provide a real starting line number here
}
-static inline bool useHTML5Parser(Document* document)
-{
- ASSERT(document);
- Settings* settings = document->page() ? document->page()->settings() : 0;
- return settings && settings->html5ParserEnabled();
-}
-
void ScriptElement::finishParsingChildren(ScriptElementData& data, const String& sourceUrl)
{
// The parser just reached </script>. If we have no src and no text,
@@ -137,6 +141,7 @@ ScriptElementData::ScriptElementData(ScriptElement* scriptElement, Element* elem
, m_element(element)
, m_cachedScript(0)
, m_createdByParser(false)
+ , m_writeDisabled(false)
, m_requested(false)
, m_evaluated(false)
, m_firedLoad(false)
@@ -191,7 +196,29 @@ void ScriptElementData::evaluateScript(const ScriptSourceCode& sourceCode)
m_evaluated = true;
+ // http://www.whatwg.org/specs/web-apps/current-work/#script
+
+ // If the script element's "write-neutralised" flag is set, then flag
+ // the Document the script element was in when the "write-neutralised"
+ // flag was set as being itself "write-neutralised". Let neutralised doc
+ // be that Document.
+ if (m_writeDisabled) {
+ ASSERT(!m_element->document()->writeDisabled());
+ m_element->document()->setWriteDisabled(true);
+ }
+
+ // Create a script from the script element node, using the script
+ // block's source and the script block's type.
+ // Note: This is where the script is compiled and actually executed.
frame->script()->evaluate(sourceCode);
+
+ // Remove the "write-neutralised" flag from neutralised doc, if it was
+ // set in the earlier step.
+ if (m_writeDisabled) {
+ ASSERT(m_element->document()->writeDisabled());
+ m_element->document()->setWriteDisabled(false);
+ }
+
Document::updateStyleForAllDocuments();
}
}
diff --git a/WebCore/dom/ScriptElement.h b/WebCore/dom/ScriptElement.h
index c663e43..698ffbc 100644
--- a/WebCore/dom/ScriptElement.h
+++ b/WebCore/dom/ScriptElement.h
@@ -82,6 +82,8 @@ public:
Element* element() const { return m_element; }
bool createdByParser() const { return m_createdByParser; }
void setCreatedByParser(bool value) { m_createdByParser = value; }
+ bool writeDisabled() const { return m_writeDisabled; }
+ void setWriteDisabled(bool value) { m_writeDisabled = value; }
bool haveFiredLoadEvent() const { return m_firedLoad; }
void setHaveFiredLoadEvent(bool firedLoad) { m_firedLoad = firedLoad; }
@@ -99,6 +101,7 @@ private:
Element* m_element;
CachedResourceHandle<CachedScript> m_cachedScript;
bool m_createdByParser; // HTML5: "parser-inserted"
+ bool m_writeDisabled; // http://www.whatwg.org/specs/web-apps/current-work/#write-neutralised
bool m_requested;
bool m_evaluated; // HTML5: "already started"
bool m_firedLoad;
diff --git a/WebCore/html/HTMLDocumentParser.cpp b/WebCore/html/HTMLDocumentParser.cpp
index baf6e25..723fbe7 100644
--- a/WebCore/html/HTMLDocumentParser.cpp
+++ b/WebCore/html/HTMLDocumentParser.cpp
@@ -213,22 +213,16 @@ void HTMLDocumentParser::didPumpLexer()
#endif
}
+bool HTMLDocumentParser::hasInsertionPoint()
+{
+ return m_input.hasInsertionPoint();
+}
+
void HTMLDocumentParser::insert(const SegmentedString& source)
{
if (m_parserStopped)
return;
- if (m_scriptRunner && !m_scriptRunner->inScriptExecution() && m_input.haveSeenEndOfFile()) {
- // document.write was called without a current insertion point.
- // According to the spec, we're supposed to implicitly open the
- // document. Unfortunately, that behavior isn't sufficiently compatible
- // with the web. The working group is mulling over what exactly to
- // do. In the meantime, we're going to try one of the potential
- // solutions, which is to ignore the write.
- // http://www.w3.org/Bugs/Public/show_bug.cgi?id=9767
- return;
- }
-
{
NestingLevelIncrementer nestingLevelIncrementer(m_writeNestingLevel);
@@ -324,7 +318,7 @@ bool HTMLDocumentParser::inScriptExecution() const
{
if (!m_scriptRunner)
return false;
- return m_scriptRunner->inScriptExecution();
+ return m_scriptRunner->isExecutingScript();
}
int HTMLDocumentParser::lineNumber() const
@@ -402,7 +396,7 @@ void HTMLDocumentParser::executeScriptsWaitingForStylesheets()
// is a re-entrant call from encountering a </ style> tag.
if (!m_scriptRunner->hasScriptsWaitingForStylesheets())
return;
- ASSERT(!m_scriptRunner->inScriptExecution());
+ ASSERT(!m_scriptRunner->isExecutingScript());
ASSERT(m_treeBuilder->isPaused());
// Note: We only ever wait on one script at a time, so we always know this
// is the one we were waiting on and can un-pause the tree builder.
diff --git a/WebCore/html/HTMLDocumentParser.h b/WebCore/html/HTMLDocumentParser.h
index b2a65ca..cc46d31 100644
--- a/WebCore/html/HTMLDocumentParser.h
+++ b/WebCore/html/HTMLDocumentParser.h
@@ -64,6 +64,7 @@ public:
private:
// DocumentParser
+ virtual bool hasInsertionPoint();
virtual void insert(const SegmentedString&);
virtual void append(const SegmentedString&);
virtual void finish();
diff --git a/WebCore/html/HTMLInputStream.h b/WebCore/html/HTMLInputStream.h
index d7c1c9c..a709bd9 100644
--- a/WebCore/html/HTMLInputStream.h
+++ b/WebCore/html/HTMLInputStream.h
@@ -64,6 +64,21 @@ public:
m_first.append(string);
}
+ bool hasInsertionPoint() const
+ {
+ if (&m_first != m_last)
+ return true;
+ if (!haveSeenEndOfFile()) {
+ // FIXME: Somehow we need to understand the difference between
+ // input streams that are coming off the network and streams that
+ // were created with document.open(). In the later case, we always
+ // have an isertion point at the end of the stream until someone
+ // calls document.close().
+ return true;
+ }
+ return false;
+ }
+
void markEndOfFile()
{
// FIXME: This should use InputStreamPreprocessor::endOfFileMarker
@@ -73,7 +88,7 @@ public:
m_last->close();
}
- bool haveSeenEndOfFile()
+ bool haveSeenEndOfFile() const
{
return m_last->isClosed();
}
diff --git a/WebCore/html/HTMLScriptRunner.cpp b/WebCore/html/HTMLScriptRunner.cpp
index 29790c0..f4b7013 100644
--- a/WebCore/html/HTMLScriptRunner.cpp
+++ b/WebCore/html/HTMLScriptRunner.cpp
@@ -154,7 +154,7 @@ void HTMLScriptRunner::executeScript(Element* element, const ScriptSourceCode& s
ASSERT(scriptElement);
if (!scriptElement->shouldExecuteAsJavaScript())
return;
- ASSERT(inScriptExecution());
+ ASSERT(isExecutingScript());
if (!m_document->frame())
return;
m_document->frame()->script()->executeScript(sourceCode);
diff --git a/WebCore/html/HTMLScriptRunner.h b/WebCore/html/HTMLScriptRunner.h
index f93ae10..cc69443 100644
--- a/WebCore/html/HTMLScriptRunner.h
+++ b/WebCore/html/HTMLScriptRunner.h
@@ -53,7 +53,7 @@ public:
bool hasScriptsWaitingForStylesheets() const { return m_hasScriptsWaitingForStylesheets; }
bool executeScriptsWaitingForStylesheets();
- bool inScriptExecution() { return !!m_scriptNestingLevel; }
+ bool isExecutingScript() { return !!m_scriptNestingLevel; }
private:
// A container for an external script which may be loaded and executed.
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list