Title: [205050] trunk
Revision
205050
Author
[email protected]
Date
2016-08-26 14:46:07 -0700 (Fri, 26 Aug 2016)

Log Message

The :enabled/:disabled selectors should only match elements that can be disabled.
<https://webkit.org/b/161255>

Reviewed by Chris Dumez.

LayoutTests/imported/w3c:

* web-platform-tests/html/semantics/selectors/pseudo-classes/disabled-expected.txt:

Source/WebCore:

Per the HTML spec, only the following elements can be actually disabled:

    button, input, select, textarea, optgroup, option, menuitem, fieldset

Since HTMLOutputElement inherits from HTMLFormControlElement, it had some
misguided ideas about being disableable. This was causing it to get matched
by :enabled and :disabled selectors.

Test: imported/w3c/web-platform-tests/html/semantics/selectors/pseudo-classes/disabled.html

* css/SelectorChecker.cpp:
(WebCore::SelectorChecker::checkOne):
* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::addPseudoClassType):
* css/SelectorCheckerTestFunctions.h:
(WebCore::matchesDisabledPseudoClass):
(WebCore::matchesEnabledPseudoClass): Renamed from isEnabled/isDisabled. Now only allows
:enabled and :disabled selectors to match elements that are actually disableable.

* html/HTMLElement.h:
* html/HTMLElement.cpp:
(WebCore::HTMLElement::canBeActuallyDisabled):
(WebCore::HTMLElement::isActuallyDisabled): Added supporting functions for the aforementioned selectors.

* html/HTMLFormControlElement.cpp:
(WebCore::HTMLFormControlElement::parseAttribute): Don't care about disabled state
changes in elements that are not disableable in the first place.

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (205049 => 205050)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2016-08-26 21:41:28 UTC (rev 205049)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2016-08-26 21:46:07 UTC (rev 205050)
@@ -1,3 +1,12 @@
+2016-08-26  Andreas Kling  <[email protected]>
+
+        The :enabled/:disabled selectors should only match elements that can be disabled.
+        <https://webkit.org/b/161255>
+
+        Reviewed by Chris Dumez.
+
+        * web-platform-tests/html/semantics/selectors/pseudo-classes/disabled-expected.txt:
+
 2016-08-26  Chris Dumez  <[email protected]>
 
         HTMLAreaElement's coords attributes parsing does not comply with the HTML specification

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/selectors/pseudo-classes/disabled-expected.txt (205049 => 205050)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/selectors/pseudo-classes/disabled-expected.txt	2016-08-26 21:41:28 UTC (rev 205049)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/selectors/pseudo-classes/disabled-expected.txt	2016-08-26 21:46:07 UTC (rev 205050)
@@ -1,10 +1,10 @@
 
-FAIL ':disabled' should match only disabled elements assert_array_equals: lengths differ, expected 9 got 10
-FAIL ':disabled' should not match elements whose disabled attribute has been removed assert_array_equals: lengths differ, expected 8 got 9
-FAIL ':disabled' should also match elements whose disabled attribute has been set assert_array_equals: lengths differ, expected 9 got 10
-FAIL ':disabled' should also match elements whose disabled attribute has been set twice assert_array_equals: lengths differ, expected 9 got 10
-FAIL ':disabled' should also match disabled elements whose type has changed assert_array_equals: lengths differ, expected 9 got 10
-FAIL ':disabled' should not match elements not in the document assert_array_equals: lengths differ, expected 9 got 10
+PASS ':disabled' should match only disabled elements 
+PASS ':disabled' should not match elements whose disabled attribute has been removed 
+PASS ':disabled' should also match elements whose disabled attribute has been set 
+PASS ':disabled' should also match elements whose disabled attribute has been set twice 
+PASS ':disabled' should also match disabled elements whose type has changed 
+PASS ':disabled' should not match elements not in the document 
 button1 button2         
 Name on card: 
 

Modified: trunk/Source/WebCore/ChangeLog (205049 => 205050)


