Title: [289693] trunk
Revision
289693
Author
[email protected]
Date
2022-02-12 07:34:57 -0800 (Sat, 12 Feb 2022)

Log Message

Suppress style invalidation when matching :checked
https://bugs.webkit.org/show_bug.cgi?id=235910

Patch by Rob Buis <[email protected]> on 2022-02-12
Reviewed by Antti Koivisto.

Source/WebCore:

Suppress style invalidation when matching :checked for option elements.

Test: fast/selectors/has-select-option-crash.html

* css/SelectorCheckerTestFunctions.h:
(WebCore::isChecked):
* html/HTMLOptionElement.cpp:
(WebCore::HTMLOptionElement::selected const):
(WebCore::HTMLOptionElement::setSelectedState):
* html/HTMLOptionElement.h:
* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::updateListItemSelectedStates):
(WebCore::HTMLSelectElement::recalcListItems const):
* html/HTMLSelectElement.h:

LayoutTests:

* fast/selectors/has-select-option-crash-expected.txt: Added.
* fast/selectors/has-select-option-crash.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (289692 => 289693)


--- trunk/LayoutTests/ChangeLog	2022-02-12 15:29:06 UTC (rev 289692)
+++ trunk/LayoutTests/ChangeLog	2022-02-12 15:34:57 UTC (rev 289693)
@@ -1,3 +1,13 @@
+2022-02-12  Rob Buis  <[email protected]>
+
+        Suppress style invalidation when matching :checked
+        https://bugs.webkit.org/show_bug.cgi?id=235910
+
+        Reviewed by Antti Koivisto.
+
+        * fast/selectors/has-select-option-crash-expected.txt: Added.
+        * fast/selectors/has-select-option-crash.html: Added.
+
 2022-02-11  Alan Bujtas  <[email protected]>
 
         `contain:content` breaks fullscreen

Added: trunk/LayoutTests/fast/selectors/has-select-option-crash-expected.txt (0 => 289693)


--- trunk/LayoutTests/fast/selectors/has-select-option-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/selectors/has-select-option-crash-expected.txt	2022-02-12 15:34:57 UTC (rev 289693)
@@ -0,0 +1 @@
+PASS

Added: trunk/LayoutTests/fast/selectors/has-select-option-crash.html (0 => 289693)


--- trunk/LayoutTests/fast/selectors/has-select-option-crash.html	                        (rev 0)
+++ trunk/LayoutTests/fast/selectors/has-select-option-crash.html	2022-02-12 15:34:57 UTC (rev 289693)
@@ -0,0 +1,18 @@
+<style>
+  :has(:not(:checked)) {
+    foo: bar;
+  }
+</style>
+<script>
+  if (window.testRunner)
+    testRunner.dumpAsText();
+  _onload_ = () => {
+    let select = document.createElement('select');
+    document.head.append(document.createElement('object'));
+    document.head.append(select);
+    select.append(document.createElement('option'));
+    document.execCommand('SelectAll');
+    select.append(document.createElement('div'));
+    document.write('PASS');
+  };
+</script>

Modified: trunk/Source/WebCore/ChangeLog (289692 => 289693)


--- trunk/Source/WebCore/ChangeLog	2022-02-12 15:29:06 UTC (rev 289692)
+++ trunk/Source/WebCore/ChangeLog	2022-02-12 15:34:57 UTC (rev 289693)
@@ -1,3 +1,25 @@
+2022-02-12  Rob Buis  <[email protected]>
+
+        Suppress style invalidation when matching :checked
+        https://bugs.webkit.org/show_bug.cgi?id=235910
+
+        Reviewed by Antti Koivisto.
+
+        Suppress style invalidation when matching :checked for option elements.
+
+        Test: fast/selectors/has-select-option-crash.html
+
+        * css/SelectorCheckerTestFunctions.h:
+        (WebCore::isChecked):
+        * html/HTMLOptionElement.cpp:
+        (WebCore::HTMLOptionElement::selected const):
+        (WebCore::HTMLOptionElement::setSelectedState):
+        * html/HTMLOptionElement.h:
+        * html/HTMLSelectElement.cpp:
+        (WebCore::HTMLSelectElement::updateListItemSelectedStates):
+        (WebCore::HTMLSelectElement::recalcListItems const):
+        * html/HTMLSelectElement.h:
+
 2022-02-12  Cameron McCormack  <[email protected]>
 
         Make WidgetHierarchyUpdatesSuspensionScope cheaper if it has nothing to do

