Skip to content
Permalink
Browse files
Web Inspector: Allow forcing pseudo class :target
https://bugs.webkit.org/show_bug.cgi?id=241707

Reviewed by Patrick Angle and Yusuke Suzuki.

Test: inspector/css/forcePseudoState.html

* Source/JavaScriptCore/inspector/protocol/CSS.json:
* Source/WebCore/inspector/agents/InspectorCSSAgent.cpp:
(WebCore::InspectorCSSAgent::forcePseudoState):
* Source/WebInspectorUI/UserInterface/Controllers/CSSManager.js:
(WI.CSSManager.displayNameForForceablePseudoClass):
(WI.CSSManager.prototype.canForcePseudoClass):

* Source/WebCore/css/SelectorChecker.cpp:
(WebCore::SelectorChecker::checkOne const):
* Source/WebCore/cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::addPseudoClassType):
(WebCore::SelectorCompiler::JSC_DEFINE_JIT_OPERATION):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsTarget):
* Source/WebCore/dom/Document.h:
(WebCore::Document::cssTargetMemoryOffset): Deleted.
Adjust the CSS JIT to also take into account Web Inspector forcibly applying `:target` styles.

* LayoutTests/inspector/css/forcePseudoState.html:
* LayoutTests/inspector/css/forcePseudoState-expected.txt:

Canonical link: https://commits.webkit.org/251656@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295651 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
dcrousso committed Jun 17, 2022
1 parent 22af2b0 commit 1e1ce5638c57513bfb166347485de8442d33a087
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 8 deletions.
@@ -42,6 +42,14 @@ Removing forced pseudo class...
PASS: Should not have any enabled pseudo classes.
PASS: Should change back to initial style.

-- Running test case: CSS.forcePseudoState.target
Forcing pseudo class...
PASS: Should have one enabled pseudo class.
PASS: Should change styles.
Removing forced pseudo class...
PASS: Should not have any enabled pseudo classes.
PASS: Should change back to initial style.

-- Running test case: CSS.forcePseudoState.visited
Forcing pseudo class...
PASS: Should have one enabled pseudo class.
@@ -15,7 +15,8 @@
{forceablePseudoClass: WI.CSSManager.ForceablePseudoClass.FocusVisible, expectedBackgroundColor: "rgb(0, 0, 30)"},
{forceablePseudoClass: WI.CSSManager.ForceablePseudoClass.FocusWithin, expectedBackgroundColor: "rgb(0, 0, 40)"},
{forceablePseudoClass: WI.CSSManager.ForceablePseudoClass.Hover, expectedBackgroundColor: "rgb(0, 0, 50)"},
{forceablePseudoClass: WI.CSSManager.ForceablePseudoClass.Visited, expectedBackgroundColor: "rgb(0, 0, 60)"},
{forceablePseudoClass: WI.CSSManager.ForceablePseudoClass.Target, expectedBackgroundColor: "rgb(0, 0, 60)"},
{forceablePseudoClass: WI.CSSManager.ForceablePseudoClass.Visited, expectedBackgroundColor: "rgb(0, 0, 70)"},
].forEach(({forceablePseudoClass, expectedBackgroundColor}) => {
suite.addTestCase({
name: "CSS.forcePseudoState." + forceablePseudoClass,
@@ -83,8 +84,11 @@
#test-element:hover {
background-color: rgb(0, 0, 50);
}
#test-element:visited {
#test-element:target {
background-color: rgb(0, 0, 60);
}
#test-element:visited {
background-color: rgb(0, 0, 70);
}
</style>
<a href="#" id="test-element"></a>
@@ -63,6 +63,7 @@
"focus-visible",
"focus-within",
"hover",
"target",
"visited"
],
"description": "Pseudo-style identifier (see <code>enum PseudoId</code> in <code>RenderStyleConstants.h</code>)."
@@ -962,7 +962,7 @@ bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalCont
return selector.matchNth(count);
}
case CSSSelector::PseudoClassTarget:
if (&element == element.document().cssTarget())
if (&element == element.document().cssTarget() || InspectorInstrumentation::forcePseudoState(element, CSSSelector::PseudoClassTarget))
return true;
break;
case CSSSelector::PseudoClassAutofill:
@@ -77,6 +77,7 @@ static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationModuloHelper, int
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationSynchronizeAllAnimatedSVGAttribute, void, (SVGElement&));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationSynchronizeStyleAttributeInternal, void, (StyledElement* styledElement));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationEqualIgnoringASCIICaseNonNull, bool, (const StringImpl*, const StringImpl*));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationElementIsTarget, bool, (const Element*));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationIsAutofilled, bool, (const Element&));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationIsAutofilledAndObscured, bool, (const Element&));
static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(operationIsAutofilledStrongPassword, bool, (const Element&));
@@ -981,7 +982,6 @@ static inline FunctionType addPseudoClassType(const CSSSelector& selector, Selec
case CSSSelector::PseudoClassAnyLink:
case CSSSelector::PseudoClassLink:
case CSSSelector::PseudoClassRoot:
case CSSSelector::PseudoClassTarget:
fragment.pseudoClasses.add(type);
return FunctionType::SimpleSelectorChecker;
case CSSSelector::PseudoClassAnyLinkDeprecated:
@@ -1017,6 +1017,7 @@ static inline FunctionType addPseudoClassType(const CSSSelector& selector, Selec
case CSSSelector::PseudoClassLastChild:
case CSSSelector::PseudoClassOnlyChild:
case CSSSelector::PseudoClassPlaceholderShown:
case CSSSelector::PseudoClassTarget:
fragment.pseudoClasses.add(type);
if (selectorContext == SelectorContext::QuerySelector)
return FunctionType::SimpleSelectorChecker;
@@ -4186,11 +4187,18 @@ void SelectorCodeGenerator::generateElementIsScopeRoot(Assembler::JumpList& fail
failureCases.append(m_assembler.branchPtr(Assembler::NotEqual, scope, elementAddressRegister));
}

JSC_DEFINE_JIT_OPERATION(operationElementIsTarget, bool, (const Element* element))
{
return element == element->document().cssTarget() || InspectorInstrumentation::forcePseudoState(*element, CSSSelector::PseudoClassTarget);
}

void SelectorCodeGenerator::generateElementIsTarget(Assembler::JumpList& failureCases)
{
LocalRegister document(m_registerAllocator);
DOMJIT::loadDocument(m_assembler, elementAddressRegister, document);
failureCases.append(m_assembler.branchPtr(Assembler::NotEqual, Assembler::Address(document, Document::cssTargetMemoryOffset()), elementAddressRegister));
// FIXME: <https://webkit.org/b/241733> optimize CSS JIT for `:target`
FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls);
functionCall.setFunctionAddress(operationElementIsTarget);
functionCall.setOneArgument(elementAddressRegister);
failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
}

void SelectorCodeGenerator::generateElementIsFirstLink(Assembler::JumpList& failureCases, Assembler::RegisterID element)
@@ -823,7 +823,6 @@ class Document
// Updates for :target (CSS3 selector).
void setCSSTarget(Element*);
Element* cssTarget() const { return m_cssTarget; }
static ptrdiff_t cssTargetMemoryOffset() { return OBJECT_OFFSETOF(Document, m_cssTarget); }

WEBCORE_EXPORT void scheduleFullStyleRebuild();
void scheduleStyleRecalc();
@@ -910,6 +910,10 @@ Protocol::ErrorStringOr<void> InspectorCSSAgent::forcePseudoState(Protocol::DOM:
forcedPseudoClassesToSet.add(CSSSelector::PseudoClassFocusWithin);
break;

case Protocol::CSS::ForceablePseudoClass::Target:
forcedPseudoClassesToSet.add(CSSSelector::PseudoClassTarget);
break;

case Protocol::CSS::ForceablePseudoClass::Visited:
forcedPseudoClassesToSet.add(CSSSelector::PseudoClassVisited);
break;
@@ -277,6 +277,8 @@ WI.CSSManager = class CSSManager extends WI.Object
return WI.unlocalizedString(":focus-within");
case WI.CSSManager.ForceablePseudoClass.Hover:
return WI.unlocalizedString(":hover");
case WI.CSSManager.ForceablePseudoClass.Target:
return WI.unlocalizedString(":target");
case WI.CSSManager.ForceablePseudoClass.Visited:
return WI.unlocalizedString(":visited");
}
@@ -378,6 +380,7 @@ WI.CSSManager = class CSSManager extends WI.Object

case WI.CSSManager.ForceablePseudoClass.FocusVisible:
case WI.CSSManager.ForceablePseudoClass.FocusWithin:
case WI.CSSManager.ForceablePseudoClass.Target:
// COMPATIBILITY (iOS 15.4): CSS.ForceablePseudoClass did not exist yet.
return !!InspectorBackend.Enum.CSS.ForceablePseudoClass;
}
@@ -849,6 +852,7 @@ WI.CSSManager.ForceablePseudoClass = {
FocusVisible: "focus-visible",
FocusWithin: "focus-within",
Hover: "hover",
Target: "target",
Visited: "visited",
};

0 comments on commit 1e1ce56

Please sign in to comment.