Title: [273474] trunk/Source/WebCore
Revision
273474
Author
rn...@webkit.org
Date
2021-02-24 22:50:56 -0800 (Wed, 24 Feb 2021)

Log Message

Optimize the code to check if an element delegates focus to its shadow root or not
https://bugs.webkit.org/show_bug.cgi?id=222404

Reviewed by Simon Fraser.

Add a fast path for checking whether a given element is a shadow host with a shadow root
with delegatesFocus set to true in with a new node flag: DelegatesFocusToShadowRoot.

The flag is set in Element::attachShadow and never cleared as delegatesFocus can never be unset.

No new tests since there should be no observable behavioral differences.

* dom/Element.cpp:
(WebCore::Element::isKeyboardFocusable const): Optimized this code using the new flag.
(WebCore::shadowRootWithDelegatesFocus): Set the flag.
(WebCore::isProgramaticallyFocusable): Optimized this code using the new flag.
(WebCore::Element::focus): Ditto.
* dom/Node.h:
(WebCore::Node::delegatesFocusToShadowRoot const): Added.
(WebCore::Node::NodeFlag): Added NodeFlag::DelegatesFocusToShadowRoot.
(WebCore::Node::setDelegatesFocusToShadowRoot): Added.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (273473 => 273474)


--- trunk/Source/WebCore/ChangeLog	2021-02-25 06:45:27 UTC (rev 273473)
+++ trunk/Source/WebCore/ChangeLog	2021-02-25 06:50:56 UTC (rev 273474)
@@ -1,3 +1,27 @@
+2021-02-24  Ryosuke Niwa  <rn...@webkit.org>
+
+        Optimize the code to check if an element delegates focus to its shadow root or not
+        https://bugs.webkit.org/show_bug.cgi?id=222404
+
+        Reviewed by Simon Fraser.
+
+        Add a fast path for checking whether a given element is a shadow host with a shadow root
+        with delegatesFocus set to true in with a new node flag: DelegatesFocusToShadowRoot.
+
+        The flag is set in Element::attachShadow and never cleared as delegatesFocus can never be unset.
+
+        No new tests since there should be no observable behavioral differences.
+
+        * dom/Element.cpp:
+        (WebCore::Element::isKeyboardFocusable const): Optimized this code using the new flag.
+        (WebCore::shadowRootWithDelegatesFocus): Set the flag.
+        (WebCore::isProgramaticallyFocusable): Optimized this code using the new flag.
+        (WebCore::Element::focus): Ditto.
+        * dom/Node.h:
+        (WebCore::Node::delegatesFocusToShadowRoot const): Added.
+        (WebCore::Node::NodeFlag): Added NodeFlag::DelegatesFocusToShadowRoot.
+        (WebCore::Node::setDelegatesFocusToShadowRoot): Added.
+
 2021-02-24  Rob Buis  <rb...@igalia.com>
 
         [css-grid] Do not allow negative heights

Modified: trunk/Source/WebCore/dom/Element.cpp (273473 => 273474)


--- trunk/Source/WebCore/dom/Element.cpp	2021-02-25 06:45:27 UTC (rev 273473)
+++ trunk/Source/WebCore/dom/Element.cpp	2021-02-25 06:50:56 UTC (rev 273474)
@@ -315,11 +315,8 @@
 {
     if (!(isFocusable() && !shouldBeIgnoredInSequentialFocusNavigation() && tabIndexSetExplicitly().valueOr(0) >= 0))
         return false;
-    if (auto* root = shadowRoot()) {
-        if (root->delegatesFocus())
-            return false;
-    }
-    return true;
+    ASSERT(delegatesFocusToShadowRoot() == (shadowRoot() && shadowRoot()->delegatesFocus()));
+    return !delegatesFocusToShadowRoot();
 }
 
 bool Element::isMouseFocusable() const
@@ -2393,6 +2390,8 @@
     if (init.mode == ShadowRootMode::UserAgent)
         return Exception { TypeError };
     auto shadow = ShadowRoot::create(document(), init.mode, init.delegatesFocus ? ShadowRoot::DelegatesFocus::Yes : ShadowRoot::DelegatesFocus::No);
+    if (init.delegatesFocus)
+        setDelegatesFocusToShadowRoot();
     auto& result = shadow.get();
     addShadowRoot(WTFMove(shadow));
     return result;
@@ -2976,7 +2975,8 @@
 {
     ScriptDisallowedScope::InMainThread scriptDisallowedScope;
 
-    if (shadowRootWithDelegatesFocus(element))
+    ASSERT(element.delegatesFocusToShadowRoot() == !!shadowRootWithDelegatesFocus(element));
+    if (element.delegatesFocusToShadowRoot())
         return false;
 
     // If the stylesheets have already been loaded we can reliably check isFocusable.
@@ -3023,7 +3023,9 @@
     if (&newTarget->document() != document.ptr())
         return;
 
-    if (auto root = shadowRootWithDelegatesFocus(*this)) {
+    ASSERT(delegatesFocusToShadowRoot() == !!shadowRootWithDelegatesFocus(*this));
+    if (delegatesFocusToShadowRoot()) {
+        auto root = shadowRootWithDelegatesFocus(*this);
         auto currentlyFocusedElement = makeRefPtr(document->focusedElement());
         if (root->containsIncludingShadowDOM(currentlyFocusedElement.get())) {
             if (document->page())

Modified: trunk/Source/WebCore/dom/Node.h (273473 => 273474)


--- trunk/Source/WebCore/dom/Node.h	2021-02-25 06:45:27 UTC (rev 273473)
+++ trunk/Source/WebCore/dom/Node.h	2021-02-25 06:50:56 UTC (rev 273474)
@@ -222,6 +222,7 @@
     ShadowRoot* containingShadowRoot() const;
     ShadowRoot* shadowRoot() const;
     bool isClosedShadowHidden(const Node&) const;
+    bool delegatesFocusToShadowRoot() const { return hasNodeFlag(NodeFlag::DelegatesFocusToShadowRoot); }
 
     HTMLSlotElement* assignedSlot() const;
     HTMLSlotElement* assignedSlotForBindings() const;
@@ -550,8 +551,9 @@
         ContainsFullScreenElement = 1 << 25,
 #endif
         IsComputedStyleInvalidFlag = 1 << 26,
+        DelegatesFocusToShadowRoot = 1 << 27,
 
-        // Bits 27-31 are free.
+        // Bits 28-31 are free.
     };
 
     enum class TabIndexState : uint8_t {
@@ -591,6 +593,8 @@
     void setIsParsingChildrenFinished() { setNodeFlag(NodeFlag::IsParsingChildrenFinished); }
     void clearIsParsingChildrenFinished() { clearNodeFlag(NodeFlag::IsParsingChildrenFinished); }
 
+    void setDelegatesFocusToShadowRoot() { setNodeFlag(NodeFlag::DelegatesFocusToShadowRoot); }
+
     constexpr static auto DefaultNodeFlags = OptionSet<NodeFlag>(NodeFlag::IsParsingChildrenFinished);
     constexpr static auto CreateOther = DefaultNodeFlags;
     constexpr static auto CreateCharacterData = DefaultNodeFlags | NodeFlag::IsCharacterData;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to