Source/WebCore/ChangeLog

 12013-08-29 Christophe Dumez <ch.dumez@sisa.samsung.com>
 2
 3 According to DOM4, all DocType nodes should have a document
 4 https://bugs.webkit.org/show_bug.cgi?id=99244
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Doctypes now always have a node document and can be moved across document boundaries as per
 9 the latest DOM4 specification:
 10 http://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype
 11 http://dom.spec.whatwg.org/#dom-node-ownerdocument
 12
 13 This means that DOMImplementation.createDocumentType() now sets the ownerDocument of the
 14 new DocumentType Node to the associated document of the current "context" object. In
 15 DOM4, all nodes have a document at all times. DocumentType nodes can now be moved across
 16 document boundaries so that the node can be added to a Document after being created.
 17
 18 This means we will no longer need to special case DocumentType nodes in the code and
 19 Node::document() can no longer return NULL, which means that we'll be able to remove
 20 NULL checks in call sites.
 21
 22 Firefox stable and since recently Blink already follow DOM4 here while IE10 does not (yet).
 23
 24 Test: fast/dom/createDocumentType-ownerDocument.html
 25
 26 * dom/ContainerNode.cpp:
 27 (WebCore::checkAcceptChild):
 28 * dom/DOMImplementation.cpp:
 29 (WebCore::DOMImplementation::createDocumentType):
 30 (WebCore::DOMImplementation::createDocument):
 31 * dom/Node.h:
 32 (WebCore::Node::document):
 33
1342013-08-29 Pratik Solanki <pratik.solanki@gmail.com>
235
336 SharedBuffer m_segments and m_dataArray must be exclusive

Source/WebCore/dom/ContainerNode.cpp

