Title: [109251] trunk
Revision
109251
Author
[email protected]
Date
2012-02-29 13:17:28 -0800 (Wed, 29 Feb 2012)

Log Message

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

Patch by Kaustubh Atrawalkar <[email protected]> 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.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (109250 => 109251)


--- trunk/LayoutTests/ChangeLog	2012-02-29 21:15:27 UTC (rev 109250)
+++ trunk/LayoutTests/ChangeLog	2012-02-29 21:17:28 UTC (rev 109251)
@@ -1,3 +1,20 @@
+2012-02-29  Kaustubh Atrawalkar  <[email protected]>
+
+        ShadowRoot need innerHTML
+        https://bugs.webkit.org/show_bug.cgi?id=78473
+
+        Reviewed by Hajime Morita.
+
+        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.
+
 2012-02-29  Adam Klein  <[email protected]>
 
         Unreviewed gardening, mark a test as waiting for rebaselining after a skia update.

Added: trunk/LayoutTests/fast/dom/shadow/shadow-root-innerHTML-expected.txt (0 => 109251)


--- trunk/LayoutTests/fast/dom/shadow/shadow-root-innerHTML-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-root-innerHTML-expected.txt	2012-02-29 21:17:28 UTC (rev 109251)
@@ -0,0 +1,18 @@
+This tests the innerHTML property of a shadow root.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+PASS 'innerHTML' in internals.shadowRoot is false
+PASS root.innerHTML is defined.
+PASS root.innerHTML is '<div id="div1"></div><div id="div2"></div>'
+PASS root.innerHTML is 'Hello'
+PASS root.innerHTML is '<p id="p3">HelloWorld</p>'
+PASS root.firstChild.nodeName is 'P'
+PASS root.querySelectorAll('div') is []
+PASS root.getElementById('p3').innerHTML is 'HelloWorld'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/shadow/shadow-root-innerHTML.html (0 => 109251)


--- trunk/LayoutTests/fast/dom/shadow/shadow-root-innerHTML.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/shadow/shadow-root-innerHTML.html	2012-02-29 21:17:28 UTC (rev 109251)
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<div id="console">
+</div>
+<script>
+description("This tests the innerHTML property of a shadow root.");
+
+if (!window.internals)
+    debug('This test runs on DRT only');
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+
+host = document.createElement("div");
+document.body.appendChild(host);
+root = new WebKitShadowRoot(host);
+
+var div1 = document.createElement("div");
+div1.setAttribute("id", "div1");
+root.appendChild(div1);
+
+var div2 = document.createElement("div");
+div2.setAttribute("id", "div2");
+root.appendChild(div2);
+
+shouldBeFalse("'innerHTML' in internals.shadowRoot");
+shouldBeDefined("root.innerHTML");
+shouldBe("root.innerHTML", "'<div id=\"div1\"></div><div id=\"div2\"></div>'");
+
+root.innerHTML = "Hello";
+shouldBe("root.innerHTML", "'Hello'");
+
+root.innerHTML = "<p id=\"p3\">HelloWorld</p>";
+
+shouldBe("root.innerHTML", "'<p id=\"p3\">HelloWorld</p>'");
+shouldBe("root.firstChild.nodeName", "'P'");
+shouldBe("root.querySelectorAll('div')", "[]");
+shouldBe("root.getElementById('p3').innerHTML", "'HelloWorld'");
+
+}
+var successfullyParsed = true;
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/platform/mac/Skipped (109250 => 109251)


--- trunk/LayoutTests/platform/mac/Skipped	2012-02-29 21:15:27 UTC (rev 109250)
+++ trunk/LayoutTests/platform/mac/Skipped	2012-02-29 21:17:28 UTC (rev 109251)
@@ -432,6 +432,7 @@
 fast/dom/shadow/shadow-root-js-api.html
 fast/dom/shadow/shadow-disable.html
 fast/dom/shadow/shadow-root-attached.html
