Bug 208283 - Web Inspector: AXI: disabled buttons shouldn't be focusable
Summary: Web Inspector: AXI: disabled buttons shouldn't be focusable
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Inspector (show other bugs)
Version: WebKit Nightly Build
Hardware: All All
: P2 Normal
Assignee: Nikita Vasilyev
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2020-02-26 18:54 PST by Nikita Vasilyev
Modified: 2020-03-19 20:43 PDT (History)
3 users (show)

See Also:


Attachments
Patch (3.66 KB, patch)
2020-02-26 18:57 PST, Nikita Vasilyev
no flags Details | Formatted Diff | Diff
Patch (4.69 KB, patch)
2020-03-06 19:11 PST, Nikita Vasilyev
no flags Details | Formatted Diff | Diff
Patch (4.60 KB, patch)
2020-03-06 20:54 PST, Nikita Vasilyev
hi: review+
Details | Formatted Diff | Diff
Patch (4.75 KB, patch)
2020-03-19 13:35 PDT, Nikita Vasilyev
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Nikita Vasilyev 2020-02-26 18:54:58 PST
When pressing Tab/Shift-Tab, it shouldn't focus on disabled buttons.
Comment 1 Radar WebKit Bug Importer 2020-02-26 18:55:15 PST
<rdar://problem/59832150>
Comment 2 Nikita Vasilyev 2020-02-26 18:57:39 PST
Created attachment 391831 [details]
Patch
Comment 3 Devin Rousso 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`?
Comment 4 Nikita Vasilyev 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.
Comment 5 Nikita Vasilyev 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.
Comment 6 Devin Rousso 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.
Comment 7 Nikita Vasilyev 2020-03-06 19:11:31 PST
Created attachment 392838 [details]
Patch
Comment 8 Devin Rousso 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.
Comment 9 Nikita Vasilyev 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.
Comment 10 Nikita Vasilyev 2020-03-06 20:54:14 PST
Created attachment 392847 [details]
Patch
Comment 11 Devin Rousso 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.
Comment 12 Nikita Vasilyev 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!
Comment 13 Nikita Vasilyev 2020-03-19 13:35:04 PDT
Created attachment 394014 [details]
Patch
Comment 14 EWS 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].
Comment 15 Devin Rousso 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