Bug 133163 - AX: WebKit does not recognize ARIA 1.1 tables
Summary: AX: WebKit does not recognize ARIA 1.1 tables
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Accessibility (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Normal
Assignee: chris fleizach
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2014-05-21 18:46 PDT by James Craig
Modified: 2014-05-28 11:32 PDT (History)
9 users (show)

See Also:


Attachments
test case (323 bytes, text/html)
2014-05-21 18:46 PDT, James Craig
no flags Details
patch (4.27 KB, patch)
2014-05-22 17:52 PDT, chris fleizach
darin: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description James Craig 2014-05-21 18:46:23 PDT
Created attachment 231847 [details]
test case

This is how we're planning to transition into ARIA 1.1 static tables from ARIA 1.0 grids. (Yes, I know the example is redundant.)

WebKit exposes this as 0 columns, 0 rows due to the fallback role tokens.

<table border="0" role="table grid">
  <tr role="row">
    <th role="columnheader">Foo</th>
    <th role="columnheader">Bar</th>
    <th role="columnheader">Baz</th>
  </tr>
  <tr role="row">
    <td role="cell gridcell">Bif</td>
    <td role="cell gridcell">Baf</td>
    <td role="cell gridcell">Bop</td>
  </tr>
</table>

Technically this should "work" as an ARIA 1.0 grid, today. Roles should fall back to grid/gridcell, respectively.
Comment 1 Radar WebKit Bug Importer 2014-05-21 18:47:22 PDT
<rdar://problem/16997147>
Comment 2 chris fleizach 2014-05-22 17:52:33 PDT
Created attachment 231926 [details]
patch
Comment 3 Darin Adler 2014-05-26 09:06:35 PDT
Comment on attachment 231926 [details]
patch

View in context: https://bugs.webkit.org/attachment.cgi?id=231926&action=review

I’m OK with this change, but it doesn’t seem to cover the edge cases of parsing the role attribute very well.

> Source/WebCore/accessibility/AXObjectCache.cpp:257
> +    String roleValue = toElement(node)->fastGetAttribute(roleAttr);

The return value from fastGetAttribute is const AtomicString&, not String. Putting it into a String is OK, but not a good idiom to use most of the time. I’d suggest const AtomicString& or auto& for the type of this value.

> Source/WebCore/accessibility/AXObjectCache.cpp:259
> +    if (roleValue.isEmpty() && equalIgnoringCase(role, nullAtom))
> +        return true;

We don’t need to use equalIgnoringCase to check if the passed role is null; also, if the role passed is null, I don’t think we really want to run space splitting code below. That would return true if there was a leading or trailing space or two spaces in a row, and I don’t think that’s what we want. You should write this:

    if (role.isNull())
        return roleValue.isEmpty();

But we should also consider if a role of null should match a role attribute consisting entirely of spaces. As written, a role of null will return true if the role attribute is not present, or if it’s present and the empty string, but not if it’s present and has only spaces in it.

> Source/WebCore/accessibility/AXObjectCache.cpp:267
> +    Vector<String> roles;
> +    roleValue.split(' ', roles);
> +    for (const auto& splitRole : roles) {
> +        if (equalIgnoringCase(splitRole, role))
> +            return true;
> +    }
> +    return false;

Is a literal space character the only separator that works? What about other kinds of whitespace? Actually allocating a vector of strings is not a very efficient way to do this operation. We have a class in the DOM, SpaceSplitString, designed for this kind of thing, although it’s probably also allocating a vector and probably not optimized for the use here. But to use it we would just write:

    return SpaceSplitString(roleValue, true).contains(role);

The class is old enough that we use a boolean for the case folding (not an enum as we would in more modern code). I’m not sure that SpaceSplitString will get the edge cases exactly right. To find out we would need more test cases.
Comment 4 chris fleizach 2014-05-27 17:27:46 PDT
(In reply to comment #3)
> (From update of attachment 231926 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=231926&action=review
> 
> I’m OK with this change, but it doesn’t seem to cover the edge cases of parsing the role attribute very well.
> 
> > Source/WebCore/accessibility/AXObjectCache.cpp:257
> > +    String roleValue = toElement(node)->fastGetAttribute(roleAttr);
> 
> The return value from fastGetAttribute is const AtomicString&, not String. Putting it into a String is OK, but not a good idiom to use most of the time. I’d suggest const AtomicString& or auto& for the type of this value.
> 
> > Source/WebCore/accessibility/AXObjectCache.cpp:259
> > +    if (roleValue.isEmpty() && equalIgnoringCase(role, nullAtom))
> > +        return true;
> 
> We don’t need to use equalIgnoringCase to check if the passed role is null; also, if the role passed is null, I don’t think we really want to run space splitting code below. That would return true if there was a leading or trailing space or two spaces in a row, and I don’t think that’s what we want. You should write this:
> 
>     if (role.isNull())
>         return roleValue.isEmpty();
> 
> But we should also consider if a role of null should match a role attribute consisting entirely of spaces. As written, a role of null will return true if the role attribute is not present, or if it’s present and the empty string, but not if it’s present and has only spaces in it.
> 
> > Source/WebCore/accessibility/AXObjectCache.cpp:267
> > +    Vector<String> roles;
> > +    roleValue.split(' ', roles);
> > +    for (const auto& splitRole : roles) {
> > +        if (equalIgnoringCase(splitRole, role))
> > +            return true;
> > +    }
> > +    return false;
> 
> Is a literal space character the only separator that works? What about other kinds of whitespace? Actually allocating a vector of strings is not a very efficient way to do this operation. We have a class in the DOM, SpaceSplitString, designed for this kind of thing, although it’s probably also allocating a vector and probably not optimized for the use here. But to use it we would just write:
> 
>     return SpaceSplitString(roleValue, true).contains(role);
> 
> The class is old enough that we use a boolean for the case folding (not an enum as we would in more modern code). I’m not sure that SpaceSplitString will get the edge cases exactly right. To find out we would need more test cases.

Thanks for the review. I'll apply these comments and use SpaceSplitString and add a few more test cases to see what falls out.
Comment 5 chris fleizach 2014-05-28 11:32:50 PDT
http://trac.webkit.org/changeset/169427