Changing pseudoClass (:indeterminate) should cause distribution
authorshinyak@chromium.org <shinyak@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Nov 2012 15:55:13 +0000 (15:55 +0000)
committershinyak@chromium.org <shinyak@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Nov 2012 15:55:13 +0000 (15:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=101903

Reviewed by Dimitri Glazkov.

Source/WebCore:

<progress> and <input type="checkbox"> have 'indeterminate' state. When their state is changed, we have to
invalidate distribution if necessary. To check it, we collect a feature that :invalidate is used in select attributes.

For <input>, we also have to see 'type' is changed. According to the spec, :indeterminate should match only
progress element or <input type="checkbox">. So changing 'type' might also change :indeterminate state.

Tests: fast/dom/shadow/pseudoclass-update-indeterminate-input.html
       fast/dom/shadow/pseudoclass-update-indeterminate-progress.html

* dom/ElementShadow.cpp:
(WebCore::invalidateParentDistributionIfNecessary): Since we will add a lot of pseudoClass check later, we would like to
have this kind of helper method. We will add various pseudoClass check (see Bug 101697), we reuse CSSSelector::PseudoType
here.
(WebCore):
* dom/ElementShadow.h:
(WebCore):
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::updateType): Invalidate parent distribution anyway, since it changes various internal states.
(WebCore::HTMLInputElement::setIndeterminate): Invalidate parent distribution if necessary.
* html/HTMLProgressElement.cpp:
(WebCore::HTMLProgressElement::didElementStateChange):
* html/shadow/SelectRuleFeatureSet.cpp:
(WebCore::SelectRuleFeatureSet::SelectRuleFeatureSet): Adds m_usesIndeterminate feature.
(WebCore::SelectRuleFeatureSet::add):
(WebCore::SelectRuleFeatureSet::clear):
(WebCore::SelectRuleFeatureSet::collectFeaturesFromSelector):
* html/shadow/SelectRuleFeatureSet.h:
(WebCore::SelectRuleFeatureSet::hasSelectorForIndeterminate):
(SelectRuleFeatureSet):

LayoutTests:

* fast/dom/shadow/pseudoclass-update-indeterminate-input-expected.html: Added.
* fast/dom/shadow/pseudoclass-update-indeterminate-input.html: Added.
* fast/dom/shadow/pseudoclass-update-indeterminate-progress-expected.html: Added.
* fast/dom/shadow/pseudoclass-update-indeterminate-progress.html: Added.

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

12 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/shadow/pseudoclass-update-indeterminate-input-expected.html [new file with mode: 0644]
LayoutTests/fast/dom/shadow/pseudoclass-update-indeterminate-input.html [new file with mode: 0644]
LayoutTests/fast/dom/shadow/pseudoclass-update-indeterminate-progress-expected.html [new file with mode: 0644]
LayoutTests/fast/dom/shadow/pseudoclass-update-indeterminate-progress.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/ElementShadow.cpp
Source/WebCore/dom/ElementShadow.h
Source/WebCore/html/HTMLInputElement.cpp
Source/WebCore/html/HTMLProgressElement.cpp
Source/WebCore/html/shadow/SelectRuleFeatureSet.cpp
Source/WebCore/html/shadow/SelectRuleFeatureSet.h

index c5a9b21..3cd6aec 100644 (file)
@@ -1,3 +1,15 @@
+2012-11-13  Shinya Kawanaka  <shinyak@chromium.org>
+
+        Changing pseudoClass (:indeterminate) should cause distribution
+        https://bugs.webkit.org/show_bug.cgi?id=101903
+
+        Reviewed by Dimitri Glazkov.
+
+        * fast/dom/shadow/pseudoclass-update-indeterminate-input-expected.html: Added.
+        * fast/dom/shadow/pseudoclass-update-indeterminate-input.html: Added.
+        * fast/dom/shadow/pseudoclass-update-indeterminate-progress-expected.html: Added.
+        * fast/dom/shadow/pseudoclass-update-indeterminate-progress.html: Added.
+
 2012-11-13  Stephen Chenney  <schenney@chromium.org>
 
         Reverting expectations update because it breaks lint