--- trunk/Source/WebCore/ChangeLog	2016-08-26 21:41:28 UTC (rev 205049)
+++ trunk/Source/WebCore/ChangeLog	2016-08-26 21:46:07 UTC (rev 205050)
@@ -1,3 +1,38 @@
+2016-08-26  Andreas Kling  <[email protected]>
+
+        The :enabled/:disabled selectors should only match elements that can be disabled.
+        <https://webkit.org/b/161255>
+
+        Reviewed by Chris Dumez.
+
+        Per the HTML spec, only the following elements can be actually disabled:
+
+            button, input, select, textarea, optgroup, option, menuitem, fieldset
+
+        Since HTMLOutputElement inherits from HTMLFormControlElement, it had some
+        misguided ideas about being disableable. This was causing it to get matched
+        by :enabled and :disabled selectors.
+
+        Test: imported/w3c/web-platform-tests/html/semantics/selectors/pseudo-classes/disabled.html
+
+        * css/SelectorChecker.cpp:
+        (WebCore::SelectorChecker::checkOne):
+        * cssjit/SelectorCompiler.cpp:
+        (WebCore::SelectorCompiler::addPseudoClassType):
+        * css/SelectorCheckerTestFunctions.h:
+        (WebCore::matchesDisabledPseudoClass):
+        (WebCore::matchesEnabledPseudoClass): Renamed from isEnabled/isDisabled. Now only allows
+        :enabled and :disabled selectors to match elements that are actually disableable.
+
+        * html/HTMLElement.h:
+        * html/HTMLElement.cpp:
+        (WebCore::HTMLElement::canBeActuallyDisabled):
+        (WebCore::HTMLElement::isActuallyDisabled): Added supporting functions for the aforementioned selectors.
+
+        * html/HTMLFormControlElement.cpp:
+        (WebCore::HTMLFormControlElement::parseAttribute): Don't care about disabled state
+        changes in elements that are not disableable in the first place.
+
 2016-08-26  Chris Dumez  <[email protected]>
 
         REGRESSION(r204028): Fix unused-but-set-variable warning in generated JSNavigator.cpp

Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (205049 => 205050)


--- trunk/Source/WebCore/css/SelectorChecker.cpp	2016-08-26 21:41:28 UTC (rev 205049)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp	2016-08-26 21:46:07 UTC (rev 205050)
@@ -982,13 +982,13 @@
             }
             break;
         case CSSSelector::PseudoClassEnabled:
-            return isEnabled(element);
+            return matchesEnabledPseudoClass(element);
         case CSSSelector::PseudoClassFullPageMedia:
             return isMediaDocument(element);
         case CSSSelector::PseudoClassDefault:
             return matchesDefaultPseudoClass(element);
         case CSSSelector::PseudoClassDisabled:
-            return isDisabled(element);
+            return matchesDisabledPseudoClass(element);
         case CSSSelector::PseudoClassReadOnly:
             return matchesReadOnlyPseudoClass(element);
         case CSSSelector::PseudoClassReadWrite:

Modified: trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h (205049 => 205050)


--- trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h	2016-08-26 21:41:28 UTC (rev 205049)
+++ trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h	2016-08-26 21:46:07 UTC (rev 205050)
@@ -51,16 +51,16 @@
     return element.matchesDefaultPseudoClass();
 }
 
-ALWAYS_INLINE bool isDisabled(const Element& element)
+// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
+ALWAYS_INLINE bool matchesDisabledPseudoClass(const Element& element)
 {
-    return (is<HTMLFormControlElement>(element) || is<HTMLOptionElement>(element) || is<HTMLOptGroupElement>(element))
-        && element.isDisabledFormControl();
+    return is<HTMLElement>(element) && downcast<HTMLElement>(element).isActuallyDisabled();
 }
 
-ALWAYS_INLINE bool isEnabled(const Element& element)
+// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
+ALWAYS_INLINE bool matchesEnabledPseudoClass(const Element& element)
 {
-    return (is<HTMLFormControlElement>(element) || is<HTMLOptionElement>(element) || is<HTMLOptGroupElement>(element))
-        && !element.isDisabledFormControl();
+    return is<HTMLElement>(element) && downcast<HTMLElement>(element).canBeActuallyDisabled() && !element.isDisabledFormControl();
 }
 
 #if ENABLE(CUSTOM_ELEMENTS)

Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (205049 => 205050)


--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp	2016-08-26 21:41:28 UTC (rev 205049)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp	2016-08-26 21:46:07 UTC (rev 205050)
@@ -539,10 +539,10 @@
         fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr(matchesDefaultPseudoClass));
         return FunctionType::SimpleSelectorChecker;
     case CSSSelector::PseudoClassDisabled:
