Commit 96cb3618 authored by Rob Dodson's avatar Rob Dodson Committed by Commit Bot

DevTools: Add support for :focus-visible selector

Image: https://imgur.com/pv5mo8l

Bug: 817199
Change-Id: I3f2fbdde41f5126be392e6197edbf5cf9cc44744
Reviewed-on: https://chromium-review.googlesource.com/961881Reviewed-by: default avatarJoel Einbinder <einbinder@chromium.org>
Reviewed-by: default avatarPavel Feldman <pfeldman@chromium.org>
Reviewed-by: default avatarAlice Boxhall <aboxhall@chromium.org>
Commit-Queue: Rob Dodson <robdodson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543915}
parent e61bdc1e
...@@ -1361,10 +1361,19 @@ bool SelectorChecker::MatchesFocusPseudoClass(const Element& element) { ...@@ -1361,10 +1361,19 @@ bool SelectorChecker::MatchesFocusPseudoClass(const Element& element) {
} }
bool SelectorChecker::MatchesFocusVisiblePseudoClass(const Element& element) { bool SelectorChecker::MatchesFocusVisiblePseudoClass(const Element& element) {
bool force_pseudo_state = false;
probe::forcePseudoState(const_cast<Element*>(&element),
CSSSelector::kPseudoFocusVisible,
&force_pseudo_state);
if (force_pseudo_state)
return true;
bool always_show_focus_ring = bool always_show_focus_ring =
IsHTMLFormControlElement(element) && IsHTMLFormControlElement(element) &&
ToHTMLFormControlElement(element).ShouldShowFocusRingOnMouseFocus(); ToHTMLFormControlElement(element).ShouldShowFocusRingOnMouseFocus();
return MatchesFocusPseudoClass(element) && // Avoid probing for force_pseudo_state. Otherwise, as currently implemented,
// :focus-visible will always match if :focus is forced, since no focus
// source flags will be set.
return element.IsFocused() && IsFrameFocused(element) &&
(!element.WasFocusedByMouse() || always_show_focus_ring); (!element.WasFocusedByMouse() || always_show_focus_ring);
} }
......
...@@ -870,6 +870,9 @@ void InspectorCSSAgent::ForcePseudoState(Element* element, ...@@ -870,6 +870,9 @@ void InspectorCSSAgent::ForcePseudoState(Element* element,
case CSSSelector::kPseudoFocusWithin: case CSSSelector::kPseudoFocusWithin:
force = forced_pseudo_state & kPseudoFocusWithin; force = forced_pseudo_state & kPseudoFocusWithin;
break; break;
case CSSSelector::kPseudoFocusVisible:
force = forced_pseudo_state & kPseudoFocusVisible;
break;
case CSSSelector::kPseudoHover: case CSSSelector::kPseudoHover:
force = forced_pseudo_state & kPseudoHover; force = forced_pseudo_state & kPseudoHover;
break; break;
......
...@@ -50,6 +50,11 @@ Elements.ElementStatePaneWidget = class extends UI.Widget { ...@@ -50,6 +50,11 @@ Elements.ElementStatePaneWidget = class extends UI.Widget {
tr = table.createChild('tr'); tr = table.createChild('tr');
tr.appendChild(createCheckbox.call(null, 'focus-within')); tr.appendChild(createCheckbox.call(null, 'focus-within'));
try {
tr.querySelector(':focus-visible'); // Will throw if not supported
tr.appendChild(createCheckbox.call(null, 'focus-visible'));
} catch (e) {
}
this.contentElement.appendChild(table); this.contentElement.appendChild(table);
UI.context.addFlavorChangeListener(SDK.DOMNode, this._update, this); UI.context.addFlavorChangeListener(SDK.DOMNode, this._update, this);
......
...@@ -104,9 +104,15 @@ Elements.ElementsTreeElement = class extends UI.TreeElement { ...@@ -104,9 +104,15 @@ Elements.ElementsTreeElement = class extends UI.TreeElement {
/** /**
* @param {!UI.ContextMenu} contextMenu * @param {!UI.ContextMenu} contextMenu
* @param {!SDK.DOMNode} node * @param {!SDK.DOMNode} node
* @suppressGlobalPropertiesCheck
*/ */
static populateForcedPseudoStateItems(contextMenu, node) { static populateForcedPseudoStateItems(contextMenu, node) {
const pseudoClasses = ['active', 'hover', 'focus', 'visited', 'focus-within']; const pseudoClasses = ['active', 'hover', 'focus', 'visited', 'focus-within'];
try {
document.querySelector(':focus-visible'); // Will throw if not supported
pseudoClasses.push('focus-visible');
} catch (e) {
}
const forcedPseudoState = node.domModel().cssModel().pseudoState(node); const forcedPseudoState = node.domModel().cssModel().pseudoState(node);
const stateMenu = contextMenu.debugSection().appendSubMenuItem(Common.UIString('Force state')); const stateMenu = contextMenu.debugSection().appendSubMenuItem(Common.UIString('Force state'));
for (let i = 0; i < pseudoClasses.length; ++i) { for (let i = 0; i < pseudoClasses.length; ++i) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment