Skip to content
Permalink
Browse files
ShadowRoot.cloneNode() must always throw a DATA_CLONE_ERR exception.
https://bugs.webkit.org/show_bug.cgi?id=91704

Reviewed by Dimitri Glazkov.

Source/WebCore:

According to the spec, ShadowRoot.cloneNode() should throw a DATA_CLONE_ERR exception. The existing implementation
returned null object instead.

We change the cloneNode() interface so that we can throw an exception from cloneNode().

Test: fast/dom/shadow/shadowroot-clonenode.html

* dom/Attr.cpp:
(WebCore::Attr::cloneNode):
* dom/Attr.h:
* dom/CDATASection.cpp:
(WebCore::CDATASection::cloneNode):
* dom/CDATASection.h:
(CDATASection):
* dom/Comment.cpp:
(WebCore::Comment::cloneNode):
* dom/Comment.h:
(Comment):
* dom/Document.cpp:
(WebCore::Document::cloneNode):
* dom/Document.h:
(Document):
* dom/DocumentFragment.cpp:
(WebCore::DocumentFragment::cloneNode):
* dom/DocumentFragment.h:
(DocumentFragment):
* dom/DocumentType.cpp:
(WebCore::DocumentType::cloneNode):
* dom/DocumentType.h:
(DocumentType):
* dom/Element.cpp:
(WebCore::Element::cloneNode):
* dom/Element.h:
(Element):
* dom/EntityReference.cpp:
(WebCore::EntityReference::cloneNode):
* dom/EntityReference.h:
(EntityReference):
* dom/Node.h:
(Node):
(WebCore::Node::cloneNode):
* dom/Node.idl:
* dom/ProcessingInstruction.cpp:
(WebCore::ProcessingInstruction::cloneNode):
* dom/ProcessingInstruction.h:
(ProcessingInstruction):
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::cloneNode):
* dom/ShadowRoot.h:
(ShadowRoot):
* dom/Text.cpp:
(WebCore::Text::cloneNode):
* dom/Text.h:
(Text):

LayoutTests:

* fast/dom/shadow/shadowroot-clonenode-expected.txt: Added.
* fast/dom/shadow/shadowroot-clonenode.html: Added.


Canonical link: https://commits.webkit.org/112364@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@126127 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Shinya Kawanaka committed Aug 21, 2012
1 parent 3b62f2c commit ce7c38024d68b832dd88cdc779b22f68d17730cc
Showing 28 changed files with 137 additions and 24 deletions.
@@ -1,3 +1,13 @@
2012-08-20 Shinya Kawanaka <shinyak@chromium.org>

ShadowRoot.cloneNode() must always throw a DATA_CLONE_ERR exception.
https://bugs.webkit.org/show_bug.cgi?id=91704

Reviewed by Dimitri Glazkov.

* fast/dom/shadow/shadowroot-clonenode-expected.txt: Added.
* fast/dom/shadow/shadowroot-clonenode.html: Added.

2012-08-20 Kenneth Russell <kbr@google.com>

Unreviewed Chromium gardening. Improved how a few test
@@ -0,0 +1,10 @@
Calling ShadowRoot.cloneNode() should throw a DATA_CLONE_ERR exception.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS exceptionCode is DOMException.DATA_CLONE_ERR
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,26 @@
<!DOCTYPE>
<html>
<script src="../../js/resources/js-test-pre.js"></script>
<script src="resources/polyfill.js"></script>

<pre id="console"></pre>

<script>
description('Calling ShadowRoot.cloneNode() should throw a DATA_CLONE_ERR exception.');

var host = document.createElement('div');
var shadowRoot = new WebKitShadowRoot(host);

var exceptionCode = null;
try {
shadowRoot.cloneNode()
} catch (e) {
exceptionCode = e.code;
}

shouldBe('exceptionCode', 'DOMException.DATA_CLONE_ERR')

finishJSTest();
</script>
<script src="../../js/resources/js-test-post.js"></script>
</html>
@@ -1,3 +1,65 @@
2012-08-20 Shinya Kawanaka <shinyak@chromium.org>

ShadowRoot.cloneNode() must always throw a DATA_CLONE_ERR exception.
https://bugs.webkit.org/show_bug.cgi?id=91704

Reviewed by Dimitri Glazkov.

According to the spec, ShadowRoot.cloneNode() should throw a DATA_CLONE_ERR exception. The existing implementation
returned null object instead.

We change the cloneNode() interface so that we can throw an exception from cloneNode().

Test: fast/dom/shadow/shadowroot-clonenode.html

