Commit cf9b3909 authored by Chris Hall's avatar Chris Hall Committed by Commit Bot

Language attribute should only contain first value from meta tag.

AXNodeObject::Language was returning the full meta tag value "en, fr"
instead of only the first element "en" when computing the language value
for kRootWebArea.

A value containing comma is not a valid BCP47 language tag.

[1] specifies the DOM lang attribute should be a valid BCP47 language
tag, whereas a comma separated list is instead a language priority list.
I'm not sure if this necessarily applies to our accessible interface,
but it seems like the closest spec and this behaviour is consistent
with our other return values.

[1] https://html.spec.whatwg.org/multipage/dom.html#language

AX-Relnotes: n/a.

Change-Id: I0e7b2826e3cca0b9392a4add39c99244018e9dfb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2505291
Commit-Queue: Chris Hall <chrishall@chromium.org>
Reviewed-by: default avatarAlice Boxhall <aboxhall@chromium.org>
Reviewed-by: default avatarNektarios Paisios <nektar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825263}
parent 11214a8b
...@@ -3639,6 +3639,8 @@ AtomicString AXNodeObject::Language() const { ...@@ -3639,6 +3639,8 @@ AtomicString AXNodeObject::Language() const {
if (!GetNode()) if (!GetNode())
return AXObject::Language(); return AXObject::Language();
Vector<String> languages;
// If it's the root, get the computed language for the document element, // If it's the root, get the computed language for the document element,
// because the root LayoutObject doesn't have the right value. // because the root LayoutObject doesn't have the right value.
if (RoleValue() == ax::mojom::blink::Role::kRootWebArea) { if (RoleValue() == ax::mojom::blink::Role::kRootWebArea) {
...@@ -3646,9 +3648,16 @@ AtomicString AXNodeObject::Language() const { ...@@ -3646,9 +3648,16 @@ AtomicString AXNodeObject::Language() const {
if (!document_element) if (!document_element)
return g_empty_atom; return g_empty_atom;
// Ensure we return only the first language tag. ComputeInheritedLanguage
// consults ContentLanguage which can be set from 2 different sources.
// DocumentLoader::DidInstallNewDocument from HTTP headers which truncates
// until the first comma.
// HttpEquiv::Process from <meta> tag which does not truncate.
// TODO(chrishall): Consider moving this comma handling to setter side.
AtomicString lang = document_element->ComputeInheritedLanguage(); AtomicString lang = document_element->ComputeInheritedLanguage();
if (!lang.IsEmpty()) String(lang).Split(',', languages);
return lang; if (!languages.IsEmpty())
return AtomicString(languages[0].StripWhiteSpace());
} }
// Uses the style engine to figure out the object's language. // Uses the style engine to figure out the object's language.
...@@ -3660,7 +3669,6 @@ AtomicString AXNodeObject::Language() const { ...@@ -3660,7 +3669,6 @@ AtomicString AXNodeObject::Language() const {
if (!style || !style->Locale()) if (!style || !style->Locale())
return AXObject::Language(); return AXObject::Language();
Vector<String> languages;
String(style->Locale()).Split(',', languages); String(style->Locale()).Split(',', languages);
if (languages.IsEmpty()) if (languages.IsEmpty())
return AXObject::Language(); return AXObject::Language();
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
<script> <script>
setup(() => { setup(() => {
window.axRoot = accessibilityController.rootElement;
window.axCanvas = accessibilityController.accessibleElementById('canvas'); window.axCanvas = accessibilityController.accessibleElementById('canvas');
window.axParagraph = accessibilityController.accessibleElementById('paragraph'); window.axParagraph = accessibilityController.accessibleElementById('paragraph');
window.axSpan = accessibilityController.accessibleElementById('span'); window.axSpan = accessibilityController.accessibleElementById('span');
...@@ -23,6 +24,8 @@ ...@@ -23,6 +24,8 @@
async_test((t) => { async_test((t) => {
internals.setUserPreferredLanguages([ 'de' ]); internals.setUserPreferredLanguages([ 'de' ]);
assert_equals(window.axRoot.language, 'AXLanguage: en',
'The first language in the meta tag should apply.');
assert_equals(window.axCanvas.language, 'AXLanguage: en', assert_equals(window.axCanvas.language, 'AXLanguage: en',
'The first language in the meta tag should apply.'); 'The first language in the meta tag should apply.');
assert_equals(window.axParagraph.language, 'AXLanguage: en', assert_equals(window.axParagraph.language, 'AXLanguage: en',
...@@ -35,6 +38,8 @@ ...@@ -35,6 +38,8 @@
meta.content = ''; meta.content = '';
t.step_timeout(() => { t.step_timeout(() => {
assert_equals(window.axRoot.language, 'AXLanguage: de',
'The browser language should apply.');
assert_equals(window.axCanvas.language, 'AXLanguage: de', assert_equals(window.axCanvas.language, 'AXLanguage: de',
'The browser language should apply.'); 'The browser language should apply.');
assert_equals(window.axParagraph.language, 'AXLanguage: de', assert_equals(window.axParagraph.language, 'AXLanguage: de',
......
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