Changeset 177314 in webkit


Ignore:
Timestamp:
Dec 15, 2014 2:19:38 PM (9 years ago)
Author:
rniwa@webkit.org
Message:

cloneNode(true) does not clone nested template elements' contents
https://bugs.webkit.org/show_bug.cgi?id=137755

Reviewed by Darin Adler.

Source/WebCore:

The bug was caused by cloneChildNodes not copying template element's content.

Fixed the bug by adding the third behavior (CloneContent) to the polymorphic
cloneNodeInternal, which copies template element's content but not its children,
in addition to the existing CloneSelf (deep=false) and CloneChildren (deep=true).

Test: fast/dom/HTMLTemplateElement/cloneNode-nested-templates.html

  • dom/Attr.cpp:

(WebCore::Attr::cloneNodeInternal): Renamed from cloneNode.

  • dom/Attr.h:
  • dom/CDATASection.cpp:

(WebCore::CDATASection::cloneNodeInternal): Renamed from cloneNode.

  • dom/CDATASection.h:
  • dom/Comment.cpp:

(WebCore::Comment::cloneNodeInternal): Renamed from cloneNode.

  • dom/Comment.h:
  • dom/ContainerNode.cpp:

(WebCore::ContainerNode::cloneChildNodes): Calls cloneNode with CloneContent.

  • dom/Document.cpp:

(WebCore::Document::cloneNodeInternal): Renamed from cloneNode.

  • dom/Document.h:
  • dom/DocumentFragment.cpp:

(WebCore::DocumentFragment::cloneNodeInternal): Renamed from cloneNode.

  • dom/DocumentFragment.h:
  • dom/DocumentType.cpp:

(WebCore::DocumentType::cloneNodeInternal): Renamed from cloneNode.

  • dom/DocumentType.h:
  • dom/Element.cpp:

(WebCore::Element::cloneNodeInternal): Renamed from cloneNode.

  • dom/Element.h:
  • dom/EntityReference.cpp:

(WebCore::EntityReference::cloneNodeInternal): Renamed from cloneNode.

  • dom/EntityReference.h:
  • dom/Node.h:

(WebCore::Node::cloneNode): Added. It calls cloneNodeInternal with CloneSelf or CloneChildren.

  • dom/ProcessingInstruction.cpp:

(WebCore::ProcessingInstruction::cloneNodeInternal): Renamed from cloneNode.

  • dom/ProcessingInstruction.h:
  • dom/ShadowRoot.cpp:

(WebCore::ShadowRoot::cloneNodeInternal): Renamed from cloneNode. Also moved from ShadowRoot.h.

  • dom/ShadowRoot.h:
  • dom/Text.cpp:

(WebCore::Text::cloneNodeInternal): Renamed from cloneNode.

  • dom/Text.h:
  • html/HTMLTemplateElement.cpp:

(WebCore::HTMLTemplateElement::cloneNodeInternal): Renamed from cloneNode. This is the only
function in which CloneContent results in a different behavior from CloneSelf.

  • html/HTMLTemplateElement.h:

LayoutTests:

Added a regression test.

  • fast/dom/HTMLTemplateElement/cloneNode-nested-templates-expected.txt: Added.
  • fast/dom/HTMLTemplateElement/cloneNode-nested-templates.html: Added.