* dom/Attr.cpp:
(WebCore::Attr::cloneNode):
* dom/Attr.h:
* dom/CDATASection.cpp:
(WebCore::CDATASection::cloneNode):
* dom/CDATASection.h:
(CDATASection):
* dom/Comment.cpp:
(WebCore::Comment::cloneNode):
* dom/Comment.h:
(Comment):
* dom/Document.cpp:
(WebCore::Document::cloneNode):
* dom/Document.h:
(Document):
* dom/DocumentFragment.cpp:
(WebCore::DocumentFragment::cloneNode):
* dom/DocumentFragment.h:
(DocumentFragment):
* dom/DocumentType.cpp:
(WebCore::DocumentType::cloneNode):
* dom/DocumentType.h:
(DocumentType):
* dom/Element.cpp:
(WebCore::Element::cloneNode):
* dom/Element.h:
(Element):
* dom/EntityReference.cpp:
(WebCore::EntityReference::cloneNode):
* dom/EntityReference.h:
(EntityReference):
* dom/Node.h:
(Node):
(WebCore::Node::cloneNode):
* dom/Node.idl:
* dom/ProcessingInstruction.cpp:
(WebCore::ProcessingInstruction::cloneNode):
* dom/ProcessingInstruction.h:
(ProcessingInstruction):
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::cloneNode):
* dom/ShadowRoot.h:
(ShadowRoot):
* dom/Text.cpp:
(WebCore::Text::cloneNode):
* dom/Text.h:
(Text):

2012-08-20 Kent Tamura <tkent@chromium.org>

[Chromium-win] Use native digits in parsing/formatting dates in the textfield part of input[type=date]
@@ -138,7 +138,7 @@ void Attr::setNodeValue(const String& v, ExceptionCode& ec)
setValue(v, ec);
}

PassRefPtr<Node> Attr::cloneNode(bool /*deep*/)
PassRefPtr<Node> Attr::cloneNode(bool /*deep*/, ExceptionCode&)
{
RefPtr<Attr> clone = adoptRef(new Attr(document(), qualifiedName(), value()));
cloneChildNodes(clone.get());
@@ -81,7 +81,7 @@ class Attr : public ContainerNode {

virtual String nodeValue() const OVERRIDE { return value(); }
virtual void setNodeValue(const String&, ExceptionCode&);
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual PassRefPtr<Node> cloneNode(bool deep, ExceptionCode&);

virtual bool isAttributeNode() const { return true; }
virtual bool childTypeAllowed(NodeType) const;
@@ -46,7 +46,7 @@ Node::NodeType CDATASection::nodeType() const
return CDATA_SECTION_NODE;
}

PassRefPtr<Node> CDATASection::cloneNode(bool /*deep*/)
PassRefPtr<Node> CDATASection::cloneNode(bool /*deep*/, ExceptionCode&)
{
return create(document(), data());
}
@@ -36,7 +36,7 @@ class CDATASection : public Text {

virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual PassRefPtr<Node> cloneNode(bool deep, ExceptionCode&);
virtual bool childTypeAllowed(NodeType) const;
virtual PassRefPtr<Text> virtualCreate(const String&);
};
@@ -46,7 +46,7 @@ Node::NodeType Comment::nodeType() const
return COMMENT_NODE;
}

PassRefPtr<Node> Comment::cloneNode(bool /*deep*/)
PassRefPtr<Node> Comment::cloneNode(bool /*deep*/, ExceptionCode&)
{
return create(document(), data());
}
@@ -36,7 +36,7 @@ class Comment : public CharacterData {

virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual PassRefPtr<Node> cloneNode(bool deep, ExceptionCode&);
virtual bool childTypeAllowed(NodeType) const;
};

@@ -3285,7 +3285,7 @@ bool Document::canReplaceChild(Node* newChild, Node* oldChild)
return true;
}

PassRefPtr<Node> Document::cloneNode(bool /*deep*/)
PassRefPtr<Node> Document::cloneNode(bool /*deep*/, ExceptionCode&)
{
// Spec says cloning Document nodes is "implementation dependent"
// so we do not support it...
@@ -1206,7 +1206,7 @@ class Document : public ContainerNode, public TreeScope, public ScriptExecutionC
virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual bool childTypeAllowed(NodeType) const;
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual PassRefPtr<Node> cloneNode(bool deep, ExceptionCode&);
virtual bool canReplaceChild(Node* newChild, Node* oldChild);

virtual void refScriptExecutionContext() { ref(); }
@@ -68,7 +68,7 @@ bool DocumentFragment::childTypeAllowed(NodeType type) const
}
}

PassRefPtr<Node> DocumentFragment::cloneNode(bool deep)
PassRefPtr<Node> DocumentFragment::cloneNode(bool deep, ExceptionCode&)
{
RefPtr<DocumentFragment> clone = create(document());
if (deep)
@@ -44,7 +44,7 @@ class DocumentFragment : public ContainerNode {

private:
virtual NodeType nodeType() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual PassRefPtr<Node> cloneNode(bool deep, ExceptionCode&);
virtual bool childTypeAllowed(NodeType) const;
};

@@ -51,7 +51,7 @@ Node::NodeType DocumentType::nodeType() const
return DOCUMENT_TYPE_NODE;
}