diff --git a/LayoutTests/fast/dom/shadow/pseudoclass-update-indeterminate-input-expected.html b/LayoutTests/fast/dom/shadow/pseudoclass-update-indeterminate-input-expected.html
new file mode 100644 (file)
index 0000000..c08d479
--- /dev/null
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<body>
+
+<p>When input became 'indeterminate' state or not-'indeterminate' state, distribution should happen.</p>
+
+<div id="host"><span>separator 1</span><span>separator 2</span><input id="input3" type="checkbox" indeterminate="true"><span>separator 3</span><span>separator 4</span><input id="input5" type="checkbox" indeterminate="true"><span>separator 5</span></div>
+
+<script>
+input3.indeterminate = true;
+input5.indeterminate = true;
+</script>
+
+
+</body>
+</html>
+
diff --git a/LayoutTests/fast/dom/shadow/pseudoclass-update-indeterminate-input.html b/LayoutTests/fast/dom/shadow/pseudoclass-update-indeterminate-input.html
new file mode 100644 (file)
index 0000000..1a86a57
--- /dev/null
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="resources/polyfill.js"></script>
+</head>
+
+<body>
+
+<p>When input became 'indeterminate' state or not-'indeterminate' state, distribution should happen.</p>
+
+<div id="host">
+    <input id="input1" type="checkbox">
+    <span>separator 1</span>
+    <input id="input2" type="checkbox">
+    <span>separator 2</span>
+    <input id="input3" type="checkbox">
+    <span>separator 3</span>
+    <input id="input4" type="text">
+    <span>separator 4</span>
+    <input id="input5" type="text">
+    <span>separator 5</span>
+    <input id="input6" type="text">
+</div>
+<script>
+if (window.testRunner)
+    testRunner.waitUntilDone();
+
+input1.indeterminate = true;
+input2.indeterminate = true;
+input4.indeterminate = true;
+input5.indeterminate = true;
+
+var shadowRoot = new WebKitShadowRoot(host);
+shadowRoot.innerHTML = '<content select="span, input:indeterminate"></content>';
+
+setTimeout(function() {
+    input1.indeterminate = false;
+    input3.indeterminate = true;
+    input4.indeterminate = false;
+    input6.indeterminate = true;
+    
+    input2.type = 'text';
+    input5.type = 'checkbox';
+    testRunner.notifyDone();
+}, 0);
+
+</script>
+</body>
+</html>
+
diff --git a/LayoutTests/fast/dom/shadow/pseudoclass-update-indeterminate-progress-expected.html b/LayoutTests/fast/dom/shadow/pseudoclass-update-indeterminate-progress-expected.html
new file mode 100644 (file)
index 0000000..132e54b
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+
+<body>
+
+<p>When progress became 'indeterminate' or not-'indeterminate', distribution should happen.</p>
+
+<div id="host"><progress id="progress1"></progress><span>separator</span></div>
+</body>
+</html>
+
diff --git a/LayoutTests/fast/dom/shadow/pseudoclass-update-indeterminate-progress.html b/LayoutTests/fast/dom/shadow/pseudoclass-update-indeterminate-progress.html
new file mode 100644 (file)
index 0000000..b03798b
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="resources/polyfill.js"></script>
+</head>
+
+<body>
+
+<p>When progress became 'indeterminate' or not-'indeterminate', distribution should happen.</p>
+
+<div id="host">
+    <progress id="progress1"></progress>
+    <span>separator</span>
+    <progress id="progress2"></progress>
+</div>
+<script>
+if (window.testRunner)
+    testRunner.waitUntilDone();
+
+var shadowRoot = new WebKitShadowRoot(host);
+shadowRoot.innerHTML = '<content select="span,progress:indeterminate"></content>';
+progress1.value = '30';
+
+setTimeout(function() {
+    progress1.removeAttribute('value');
+    progress2.value = '70';
+    testRunner.notifyDone();
+}, 0);
+
+</script>
+</body>
+</html>
+
index 4c70c99..89e8f81 100644 (file)
@@ -1,3 +1,40 @@
+2012-11-13  Shinya Kawanaka  <shinyak@chromium.org>
+
+        Changing pseudoClass (:indeterminate) should cause distribution
+        https://bugs.webkit.org/show_bug.cgi?id=101903
+
+        Reviewed by Dimitri Glazkov.
+
+        <progress> and <input type="checkbox"> have 'indeterminate' state. When their state is changed, we have to
+        invalidate distribution if necessary. To check it, we collect a feature that :invalidate is used in select attributes.
+
+        For <input>, we also have to see 'type' is changed. According to the spec, :indeterminate should match only
+        progress element or <input type="checkbox">. So changing 'type' might also change :indeterminate state.
+
+        Tests: fast/dom/shadow/pseudoclass-update-indeterminate-input.html
+               fast/dom/shadow/pseudoclass-update-indeterminate-progress.html
+
+        * dom/ElementShadow.cpp:
+        (WebCore::invalidateParentDistributionIfNecessary): Since we will add a lot of pseudoClass check later, we would like to
+        have this kind of helper method. We will add various pseudoClass check (see Bug 101697), we reuse CSSSelector::PseudoType
+        here.
+        (WebCore):
+        * dom/ElementShadow.h:
+        (WebCore):
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::updateType): Invalidate parent distribution anyway, since it changes various internal states.
+        (WebCore::HTMLInputElement::setIndeterminate): Invalidate parent distribution if necessary.
+        * html/HTMLProgressElement.cpp:
+        (WebCore::HTMLProgressElement::didElementStateChange):
+        * html/shadow/SelectRuleFeatureSet.cpp:
+        (WebCore::SelectRuleFeatureSet::SelectRuleFeatureSet): Adds m_usesIndeterminate feature.
+        (WebCore::SelectRuleFeatureSet::add):
+        (WebCore::SelectRuleFeatureSet::clear):
+        (WebCore::SelectRuleFeatureSet::collectFeaturesFromSelector):
+        * html/shadow/SelectRuleFeatureSet.h:
+        (WebCore::SelectRuleFeatureSet::hasSelectorForIndeterminate):
+        (SelectRuleFeatureSet):
+
 2012-11-13  Andreas Kling  <kling@webkit.org>
 
         Exploit ElementAttributeData sharing in Node.cloneNode.