-        fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr(isDisabled));
+        fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr(matchesDisabledPseudoClass));
         return FunctionType::SimpleSelectorChecker;
     case CSSSelector::PseudoClassEnabled:
-        fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr(isEnabled));
+        fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr(matchesEnabledPseudoClass));
         return FunctionType::SimpleSelectorChecker;
 #if ENABLE(CUSTOM_ELEMENTS)
     case CSSSelector::PseudoClassDefined:

Modified: trunk/Source/WebCore/html/HTMLElement.cpp (205049 => 205050)


--- trunk/Source/WebCore/html/HTMLElement.cpp	2016-08-26 21:41:28 UTC (rev 205049)
+++ trunk/Source/WebCore/html/HTMLElement.cpp	2016-08-26 21:46:07 UTC (rev 205050)
@@ -41,12 +41,19 @@
 #include "FrameView.h"
 #include "HTMLBDIElement.h"
 #include "HTMLBRElement.h"
+#include "HTMLButtonElement.h"
 #include "HTMLCollection.h"
 #include "HTMLDocument.h"
 #include "HTMLElementFactory.h"
+#include "HTMLFieldSetElement.h"
 #include "HTMLFormElement.h"
+#include "HTMLInputElement.h"
 #include "HTMLNames.h"
+#include "HTMLOptGroupElement.h"
+#include "HTMLOptionElement.h"
 #include "HTMLParserIdioms.h"
+#include "HTMLSelectElement.h"
+#include "HTMLTextAreaElement.h"
 #include "HTMLTextFormControlElement.h"
 #include "NodeTraversal.h"
 #include "RenderElement.h"
@@ -1059,6 +1066,22 @@
     return !isDisabledFormControl() && Element::willRespondToMouseClickEvents();
 }
 
+bool HTMLElement::canBeActuallyDisabled() const
+{
+    return is<HTMLButtonElement>(*this)
+        || is<HTMLInputElement>(*this)
+        || is<HTMLSelectElement>(*this)
+        || is<HTMLTextAreaElement>(*this)
+        || is<HTMLOptGroupElement>(*this)
+        || is<HTMLOptionElement>(*this)
+        || is<HTMLFieldSetElement>(*this);
+}
+
+bool HTMLElement::isActuallyDisabled() const
+{
+    return canBeActuallyDisabled() && isDisabledFormControl();
+}
+
 } // namespace WebCore
 
 #ifndef NDEBUG

Modified: trunk/Source/WebCore/html/HTMLElement.h (205049 => 205050)


--- trunk/Source/WebCore/html/HTMLElement.h	2016-08-26 21:41:28 UTC (rev 205049)
+++ trunk/Source/WebCore/html/HTMLElement.h	2016-08-26 21:46:07 UTC (rev 205050)
@@ -95,6 +95,10 @@
 
     static const AtomicString& eventNameForEventHandlerAttribute(const QualifiedName& attributeName);
 
+    // Only some element types can be disabled: https://html.spec.whatwg.org/multipage/scripting.html#concept-element-disabled
+    bool canBeActuallyDisabled() const;
+    bool isActuallyDisabled() const;
+
 protected:
     HTMLElement(const QualifiedName& tagName, Document&, ConstructionType);
 

Modified: trunk/Source/WebCore/html/HTMLFormControlElement.cpp (205049 => 205050)


--- trunk/Source/WebCore/html/HTMLFormControlElement.cpp	2016-08-26 21:41:28 UTC (rev 205049)
+++ trunk/Source/WebCore/html/HTMLFormControlElement.cpp	2016-08-26 21:46:07 UTC (rev 205050)
@@ -146,10 +146,12 @@
     if (name == formAttr)
         formAttributeChanged();
     else if (name == disabledAttr) {
-        bool oldDisabled = m_disabled;
-        m_disabled = !value.isNull();
-        if (oldDisabled != m_disabled)
-            disabledAttributeChanged();
+        if (canBeActuallyDisabled()) {
+            bool oldDisabled = m_disabled;
+            m_disabled = !value.isNull();
+            if (oldDisabled != m_disabled)
+                disabledAttributeChanged();
+        }
     } else if (name == readonlyAttr) {
         bool wasReadOnly = m_isReadOnly;
         m_isReadOnly = !value.isNull();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to