Modified: trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h (289692 => 289693)


--- trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h	2022-02-12 15:29:06 UTC (rev 289692)
+++ trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h	2022-02-12 15:34:57 UTC (rev 289693)
@@ -115,7 +115,7 @@
         return inputElement.shouldAppearChecked() && !inputElement.shouldAppearIndeterminate();
     }
     if (is<HTMLOptionElement>(element))
-        return const_cast<HTMLOptionElement&>(downcast<HTMLOptionElement>(element)).selected();
+        return const_cast<HTMLOptionElement&>(downcast<HTMLOptionElement>(element)).selected(AllowStyleInvalidation::No);
 
     return false;
 }

Modified: trunk/Source/WebCore/html/HTMLOptionElement.cpp (289692 => 289693)


--- trunk/Source/WebCore/html/HTMLOptionElement.cpp	2022-02-12 15:29:06 UTC (rev 289692)
+++ trunk/Source/WebCore/html/HTMLOptionElement.cpp	2022-02-12 15:34:57 UTC (rev 289693)
@@ -210,10 +210,10 @@
     setAttributeWithoutSynchronization(valueAttr, value);
 }
 
-bool HTMLOptionElement::selected() const
+bool HTMLOptionElement::selected(AllowStyleInvalidation allowStyleInvalidation) const
 {
     if (RefPtr select = ownerSelectElement())
-        select->updateListItemSelectedStates();
+        select->updateListItemSelectedStates(allowStyleInvalidation);
     return m_isSelected;
 }
 
@@ -228,12 +228,14 @@
         select->optionSelectionStateChanged(*this, selected);
 }
 
-void HTMLOptionElement::setSelectedState(bool selected)
+void HTMLOptionElement::setSelectedState(bool selected, AllowStyleInvalidation allowStyleInvalidation)
 {
     if (m_isSelected == selected)
         return;
 
-    Style::PseudoClassChangeInvalidation checkedInvalidation(*this, CSSSelector::PseudoClassChecked, selected);
+    std::optional<Style::PseudoClassChangeInvalidation> checkedInvalidation;
+    if (allowStyleInvalidation == AllowStyleInvalidation::Yes)
+        emplace(checkedInvalidation, *this, { { CSSSelector::PseudoClassChecked, selected } });
 
     m_isSelected = selected;
 

Modified: trunk/Source/WebCore/html/HTMLOptionElement.h (289692 => 289693)


--- trunk/Source/WebCore/html/HTMLOptionElement.h	2022-02-12 15:29:06 UTC (rev 289692)
+++ trunk/Source/WebCore/html/HTMLOptionElement.h	2022-02-12 15:34:57 UTC (rev 289693)
@@ -30,6 +30,8 @@
 
 class HTMLSelectElement;
 
+enum class AllowStyleInvalidation { Yes, No };
+
 class HTMLOptionElement final : public HTMLElement {
     WTF_MAKE_ISO_ALLOCATED(HTMLOptionElement);
 public:
@@ -45,7 +47,7 @@
     WEBCORE_EXPORT String value() const;
     WEBCORE_EXPORT void setValue(const String&);
 
-    WEBCORE_EXPORT bool selected() const;
+    WEBCORE_EXPORT bool selected(AllowStyleInvalidation = AllowStyleInvalidation::Yes) const;
     WEBCORE_EXPORT void setSelected(bool);
 
     WEBCORE_EXPORT HTMLSelectElement* ownerSelectElement() const;
@@ -60,7 +62,7 @@
 
     String textIndentedToRespectGroupLabel() const;
 
-    void setSelectedState(bool);
+    void setSelectedState(bool, AllowStyleInvalidation = AllowStyleInvalidation::Yes);
     bool selectedWithoutUpdate() const { return m_isSelected; }
 
 private:

Modified: trunk/Source/WebCore/html/HTMLSelectElement.cpp (289692 => 289693)


--- trunk/Source/WebCore/html/HTMLSelectElement.cpp	2022-02-12 15:29:06 UTC (rev 289692)
+++ trunk/Source/WebCore/html/HTMLSelectElement.cpp	2022-02-12 15:34:57 UTC (rev 289693)
@@ -41,7 +41,6 @@
 #include "HTMLHRElement.h"
 #include "HTMLNames.h"
 #include "HTMLOptGroupElement.h"
-#include "HTMLOptionElement.h"
 #include "HTMLOptionsCollection.h"
 #include "HTMLParserIdioms.h"
 #include "KeyboardEvent.h"
@@ -365,10 +364,10 @@
     return ensureRareData().ensureNodeLists().addCachedCollection<HTMLOptionsCollection>(*this, SelectOptions);
 }
 
-void HTMLSelectElement::updateListItemSelectedStates()
+void HTMLSelectElement::updateListItemSelectedStates(AllowStyleInvalidation allowStyleInvalidation)
 {
     if (m_shouldRecalcListItems)
-        recalcListItems();
+        recalcListItems(true, allowStyleInvalidation);
 }
 
 CompletionHandlerCallingScope HTMLSelectElement::optionToSelectFromChildChangeScope(const ContainerNode::ChildChange& change, HTMLOptGroupElement* parentOptGroup)
@@ -801,7 +800,7 @@
         cache->childrenChanged(this);
 }
 