+fast/dom/shadow/shadow-root-innerHTML.html
 fast/dom/shadow/shadow-root-new.html
 fast/dom/shadow/shadow-ul-li.html
 fast/dom/shadow/multiple-shadowroot.html

Modified: trunk/LayoutTests/platform/qt/Skipped (109250 => 109251)


--- trunk/LayoutTests/platform/qt/Skipped	2012-02-29 21:15:27 UTC (rev 109250)
+++ trunk/LayoutTests/platform/qt/Skipped	2012-02-29 21:17:28 UTC (rev 109251)
@@ -170,6 +170,7 @@
 fast/dom/shadow/shadow-disable.html
 fast/dom/shadow/shadow-on-image.html
 fast/dom/shadow/shadow-root-attached.html
+fast/dom/shadow/shadow-root-innerHTML.html
 fast/dom/shadow/shadow-root-new.html
 fast/dom/shadow/shadow-ul-li.html
 fast/dom/shadow/multiple-shadowroot.html

Modified: trunk/LayoutTests/platform/win/Skipped (109250 => 109251)


--- trunk/LayoutTests/platform/win/Skipped	2012-02-29 21:15:27 UTC (rev 109250)
+++ trunk/LayoutTests/platform/win/Skipped	2012-02-29 21:17:28 UTC (rev 109251)
@@ -1458,6 +1458,7 @@
 fast/dom/shadow/shadow-root-js-api.html
 fast/dom/shadow/shadow-disable.html
 fast/dom/shadow/shadow-root-attached.html
+fast/dom/shadow/shadow-root-innerHTML.html
 fast/dom/shadow/shadow-root-new.html
 fast/dom/shadow/shadow-ul-li.html
 fast/dom/shadow/multiple-shadowroot.html

Modified: trunk/LayoutTests/platform/wincairo/Skipped (109250 => 109251)


--- trunk/LayoutTests/platform/wincairo/Skipped	2012-02-29 21:15:27 UTC (rev 109250)
+++ trunk/LayoutTests/platform/wincairo/Skipped	2012-02-29 21:17:28 UTC (rev 109251)
@@ -1972,6 +1972,7 @@
 fast/dom/shadow/shadow-root-js-api.html
 fast/dom/shadow/shadow-disable.html
 fast/dom/shadow/shadow-root-attached.html
+fast/dom/shadow/shadow-root-innerHTML.html
 fast/dom/shadow/shadow-root-new.html
 fast/dom/shadow/multiple-shadowroot.html
 fast/dom/shadow/multiple-shadowroot-rendering.html

Modified: trunk/LayoutTests/platform/wk2/Skipped (109250 => 109251)


--- trunk/LayoutTests/platform/wk2/Skipped	2012-02-29 21:15:27 UTC (rev 109250)
+++ trunk/LayoutTests/platform/wk2/Skipped	2012-02-29 21:17:28 UTC (rev 109251)
@@ -1069,6 +1069,7 @@
 fast/dom/shadow/shadow-root-js-api.html
 fast/dom/shadow/shadow-disable.html
 fast/dom/shadow/shadow-root-attached.html
+fast/dom/shadow/shadow-root-innerHTML.html
 fast/dom/shadow/shadow-root-new.html
 fast/dom/shadow/shadow-ul-li.html
 fast/dom/shadow/multiple-shadowroot.html

Modified: trunk/Source/WebCore/ChangeLog (109250 => 109251)


--- trunk/Source/WebCore/ChangeLog	2012-02-29 21:15:27 UTC (rev 109250)
+++ trunk/Source/WebCore/ChangeLog	2012-02-29 21:17:28 UTC (rev 109251)
@@ -1,3 +1,35 @@
+2012-02-29  Kaustubh Atrawalkar  <[email protected]>
+
+        ShadowRoot need innerHTML
+        https://bugs.webkit.org/show_bug.cgi?id=78473
+
+        Reviewed by Hajime Morita.
+
+        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):
+
 2012-02-29  Julien Chaffraix  <[email protected]>
 
         Stop doubling maximalOutlineSize during painting

Modified: trunk/Source/WebCore/dom/ShadowRoot.cpp (109250 => 109251)


--- trunk/Source/WebCore/dom/ShadowRoot.cpp	2012-02-29 21:15:27 UTC (rev 109250)
+++ trunk/Source/WebCore/dom/ShadowRoot.cpp	2012-02-29 21:17:28 UTC (rev 109251)
@@ -28,6 +28,7 @@
 #include "ShadowRoot.h"
 
 #include "Document.h"
+#include "DocumentFragment.h"
 #include "Element.h"
 #include "HTMLContentElement.h"
 #include "HTMLContentSelector.h"
@@ -36,6 +37,7 @@
 #include "NodeRareData.h"
 #include "ShadowTree.h"
 #include "SVGNames.h"
+#include "markup.h"
 
 #if ENABLE(SHADOW_DOM)
 #include "RuntimeEnabledFeatures.h"
@@ -142,6 +144,18 @@
     return 0;
 }
 
+String ShadowRoot::innerHTML() const
+{
+    return createMarkup(this, ChildrenOnly);
+}
+
+void ShadowRoot::setInnerHTML(const String& markup, ExceptionCode& ec)
+{
+    RefPtr<DocumentFragment> fragment = createFragmentFromSource(markup, host(), ec);
+    if (fragment)
+        replaceChildrenWithFragment(this, fragment.release(), ec);
+}
+
 bool ShadowRoot::childTypeAllowed(NodeType type) const
 {
     switch (type) {

Modified: trunk/Source/WebCore/dom/ShadowRoot.h (109250 => 109251)


--- trunk/Source/WebCore/dom/ShadowRoot.h	2012-02-29 21:15:27 UTC (rev 109250)
+++ trunk/Source/WebCore/dom/ShadowRoot.h	2012-02-29 21:17:28 UTC (rev 109251)
@@ -70,6 +70,9 @@
     Element* host() const { return shadowHost(); }
     ShadowTree* tree() const;
 
+    String innerHTML() const;
+    void setInnerHTML(const String&, ExceptionCode&);
+
     ShadowRoot* youngerShadowRoot() const { return prev(); }
     ShadowRoot* olderShadowRoot() const { return next(); }
 

Modified: trunk/Source/WebCore/dom/ShadowRoot.idl (109250 => 109251)


--- trunk/Source/WebCore/dom/ShadowRoot.idl	2012-02-29 21:15:27 UTC (rev 109250)
+++ trunk/Source/WebCore/dom/ShadowRoot.idl	2012-02-29 21:17:28 UTC (rev 109251)
@@ -33,6 +33,10 @@
         ConstructorRaisesException
     ] ShadowRoot : DocumentFragment {
         readonly attribute Element host;
+
+        attribute [TreatNullAs=NullString] DOMString innerHTML
+            setter raises(DOMException);
+
         Element getElementById(in [Optional=DefaultIsUndefined] DOMString elementId);
         NodeList getElementsByClassName(in [Optional=DefaultIsUndefined] DOMString className);
         NodeList getElementsByTagName(in [Optional=DefaultIsUndefined] DOMString tagName);

Modified: trunk/Source/WebCore/editing/markup.cpp (109250 => 109251)


--- trunk/Source/WebCore/editing/markup.cpp	2012-02-29 21:15:27 UTC (rev 109250)
+++ trunk/Source/WebCore/editing/markup.cpp	2012-02-29 21:17:28 UTC (rev 109251)
@@ -39,10 +39,12 @@
 #include "CSSStyleSelector.h"
 #include "CSSValue.h"
 #include "CSSValueKeywords.h"
+#include "ChildListMutationScope.h"
 #include "DeleteButtonController.h"
 #include "DocumentFragment.h"
 #include "DocumentType.h"
 #include "Editor.h"
+#include "ExceptionCode.h"
 #include "Frame.h"
 #include "HTMLBodyElement.h"
 #include "HTMLElement.h"
@@ -990,4 +992,80 @@
     return markup.toString();
 }
 
+PassRefPtr<DocumentFragment> createFragmentFromSource(const String& markup, Element* contextElement, ExceptionCode& ec)
+{
+    Document* document = contextElement->document();
+    RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
+
+    if (document->isHTMLDocument()) {
+        fragment->parseHTML(markup, contextElement);
+        return fragment;
+    }
+
+    bool wasValid = fragment->parseXML(markup, contextElement);
+    if (!wasValid) {
+        ec = INVALID_STATE_ERR;
+        return 0;
+    }
+    return fragment.release();
 }
+
+static inline bool hasOneChild(ContainerNode* node)
+{
+    Node* firstChild = node->firstChild();
+    return firstChild && !firstChild->nextSibling();
+}
+
+static inline bool hasOneTextChild(ContainerNode* node)
+{
+    return hasOneChild(node) && node->firstChild()->isTextNode();
+}
+
+void replaceChildrenWithFragment(ContainerNode* containerNode, PassRefPtr<DocumentFragment> fragment, ExceptionCode& ec)
+{
+#if ENABLE(MUTATION_OBSERVERS)
+    ChildListMutationScope mutation(containerNode);
+#endif
+
+    if (!fragment->firstChild()) {
+        containerNode->removeChildren();
+        return;
+    }
+
+    if (hasOneTextChild(containerNode) && hasOneTextChild(fragment.get())) {
+        toText(containerNode->firstChild())->setData(toText(fragment->firstChild())->data(), ec);
+        return;
+    }
+
+    if (hasOneChild(containerNode)) {
+        containerNode->replaceChild(fragment, containerNode->firstChild(), ec);
+        return;
+    }
+
+    containerNode->removeChildren();
+    containerNode->appendChild(fragment, ec);
+}
+
+void replaceChildrenWithText(ContainerNode* containerNode, const String& text, ExceptionCode& ec)
+{
+#if ENABLE(MUTATION_OBSERVERS)
+    ChildListMutationScope mutation(containerNode);
+#endif
+
+    if (hasOneTextChild(containerNode)) {
+        toText(containerNode->firstChild())->setData(text, ec);
+        return;
+    }
+
+    RefPtr<Text> textNode = Text::create(containerNode->document(), text);
+
+    if (hasOneChild(containerNode)) {
+        containerNode->replaceChild(textNode.release(), containerNode->firstChild(), ec);
+        return;
+    }
+
+    containerNode->removeChildren();
+    containerNode->appendChild(textNode.release(), ec);
+}
+
+}

