Diff
Modified: trunk/Source/WebCore/ChangeLog (274172 => 274173)
--- trunk/Source/WebCore/ChangeLog 2021-03-09 21:27:27 UTC (rev 274172)
+++ trunk/Source/WebCore/ChangeLog 2021-03-09 21:36:01 UTC (rev 274173)
@@ -1,3 +1,38 @@
+2021-03-09 Manuel Rego Casasnovas <[email protected]>
+
+ [selectors] Move :focus-viisble & :focus-within flags from Node to UserActionElementSet
+ https://bugs.webkit.org/show_bug.cgi?id=222647
+
+ Reviewed by Antti Koivisto.
+
+ This patch avoids using flags in Node.h for :focus-visible and :focus-within pseudo classes,
+ and move them to UserActionElementSet.
+ This makes them consistent with :focus flag, and saves some bits in Node.h for other flags in the future.
+
+ On top of that this makes :focus-within SelectorCompiler implementation consistent with :focus and :focus-visible implementations.
+
+ * css/SelectorCheckerTestFunctions.h:
+ (WebCore::matchesFocusWithinPseudoClass):
+ * cssjit/SelectorCompiler.cpp:
+ (WebCore::SelectorCompiler::JSC_DEFINE_JIT_OPERATION):
+ (WebCore::SelectorCompiler::addPseudoClassType):
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementMatching):
+ * dom/Element.cpp:
+ (WebCore::Element::isUserActionElementHasFocusVisible const):
+ (WebCore::Element::isUserActionElementHasFocusWithin const):
+ (WebCore::Element::setHasFocusVisible):
+ (WebCore::Element::setHasFocusWithin):
+ * dom/Element.h:
+ (WebCore::Element::hasFocusVisible const):
+ (WebCore::Element::hasFocusWithin const):
+ * dom/Node.h:
+ (WebCore::Node::flagIsLink):
+ * dom/UserActionElementSet.h:
+ (WebCore::UserActionElementSet::hasFocusVisible):
+ (WebCore::UserActionElementSet::hasFocusWithin):
+ (WebCore::UserActionElementSet::setHasFocusVisible):
+ (WebCore::UserActionElementSet::setHasFocusWithin):
+
2021-03-09 Antti Koivisto <[email protected]>
REGRESSION (r273003): Animated style may lose original display property value
Modified: trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h (274172 => 274173)
--- trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h 2021-03-09 21:27:27 UTC (rev 274172)
+++ trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h 2021-03-09 21:36:01 UTC (rev 274173)
@@ -480,4 +480,12 @@
return element.hasFocusVisible() && isFrameFocused(element);
}
+ALWAYS_INLINE bool matchesFocusWithinPseudoClass(const Element& element)
+{
+ if (InspectorInstrumentation::forcePseudoState(element, CSSSelector::PseudoClassFocusWithin))
+ return true;
+
+ return element.hasFocusWithin() && isFrameFocused(element);
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (274172 => 274173)
--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2021-03-09 21:27:27 UTC (rev 274172)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2021-03-09 21:36:01 UTC (rev 274173)
@@ -86,6 +86,7 @@
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesDirectFocusPseudoClass, bool, (const Element&));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesFocusPseudoClass, bool, (const Element&));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesFocusVisiblePseudoClass, bool, (const Element&));
+static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesFocusWithinPseudoClass, bool, (const Element&));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationIsMediaDocument, bool, (const Element&));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationIsInRange, bool, (const Element&));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationMatchesIndeterminatePseudoClass, bool, (const Element&));
@@ -387,7 +388,6 @@
void generateElementIsRoot(Assembler::JumpList& failureCases);
void generateElementIsScopeRoot(Assembler::JumpList& failureCases);
void generateElementIsTarget(Assembler::JumpList& failureCases);
- void generateElementHasFocusWithin(Assembler::JumpList& failureCases);
// Helpers.
void generateAddStyleRelationIfResolvingStyle(Assembler::RegisterID element, Style::Relation::Type, Optional<Assembler::RegisterID> value = { });
@@ -637,6 +637,11 @@
return matchesFocusVisiblePseudoClass(element);
}
+JSC_DEFINE_JIT_OPERATION(operationMatchesFocusWithinPseudoClass, bool, (const Element& element))
+{
+ return matchesFocusWithinPseudoClass(element);
+}
+
JSC_DEFINE_JIT_OPERATION(operationIsMediaDocument, bool, (const Element& element))
{
return isMediaDocument(element);
@@ -788,6 +793,9 @@
case CSSSelector::PseudoClassFocusVisible:
fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr<JSC::OperationPtrTag>(operationMatchesFocusVisiblePseudoClass));
return FunctionType::SimpleSelectorChecker;
+ case CSSSelector::PseudoClassFocusWithin:
+ fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr<JSC::OperationPtrTag>(operationMatchesFocusWithinPseudoClass));
+ return FunctionType::SimpleSelectorChecker;
case CSSSelector::PseudoClassFullPageMedia:
fragment.unoptimizedPseudoClasses.append(JSC::FunctionPtr<JSC::OperationPtrTag>(operationIsMediaDocument));
return FunctionType::SimpleSelectorChecker;
@@ -928,7 +936,6 @@
case CSSSelector::PseudoClassLastChild:
case CSSSelector::PseudoClassOnlyChild:
case CSSSelector::PseudoClassPlaceholderShown:
- case CSSSelector::PseudoClassFocusWithin:
fragment.pseudoClasses.add(type);
if (selectorContext == SelectorContext::QuerySelector)
return FunctionType::SimpleSelectorChecker;
@@ -2844,9 +2851,6 @@
if (fragment.pseudoClasses.contains(CSSSelector::PseudoClassTarget))
generateElementIsTarget(matchingPostTagNameFailureCases);
- if (fragment.pseudoClasses.contains(CSSSelector::PseudoClassFocusWithin))
- generateElementHasFocusWithin(matchingPostTagNameFailureCases);
-
for (unsigned i = 0; i < fragment.unoptimizedPseudoClasses.size(); ++i)
generateElementFunctionCallTest(matchingPostTagNameFailureCases, fragment.unoptimizedPseudoClasses[i]);
@@ -4141,11 +4145,6 @@
failureCases.append(m_assembler.branchPtr(Assembler::NotEqual, Assembler::Address(document, Document::cssTargetMemoryOffset()), elementAddressRegister));
}
-void SelectorCodeGenerator::generateElementHasFocusWithin(Assembler::JumpList& failureCases)
-{
- failureCases.append(m_assembler.branchTest32(Assembler::Zero, Assembler::Address(elementAddressRegister, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagHasFocusWithin())));
-}
-
void SelectorCodeGenerator::generateElementIsFirstLink(Assembler::JumpList& failureCases, Assembler::RegisterID element)
{
LocalRegister currentElement(m_registerAllocator);
Modified: trunk/Source/WebCore/dom/Element.cpp (274172 => 274173)
--- trunk/Source/WebCore/dom/Element.cpp 2021-03-09 21:27:27 UTC (rev 274172)
+++ trunk/Source/WebCore/dom/Element.cpp 2021-03-09 21:36:01 UTC (rev 274173)
@@ -679,6 +679,18 @@
return document().userActionElements().isBeingDragged(*this);
}
+bool Element::isUserActionElementHasFocusVisible() const
+{
+ ASSERT(isUserActionElement());
+ return document().userActionElements().hasFocusVisible(*this);
+}
+
+bool Element::isUserActionElementHasFocusWithin() const
+{
+ ASSERT(isUserActionElement());
+ return document().userActionElements().hasFocusWithin(*this);
+}
+
void Element::setActive(bool flag, bool pause, Style::InvalidationScope invalidationScope)
{
if (flag == active())
@@ -763,7 +775,7 @@
return;
Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassFocusVisible);
- setNodeFlag(NodeFlag::HasFocusVisible, flag);
+ document().userActionElements().setHasFocusVisible(*this, flag);
}
void Element::setHasFocusWithin(bool flag)
@@ -772,7 +784,7 @@
return;
{
Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassFocusWithin);
- setNodeFlag(NodeFlag::HasFocusWithin, flag);
+ document().userActionElements().setHasFocusWithin(*this, flag);
}
}
Modified: trunk/Source/WebCore/dom/Element.h (274172 => 274173)
--- trunk/Source/WebCore/dom/Element.h 2021-03-09 21:27:27 UTC (rev 274172)
+++ trunk/Source/WebCore/dom/Element.h 2021-03-09 21:36:01 UTC (rev 274173)
@@ -319,8 +319,8 @@
bool hovered() const { return isUserActionElement() && isUserActionElementHovered(); }
bool focused() const { return isUserActionElement() && isUserActionElementFocused(); }
bool isBeingDragged() const { return isUserActionElement() && isUserActionElementDragged(); }
- bool hasFocusVisible() const { return hasNodeFlag(NodeFlag::HasFocusVisible); };
- bool hasFocusWithin() const { return hasNodeFlag(NodeFlag::HasFocusWithin); };
+ bool hasFocusVisible() const { return isUserActionElement() && isUserActionElementHasFocusVisible(); }
+ bool hasFocusWithin() const { return isUserActionElement() && isUserActionElementHasFocusWithin(); };
virtual void setActive(bool = true, bool pause = false, Style::InvalidationScope = Style::InvalidationScope::All);
virtual void setHovered(bool = true, Style::InvalidationScope = Style::InvalidationScope::All);
@@ -654,6 +654,8 @@
bool isUserActionElementFocused() const;
bool isUserActionElementHovered() const;
bool isUserActionElementDragged() const;
+ bool isUserActionElementHasFocusVisible() const;
+ bool isUserActionElementHasFocusWithin() const;
virtual void didAddUserAgentShadowRoot(ShadowRoot&) { }
Modified: trunk/Source/WebCore/dom/Node.h (274172 => 274173)
--- trunk/Source/WebCore/dom/Node.h 2021-03-09 21:27:27 UTC (rev 274172)
+++ trunk/Source/WebCore/dom/Node.h 2021-03-09 21:36:01 UTC (rev 274173)
@@ -513,8 +513,6 @@
static int32_t flagIsShadowRoot() { return static_cast<int32_t>(NodeFlag::IsShadowRoot); }
static int32_t flagIsHTML() { return static_cast<int32_t>(NodeFlag::IsHTMLElement); }
static int32_t flagIsLink() { return static_cast<int32_t>(NodeFlag::IsLink); }
- static int32_t flagHasFocusVisible() { return static_cast<int32_t>(NodeFlag::HasFocusVisible); }
- static int32_t flagHasFocusWithin() { return static_cast<int32_t>(NodeFlag::HasFocusWithin); }
static int32_t flagIsParsingChildrenFinished() { return static_cast<int32_t>(NodeFlag::IsParsingChildrenFinished); }
#endif // ENABLE(JIT)
@@ -539,24 +537,22 @@
// be stored in the same memory word as the Node bits above.
IsDocumentFragmentForInnerOuterHTML = 1 << 14, // DocumentFragment
IsEditingText = 1 << 15, // Text
- HasFocusWithin = 1 << 16, // Element
- IsLink = 1 << 17,
- IsUserActionElement = 1 << 18,
- IsParsingChildrenFinished = 1 << 19,
- HasSyntheticAttrChildNodes = 1 << 20,
- SelfOrAncestorHasDirAuto = 1 << 21,
+ IsLink = 1 << 16, // Element
+ IsUserActionElement = 1 << 17,
+ IsParsingChildrenFinished = 1 << 18,
+ HasSyntheticAttrChildNodes = 1 << 19,
+ SelfOrAncestorHasDirAuto = 1 << 20,
- HasCustomStyleResolveCallbacks = 1 << 22,
+ HasCustomStyleResolveCallbacks = 1 << 21,
- HasPendingResources = 1 << 23,
- HasElementIdentifier = 1 << 24,
+ HasPendingResources = 1 << 22,
+ HasElementIdentifier = 1 << 23,
#if ENABLE(FULLSCREEN_API)
- ContainsFullScreenElement = 1 << 25,
+ ContainsFullScreenElement = 1 << 24,
#endif
- IsComputedStyleInvalidFlag = 1 << 26,
+ IsComputedStyleInvalidFlag = 1 << 25,
- HasFocusVisible = 1 << 27,
- // Bits 27-31 are free.
+ // Bits 26-31 are free.
};
enum class TabIndexState : uint8_t {
Modified: trunk/Source/WebCore/dom/UserActionElementSet.h (274172 => 274173)
--- trunk/Source/WebCore/dom/UserActionElementSet.h 2021-03-09 21:27:27 UTC (rev 274172)
+++ trunk/Source/WebCore/dom/UserActionElementSet.h 2021-03-09 21:36:01 UTC (rev 274173)
@@ -43,6 +43,8 @@
bool isHovered(const Element& element) { return hasFlag(element, Flag::IsHovered); }
bool isInActiveChain(const Element& element) { return hasFlag(element, Flag::InActiveChain); }
bool isBeingDragged(const Element& element) { return hasFlag(element, Flag::IsBeingDragged); }
+ bool hasFocusVisible(const Element& element) { return hasFlag(element, Flag::HasFocusVisible); }
+ bool hasFocusWithin(const Element& element) { return hasFlag(element, Flag::HasFocusWithin); }
void setActive(Element& element, bool enable) { setFlags(element, enable, Flag::IsActive); }
void setFocused(Element& element, bool enable) { setFlags(element, enable, Flag::IsFocused); }
@@ -49,6 +51,8 @@
void setHovered(Element& element, bool enable) { setFlags(element, enable, Flag::IsHovered); }
void setInActiveChain(Element& element, bool enable) { setFlags(element, enable, Flag::InActiveChain); }
void setBeingDragged(Element& element, bool enable) { setFlags(element, enable, Flag::IsBeingDragged); }
+ void setHasFocusVisible(Element& element, bool enable) { setFlags(element, enable, Flag::HasFocusVisible); }
+ void setHasFocusWithin(Element& element, bool enable) { setFlags(element, enable, Flag::HasFocusWithin); }
void clearActiveAndHovered(Element& element) { clearFlags(element, { Flag::IsActive, Flag::InActiveChain, Flag::IsHovered }); }
@@ -61,6 +65,8 @@
IsHovered = 1 << 2,
IsFocused = 1 << 3,
IsBeingDragged = 1 << 4,
+ HasFocusVisible = 1 << 5,
+ HasFocusWithin = 1 << 6,
};
void setFlags(Element& element, bool enable, OptionSet<Flag> flags) { enable ? setFlags(element, flags) : clearFlags(element, flags); }