Skip to content

Conversation

@patrickhlauke
Copy link
Contributor

This rule is primarily aimed at catching situations where 3.1.1 Language of Page fails, which also leads to automatically failing 3.1.2 (since if the language for the overall page cannot be programmatically
determined, neither can the language for any text nodes in the page itself unless there's been some explicit language definition further down in the DOM tree)

Closes issue(s):

Need for Final Call:

This will require a 2 weeks Final Call

Pull Request Etiquette

When creating PR:

  • Make sure you requesting to pull a branch (right side) to the develop branch (left side).

After creating PR:

  • Add yourself (and co-authors) as "Assignees" for PR.
  • Add label to indicate if it's a Rule, Definition or Chore.
  • Close the issue that the PR resolves (and make sure the issue is referenced in the top of this comment)
  • Optionally request feedback from anyone in particular by assigning them as "Reviewers".

How to Review And Approve

  • Go to the “Files changed” tab
  • Here you will have the option to leave comments on different lines.
  • Once the review is completed, find the “Review changes” button in the top right, select “Approve” (if you are really confident in the rule) or "Request changes" and click “Submit review”.
  • Make sure to also review the proposed Final Call period. In case of disagreement, the longer period wins.

This rule is primarily aimed at catching situations where 3.1.1 Language of Page fails, which also leads to automatically failing 3.1.2 (since if the language for the overall page cannot be programmatically
determined, neither can the language for any text nodes in the page itself unless there's been some explicit language definition further down in the DOM tree)

Closes #1009
@CLAassistant
Copy link

CLAassistant commented Nov 21, 2019

CLA assistant check
All committers have signed the CLA.

@patrickhlauke
Copy link
Contributor Author

(note that I made this contribution from my own fork, as I don't think I can just clone and add a new branch directly here? for that reason, I'm also unable to add a label/assign myself)

@patrickhlauke
Copy link
Contributor Author

I'll also add that this is my first stab at doing an ACT rule, so I expect that I made some fundamental logic/form errors...

@Jym77 Jym77 added the Rule Use this label for a new rule that does not exist already label Nov 21, 2019
Copy link
Collaborator

@Jym77 Jym77 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a good start 😄 Most of my comments are on global style issues and not on the logic of the rule…
Additional points:

  1. many links are missing. Notably, "included in the accessibility tree", "flat tree", all the Success Criteria, … Please add them all over the place. You can use "footnote style" reference of markdown for links that are used several time.
  2. Add the Understanding document to Background. Also add CSS scoping with the WiP mention given that you reference it (check what is done in other rules).
  3. Given that you work on the flat tree (which makes sense), you need to add example with shadow tree. Given the nature of the rule, probably something where the shadow tree + flattening is "moving" a lang attribute. Maybe something with a slot where the slotted element has no lang ancestor in the light tree, but shadow tree manipulation put it under an element with a lang (or the other way around).
  4. Maybe having an example with an iframe to show that the rule stops at document boundaries.
  5. There can also be a failed example where one element is OK but another one is not. This illustrates that the SC fails if there is at least one failed outcome.

Good job!

rule_type: atomic
description: |
This rule checks that the language of an element in the page body can be programmatically determined.
accessibility_requirements: # Remove whatever is not applicable
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the rule is also mapping to 3.1.1: if an element has no ancestor with a valid lang, then the document element has no valid lang.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i understood accessibility_requirements as the list of (in this case) WCAG SCs that this is used to test conformance to. as this rule is scoped to descendants of body, it cannot be used to test 3.1.1 language of the page itself, as that needs to (in HTML) be defined for the html element?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the rule is not designed to test SC 3.1.1, but it still does test a bit of it indirectly…
As always, we focus on the fail-on-fail relationship. A failure of this rule indicates a failure of SC 3.1.1 (in addition to 3.1.2). A Pass on this rule does not indicate a Pass of 3.1.1, but neither of 3.1.2… That's how it is for most rules.

Then, it is true also that a failure of this rule implies a failure of HTML page has lang attribute, and that is why it fails 3.1.1. That's also OK. This rule checks more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wondering now if another failure purely for this rule (which i've not added here, but can if it's deemed an actual failure) would be something like

<html lang="en">
  <body>
    <div lang="foo">
      <p>Content</p>
    </div>
  </body>
</html>

where the p fails because its ancestor div has an invalid language attribute, but the page itself does pass 3.1.1...and so a failure of this rule does not indicate a failure of 3.1.1

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rule currently does not fail that because "any of its [the p] ancestor" has a valid lang tag.
I agree that this is a failure of 3.1.2 but not of 3.1.1

I see 2 possibilities:
=> Change the rule to "its closest ancestor with a lang attribute" or something similar. This makes the rule more tricky. In this case, it would indeed not map to 3.1.1
=> Leave the rule as is. This keeps the rule simpler and more focused. This case is already handled by Element within body has valid lang attribute, so there is no real need to enforce it in this rule. The main "problem" with this solution is that Passed Examples must pass the SC, so we cannot use this as a Passed Example to illustrate the limitation of the rule. This is not really a big deal…

Given that this case is already handle by anther rule, I'd rather keep this rule simple.

@patrickhlauke
Copy link
Contributor Author

Just on this point

  1. There can also be a failed example where one element is OK but another one is not. This illustrates that the SC fails if there is at least one failed outcome.

doesn't the rule get applied to every single element separately, in isolation? Don't quite understand therefore why there should be an example with two separate elements, as they'd be tested individually?

@Jym77
Copy link
Collaborator

Jym77 commented Nov 21, 2019

Yes, the rule is applied to every element.

<body>
  <p lang="en" id="ok">Hello</p>
  <p id="ko">World</p>
</body>

the ok element is passing the rule. The ko element is failing the rule. As a result of a single failure of the rule, the SC also fails. Having a Failed Example like that remind of that "single fail is enough" relationship to the SC.
Not a very strong point for adding the example, I admit 😄 And I won't push it further if you or others think it's not necessarily.

@Jym77
Copy link
Collaborator

Jym77 commented Nov 21, 2019

Also, I forgot to mention that you need to add yourself as "contributor" in package.json. You can either do it as part of this PR or open a separate one. Given the usual delay we have for finishing rule PRs, it might be worth making a quick separate PR for this instead…

- add relevant links and background references
- remove redundant `style="display:none"` inapplicable example
- add failed example with invalid language subtag
- add failed example which includes another passing element
- remove note about examples also failing 3.1.1
- more specifically scope applicability to elements that have text nodes as child elements
- make the description for examples slightly less robotic sounding "Language" > "The language"
@patrickhlauke
Copy link
Contributor Author

  1. many links are missing. Notably, "included in the accessibility tree", "flat tree", all the Success Criteria, … Please add them all over the place. You can use "footnote style" reference of markdown for links that are used several time.
  2. Add the Understanding document to Background. Also add CSS scoping with the WiP mention given that you reference it (check what is done in other rules).
  3. Given that you work on the flat tree (which makes sense), you need to add example with shadow tree. Given the nature of the rule, probably something where the shadow tree + flattening is "moving" a lang attribute. Maybe something with a slot where the slotted element has no lang ancestor in the light tree, but shadow tree manipulation put it under an element with a lang (or the other way around).
  4. Maybe having an example with an iframe to show that the rule stops at document boundaries.
  5. There can also be a failed example where one element is OK but another one is not. This illustrates that the SC fails if there is at least one failed outcome.

Done 1, 2 and 5. Have to admit that for 3 I have no idea what that even means, and 4 not quite sure how that would be shown/expressed in a code sample. Any hints for those two would be appreciated.

@Jym77
Copy link
Collaborator

Jym77 commented Nov 21, 2019

  1. Given that you work on the flat tree (which makes sense), you need to add example with shadow tree. Given the nature of the rule, probably something where the shadow tree + flattening is "moving" a lang attribute. Maybe something with a slot where the slotted element has no lang ancestor in the light tree, but shadow tree manipulation put it under an element with a lang (or the other way around).
  2. Maybe having an example with an iframe to show that the rule stops at document boundaries.

Done 1, 2 and 5. Have to admit that for 3 I have no idea what that even means, and 4 not quite sure how that would be shown/expressed in a code sample. Any hints for those two would be appreciated.

From the top of my head…

<html>
<body>
  <div lang="en">Hello
  <iframe srcdoc="<body><div>World</div></body>" />
  </div>
</body>
</html>

The div inside the iframe has no lang because in your expectation the "ancestor" is restricted in the same document. This the rule fails on it.
It's been discussed whether lang should leak inside iframe or not (it is a leak of information to an external resource). I'm not sure what the actual conclusion is 😕 but it's worth illustrating how the rule work.

For the shadow tree, … hmmm…

<html>
<body>
      <div id="host">
        <span>Hello world</span>
      </div>
      
      <script>
        const host = document.getElementById('host')
        const shadowRoot = host.attachShadow({ mode: 'open' })
      
        shadowRoot.innerHTML =
          '<div lang="en"><slot></slot></div>'
      </script>
  </body><html>

In the flat tree, the span is slotted inside the shadow tree and thus has the div lang="en" as parent. So this passes the rule even if it looks like the span has no language…
(the substitution can be made a bit more explicit by naming the slot if you want)

If you use instead shadowRoot.innerHTML='<div></div>', then there is no slot and the span disappears from the flat tree (and is not rendered), hence the rule is inapplicable. But it is less stricking (a simple host.innerHTML='<div></div>' would have the same effect).

rule_type: atomic
description: |
This rule checks that the language of an element in the page body can be programmatically determined.
accessibility_requirements: # Remove whatever is not applicable
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rule currently does not fail that because "any of its [the p] ancestor" has a valid lang tag.
I agree that this is a failure of 3.1.2 but not of 3.1.1

I see 2 possibilities:
=> Change the rule to "its closest ancestor with a lang attribute" or something similar. This makes the rule more tricky. In this case, it would indeed not map to 3.1.1
=> Leave the rule as is. This keeps the rule simpler and more focused. This case is already handled by Element within body has valid lang attribute, so there is no real need to enforce it in this rule. The main "problem" with this solution is that Passed Examples must pass the SC, so we cannot use this as a Passed Example to illustrate the limitation of the rule. This is not really a big deal…

Given that this case is already handle by anther rule, I'd rather keep this rule simple.

Comment on lines +65 to +93
#### Passed Example 2

The language of the `p` element is inherited by the `lang` attribute on the `div` parent element. Note that this example fails 3.1.1 Language of Page (Level: A) as the `html` root element lacks a `lang` attribute.

```html
<html>
<body>
<div lang="en">
<p>Content</p>
</div>
</body>
</html>
```

#### Passed Example 3

The language of the `p` element is inherited by the `lang` attribute on the `div` ancestor element. Note that this example fails 3.1.1 Language of Page (Level: A) as the `html` root element lacks a `lang` attribute.

```html
<html>
<body>
<div lang="en">
<div>
<p>Content</p>
</div>
</div>
</body>
</html>
```
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two examples are actually pretty much the same (the lang attribute is on an ancestor which is not the html element). You can remove one of them.

OTOH, I think it would be good to add an example to illustrate the "child text node" part of the rule.

<body>
<div>
<p lang="en">Hello</p>
</div>
</body>

The p is good. The div is inapplicable. So this passes the rule.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the rule to "its closest ancestor with a lang attribute" or something similar

I think I'm actually tending towards this one, as the closest ancestor is indeed what plays the major part in the essence of this rule, as it relates more closely in how the language of the specific element itself is calculated/programmatically determined.

And mainly, because I do think there's value in making sure that it's clear that there can be failures of this rule that fail 3.1.2 but not 3.1.1.

Copy link
Contributor Author

@patrickhlauke patrickhlauke Nov 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two examples are actually pretty much the same

ah, good spot. wanted to make the difference between parent and ancestor clear (or rather, that we're not just talking about parent), but probably no need to do two examples that are so close to each other. will go with ancestor one, as parent is just a special case of ancestor

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that you can also go even simpler:
check the existence of a lang attribute, not its validity. Then you can go for any ancestor without problem, the rule is much simpler and keep a single concern (it does not need to know what are valid/invalid language tags). Given that we already have rules that check validity of language tags, this is not going to be a real problem.

The point here being that we don't need the rule to be completely covering a single SC. It is better (imho) to have simple rules checking a simple thing and use a combination of rules to cover a SC (rules are already complicated beast, keeping them simple helps writers, readers and testers; simpler rules are also better for separation of concern).

This is a personal opinion and mostly showing what can be done. Of course, go the direction you want 😄 given that you are the one doing the job in the first place…

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'll mull it over. appreciate the thorough discussion on this, particularly as i dove in on the deep end here :)

@WilcoFiers
Copy link
Member

I'm going to close this as this PR has not been updated in 8 months. If someone wants to pick this up again, we can reopen the PR or create a new one.

@WilcoFiers WilcoFiers closed this Jun 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Rule Use this label for a new rule that does not exist already

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants