<style scoped>: Add 'scoped' attribute
authorrolandsteiner@chromium.org <rolandsteiner@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 8 Sep 2011 22:17:34 +0000 (22:17 +0000)
committerrolandsteiner@chromium.org <rolandsteiner@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 8 Sep 2011 22:17:34 +0000 (22:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=67718

Source/WebCore:

Add 'scoped' attribute to IDL and attribute list,
implement and test setting/resetting of the attribute.

Reviewed by Dimitri Glazkov.

Test: fast/css/style-scoped/basic-attribute.html

* html/HTMLAttributeNames.in:
* html/HTMLStyleElement.cpp:
(WebCore::HTMLStyleElement::scoped):
(WebCore::HTMLStyleElement::setScoped):
(WebCore::HTMLStyleElement::scopingElement):
* html/HTMLStyleElement.h:
* html/HTMLStyleElement.idl:

LayoutTests:

Test setting/resetting of the 'scoped' attribute in various circumstances.

Reviewed by Dimitri Glazkov.

* fast/css/style-scoped/basic-attribute-expected.txt: Added.
* fast/css/style-scoped/basic-attribute.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@94809 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/css/style-scoped/basic-attribute-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/style-scoped/basic-attribute.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLAttributeNames.in
Source/WebCore/html/HTMLStyleElement.cpp
Source/WebCore/html/HTMLStyleElement.h
Source/WebCore/html/HTMLStyleElement.idl

index 769e11d..40c1c1e 100644 (file)
@@ -1,3 +1,15 @@
+2011-09-08  Roland Steiner  <rolandsteiner@chromium.org>
+
+        <style scoped>: Add 'scoped' attribute
+        https://bugs.webkit.org/show_bug.cgi?id=67718
+
+        Test setting/resetting of the 'scoped' attribute in various circumstances.
+
+        Reviewed by Dimitri Glazkov.
+
+        * fast/css/style-scoped/basic-attribute-expected.txt: Added.
+        * fast/css/style-scoped/basic-attribute.html: Added.
+
 2011-09-08  Tony Chang  <tony@chromium.org>
 
         remove fast/exclusions/triangle-exclusion.html which was originally added as a placeholder
diff --git a/LayoutTests/fast/css/style-scoped/basic-attribute-expected.txt b/LayoutTests/fast/css/style-scoped/basic-attribute-expected.txt
new file mode 100644 (file)
index 0000000..58a0986
--- /dev/null
@@ -0,0 +1,62 @@
+Basic test for the <style scoped> attribute.
+
+--- Initial ---
+PASS global1.getAttribute('scoped') is null
+PASS global1.scoped is false
+PASS global2.getAttribute('scoped') is null
+PASS global2.scoped is false
+PASS testBooleanAttribute(scoped1, 'scoped') is true
+PASS scoped1.scoped is true
+PASS testBooleanAttribute(scoped2, 'scoped') is true
+PASS scoped2.scoped is true
+PASS testBooleanAttribute(scoped3, 'scoped') is true
+PASS scoped3.scoped is true
+--- After insertion into tree ---
+PASS global1.getAttribute('scoped') is null
+PASS global1.scoped is false
+PASS global2.getAttribute('scoped') is null
+PASS global2.scoped is false
+PASS testBooleanAttribute(scoped1, 'scoped') is true
+PASS scoped1.scoped is true
+PASS testBooleanAttribute(scoped2, 'scoped') is true
+PASS scoped2.scoped is true
+PASS testBooleanAttribute(scoped3, 'scoped') is true
+PASS scoped3.scoped is true
+--- Inverting 'scoped' attribute while in tree ---
+PASS testBooleanAttribute(global1, 'scoped') is true
+PASS global1.scoped is true
+PASS testBooleanAttribute(global2, 'scoped') is true
+PASS global2.scoped is true
+PASS scoped1.getAttribute('scoped') is null
+PASS scoped1.scoped is false
+PASS scoped2.getAttribute('scoped') is null
+PASS scoped2.scoped is false
+PASS scoped3.getAttribute('scoped') is null
+PASS scoped3.scoped is false
+--- After removal from tree (attribute is still inverted) ---
+PASS testBooleanAttribute(global1, 'scoped') is true
+PASS global1.scoped is true
+PASS testBooleanAttribute(global2, 'scoped') is true
+PASS global2.scoped is true
+PASS scoped1.getAttribute('scoped') is null
+PASS scoped1.scoped is false
+PASS scoped2.getAttribute('scoped') is null
+PASS scoped2.scoped is false
+PASS scoped3.getAttribute('scoped') is null
+PASS scoped3.scoped is false
+--- Inverting 'scoped' attribute again, while outside tree ---
+PASS global1.getAttribute('scoped') is null
+PASS global1.scoped is false
+PASS global2.getAttribute('scoped') is null
+PASS global2.scoped is false
+PASS testBooleanAttribute(scoped1, 'scoped') is true
+PASS scoped1.scoped is true
+PASS testBooleanAttribute(scoped2, 'scoped') is true
+PASS scoped2.scoped is true
+PASS testBooleanAttribute(scoped3, 'scoped') is true
+PASS scoped3.scoped is true
+--- DONE ---
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/css/style-scoped/basic-attribute.html b/LayoutTests/fast/css/style-scoped/basic-attribute.html
new file mode 100644 (file)
index 0000000..79135fe
--- /dev/null
@@ -0,0 +1,124 @@
+<html>
+<head>
+    <link rel="stylesheet" href="../../js/resources/js-test-style.css">
+    <script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+    <p>Basic test for the &lt;style scoped&gt; attribute.</p>
+    <div id="scope">
+        <style id="global1"></style>
+        <style scoped='scoped' id="scoped1"></style>
+    </div>
+
+    <div id="console"></div>
+
+    <script>
+        function testBooleanAttribute(elem, attr)
+        {
+            var val = elem.getAttribute(attr);
+            if (val === null)
+                return false
+            if (val === '' || val === attr)
+                return true;
+            throw "Illegal value for boolean attribute!";
+        }
+    
+        var scope = document.getElementById('scope');
+
+        var global1 = document.getElementById('global1');
+        var scoped1 = document.getElementById('scoped1');
+
+        var global2 = document.createElement('style');
+        var scoped2 = document.createElement('style');
+        scoped2.setAttribute('scoped', 'scoped');
+        var scoped3 = document.createElement('style');
+        scoped3.scoped = true;
+
+        debug("--- Initial ---");
+        shouldBeNull("global1.getAttribute('scoped')");
+        shouldBeFalse("global1.scoped");
+        shouldBeNull("global2.getAttribute('scoped')");
+        shouldBeFalse("global2.scoped");
+        shouldBeTrue("testBooleanAttribute(scoped1, 'scoped')");
+        shouldBeTrue("scoped1.scoped");
+        shouldBeTrue("testBooleanAttribute(scoped2, 'scoped')");
+        shouldBeTrue("scoped2.scoped");
+        shouldBeTrue("testBooleanAttribute(scoped3, 'scoped')");
+        shouldBeTrue("scoped3.scoped");
+
+        debug("--- After insertion into tree ---")
+        scope.appendChild(global2);
+        scope.appendChild(scoped2);
+        scope.appendChild(scoped3);
+
+        shouldBeNull("global1.getAttribute('scoped')");
+        shouldBeFalse("global1.scoped");
+        shouldBeNull("global2.getAttribute('scoped')");
+        shouldBeFalse("global2.scoped");
+        shouldBeTrue("testBooleanAttribute(scoped1, 'scoped')");
+        shouldBeTrue("scoped1.scoped");
+        shouldBeTrue("testBooleanAttribute(scoped2, 'scoped')");
+        shouldBeTrue("scoped2.scoped");
+        shouldBeTrue("testBooleanAttribute(scoped3, 'scoped')");
+        shouldBeTrue("scoped3.scoped");
+
+        debug("--- Inverting 'scoped' attribute while in tree ---");
+        scoped1.scoped = null;
+        scoped2.scoped = false;
+        scoped3.removeAttribute('scoped');
+        global1.scoped = true;
+        global2.setAttribute('scoped', 'scoped');
+
+        shouldBeTrue("testBooleanAttribute(global1, 'scoped')");
+        shouldBeTrue("global1.scoped");
+        shouldBeTrue("testBooleanAttribute(global2, 'scoped')");
+        shouldBeTrue("global2.scoped");
+        shouldBeNull("scoped1.getAttribute('scoped')");
+        shouldBeFalse("scoped1.scoped");
+        shouldBeNull("scoped2.getAttribute('scoped')");
+        shouldBeFalse("scoped2.scoped");
+        shouldBeNull("scoped3.getAttribute('scoped')");
+        shouldBeFalse("scoped3.scoped");
+
+        debug("--- After removal from tree (attribute is still inverted) ---");
+        scope.removeChild(global1);
+        scope.removeChild(global2);
+        scope.removeChild(scoped1);
+        scope.removeChild(scoped2);
+        scope.removeChild(scoped3);
+
+        shouldBeTrue("testBooleanAttribute(global1, 'scoped')");
+        shouldBeTrue("global1.scoped");
+        shouldBeTrue("testBooleanAttribute(global2, 'scoped')");
+        shouldBeTrue("global2.scoped");
+        shouldBeNull("scoped1.getAttribute('scoped')");
+        shouldBeFalse("scoped1.scoped");
+        shouldBeNull("scoped2.getAttribute('scoped')");
+        shouldBeFalse("scoped2.scoped");
+        shouldBeNull("scoped3.getAttribute('scoped')");
+        shouldBeFalse("scoped3.scoped");
+
+        debug("--- Inverting 'scoped' attribute again, while outside tree ---");
+        scoped1.scoped = true;
+        scoped2.scoped = true;
+        scoped3.setAttribute('scoped', 'scoped');
+        global1.scoped = false;
+        global2.removeAttribute('scoped');
+
+        shouldBeNull("global1.getAttribute('scoped')");
+        shouldBeFalse("global1.scoped");
+        shouldBeNull("global2.getAttribute('scoped')");
+        shouldBeFalse("global2.scoped");
+        shouldBeTrue("testBooleanAttribute(scoped1, 'scoped')");
+        shouldBeTrue("scoped1.scoped");
+        shouldBeTrue("testBooleanAttribute(scoped2, 'scoped')");
+        shouldBeTrue("scoped2.scoped");
+        shouldBeTrue("testBooleanAttribute(scoped3, 'scoped')");
+        shouldBeTrue("scoped3.scoped");
+
+        debug("--- DONE ---");
+        var successfullyParsed = true;
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
index bad4607..c22d8f2 100644 (file)
@@ -1,3 +1,23 @@
+2011-09-08  Roland Steiner  <rolandsteiner@chromium.org>
+
+        <style scoped>: Add 'scoped' attribute
+        https://bugs.webkit.org/show_bug.cgi?id=67718
+
+        Add 'scoped' attribute to IDL and attribute list,
+        implement and test setting/resetting of the attribute.
+
+        Reviewed by Dimitri Glazkov.
+
+        Test: fast/css/style-scoped/basic-attribute.html
+
+        * html/HTMLAttributeNames.in:
+        * html/HTMLStyleElement.cpp:
+        (WebCore::HTMLStyleElement::scoped):
+        (WebCore::HTMLStyleElement::setScoped):
+        (WebCore::HTMLStyleElement::scopingElement):
+        * html/HTMLStyleElement.h:
+        * html/HTMLStyleElement.idl:
+
 2011-09-08  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r94781.
index 799163c..916de48 100644 (file)
@@ -266,6 +266,7 @@ rules
 sandbox
 scheme
 scope
+scoped
 scrollamount
 scrolldelay
 scrolling
index 648d0bd..7312575 100644 (file)
@@ -94,6 +94,31 @@ const AtomicString& HTMLStyleElement::type() const
     return getAttribute(typeAttr);
 }
 
+bool HTMLStyleElement::scoped() const
+{
+    return fastHasAttribute(scopedAttr);
+}
+
+void HTMLStyleElement::setScoped(bool scopedValue)
+{
+    setBooleanAttribute(scopedAttr, scopedValue);
+}
+
+Element* HTMLStyleElement::scopingElement() const
+{
+    if (!scoped())
+        return 0;
+
+    // FIXME: This probably needs to be refined for scoped stylesheets within shadow DOM.
+    // As written, such a stylesheet could style the host element, as well as children of the host.
+    // OTOH, this paves the way for a :bound-element implementation.
+    ContainerNode* parentOrHost = parentOrHostNode();
+    if (!parentOrHost || !parentOrHost->isElementNode())
+        return 0;
+
+    return toElement(parentOrHost);
+}
+
 void HTMLStyleElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
 {    
     HTMLElement::addSubresourceAttributeURLs(urls);
index af28085..52e4f77 100644 (file)
@@ -37,6 +37,10 @@ public:
 
     void setType(const AtomicString&);
 
+    bool scoped() const;
+    void setScoped(bool);
+    Element* scopingElement() const;
+
     using StyleElement::sheet;
 
     bool disabled() const;
index c98629c..e863965 100644 (file)
@@ -22,6 +22,7 @@ module html {
 
     interface HTMLStyleElement : HTMLElement {
         attribute boolean disabled;
+        attribute boolean scoped;
         attribute [Reflect] DOMString media;
         attribute [Reflect] DOMString type;