@@static inline ExceptionCode checkAcceptChild(ContainerNode* newParent, Node* new
213213
214214 if (newParent->isReadOnlyNode())
215215 return NO_MODIFICATION_ALLOWED_ERR;
216  if (newChild->inDocument() && newChild->isDocumentTypeNode())
217  return HIERARCHY_REQUEST_ERR;
218216 if (containsConsideringHostElements(newChild, newParent))
219217 return HIERARCHY_REQUEST_ERR;
220218

Source/WebCore/dom/DOMImplementation.cpp

@@PassRefPtr<DocumentType> DOMImplementation::createDocumentType(const String& qua
219219 if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
220220 return 0;
221221
222  return DocumentType::create(0, qualifiedName, publicId, systemId);
 222 return DocumentType::create(m_document, qualifiedName, publicId, systemId);
223223}
224224
225225DOMImplementation* DOMImplementation::getInterface(const String& /*feature*/)

@@PassRefPtr<Document> DOMImplementation::createDocument(const String& namespaceUR
251251 return 0;
252252 }
253253
254  // WRONG_DOCUMENT_ERR: Raised if doctype has already been used with a different document or was
255  // created from a different implementation.
256  // Hixie's interpretation of the DOM Core spec suggests we should prefer
257  // other exceptions to WRONG_DOCUMENT_ERR (based on order mentioned in spec),
258  // but this matches the new DOM Core spec (http://www.w3.org/TR/domcore/).
259  if (doctype && doctype->document()) {
260  ec = WRONG_DOCUMENT_ERR;
261  return 0;
262  }
263 
264254 if (doctype)
265255 doc->appendChild(doctype);
266256 if (documentElement)

Source/WebCore/dom/Node.h

@@public:
395395
396396 unsigned nodeIndex() const;
397397
398  // Returns the DOM ownerDocument attribute. This method never returns NULL, except in the case
399  // of (1) a Document node or (2) a DocumentType node that is not used with any Document yet.
 398 // Returns the DOM ownerDocument attribute. This method never returns 0, except in the case
 399 // of a Document node.
400400 Document* ownerDocument() const;
401401
402  // Returns the document associated with this node. This method never returns NULL, except in the case
403  // of a DocumentType node that is not used with any Document yet. A Document node returns itself.
 402 // Returns the document associated with this node. This method never returns 0.
 403 // A Document node returns itself.
404404 Document* document() const
405405 {
406406 ASSERT(this);
407  // FIXME: below ASSERT is useful, but prevents the use of document() in the constructor or destructor
408  // due to the virtual function call to nodeType().
409  ASSERT(documentInternal() || (nodeType() == DOCUMENT_TYPE_NODE && !inDocument()));
 407 ASSERT(documentInternal());
410408 return documentInternal();
411409 }
412410

LayoutTests/ChangeLog

 12013-08-29 Christophe Dumez <ch.dumez@sisa.samsung.com>
 2
 3 According to DOM4, all DocType nodes should have a document
 4 https://bugs.webkit.org/show_bug.cgi?id=99244
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Add layout test to check that DocumentType Nodes have a document after being
 9 created. Also update a few existing test cases to reflect this change.
 10
 11 * fast/dom/DOMImplementation/createDocument-with-used-doctype-expected.txt:
 12 * fast/dom/DOMImplementation/createDocument-with-used-doctype.html:
 13 * fast/dom/DOMImplementation/resources/createDocument-with-used-doctype-frame.html:
 14 * fast/dom/XMLSerializer-doctype2-expected.txt:
 15 * fast/dom/XMLSerializer-doctype2.html:
 16 * fast/dom/createDocumentType-ownerDocument-expected.txt: Added.
 17 * fast/dom/createDocumentType-ownerDocument.html: Added.
 18 * fast/dom/move-nodes-across-documents.html:
 19 * fast/dom/node-iterator-with-doctype-root-expected.txt:
 20 * fast/dom/node-iterator-with-doctype-root.html:
 21 * fast/events/dispatch-event-no-document-expected.txt:
 22 * fast/events/dispatch-event-no-document.html:
 23
1242013-08-29 Joseph Pecoraro <pecoraro@apple.com>
225
326 Web Inspector: Consolidate inspector-protocol Debugger tests

LayoutTests/fast/dom/DOMImplementation/createDocument-with-used-doctype-expected.txt

1 PASS
 1document.implementation.createDocument with current document's DOCTYPE.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5PASS doc = document.implementation.createDocument(null, null, document.doctype) did not throw exception.
 6PASS doc.doctype is doctype
 7PASS doc.firstChild is doctype
 8PASS document.doctype is null
 9
 10
 11
 12
 13
 14PASS successfullyParsed is true
 15
 16TEST COMPLETE
217

LayoutTests/fast/dom/DOMImplementation/createDocument-with-used-doctype.html

11<body>
 2<script src="../../js/resources/js-test-pre.js"></script>
23<script>
3 if (window.testRunner) {
4  testRunner.dumpAsText();
5  testRunner.waitUntilDone();
6 }
7 
8 function gc()
9 {
10  if (window.GCController)
11  return GCController.collect();
12 
13  for (var i = 0; i < 10000; i++)
14  var s = new String("");
15 }
 4window.jsTestIsAsync = true;
165
176// Reload multiple times, to make crashing more likely.
187var iterationsLeft = 50;

@@function test()
2211 frames[0].history.go(0);
2312 } else {
2413 gc();
25  document.getElementById("result").innerText = frames[0].document.body.textContent;
26  if (window.testRunner)
27  testRunner.notifyDone();
 14 debug(frames[0].document.body.outerHTML);
 15 finishJSTest();
2816 }
2917}
3018</script>
31 <div id="result">FAIL</div>
3219<iframe src="resources/createDocument-with-used-doctype-frame.html" onload="test()"></iframe>
 20<script src="../../js/resources/js-test-post.js"></script>
3321</body>

LayoutTests/fast/dom/DOMImplementation/resources/createDocument-with-used-doctype-frame.html

11<!doctype html>
2 <title>document.implementation.createDocument with current document's DOCTYPE</title>
 2<html>
 3<head>
 4<script src="../../../js/resources/js-test-pre.js"></script>
 5</head>
