Bug 208283

Summary: Web Inspector: AXI: disabled buttons shouldn't be focusable
Product: WebKit Reporter: Nikita Vasilyev <nvasilyev>
Component: Web InspectorAssignee: Nikita Vasilyev <nvasilyev>
Status: RESOLVED FIXED    
Severity: Normal CC: hi, inspector-bugzilla-changes, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: All   
OS: All   
Attachments:
Description Flags
Patch
none
Patch
none
Patch
hi: review+
Patch none

Nikita Vasilyev
Reported 2020-02-26 18:54:58 PST
When pressing Tab/Shift-Tab, it shouldn't focus on disabled buttons.
Attachments
Patch (3.66 KB, patch)
2020-02-26 18:57 PST, Nikita Vasilyev
no flags
Patch (4.69 KB, patch)
2020-03-06 19:11 PST, Nikita Vasilyev
no flags
Patch (4.60 KB, patch)
2020-03-06 20:54 PST, Nikita Vasilyev
hi: review+
Patch (4.75 KB, patch)
2020-03-19 13:35 PDT, Nikita Vasilyev
no flags
Radar WebKit Bug Importer
Comment 1 2020-02-26 18:55:15 PST
Nikita Vasilyev
Comment 2 2020-02-26 18:57:39 PST
Devin Rousso
Comment 3 2020-02-26 21:03:57 PST
Comment on attachment 391831 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=391831&action=review > Source/WebInspectorUI/UserInterface/Views/ButtonNavigationItem.js:44 > + if (this._role === "button") Do we ever actually pass in anything that isn't `"button"`? I see this type of logic all over the place with navigation related things and I don't remember it ever actually being used anywhere. Perhaps we can just remove the `role` parameter entirely and always use `"button"`? > Source/WebInspectorUI/UserInterface/Views/ButtonNavigationItem.js:208 > + if (this._role === "button") Shouldn't we `this.element.removeAttribute("tabindex")` in the `else`?
Nikita Vasilyev
Comment 4 2020-02-27 00:03:29 PST
Comment on attachment 391831 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=391831&action=review >> Source/WebInspectorUI/UserInterface/Views/ButtonNavigationItem.js:44 >> + if (this._role === "button") > > Do we ever actually pass in anything that isn't `"button"`? I see this type of logic all over the place with navigation related things and I don't remember it ever actually being used anywhere. Perhaps we can just remove the `role` parameter entirely and always use `"button"`? WI.RadioButtonNavigationItem passes "tab". (Perhaps WI.RadioButtonNavigationItem should be renamed to something like WI.TabButtonNavigationItem. This is out of the scope of this bug.) >> Source/WebInspectorUI/UserInterface/Views/ButtonNavigationItem.js:208 >> + if (this._role === "button") > > Shouldn't we `this.element.removeAttribute("tabindex")` in the `else`? It wouldn't make a difference. It would only run for WI.RadioButtonNavigationItem during the class instantiation, and RadioButtonNavigationItem doesn't have any tabIndex set at that time. RadioButtonNavigationItem is never disabled so _updateTabIndex would never get called from there.
Nikita Vasilyev
Comment 5 2020-02-27 00:09:41 PST
I don't want to do this in this patch, but perhaps it's worth refactoring RadioButtonNavigationItem. Currently, RadioButtonNavigationItem extends ButtonNavigationItem, which extends NavigationItem. Perhaps it would be less confusing if RadioButtonNavigationItem extended NavigationItem directly.
Devin Rousso
Comment 6 2020-03-05 16:24:40 PST
Comment on attachment 391831 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=391831&action=review >>> Source/WebInspectorUI/UserInterface/Views/ButtonNavigationItem.js:208 >>> + if (this._role === "button") >> >> Shouldn't we `this.element.removeAttribute("tabindex")` in the `else`? > > It wouldn't make a difference. It would only run for WI.RadioButtonNavigationItem during the class instantiation, and RadioButtonNavigationItem doesn't have any tabIndex set at that time. > RadioButtonNavigationItem is never disabled so _updateTabIndex would never get called from there. What about if an instance of `WI.RadioButtonNavigationItem` called `.enabled = false;` and then `.enabled = true`? It would get called then, and the `tabIndex` wouldn't be reset.
Nikita Vasilyev
Comment 7 2020-03-06 19:11:31 PST
Devin Rousso
Comment 8 2020-03-06 20:22:46 PST
Comment on attachment 392838 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=392838&action=review > Source/WebInspectorUI/UserInterface/Views/ButtonNavigationItem.js:164 > + if (this._role === "button") > + this.element.tabIndex = 0; > + else > + this.element.tabIndex = -1; Why not just inline this `this.element.tabIndex = (this._role === "button") ? 0 : -1;`? > Source/WebInspectorUI/UserInterface/Views/RadioButtonNavigationItem.js:72 > + if (!this._enabled) { Style: in subclasses, we shouldn't use the private variables of superclasses, so please use `this.enabled` > Source/WebInspectorUI/UserInterface/Views/RadioButtonNavigationItem.js:80 > + if (this.selected) > + this.element.tabIndex = 0; > + else > + this.element.tabIndex = -1; Why not just have this as part of the `if` in `super.updateTabIndex`? All basic `WI.ButtonNavigationItem` will already pass `this._role === "button"`, and everyone else should only be tabbabale if they're selected. At the very least, this deserves an explanation (or at least a warning) that you're not calling `super.updateTabIndex`. I'd really prefer it if you changed it so that it doesn't completely override `super.updateTabIndex`, as that can make it harder to adjust things in the future as someone reading the base class won't necessarily know about the fact that this was overriding it and would therefore not be affected by any of the aforementioned changes.
Nikita Vasilyev
Comment 9 2020-03-06 20:43:12 PST
Comment on attachment 392838 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=392838&action=review >> Source/WebInspectorUI/UserInterface/Views/RadioButtonNavigationItem.js:72 >> + if (!this._enabled) { > > Style: in subclasses, we shouldn't use the private variables of superclasses, so please use `this.enabled` Right, thanks. >> Source/WebInspectorUI/UserInterface/Views/RadioButtonNavigationItem.js:80 >> + this.element.tabIndex = -1; > > Why not just have this as part of the `if` in `super.updateTabIndex`? All basic `WI.ButtonNavigationItem` will already pass `this._role === "button"`, and everyone else should only be tabbabale if they're selected. > > At the very least, this deserves an explanation (or at least a warning) that you're not calling `super.updateTabIndex`. I'd really prefer it if you changed it so that it doesn't completely override `super.updateTabIndex`, as that can make it harder to adjust things in the future as someone reading the base class won't necessarily know about the fact that this was overriding it and would therefore not be affected by any of the aforementioned changes. Only selected radio button should be tabbable. I can call super.updateTabIndex for consistency. It would make no difference here.
Nikita Vasilyev
Comment 10 2020-03-06 20:54:14 PST
Devin Rousso
Comment 11 2020-03-11 10:25:45 PDT
Comment on attachment 392847 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=392847&action=review r=me > Source/WebInspectorUI/UserInterface/Views/RadioButtonNavigationItem.js:74 > + if (!this.enabled) { It'd be nice to avoid doing this check twice. Right now, we also could potentially end up setting the `tabIndex` twice in this function, which is also unfortunate. Perhaps we could create a protected `get tabbable` that _can_ be overridden by subclasses. ButtonNavigationItem.js ``` updateTabIndex() { if (!this._enabled) { this.element.tabIndex = -1; return; } this.element.tabIndex = this.tabbable ? 0 : -1; } get tabbable() { // Can be overridden by subclasses. return this._role === "button"; } ``` RadioButtonNavigationItem.js ``` get tabbable() { return this.selected; } ``` I guess if you do end up removing `WI.ButtonNavigationItem` as a superclass of `WI.RadioButtonNavigationItem`, then this would kinda have to be needed tho.
Nikita Vasilyev
Comment 12 2020-03-19 13:34:35 PDT
Comment on attachment 392847 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=392847&action=review >> Source/WebInspectorUI/UserInterface/Views/RadioButtonNavigationItem.js:74 >> + if (!this.enabled) { > > It'd be nice to avoid doing this check twice. Right now, we also could potentially end up setting the `tabIndex` twice in this function, which is also unfortunate. Perhaps we could create a protected `get tabbable` that _can_ be overridden by subclasses. > > ButtonNavigationItem.js > ``` > updateTabIndex() > { > if (!this._enabled) { > this.element.tabIndex = -1; > return; > } > > this.element.tabIndex = this.tabbable ? 0 : -1; > } > > get tabbable() > { > // Can be overridden by subclasses. > return this._role === "button"; > } > ``` > > RadioButtonNavigationItem.js > ``` > get tabbable() > { > return this.selected; > } > ``` > > I guess if you do end up removing `WI.ButtonNavigationItem` as a superclass of `WI.RadioButtonNavigationItem`, then this would kinda have to be needed tho. I like the `tabbable` getter!
Nikita Vasilyev
Comment 13 2020-03-19 13:35:04 PDT
EWS
Comment 14 2020-03-19 14:41:38 PDT
Committed r258730: <https://trac.webkit.org/changeset/258730> All reviewed patches have been landed. Closing bug and clearing flags on attachment 394014 [details].
Devin Rousso
Comment 15 2020-03-19 20:43:53 PDT
Comment on attachment 394014 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=394014&action=review > Source/WebInspectorUI/UserInterface/Views/ButtonNavigationItem.js:179 > + return this._role === "button"; NIT: this probably could've had a `// Can be overridden by subclasses.` comment :P
Note You need to log in before you can comment on or make changes to this bug.