Changeset 109251 in webkit


Ignore:
Timestamp:
Feb 29, 2012 1:17:28 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

ShadowRoot need innerHTML
https://bugs.webkit.org/show_bug.cgi?id=78473

Patch by Kaustubh Atrawalkar <Kaustubh Atrawalkar> on 2012-02-29
Reviewed by Hajime Morita.

Source/WebCore:

Refactor code for sharing common code between HTMLElement & ShadowRoot.
Implement innerHTML attribute for ShadowRoot.

Test: fast/dom/shadow/shadow-root-innerHTML.html

  • dom/ShadowRoot.cpp:

(WebCore::ShadowRoot::cloneNode):
(WebCore):
(WebCore::ShadowRoot::innerHTML):
(WebCore::ShadowRoot::setInnerHTML):

  • dom/ShadowRoot.h:

(ShadowRoot):

  • dom/ShadowRoot.idl:
  • editing/markup.cpp:

(WebCore::urlToMarkup):
(WebCore):
(WebCore::createFragmentFromSource):
(WebCore::hasOneChild):
(WebCore::hasOneTextChild):
(WebCore::replaceChildrenWithFragment):
(WebCore::replaceChildrenWithText):

  • editing/markup.h:
  • html/HTMLElement.cpp:

(WebCore):

LayoutTests:

Implement innerHTML attribute for ShadowRoot.

  • fast/dom/shadow/shadow-root-innerHTML-expected.txt: Added.
  • fast/dom/shadow/shadow-root-innerHTML.html: Added.
  • platform/qt/Skipped: Added test case in Skipped as ShadowRoot is supported by Chromium only.
  • platform/mac/Skipped: ditto.
  • platform/win/Skipped: ditto.
  • platform/wincairo/Skipped: ditto.
  • platform/wk2/Skipped: ditto.