36<body>
4 FAIL (Script did not run);
57<script>
6 document.body.textContent = "FAIL";
7 try {
8  document.implementation.createDocument(null, null, document.doctype);
9  document.body.textContent = "FAIL (no exception)";
10 }
11 catch(e) {
12  if (e.code === DOMException.WRONG_DOCUMENT_ERR || e.code === DOMException.NOT_SUPPORTED_ERR)
13  document.body.textContent = "PASS";
14  else
15  document.body.textContent = "FAIL (wrong exception: " + e.code + ")";
16 }
 8description("document.implementation.createDocument with current document's DOCTYPE.");
 9
 10var doctype = document.doctype;
 11var doc;
 12shouldNotThrow("doc = document.implementation.createDocument(null, null, document.doctype)");
 13shouldBe('doc.doctype', 'doctype');
 14shouldBe('doc.firstChild', 'doctype');
 15shouldBe('document.doctype', 'null');
1716</script>
 17</body>
 18</html>

LayoutTests/fast/dom/XMLSerializer-doctype2-expected.txt

1 This tests XMLSerializer.serializeToString() on a DocumentType node that does not have a document associated with it. It should throw an INVALID_ACCESS_ERR DOMException.
2 PASS: an Error: InvalidAccessError: DOM Exception 15 was thrown as expected.
 1This tests XMLSerializer.serializeToString() on a newly created DocumentType node does not throw since the node has an associated document.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS text = serializer.serializeToString(docType) did not throw exception.
 7PASS text is "<!DOCTYPE aDocTypeName PUBLIC \"aPublicID\" \"aSystemID\">"
 8

LayoutTests/fast/dom/XMLSerializer-doctype2.html

11<html>
22<head>
3  <script>
4  function debug(str) {
5  li = document.createElement('li');
6  li.appendChild(document.createTextNode(str));
7  document.getElementById('console').appendChild(li);
8  }
9 
10  function runTests() {
11  if (window.testRunner)
12  testRunner.dumpAsText();
13 
14  var docType = window.document.implementation.createDocumentType("aDocTypeName", "aPublicID", "aSystemID");
 3<script src="../js/resources/js-test-pre.js"></script>
 4</head>
 5<body>
 6<script>
 7description("This tests XMLSerializer.serializeToString() on a newly created DocumentType node does not throw since the node has an associated document.");
158
16  var serializer = new XMLSerializer();
 9var docType = window.document.implementation.createDocumentType("aDocTypeName", "aPublicID", "aSystemID");
1710
18  try {
19  var text = serializer.serializeToString(docType);
20  debug("FAIL: XMLSerializer.serializeToString() should throw an exception if it tries to serialize a documentless DocumentType node.");
21  } catch (e) {
22  if (e == "Error: InvalidAccessError: DOM Exception 15")
23  debug("PASS: an " + e + " was thrown as expected.")
24  else
25  debug("FAIL: XMLSerializer.serializeToString() should throw an INVALID_ACCESS_ERR DOMExeption if it tries to serialize a documentless DocumentType node.");
26  }
27  }
28  </script>
29 </head>
30 <body onload="runTests()">
31 This tests XMLSerializer.serializeToString() on a DocumentType node that does not have a document associated
32 with it. It should throw an INVALID_ACCESS_ERR DOMException.
 11var serializer = new XMLSerializer();
3312
34 <ul id="console">
35 </ul>
 13var text;
 14shouldNotThrow("text = serializer.serializeToString(docType)");
 15shouldBeEqualToString("text", "<!DOCTYPE aDocTypeName PUBLIC \"aPublicID\" \"aSystemID\">");
 16</script>
 17<script src="../js/resources/js-test-pre.js"></script>
3618</body>
3719</html>

LayoutTests/fast/dom/createDocumentType-ownerDocument-expected.txt

 1Tests that DOMImplementation.createDocumentType() properly sets the node's document to the associated document of the context object.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS docType.ownerDocument is document
 7PASS newDocument = document.implementation.createDocument('', null, docType) did not throw exception.
 8PASS newDocument.doctype is docType
 9PASS newDocument.doctype.ownerDocument is newDocument
 10PASS successfullyParsed is true
 11
 12TEST COMPLETE
 13

