Commit 53f3fee9 authored by Regan Hsu's avatar Regan Hsu Committed by Commit Bot

[CrOS A11y] Fix more complicated cases of "Learn More" sentences.

This is a follow up to
https://chromium-review.googlesource.com/c/chromium/src/+/1967803,
addressing more complicated cases of using the settings-localized-link
element.

Bug: 1015924d
Change-Id: I38d64731511f8fd64ec474db47327ff4241b4841
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1971056Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Commit-Queue: Regan Hsu <hsuregan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#727012}
parent c7b2eef8
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
This device will get automatic software and security updates until <ph name="MONTH_AND_YEAR">$1<ex>September 2020</ex></ph>. &lt;a target="_blank" href="<ph name="URL">$2<ex>https://google.com/</ex></ph>"&gt;Learn more&lt;/a&gt; This device will get automatic software and security updates until <ph name="MONTH_AND_YEAR">$1<ex>September 2020</ex></ph>. &lt;a target="_blank" href="<ph name="URL">$2<ex>https://google.com/</ex></ph>"&gt;Learn more&lt;/a&gt;
</message> </message>
<message name="IDS_SETTINGS_ABOUT_PAGE_LAST_UPDATE_MESSAGE" desc="Message shown on the top level about page to inform the user that this device will no longer receive latest software updates."> <message name="IDS_SETTINGS_ABOUT_PAGE_LAST_UPDATE_MESSAGE" desc="Message shown on the top level about page to inform the user that this device will no longer receive latest software updates.">
This is the last automatic software and security update for this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>. To get future updates, upgrade to a newer model. <ph name="LINK_BEGIN">&lt;a&gt;</ph>Learn more<ph name="LINK_END">&lt;/a&gt;</ph> This is the last automatic software and security update for this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>. To get future updates, upgrade to a newer model. &lt;a target="_blank" href="<ph name="URL">$2<ex>https://google.com/</ex></ph>"&gt;Learn more&lt;/a&gt;
</message> </message>
<message name="IDS_SETTINGS_ABOUT_PAGE_RELAUNCH" desc="The label for the relaunch button that relaunches the browser once update is complete"> <message name="IDS_SETTINGS_ABOUT_PAGE_RELAUNCH" desc="The label for the relaunch button that relaunches the browser once update is complete">
Restart Restart
......
...@@ -92,6 +92,7 @@ js_library("internet_subpage") { ...@@ -92,6 +92,7 @@ js_library("internet_subpage") {
":internet_page_browser_proxy", ":internet_page_browser_proxy",
"../..:route", "../..:route",
"../..:route_origin_behavior", "../..:route_origin_behavior",
"../localized_link:localized_link",
"//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior", "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior",
"//ui/webui/resources/cr_components/chromeos/network:onc_mojo", "//ui/webui/resources/cr_components/chromeos/network:onc_mojo",
"//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo", "//ui/webui/resources/cr_elements/policy:cr_policy_network_behavior_mojo",
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
<link rel="import" href="internet_page_browser_proxy.html"> <link rel="import" href="internet_page_browser_proxy.html">
<link rel="import" href="../localized_link/localized_link.html">
<link rel="import" href="../../chromeos/os_settings_icons_css.html"> <link rel="import" href="../../chromeos/os_settings_icons_css.html">
<link rel="import" href="../../i18n_setup.html"> <link rel="import" href="../../i18n_setup.html">
<link rel="import" href="../../route.html"> <link rel="import" href="../../route.html">
...@@ -160,11 +161,12 @@ ...@@ -160,11 +161,12 @@
</template> </template>
<!-- Text shown if no networks exist. --> <!-- Text shown if no networks exist. -->
<div hidden="[[shouldShowNetworkList_(networkStateList_)]]" <settings-localized-link
inner-h-t-m-l= class="no-networks"
"[[getNoNetworksInnerHtml_(deviceState, tetherDeviceState)]]" hidden="[[shouldShowNetworkList_(networkStateList_)]]"
class="no-networks"> localized-string=
</div> "[[getNoNetworksInnerHtml_(deviceState, tetherDeviceState)]]">
</settings-localized-link>
<template is="dom-if" if="[[matchesType_('VPN', deviceState)]]"> <template is="dom-if" if="[[matchesType_('VPN', deviceState)]]">
<!-- Third party VPNs. --> <!-- Third party VPNs. -->
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
/** /**
* @fileoverview 'settings-localized-link' takes a localized string that * @fileoverview 'settings-localized-link' takes a localized string that
* contains exactly one anchor tag, and labels the string contained within the * contains up to one anchor tag, and labels the string contained within the
* anchor tag with the entire localized string. The string should not be bound * anchor tag with the entire localized string. The string should not be bound
* by element tags. The string should not contain any elements other than the * by element tags. The string should not contain any elements other than the
* single anchor tagged element that will be aria-labelledby the entire string. * single anchor tagged element that will be aria-labelledby the entire string.
...@@ -13,6 +13,11 @@ ...@@ -13,6 +13,11 @@
* *
* The "Learn More" will be aria-labelledby like so: "lorem ipsum Learn More * The "Learn More" will be aria-labelledby like so: "lorem ipsum Learn More
* dolor sit". Meanwhile, "Lorem ipsum" and "dolor sit" will be aria-hidden. * dolor sit". Meanwhile, "Lorem ipsum" and "dolor sit" will be aria-hidden.
*
* This element also supports strings that do not contain anchor tags; in this
* case, the element gracefully falls back to normal text. This can be useful
* when the property is data-bound to a function which sometimes returns a
* string with a link and sometimes returns a normal string.
*/ */
Polymer({ Polymer({
...@@ -20,8 +25,8 @@ Polymer({ ...@@ -20,8 +25,8 @@ Polymer({
properties: { properties: {
/** /**
* The localized string that should contain one anchor tag, the text within * The localized string that contains up to one anchor tag, the text
* which will be aria-labelledby the entire localizedString. * within which will be aria-labelledby the entire localizedString.
*/ */
localizedString: String, localizedString: String,
...@@ -73,6 +78,12 @@ Polymer({ ...@@ -73,6 +78,12 @@ Polymer({
}); });
const anchorTags = tempEl.getElementsByTagName('a'); const anchorTags = tempEl.getElementsByTagName('a');
// In the event the provided localizedString contains only text nodes,
// populate the contents with the provided localizedString.
if (anchorTags.length == 0) {
return localizedString;
}
assert(anchorTags.length == 1, assert(anchorTags.length == 1,
'settings-localized-link should contain exactly one anchor tag'); 'settings-localized-link should contain exactly one anchor tag');
anchorTags[0].setAttribute('aria-labelledby', ariaLabelledByIds.join(' ')); anchorTags[0].setAttribute('aria-labelledby', ariaLabelledByIds.join(' '));
......
...@@ -30,6 +30,7 @@ js_library("os_about_page") { ...@@ -30,6 +30,7 @@ js_library("os_about_page") {
js_library("detailed_build_info") { js_library("detailed_build_info") {
deps = [ deps = [
"../../about_page:about_page_browser_proxy", "../../about_page:about_page_browser_proxy",
"../localized_link:localized_link",
"//ui/webui/resources/cr_elements/policy:cr_policy_indicator_behavior", "//ui/webui/resources/cr_elements/policy:cr_policy_indicator_behavior",
"//ui/webui/resources/js:assert", "//ui/webui/resources/js:assert",
"//ui/webui/resources/js:i18n_behavior", "//ui/webui/resources/js:i18n_behavior",
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
<link rel="import" href="channel_switcher_dialog.html"> <link rel="import" href="channel_switcher_dialog.html">
<link rel="import" href="../../i18n_setup.html"> <link rel="import" href="../../i18n_setup.html">
<link rel="import" href="../../settings_shared_css.html"> <link rel="import" href="../../settings_shared_css.html">
<link rel="import" href="../localized_link/localized_link.html">
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html">
...@@ -55,15 +56,9 @@ ...@@ -55,15 +56,9 @@
class="settings-box two-line single-column" class="settings-box two-line single-column"
hidden="[[!eolMessageWithMonthAndYear]]"> hidden="[[!eolMessageWithMonthAndYear]]">
<div role="heading" aria-level="2">$i18n{aboutEndOfLifeTitle}</div> <div role="heading" aria-level="2">$i18n{aboutEndOfLifeTitle}</div>
<div class="secondary"> <settings-localized-link class="secondary"
<span id="eolMessageWithMonthAndYear" aria-hidden="true"> localized-string="[[eolMessageWithMonthAndYear]]">
[[eolMessageWithMonthAndYear]] </settings-localized-link>
</span>
<a href="$i18nRaw{endOfLifeLearnMoreURL}"
aria-describedby="eolMessageWithMonthAndYear" target="_blank">
$i18n{learnMore}
</a>
</div>
</div> </div>
<cr-link-row class="hr" label="$i18n{aboutBuildDetailsTitle}" <cr-link-row class="hr" label="$i18n{aboutBuildDetailsTitle}"
on-click="onBuildDetailsTap_" external> on-click="onBuildDetailsTap_" external>
......
...@@ -117,12 +117,10 @@ ...@@ -117,12 +117,10 @@
$i18n{learnMore} $i18n{learnMore}
</a> </a>
</div> </div>
<div id="endOfLifeMessageContainer" hidden="[[!hasEndOfLife_]]"> <settings-localized-link
<settings-localized-link id="endOfLifeMessageContainer" hidden="[[!hasEndOfLife_]]"
localized-string="$i18n{endOfLifeMessage}" localized-string="$i18n{endOfLifeMessage}">
link-url="$i18n{endOfLifeLearnMoreURL}"> </settings-localized-link>
</settings-localized-link>
</div>
<div class="secondary">$i18n{aboutBrowserVersion}</div> <div class="secondary">$i18n{aboutBrowserVersion}</div>
</div> </div>
<div class="separator" hidden="[[!showButtonContainer_]]"></div> <div class="separator" hidden="[[!showButtonContainer_]]"></div>
......
...@@ -53,6 +53,7 @@ if (is_chromeos) { ...@@ -53,6 +53,7 @@ if (is_chromeos) {
":multidevice_feature_behavior", ":multidevice_feature_behavior",
"..:route", "..:route",
"..:route_origin_behavior", "..:route_origin_behavior",
"../chromeos/localized_link:localized_link",
"//ui/webui/resources/js:cr", "//ui/webui/resources/js:cr",
] ]
} }
...@@ -70,6 +71,7 @@ if (is_chromeos) { ...@@ -70,6 +71,7 @@ if (is_chromeos) {
":multidevice_constants", ":multidevice_constants",
":multidevice_feature_behavior", ":multidevice_feature_behavior",
"..:route", "..:route",
"../chromeos/localized_link:localized_link",
"../controls:password_prompt_dialog", "../controls:password_prompt_dialog",
"//ui/webui/resources/js:cr", "//ui/webui/resources/js:cr",
"//ui/webui/resources/js:web_ui_listener_behavior", "//ui/webui/resources/js:web_ui_listener_behavior",
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
<link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
<link rel="import" href="../chromeos/localized_link/localized_link.html">
<link rel="import" href="../icons.html"> <link rel="import" href="../icons.html">
<link rel="import" href="../route.html"> <link rel="import" href="../route.html">
<link rel="import" href="../route_origin_behavior.html"> <link rel="import" href="../route_origin_behavior.html">
...@@ -39,10 +40,11 @@ ...@@ -39,10 +40,11 @@
</slot> </slot>
<div id="item-text-container" class="middle"> <div id="item-text-container" class="middle">
<div id="featureName">[[getFeatureName(feature)]]</div> <div id="featureName">[[getFeatureName(feature)]]</div>
<div class="secondary" <settings-localized-link
class="secondary"
id="featureSecondary" id="featureSecondary"
inner-h-t-m-l="[[getFeatureSummaryHtml(feature)]]"> localized-string="[[getFeatureSummaryHtml(feature)]]">
</div> </settings-localized-link>
</div> </div>
<template is="dom-if" <template is="dom-if"
if="[[hasSubpageClickHandler_( if="[[hasSubpageClickHandler_(
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
<link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
<link rel="import" href="../chromeos/localized_link/localized_link.html">
<link rel="import" href="../i18n_setup.html"> <link rel="import" href="../i18n_setup.html">
<link rel="import" href="../icons.html"> <link rel="import" href="../icons.html">
<link rel="import" href="../route.html"> <link rel="import" href="../route.html">
...@@ -47,9 +48,10 @@ ...@@ -47,9 +48,10 @@
<div id="multidevice-label"> <div id="multidevice-label">
[[getLabelText_(pageContentData)]] [[getLabelText_(pageContentData)]]
</div> </div>
<div id="multideviceSubLabel" class="secondary" <settings-localized-link id="multideviceSubLabel"
inner-h-t-m-l="[[getSubLabelInnerHtml_(pageContentData)]]"> class="secondary"
</div> localized-string="[[getSubLabelInnerHtml_(pageContentData)]]">
</settings-localized-link>
</div> </div>
<template is="dom-if" <template is="dom-if"
if="[[doesClickOpenSubpage_(pageContentData)]]" if="[[doesClickOpenSubpage_(pageContentData)]]"
......
...@@ -340,12 +340,11 @@ AboutHandler* AboutHandler::Create(content::WebUIDataSource* html_source, ...@@ -340,12 +340,11 @@ AboutHandler* AboutHandler::Create(content::WebUIDataSource* html_source,
os_with_linux_license); os_with_linux_license);
html_source->AddBoolean("aboutEnterpriseManaged", IsEnterpriseManaged()); html_source->AddBoolean("aboutEnterpriseManaged", IsEnterpriseManaged());
html_source->AddString( html_source->AddString("endOfLifeMessage",
"endOfLifeMessage", l10n_util::GetStringFUTF16(
l10n_util::GetStringFUTF16(IDS_SETTINGS_ABOUT_PAGE_LAST_UPDATE_MESSAGE, IDS_SETTINGS_ABOUT_PAGE_LAST_UPDATE_MESSAGE,
ui::GetChromeOSDeviceName())); ui::GetChromeOSDeviceName(),
html_source->AddString("endOfLifeLearnMoreURL", base::ASCIIToUTF16(chrome::kEolNotificationURL)));
base::ASCIIToUTF16(chrome::kEolNotificationURL));
#endif #endif
return new AboutHandler(); return new AboutHandler();
......
...@@ -65,4 +65,14 @@ suite('localized_link', function() { ...@@ -65,4 +65,14 @@ suite('localized_link', function() {
`<a href="http://google.com" id="id0" aria-labelledby="id0">` + `<a href="http://google.com" id="id0" aria-labelledby="id0">` +
`pre-populated link</a>`); `pre-populated link</a>`);
}); });
test('NoLinkPresent', function() {
document.body.innerHTML = GetLocalizedStringWithLinkElementHtml(
`No anchor tags in this sentence.`, ``);
localizedStringWithLink =
document.body.querySelector('settings-localized-link');
assertEquals(
localizedStringWithLink.$.container.innerHTML,
`No anchor tags in this sentence.`);
});
}); });
...@@ -94,7 +94,8 @@ suite('Multidevice', function() { ...@@ -94,7 +94,8 @@ suite('Multidevice', function() {
}); });
test('link click does not navigate to subpage', function() { test('link click does not navigate to subpage', function() {
const link = featureItem.$$('#featureSecondary > a'); const link =
featureItem.$$('#featureSecondary').$.container.querySelector('a');
assertTrue(!!link); assertTrue(!!link);
checkWhetherClickRoutesAway(link, false); checkWhetherClickRoutesAway(link, false);
}); });
......
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