Modified: trunk/Source/WebCore/editing/markup.h (109250 => 109251)


--- trunk/Source/WebCore/editing/markup.h	2012-02-29 21:15:27 UTC (rev 109250)
+++ trunk/Source/WebCore/editing/markup.h	2012-02-29 21:17:28 UTC (rev 109251)
@@ -33,6 +33,7 @@
 
 namespace WebCore {
 
+    class ContainerNode;
     class Document;
     class DocumentFragment;
     class Element;
@@ -40,6 +41,8 @@
     class Node;
     class Range;
 
+    typedef int ExceptionCode;
+
     enum EChildrenOnly { IncludeNode, ChildrenOnly };
     enum EAbsoluteURLs { DoNotResolveURLs, ResolveAllURLs, ResolveNonLocalURLs };
 
@@ -47,9 +50,14 @@
     PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document*, const String& markup, const String& baseURL, FragmentScriptingPermission = FragmentScriptingAllowed);
     PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document*, const String& markup, unsigned fragmentStart, unsigned fragmentEnd, const String& baseURL, FragmentScriptingPermission);
     PassRefPtr<DocumentFragment> createFragmentFromNodes(Document*, const Vector<Node*>&);
+    PassRefPtr<DocumentFragment> createFragmentFromSource(const String&, Element*, ExceptionCode&);
 
     bool isPlainTextMarkup(Node *node);
 