PassRefPtr<Node> DocumentType::cloneNode(bool /*deep*/)
PassRefPtr<Node> DocumentType::cloneNode(bool /*deep*/, ExceptionCode&)
{
return create(document(), m_name, m_publicId, m_systemId);
}
@@ -52,7 +52,7 @@ class DocumentType : public Node {
virtual KURL baseURI() const;
virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual PassRefPtr<Node> cloneNode(bool deep, ExceptionCode&);

virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
@@ -176,7 +176,7 @@ DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, error);
DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, focus);
DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, load);

PassRefPtr<Node> Element::cloneNode(bool deep)
PassRefPtr<Node> Element::cloneNode(bool deep, ExceptionCode&)
{
return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
}
@@ -501,7 +501,7 @@ class Element : public ContainerNode {

// cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren
// are used instead.
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual PassRefPtr<Node> cloneNode(bool deep, ExceptionCode&);
virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren();

QualifiedName m_tagName;
@@ -46,7 +46,7 @@ Node::NodeType EntityReference::nodeType() const
return ENTITY_REFERENCE_NODE;
}

PassRefPtr<Node> EntityReference::cloneNode(bool)
PassRefPtr<Node> EntityReference::cloneNode(bool, ExceptionCode&)
{
return create(document(), m_entityName);
}
@@ -35,7 +35,7 @@ class EntityReference : public ContainerNode {

virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual PassRefPtr<Node> cloneNode(bool deep, ExceptionCode&);

String m_entityName;
};
@@ -27,6 +27,7 @@

#include "EditingBoundary.h"
#include "EventTarget.h"
#include "ExceptionCodePlaceholder.h"
#include "KURLHash.h"
#include "LayoutTypes.h"
#include "MutationObserver.h"
@@ -186,7 +187,8 @@ class Node : public EventTarget, public ScriptWrappable, public TreeShared<Node,

void remove(ExceptionCode&);
bool hasChildNodes() const { return firstChild(); }
virtual PassRefPtr<Node> cloneNode(bool deep) = 0;
virtual PassRefPtr<Node> cloneNode(bool deep, ExceptionCode&) = 0;
PassRefPtr<Node> cloneNode(bool deep) { return cloneNode(deep, ASSERT_NO_EXCEPTION); }
const AtomicString& localName() const { return virtualLocalName(); }
const AtomicString& namespaceURI() const { return virtualNamespaceURI(); }
const AtomicString& prefix() const { return virtualPrefix(); }
@@ -79,7 +79,9 @@ module core {
raises(DOMException);

boolean hasChildNodes();
Node cloneNode(in [Optional=DefaultIsUndefined] boolean deep);
Node cloneNode(in [Optional=DefaultIsUndefined] boolean deep)
raises(DOMException);

void normalize();

// Introduced in DOM Level 2:
@@ -97,7 +97,7 @@ void ProcessingInstruction::setNodeValue(const String& nodeValue, ExceptionCode&
setData(nodeValue, ec);
}

PassRefPtr<Node> ProcessingInstruction::cloneNode(bool /*deep*/)
PassRefPtr<Node> ProcessingInstruction::cloneNode(bool /*deep*/, ExceptionCode&)
{
// FIXME: Is it a problem that this does not copy m_localHref?
// What about other data members?
@@ -60,7 +60,7 @@ class ProcessingInstruction : public Node, private CachedStyleSheetClient {
virtual NodeType nodeType() const;
virtual String nodeValue() const;
virtual void setNodeValue(const String&, ExceptionCode&);
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual PassRefPtr<Node> cloneNode(bool deep, ExceptionCode&);
virtual bool offsetInCharacters() const;
virtual int maxCharacterOffset() const;

@@ -139,9 +139,10 @@ String ShadowRoot::nodeName() const
return "#shadow-root";
}

PassRefPtr<Node> ShadowRoot::cloneNode(bool)
PassRefPtr<Node> ShadowRoot::cloneNode(bool, ExceptionCode& ec)
{
// ShadowRoot should not be arbitrarily cloned.
ec = DATA_CLONE_ERR;
return 0;
}

@@ -97,7 +97,7 @@ class ShadowRoot : public DocumentFragment, public TreeScope, public DoublyLinke
explicit ShadowRoot(Document*);
virtual ~ShadowRoot();
virtual String nodeName() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual PassRefPtr<Node> cloneNode(bool deep, ExceptionCode&);
virtual bool childTypeAllowed(NodeType) const;
virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE;

@@ -184,7 +184,7 @@ Node::NodeType Text::nodeType() const
return TEXT_NODE;
}

PassRefPtr<Node> Text::cloneNode(bool /*deep*/)
PassRefPtr<Node> Text::cloneNode(bool /*deep*/, ExceptionCode&)
{
return create(document(), data());
}
@@ -58,7 +58,7 @@ class Text : public CharacterData {
private:
virtual String nodeName() const;
virtual NodeType nodeType() const;
virtual PassRefPtr<Node> cloneNode(bool deep);
virtual PassRefPtr<Node> cloneNode(bool deep, ExceptionCode&);
virtual bool rendererIsNeeded(const NodeRenderingContext&);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
virtual bool childTypeAllowed(NodeType) const;

0 comments on commit ce7c380

Please sign in to comment.