index d0705ef..f0de1da 100644 (file)
@@ -265,4 +265,21 @@ void ElementShadow::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
     info.addMember(m_distributor);
 }
 
+void invalidateParentDistributionIfNecessary(Element* element, CSSSelector::PseudoType updatedPseudoType)
+{
+    ElementShadow* elementShadow = shadowOfParentForDistribution(element);
+    if (!elementShadow)
+        return;
+
+    elementShadow->ensureSelectFeatureSetCollected();
+    switch (updatedPseudoType) {
+    case CSSSelector::PseudoIndeterminate:
+        if (elementShadow->selectRuleFeatureSet().hasSelectorForIndeterminate())
+            elementShadow->invalidateDistribution();
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+}
+
 } // namespace
index 613392b..fb41f03 100644 (file)
@@ -27,6 +27,7 @@
 #ifndef ElementShadow_h
 #define ElementShadow_h
 
+#include "CSSSelector.h"
 #include "ContentDistributor.h"
 #include "ExceptionCode.h"
 #include "SelectRuleFeatureSet.h"
@@ -89,6 +90,8 @@ private:
     bool m_shouldCollectSelectFeatureSet : 1;
 };
 
+void invalidateParentDistributionIfNecessary(Element*, CSSSelector::PseudoType updatedPseudoType);
+
 inline ShadowRoot* ElementShadow::youngestShadowRoot() const
 {
     return m_shadowRoots.head();
index e4c4609..106f505 100644 (file)
@@ -35,6 +35,7 @@
 #include "CSSValueKeywords.h"
 #include "DateTimeChooser.h"
 #include "Document.h"
+#include "ElementShadow.h"
 #include "EventNames.h"
 #include "ExceptionCode.h"
 #include "FileInputType.h"
@@ -50,6 +51,7 @@
 #include "HTMLParserIdioms.h"
 #include "IdTargetObserver.h"
 #include "InputType.h"
+#include "InsertionPoint.h"
 #include "KeyboardEvent.h"
 #include "LocalizedStrings.h"
 #include "MouseEvent.h"
@@ -531,6 +533,9 @@ void HTMLInputElement::updateType()
             updateFocusAppearance(true);
     }
 