-void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
+void HTMLSelectElement::recalcListItems(bool updateSelectedStates, AllowStyleInvalidation allowStyleInvalidation) const
 {
     m_listItems.clear();
 
@@ -816,11 +815,11 @@
                 firstOption = &option;
             if (option.selected()) {
                 if (foundSelected)
-                    foundSelected->setSelectedState(false);
+                    foundSelected->setSelectedState(false, allowStyleInvalidation);
                 foundSelected = &option;
             } else if (m_size <= 1 && !foundSelected && !option.isDisabledFormControl()) {
                 foundSelected = &option;
-                foundSelected->setSelectedState(true);
+                foundSelected->setSelectedState(true, allowStyleInvalidation);
             }
         }
     };
@@ -837,7 +836,7 @@
     }
 
     if (!foundSelected && m_size <= 1 && firstOption && !firstOption->selected())
-        firstOption->setSelectedState(true);
+        firstOption->setSelectedState(true, allowStyleInvalidation);
 }
 
 int HTMLSelectElement::selectedIndex() const

Modified: trunk/Source/WebCore/html/HTMLSelectElement.h (289692 => 289693)


--- trunk/Source/WebCore/html/HTMLSelectElement.h	2022-02-12 15:29:06 UTC (rev 289692)
+++ trunk/Source/WebCore/html/HTMLSelectElement.h	2022-02-12 15:34:57 UTC (rev 289693)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "HTMLFormControlElementWithState.h"
+#include "HTMLOptionElement.h"
 #include "TypeAhead.h"
 #include <wtf/CompletionHandler.h>
 
@@ -70,7 +71,7 @@
 
     void setRecalcListItems();
     void invalidateSelectedItems();
-    void updateListItemSelectedStates();
+    void updateListItemSelectedStates(AllowStyleInvalidation = AllowStyleInvalidation::Yes);
 
     WEBCORE_EXPORT const Vector<HTMLElement*>& listItems() const;
 
@@ -147,7 +148,7 @@
 
     void didRecalcStyle(Style::Change) final;
 
-    void recalcListItems(bool updateSelectedStates = true) const;
+    void recalcListItems(bool updateSelectedStates = true, AllowStyleInvalidation = AllowStyleInvalidation::Yes) const;
 
     void deselectItems(HTMLOptionElement* excludeElement = nullptr);
     void typeAheadFind(KeyboardEvent&);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to