Location:
trunk
Files:
2 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r109250 r109251  
     12012-02-29  Kaustubh Atrawalkar  <kaustubh@motorola.com>
     2
     3        ShadowRoot need innerHTML
     4        https://bugs.webkit.org/show_bug.cgi?id=78473
     5
     6        Reviewed by Hajime Morita.
     7
     8        Implement innerHTML attribute for ShadowRoot.
     9
     10        * fast/dom/shadow/shadow-root-innerHTML-expected.txt: Added.
     11        * fast/dom/shadow/shadow-root-innerHTML.html: Added.
     12        * platform/qt/Skipped: Added test case in Skipped as ShadowRoot is supported by Chromium only.
     13        * platform/mac/Skipped: ditto.
     14        * platform/win/Skipped: ditto.
     15        * platform/wincairo/Skipped: ditto.
     16        * platform/wk2/Skipped: ditto.
     17
    1182012-02-29  Adam Klein  <adamk@chromium.org>
    219
  • trunk/LayoutTests/platform/mac/Skipped

    r109238 r109251  
    433433fast/dom/shadow/shadow-disable.html
    434434fast/dom/shadow/shadow-root-attached.html
     435fast/dom/shadow/shadow-root-innerHTML.html
    435436fast/dom/shadow/shadow-root-new.html
    436437fast/dom/shadow/shadow-ul-li.html
  • trunk/LayoutTests/platform/qt/Skipped

    r109238 r109251  
    171171fast/dom/shadow/shadow-on-image.html
    172172fast/dom/shadow/shadow-root-attached.html
     173fast/dom/shadow/shadow-root-innerHTML.html
    173174fast/dom/shadow/shadow-root-new.html
    174175fast/dom/shadow/shadow-ul-li.html
  • trunk/LayoutTests/platform/win/Skipped

    r109238 r109251  
    14591459fast/dom/shadow/shadow-disable.html
    14601460fast/dom/shadow/shadow-root-attached.html
     1461fast/dom/shadow/shadow-root-innerHTML.html
    14611462fast/dom/shadow/shadow-root-new.html
    14621463fast/dom/shadow/shadow-ul-li.html
  • trunk/LayoutTests/platform/wincairo/Skipped

    r109238 r109251  
    19731973fast/dom/shadow/shadow-disable.html
    19741974fast/dom/shadow/shadow-root-attached.html
     1975fast/dom/shadow/shadow-root-innerHTML.html
    19751976fast/dom/shadow/shadow-root-new.html
    19761977fast/dom/shadow/multiple-shadowroot.html
  • trunk/LayoutTests/platform/wk2/Skipped

    r109179 r109251  
    10701070fast/dom/shadow/shadow-disable.html
    10711071fast/dom/shadow/shadow-root-attached.html
     1072fast/dom/shadow/shadow-root-innerHTML.html
    10721073fast/dom/shadow/shadow-root-new.html
    10731074fast/dom/shadow/shadow-ul-li.html
  • trunk/Source/WebCore/ChangeLog

    r109246 r109251  
     12012-02-29  Kaustubh Atrawalkar  <kaustubh@motorola.com>
     2
     3        ShadowRoot need innerHTML
     4        https://bugs.webkit.org/show_bug.cgi?id=78473
     5
     6        Reviewed by Hajime Morita.
     7
     8        Refactor code for sharing common code between HTMLElement & ShadowRoot.
     9        Implement innerHTML attribute for ShadowRoot.
     10
     11        Test: fast/dom/shadow/shadow-root-innerHTML.html
     12
     13        * dom/ShadowRoot.cpp:
     14        (WebCore::ShadowRoot::cloneNode):
     15        (WebCore):
     16        (WebCore::ShadowRoot::innerHTML):
     17        (WebCore::ShadowRoot::setInnerHTML):
     18        * dom/ShadowRoot.h:
     19        (ShadowRoot):
     20        * dom/ShadowRoot.idl:
     21        * editing/markup.cpp:
     22        (WebCore::urlToMarkup):
     23        (WebCore):
     24        (WebCore::createFragmentFromSource):
     25        (WebCore::hasOneChild):
     26        (WebCore::hasOneTextChild):
     27        (WebCore::replaceChildrenWithFragment):
     28        (WebCore::replaceChildrenWithText):
     29        * editing/markup.h:
     30        * html/HTMLElement.cpp:
     31        (WebCore):
     32
    1332012-02-29  Julien Chaffraix  <jchaffraix@webkit.org>
    234
  • trunk/Source/WebCore/dom/ShadowRoot.cpp

    r109096 r109251  
    2929
    3030#include "Document.h"
     31#include "DocumentFragment.h"
    3132#include "Element.h"
    3233#include "HTMLContentElement.h"
     
    3738#include "ShadowTree.h"
    3839#include "SVGNames.h"
     40#include "markup.h"
    3941
    4042#if ENABLE(SHADOW_DOM)
     
    141143    // ShadowRoot should not be arbitrarily cloned.
    142144    return 0;
     145}
     146
     147String ShadowRoot::innerHTML() const
     148{
     149    return createMarkup(this, ChildrenOnly);
     150}
     151
     152void ShadowRoot::setInnerHTML(const String& markup, ExceptionCode& ec)
     153{
     154    RefPtr<DocumentFragment> fragment = createFragmentFromSource(markup, host(), ec);
     155    if (fragment)
     156        replaceChildrenWithFragment(this, fragment.release(), ec);
    143157}
    144158
  • trunk/Source/WebCore/dom/ShadowRoot.h

    r109179 r109251  
    7171    ShadowTree* tree() const;
    7272
     73    String innerHTML() const;
     74    void setInnerHTML(const String&, ExceptionCode&);
     75
    7376    ShadowRoot* youngerShadowRoot() const { return prev(); }
    7477    ShadowRoot* olderShadowRoot() const { return next(); }
  • trunk/Source/WebCore/dom/ShadowRoot.idl

    r107304 r109251  
    3434    ] ShadowRoot : DocumentFragment {
    3535        readonly attribute Element host;
     36
     37        attribute [TreatNullAs=NullString] DOMString innerHTML
     38            setter raises(DOMException);
     39
    3640        Element getElementById(in [Optional=DefaultIsUndefined] DOMString elementId);
    3741        NodeList getElementsByClassName(in [Optional=DefaultIsUndefined] DOMString className);
  • trunk/Source/WebCore/editing/markup.cpp

    r108137 r109251  
    4040#include "CSSValue.h"
    4141#include "CSSValueKeywords.h"
     42#include "ChildListMutationScope.h"
    4243#include "DeleteButtonController.h"
    4344#include "DocumentFragment.h"
    4445#include "DocumentType.h"
    4546#include "Editor.h"
     47#include "ExceptionCode.h"
    4648#include "Frame.h"
    4749#include "HTMLBodyElement.h"
     
    991993}
    992994
    993 }
     995PassRefPtr<DocumentFragment> createFragmentFromSource(const String& markup, Element* contextElement, ExceptionCode& ec)
     996{
     997    Document* document = contextElement->document();
     998    RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
     999
     1000    if (document->isHTMLDocument()) {
     1001        fragment->parseHTML(markup, contextElement);
     1002        return fragment;
     1003    }
     1004
     1005    bool wasValid = fragment->parseXML(markup, contextElement);
     1006    if (!wasValid) {
     1007        ec = INVALID_STATE_ERR;
     1008        return 0;
     1009    }
     1010    return fragment.release();
     1011}
     1012
     1013static inline bool hasOneChild(ContainerNode* node)
     1014{
     1015    Node* firstChild = node->firstChild();
     1016    return firstChild && !firstChild->nextSibling();
     1017}
     1018
     1019static inline bool hasOneTextChild(ContainerNode* node)
     1020{
     1021    return hasOneChild(node) && node->firstChild()->isTextNode();
     1022}
     1023
     1024void replaceChildrenWithFragment(ContainerNode* containerNode, PassRefPtr<DocumentFragment> fragment, ExceptionCode& ec)
     1025{
     1026#if ENABLE(MUTATION_OBSERVERS)
     1027    ChildListMutationScope mutation(containerNode);
     1028#endif
     1029
     1030    if (!fragment->firstChild()) {
     1031        containerNode->removeChildren();
     1032        return;
     1033    }
     1034
     1035    if (hasOneTextChild(containerNode) && hasOneTextChild(fragment.get())) {
     1036        toText(containerNode->firstChild())->setData(toText(fragment->firstChild())->data(), ec);
     1037        return;
     1038    }
     1039
     1040    if (hasOneChild(containerNode)) {
     1041        containerNode->replaceChild(fragment, containerNode->firstChild(), ec);
     1042        return;
     1043    }
     1044
     1045    containerNode->removeChildren();
     1046    containerNode->appendChild(fragment, ec);
     1047}
     1048
     1049void replaceChildrenWithText(ContainerNode* containerNode, const String& text, ExceptionCode& ec)
     1050{
     1051#if ENABLE(MUTATION_OBSERVERS)
     1052    ChildListMutationScope mutation(containerNode);
     1053#endif
     1054
     1055    if (hasOneTextChild(containerNode)) {
     1056        toText(containerNode->firstChild())->setData(text, ec);
     1057        return;
     1058    }
     1059
     1060    RefPtr<Text> textNode = Text::create(containerNode->document(), text);
     1061
     1062    if (hasOneChild(containerNode)) {
     1063        containerNode->replaceChild(textNode.release(), containerNode->firstChild(), ec);
     1064        return;
     1065    }
     1066
     1067    containerNode->removeChildren();
     1068    containerNode->appendChild(textNode.release(), ec);
     1069}
     1070
     1071}
  • trunk/Source/WebCore/editing/markup.h

    r97497 r109251  
    3434namespace WebCore {
    3535
     36    class ContainerNode;
    3637    class Document;
    3738    class DocumentFragment;
     
    4041    class Node;
    4142    class Range;
     43
     44    typedef int ExceptionCode;
    4245
    4346    enum EChildrenOnly { IncludeNode, ChildrenOnly };
     
    4851    PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document*, const String& markup, unsigned fragmentStart, unsigned fragmentEnd, const String& baseURL, FragmentScriptingPermission);
    4952    PassRefPtr<DocumentFragment> createFragmentFromNodes(Document*, const Vector<Node*>&);
     53    PassRefPtr<DocumentFragment> createFragmentFromSource(const String&, Element*, ExceptionCode&);
    5054
    5155    bool isPlainTextMarkup(Node *node);
     56
     57    // These methods are used by HTMLElement & ShadowRoot to replace the children with respected fragment/text.
     58    void replaceChildrenWithFragment(ContainerNode*, PassRefPtr<DocumentFragment>, ExceptionCode&);
     59    void replaceChildrenWithText(ContainerNode*, const String&, ExceptionCode&);
    5260
    5361    String createMarkup(const Range*,
  • trunk/Source/WebCore/html/HTMLElement.cpp

    r109149 r109251  
    344344}
    345345
    346 static inline bool hasOneChild(ContainerNode* node)
    347 {
    348     Node* firstChild = node->firstChild();
    349     return firstChild && !firstChild->nextSibling();
    350 }
    351 
    352 static inline bool hasOneTextChild(ContainerNode* node)
    353 {
    354     return hasOneChild(node) && node->firstChild()->isTextNode();
    355 }
    356 
    357 static void replaceChildrenWithFragment(HTMLElement* element, PassRefPtr<DocumentFragment> fragment, ExceptionCode& ec)
    358 {
    359 #if ENABLE(MUTATION_OBSERVERS)
    360     ChildListMutationScope mutation(element);
    361 #endif
    362 
    363     if (!fragment->firstChild()) {
    364         element->removeChildren();
    365         return;
    366     }
    367 
    368     if (hasOneTextChild(element) && hasOneTextChild(fragment.get())) {
    369         toText(element->firstChild())->setData(toText(fragment->firstChild())->data(), ec);
    370         return;
    371     }
    372 
    373     if (hasOneChild(element)) {
    374         element->replaceChild(fragment, element->firstChild(), ec);
    375         return;
    376     }
    377 
    378     element->removeChildren();
    379     element->appendChild(fragment, ec);
    380 }
    381 
    382 static void replaceChildrenWithText(HTMLElement* element, const String& text, ExceptionCode& ec)
    383 {
    384 #if ENABLE(MUTATION_OBSERVERS)
    385     ChildListMutationScope mutation(element);
    386 #endif
    387 
    388     if (hasOneTextChild(element)) {
    389         toText(element->firstChild())->setData(text, ec);
    390         return;
    391     }
    392 
    393     RefPtr<Text> textNode = Text::create(element->document(), text);
    394 
    395     if (hasOneChild(element)) {
    396         element->replaceChild(textNode.release(), element->firstChild(), ec);
    397         return;
    398     }
    399 
    400     element->removeChildren();
    401     element->appendChild(textNode.release(), ec);
    402 }
    403 
    404 // We may want to move a version of this function into DocumentFragment.h/cpp
    405 static PassRefPtr<DocumentFragment> createFragmentFromSource(const String& markup, Element* contextElement, ExceptionCode& ec)
    406 {
    407     Document* document = contextElement->document();
    408     RefPtr<DocumentFragment> fragment;
    409 
    410     fragment = DocumentFragment::create(document);
    411     if (document->isHTMLDocument()) {
    412         fragment->parseHTML(markup, contextElement);
    413         return fragment;
    414     }
    415 
    416     bool wasValid = fragment->parseXML(markup, contextElement);
    417     if (!wasValid) {
    418         ec = INVALID_STATE_ERR;
    419         return 0;
    420     }
    421     return fragment;
    422 }
    423 
    424346void HTMLElement::setInnerHTML(const String& html, ExceptionCode& ec)
    425347{
Note: See TracChangeset for help on using the changeset viewer.