+    if (ElementShadow* elementShadow = shadowOfParentForDistribution(this))
+        elementShadow->invalidateDistribution();
+
     setChangedSinceLastFormControlChangeEvent(false);
 
     addToRadioButtonGroup();
@@ -914,6 +919,7 @@ void HTMLInputElement::setIndeterminate(bool newValue)
     m_isIndeterminate = newValue;
 
     setNeedsStyleRecalc();
+    invalidateParentDistributionIfNecessary(this, CSSSelector::PseudoIndeterminate);
 
     if (renderer() && renderer()->style()->hasAppearance())
         renderer()->theme()->stateChanged(renderer(), CheckedState);
index 3c4c175..3bff0b5 100644 (file)
@@ -31,6 +31,7 @@
 #include "HTMLParserIdioms.h"
 #include "ProgressShadowElement.h"
 #include "RenderProgress.h"
+#include "SelectRuleFeatureSet.h"
 #include "ShadowRoot.h"
 #include <wtf/StdLibExtras.h>
 
@@ -158,8 +159,10 @@ void HTMLProgressElement::didElementStateChange()
     if (RenderProgress* render = renderProgress()) {
         bool wasDeterminate = render->isDeterminate();
         render->updateFromElement();
-        if (wasDeterminate != isDeterminate())
+        if (wasDeterminate != isDeterminate()) {
             setNeedsStyleRecalc();
+            invalidateParentDistributionIfNecessary(this, CSSSelector::PseudoIndeterminate);
+        }
     }
 }
 
index 8852c6b..02591b8 100644 (file)
 namespace WebCore {
 
 SelectRuleFeatureSet::SelectRuleFeatureSet()
+    : m_usesIndeterminate(false)
 {
 }
 
 void SelectRuleFeatureSet::add(const SelectRuleFeatureSet& featureSet)
 {
     m_cssRuleFeatureSet.add(featureSet.m_cssRuleFeatureSet);
+    m_usesIndeterminate |= featureSet.m_usesIndeterminate;
 }
 
 void SelectRuleFeatureSet::clear()
 {
     m_cssRuleFeatureSet.clear();
+    m_usesIndeterminate = false;
 }
 
 void SelectRuleFeatureSet::collectFeaturesFromSelector(const CSSSelector* selector)
 {
     m_cssRuleFeatureSet.collectFeaturesFromSelector(selector);
+    if (selector->pseudoType() == CSSSelector::PseudoIndeterminate)
+        m_usesIndeterminate = true;
 }
 
 }
index 218f451..71226ee 100644 (file)
@@ -47,8 +47,11 @@ public:
     bool hasSelectorForClass(const AtomicString&) const;
     bool hasSelectorForAttribute(const AtomicString&) const;
 
+    bool hasSelectorForIndeterminate() const { return m_usesIndeterminate; }
+
 private:
     RuleFeatureSet m_cssRuleFeatureSet;
+    bool m_usesIndeterminate;
 };
 
 inline bool SelectRuleFeatureSet::hasSelectorForId(const AtomicString& idValue) const