Location:
trunk
Files:
2 added
28 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r177313 r177314  
     12014-12-15  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        cloneNode(true) does not clone nested template elements' contents
     4        https://bugs.webkit.org/show_bug.cgi?id=137755
     5
     6        Reviewed by Darin Adler.
     7
     8        Added a regression test.
     9
     10        * fast/dom/HTMLTemplateElement/cloneNode-nested-templates-expected.txt: Added.
     11        * fast/dom/HTMLTemplateElement/cloneNode-nested-templates.html: Added.
     12
    1132014-12-15  Benjamin Poulain  <bpoulain@apple.com>
    214
  • trunk/Source/WebCore/ChangeLog

    r177313 r177314  
     12014-12-15  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        cloneNode(true) does not clone nested template elements' contents
     4        https://bugs.webkit.org/show_bug.cgi?id=137755
     5
     6        Reviewed by Darin Adler.
     7
     8        The bug was caused by cloneChildNodes not copying template element's content.
     9
     10        Fixed the bug by adding the third behavior (CloneContent) to the polymorphic
     11        cloneNodeInternal, which copies template element's content but not its children,
     12        in addition to the existing CloneSelf (deep=false) and CloneChildren (deep=true).
     13
     14        Test: fast/dom/HTMLTemplateElement/cloneNode-nested-templates.html
     15
     16        * dom/Attr.cpp:
     17        (WebCore::Attr::cloneNodeInternal): Renamed from cloneNode.
     18        * dom/Attr.h:
     19        * dom/CDATASection.cpp:
     20        (WebCore::CDATASection::cloneNodeInternal): Renamed from cloneNode.
     21        * dom/CDATASection.h:
     22        * dom/Comment.cpp:
     23        (WebCore::Comment::cloneNodeInternal): Renamed from cloneNode.
     24        * dom/Comment.h:
     25        * dom/ContainerNode.cpp:
     26        (WebCore::ContainerNode::cloneChildNodes): Calls cloneNode with CloneContent.
     27        * dom/Document.cpp:
     28        (WebCore::Document::cloneNodeInternal): Renamed from cloneNode.
     29        * dom/Document.h:
     30        * dom/DocumentFragment.cpp:
     31        (WebCore::DocumentFragment::cloneNodeInternal): Renamed from cloneNode.
     32        * dom/DocumentFragment.h:
     33        * dom/DocumentType.cpp:
     34        (WebCore::DocumentType::cloneNodeInternal): Renamed from cloneNode.
     35        * dom/DocumentType.h:
     36        * dom/Element.cpp:
     37        (WebCore::Element::cloneNodeInternal): Renamed from cloneNode.
     38        * dom/Element.h:
     39        * dom/EntityReference.cpp:
     40        (WebCore::EntityReference::cloneNodeInternal): Renamed from cloneNode.
     41        * dom/EntityReference.h:
     42        * dom/Node.h:
     43        (WebCore::Node::cloneNode): Added. It calls cloneNodeInternal with CloneSelf or CloneChildren.
     44        * dom/ProcessingInstruction.cpp:
     45        (WebCore::ProcessingInstruction::cloneNodeInternal): Renamed from cloneNode.
     46        * dom/ProcessingInstruction.h:
     47        * dom/ShadowRoot.cpp:
     48        (WebCore::ShadowRoot::cloneNodeInternal): Renamed from cloneNode. Also moved from ShadowRoot.h.
     49        * dom/ShadowRoot.h:
     50        * dom/Text.cpp:
     51        (WebCore::Text::cloneNodeInternal): Renamed from cloneNode.
     52        * dom/Text.h:
     53        * html/HTMLTemplateElement.cpp:
     54        (WebCore::HTMLTemplateElement::cloneNodeInternal): Renamed from cloneNode. This is the only
     55        function in which CloneContent results in a different behavior from CloneSelf.
     56        * html/HTMLTemplateElement.h:
     57
    1582014-12-15  Benjamin Poulain  <bpoulain@apple.com>
    259
  • trunk/Source/WebCore/dom/Attr.cpp

    r176502 r177314  
    138138}
    139139
    140 RefPtr<Node> Attr::cloneNode(bool /*deep*/)
     140RefPtr<Node> Attr::cloneNodeInternal(CloningOperation)
    141141{
    142142    RefPtr<Attr> clone = adoptRef(new Attr(document(), qualifiedName(), value()));
  • trunk/Source/WebCore/dom/Attr.h

    r176502 r177314  
    8181    virtual String nodeValue() const override { return value(); }
    8282    virtual void setNodeValue(const String&, ExceptionCode&) override;
    83     virtual RefPtr<Node> cloneNode(bool deep) override;
     83    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
    8484
    8585    virtual bool isAttributeNode() const override { return true; }
  • trunk/Source/WebCore/dom/CDATASection.cpp

    r176502 r177314  
    4747}
    4848
    49 RefPtr<Node> CDATASection::cloneNode(bool /*deep*/)
     49RefPtr<Node> CDATASection::cloneNodeInternal(CloningOperation)
    5050{
    5151    return create(document(), data());
  • trunk/Source/WebCore/dom/CDATASection.h

    r176502 r177314  
    3737    virtual String nodeName() const override;
    3838    virtual NodeType nodeType() const override;
    39     virtual RefPtr<Node> cloneNode(bool deep) override;
     39    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
    4040    virtual bool childTypeAllowed(NodeType) const override;
    4141    virtual RefPtr<Text> virtualCreate(const String&) override;
  • trunk/Source/WebCore/dom/Comment.cpp

    r176502 r177314  
    5252}
    5353
    54 RefPtr<Node> Comment::cloneNode(bool /*deep*/)
     54RefPtr<Node> Comment::cloneNodeInternal(CloningOperation)
    5555{
    5656    return create(document(), data());
  • trunk/Source/WebCore/dom/Comment.h

    r176502 r177314  
    3838    virtual String nodeName() const override;
    3939    virtual NodeType nodeType() const override;
    40     virtual RefPtr<Node> cloneNode(bool deep) override;
     40    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
    4141    virtual bool childTypeAllowed(NodeType) const override;
    4242};
  • trunk/Source/WebCore/dom/ContainerNode.cpp

    r177301 r177314  
    770770    ExceptionCode ec = 0;
    771771    for (Node* child = firstChild(); child && !ec; child = child->nextSibling()) {
    772         RefPtr<Node> clonedChild = child->cloneNode(false);
     772        RefPtr<Node> clonedChild = child->cloneNodeInternal(CloningOperation::SelfWithTemplateContent);
    773773        clone->appendChild(clonedChild, ec);
    774774
  • trunk/Source/WebCore/dom/Document.cpp

    r177302 r177314  
    31843184}
    31853185
    3186 RefPtr<Node> Document::cloneNode(bool deep)
     3186RefPtr<Node> Document::cloneNodeInternal(CloningOperation type)
    31873187{
    31883188    RefPtr<Document> clone = cloneDocumentWithoutChildren();
    31893189    clone->cloneDataFromDocument(*this);
    3190     if (deep)
     3190    switch (type) {
     3191    case CloningOperation::OnlySelf:
     3192    case CloningOperation::SelfWithTemplateContent:
     3193        break;
     3194    case CloningOperation::Everything:
    31913195        cloneChildNodes(clone.get());
     3196        break;
     3197    }
    31923198    return clone;
    31933199}
  • trunk/Source/WebCore/dom/Document.h

    r177280 r177314  
    13091309    virtual NodeType nodeType() const override final;
    13101310    virtual bool childTypeAllowed(NodeType) const override final;
    1311     virtual RefPtr<Node> cloneNode(bool deep) override final;
     1311    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override final;
    13121312    void cloneDataFromDocument(const Document&);
    13131313
  • trunk/Source/WebCore/dom/DocumentFragment.cpp

    r176502 r177314  
    7272}
    7373
    74 RefPtr<Node> DocumentFragment::cloneNode(bool deep)
     74RefPtr<Node> DocumentFragment::cloneNodeInternal(CloningOperation type)
    7575{
    7676    RefPtr<DocumentFragment> clone = create(document());
    77     if (deep)
     77    switch (type) {
     78    case CloningOperation::OnlySelf:
     79    case CloningOperation::SelfWithTemplateContent:
     80        break;
     81    case CloningOperation::Everything:
    7882        cloneChildNodes(clone.get());
     83        break;
     84    }
    7985    return clone;
    8086}
  • trunk/Source/WebCore/dom/DocumentFragment.h

    r176502 r177314  
    4949private:
    5050    virtual NodeType nodeType() const override final;
    51     virtual RefPtr<Node> cloneNode(bool deep) override;
     51    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
    5252    virtual bool childTypeAllowed(NodeType) const override;
    5353};
  • trunk/Source/WebCore/dom/DocumentType.cpp

    r176502 r177314  
    5252}
    5353
    54 RefPtr<Node> DocumentType::cloneNode(bool /*deep*/)
     54RefPtr<Node> DocumentType::cloneNodeInternal(CloningOperation)
    5555{
    5656    return create(document(), m_name, m_publicId, m_systemId);
  • trunk/Source/WebCore/dom/DocumentType.h

    r176502 r177314  
    5353    virtual String nodeName() const override;
    5454    virtual NodeType nodeType() const override;
    55     virtual RefPtr<Node> cloneNode(bool deep) override;
     55    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
    5656
    5757    String m_name;
  • trunk/Source/WebCore/dom/Element.cpp

    r177293 r177314  
    290290DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, load);
    291291
    292 RefPtr<Node> Element::cloneNode(bool deep)
    293 {
    294     return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
     292RefPtr<Node> Element::cloneNodeInternal(CloningOperation type)
     293{
     294    switch (type) {
     295    case CloningOperation::OnlySelf:
     296    case CloningOperation::SelfWithTemplateContent:
     297        return cloneElementWithoutChildren();
     298    case CloningOperation::Everything:
     299        return cloneElementWithChildren();
     300    }
     301    ASSERT_NOT_REACHED();
     302    return nullptr;
    295303}
    296304
  • trunk/Source/WebCore/dom/Element.h

    r177293 r177314  
    633633    // cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren
    634634    // are used instead.
    635     virtual RefPtr<Node> cloneNode(bool deep) override;
     635    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
    636636    virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren();
    637637
  • trunk/Source/WebCore/dom/EntityReference.cpp

    r176502 r177314  
    4747}
    4848
    49 RefPtr<Node> EntityReference::cloneNode(bool)
     49RefPtr<Node> EntityReference::cloneNodeInternal(CloningOperation)
    5050{
    5151    return create(document(), m_entityName);
  • trunk/Source/WebCore/dom/EntityReference.h

    r176502 r177314  
    3636    virtual String nodeName() const override;
    3737    virtual NodeType nodeType() const override;
    38     virtual RefPtr<Node> cloneNode(bool deep) override;
     38    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
    3939
    4040    String m_entityName;
  • trunk/Source/WebCore/dom/Node.h

    r177301 r177314  
    204204    WEBCORE_EXPORT void remove(ExceptionCode&);
    205205    bool hasChildNodes() const { return firstChild(); }
    206     virtual RefPtr<Node> cloneNode(bool deep) = 0;
     206
     207    enum class CloningOperation {
     208        OnlySelf,
     209        SelfWithTemplateContent,
     210        Everything,
     211    };
     212    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) = 0;
     213    RefPtr<Node> cloneNode(bool deep) { return cloneNodeInternal(deep ? CloningOperation::Everything : CloningOperation::OnlySelf); }
     214
    207215    virtual const AtomicString& localName() const;
    208216    virtual const AtomicString& namespaceURI() const;
  • trunk/Source/WebCore/dom/ProcessingInstruction.cpp

    r176502 r177314  
    8080}
    8181
    82 RefPtr<Node> ProcessingInstruction::cloneNode(bool /*deep*/)
     82RefPtr<Node> ProcessingInstruction::cloneNodeInternal(CloningOperation)
    8383{
    8484    // FIXME: Is it a problem that this does not copy m_localHref?
  • trunk/Source/WebCore/dom/ProcessingInstruction.h

    r176502 r177314  
    5959    virtual String nodeName() const override;
    6060    virtual NodeType nodeType() const override;
    61     virtual RefPtr<Node> cloneNode(bool deep) override;
     61    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
    6262
    6363    virtual InsertionNotificationRequest insertedInto(ContainerNode&) override;
  • trunk/Source/WebCore/dom/ShadowRoot.cpp

    r168209 r177314  
    132132}
    133133
     134RefPtr<Node> ShadowRoot::cloneNodeInternal(CloningOperation)
     135{
     136    return nullptr; // ShadowRoots should never be cloned.
     137}
     138
    134139void ShadowRoot::removeAllEventListeners()
    135140{
  • trunk/Source/WebCore/dom/ShadowRoot.h

    r176502 r177314  
    7777    virtual void childrenChanged(const ChildChange&) override;
    7878
    79     // ShadowRoots should never be cloned.
    80     virtual RefPtr<Node> cloneNode(bool) override { return 0; }
     79    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
    8180
    8281    // FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=88834
  • trunk/Source/WebCore/dom/Text.cpp

    r176502 r177314  
    170170}
    171171
    172 RefPtr<Node> Text::cloneNode(bool /*deep*/)
     172RefPtr<Node> Text::cloneNodeInternal(CloningOperation)
    173173{
    174174    return create(document(), data());
  • trunk/Source/WebCore/dom/Text.h

    r176502 r177314  
    6565    virtual String nodeName() const override;
    6666    virtual NodeType nodeType() const override;
    67     virtual RefPtr<Node> cloneNode(bool deep) override;
     67    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
    6868    virtual bool childTypeAllowed(NodeType) const override;
    6969
  • trunk/Source/WebCore/html/HTMLTemplateElement.cpp

    r176502 r177314  
    6969}
    7070
    71 RefPtr<Node> HTMLTemplateElement::cloneNode(bool deep)
     71RefPtr<Node> HTMLTemplateElement::cloneNodeInternal(CloningOperation type)
    7272{
    73     if (!deep)
     73    RefPtr<Node> clone;
     74    switch (type) {
     75    case CloningOperation::OnlySelf:
    7476        return cloneElementWithoutChildren();
    75 
    76     RefPtr<Node> clone = cloneElementWithChildren();
     77    case CloningOperation::SelfWithTemplateContent:
     78        clone = cloneElementWithoutChildren();
     79        break;
     80    case CloningOperation::Everything:
     81        clone = cloneElementWithChildren();
     82        break;
     83    }
    7784    if (m_content)
    7885        content()->cloneChildNodes(downcast<HTMLTemplateElement>(clone.get())->content());
  • trunk/Source/WebCore/html/HTMLTemplateElement.h

    r176502 r177314  
    5151    HTMLTemplateElement(const QualifiedName&, Document&);
    5252
    53     virtual RefPtr<Node> cloneNode(bool deep) override;
     53    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
    5454    virtual void didMoveToNewDocument(Document* oldDocument) override;
    5555
Note: See TracChangeset for help on using the changeset viewer.