LayoutTests/fast/dom/createDocumentType-ownerDocument.html

 1<!DOCTYPE html>
 2<html>
 3<head>
 4<link rel="help" href="http://www.w3.org/TR/2012/WD-dom-20121206/#dom-domimplementation-createdocumenttype">
 5<script src="../js/resources/js-test-pre.js"></script>
 6</head>
 7<body>
 8<script>
 9description("Tests that DOMImplementation.createDocumentType() properly sets the node's document to the associated document of the context object.");
 10var docType = document.implementation.createDocumentType("html", null, null);
 11shouldBe("docType.ownerDocument", "document");
 12var newDocument;
 13shouldNotThrow("newDocument = document.implementation.createDocument('', null, docType)");
 14shouldBe("newDocument.doctype", "docType");
 15shouldBe("newDocument.doctype.ownerDocument", "newDocument");
 16
 17</script>
 18<script src="../js/resources/js-test-post.js"></script>
 19</body>
 20</html>

LayoutTests/fast/dom/move-nodes-across-documents.html

@@function run()
168168 });
169169 runTest(function() {
170170 iframeDoc.implementation.createDocument('', 'html', document.doctype);
171  }, 'WrongDocumentError');
 171 });
172172 runTest(function() {
173173 rangeInIframe().compareBoundaryPoints(Range.END_TO_END, rangeInCurrentDocument());
174174 }, 'WrongDocumentError');

@@function run()
179179 runTest(function() {
180180 iframeDoc.appendChild(document.doctype);
181181 console.log(document.doctype);
182  }, 'HierarchyRequestError');
 182 }, 'NotFoundError');
183183
184184 // When setting a boundary of the range in a different
185185 // document, the call should succeed and the range should be collapsed.

LayoutTests/fast/dom/node-iterator-with-doctype-root-expected.txt

11NodeIterator rooted at a DocumentType node not yet associated with a document:
2 PASS iter.referenceNode.ownerDocument is null
 2PASS iter.referenceNode.ownerDocument is document
33PASS iter.nextNode() is dt
44PASS iter.nextNode() is null
55PASS iter.previousNode() is dt

LayoutTests/fast/dom/node-iterator-with-doctype-root.html

77var dt = document.implementation.createDocumentType("foo", "", "");
88var iter = document.createNodeIterator(dt, NodeFilter.SHOW_ALL, null, true);
99debug("NodeIterator rooted at a DocumentType node not yet associated with a document:");
10 shouldBe('iter.referenceNode.ownerDocument', 'null');
 10shouldBe('iter.referenceNode.ownerDocument', 'document');
1111shouldBe('iter.nextNode()', 'dt');
1212shouldBe('iter.nextNode()', 'null');
1313shouldBe('iter.previousNode()', 'dt');

LayoutTests/fast/events/dispatch-event-no-document-expected.txt

1 The test verifies that EventTarget with an event listener but without ScriptExecutionContext (not inserted into Document) does not crash during an attempt to dispatch an event. It should just not call the handler. This is what FF 3.5 is also doing.
 1The test verifies that EventTarget with an event listener not inserted into a Document does not crash during an attempt to dispatch an event.
22
3 Test passes if there is no crash, and event is not dispatched.
 3Test passes if there is no crash, and event is dispatched.
 4
 5PASS: generic handled.
46
5 PASS

LayoutTests/fast/events/dispatch-event-no-document.html

11<script>
22function handleEvent(message) {
3  document.getElementById("log").innerHTML = "FAIL: " + message + " handled.<br>";
 3 document.getElementById("log").innerHTML = "PASS: " + message + " handled.<br>";
44}
55
66function test() {

@@function test() {
2121}
2222</script>
2323<body onload="test()">
24 <p>The test verifies that EventTarget with an event listener but without ScriptExecutionContext (not inserted into Document) does not crash during an attempt to dispatch an event. It should just not call the handler. This is what FF 3.5 is also doing.</p>
25 <p>Test passes if there is no crash, and event is not dispatched.</p>
26 <div id="log">PASS</div>
 24<p>The test verifies that EventTarget with an event listener not inserted into a Document does not crash during an attempt to dispatch an event.</p>
 25<p>Test passes if there is no crash, and event is dispatched.</p>
 26<div id="log">FAIL</div>