+    // These methods are used by HTMLElement & ShadowRoot to replace the children with respected fragment/text.
+    void replaceChildrenWithFragment(ContainerNode*, PassRefPtr<DocumentFragment>, ExceptionCode&);
+    void replaceChildrenWithText(ContainerNode*, const String&, ExceptionCode&);
+
     String createMarkup(const Range*,
         Vector<Node*>* = 0, EAnnotateForInterchange = DoNotAnnotateForInterchange, bool convertBlocksToInlines = false, EAbsoluteURLs = DoNotResolveURLs);
     String createMarkup(const Node*, EChildrenOnly = IncludeNode, Vector<Node*>* = 0, EAbsoluteURLs = DoNotResolveURLs);

Modified: trunk/Source/WebCore/html/HTMLElement.cpp (109250 => 109251)


--- trunk/Source/WebCore/html/HTMLElement.cpp	2012-02-29 21:15:27 UTC (rev 109250)
+++ trunk/Source/WebCore/html/HTMLElement.cpp	2012-02-29 21:17:28 UTC (rev 109251)
@@ -343,84 +343,6 @@
     return createMarkup(this);
 }
 
-static inline bool hasOneChild(ContainerNode* node)
-{
-    Node* firstChild = node->firstChild();
-    return firstChild && !firstChild->nextSibling();
-}
-
-static inline bool hasOneTextChild(ContainerNode* node)
-{
-    return hasOneChild(node) && node->firstChild()->isTextNode();
-}
-
-static void replaceChildrenWithFragment(HTMLElement* element, PassRefPtr<DocumentFragment> fragment, ExceptionCode& ec)
-{
-#if ENABLE(MUTATION_OBSERVERS)
-    ChildListMutationScope mutation(element);
-#endif
-
-    if (!fragment->firstChild()) {
-        element->removeChildren();
-        return;
-    }
-
-    if (hasOneTextChild(element) && hasOneTextChild(fragment.get())) {
-        toText(element->firstChild())->setData(toText(fragment->firstChild())->data(), ec);
-        return;
-    }
-
-    if (hasOneChild(element)) {
-        element->replaceChild(fragment, element->firstChild(), ec);
-        return;
-    }
-
-    element->removeChildren();
-    element->appendChild(fragment, ec);
-}
-
-static void replaceChildrenWithText(HTMLElement* element, const String& text, ExceptionCode& ec)
-{
-#if ENABLE(MUTATION_OBSERVERS)
-    ChildListMutationScope mutation(element);
-#endif
-
-    if (hasOneTextChild(element)) {
-        toText(element->firstChild())->setData(text, ec);
-        return;
-    }
-
-    RefPtr<Text> textNode = Text::create(element->document(), text);
-
-    if (hasOneChild(element)) {
-        element->replaceChild(textNode.release(), element->firstChild(), ec);
-        return;
-    }
-
-    element->removeChildren();
-    element->appendChild(textNode.release(), ec);
-}
-
-// We may want to move a version of this function into DocumentFragment.h/cpp
-static PassRefPtr<DocumentFragment> createFragmentFromSource(const String& markup, Element* contextElement, ExceptionCode& ec)
-{
-    Document* document = contextElement->document();
-    RefPtr<DocumentFragment> fragment;
-
-    fragment = DocumentFragment::create(document);
-    if (document->isHTMLDocument()) {
-        fragment->parseHTML(markup, contextElement);
-        return fragment;
-    }
-
-    bool wasValid = fragment->parseXML(markup, contextElement);
-    if (!wasValid) {
-        ec = INVALID_STATE_ERR;
-        return 0;
-    }
-    return fragment;
-}
-
 void HTMLElement::setInnerHTML(const String& html, ExceptionCode& ec)
 {
     RefPtr<DocumentFragment> fragment = createFragmentFromSource(html, this, ec);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to