зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1315201: Override AS context menu a11y title. r=sebastian
MozReview-Commit-ID: HeX7hTpVtEP --HG-- extra : rebase_source : afccf0e06bb8b1ac86ae7b0a47eda8f562bf9c55
This commit is contained in:
Родитель
97b38a996c
Коммит
cdf455e1bb
|
@ -11,7 +11,10 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<!-- a11y: When the dialog first appears, the title is announced so there is no
|
||||
need to allow refocusing the title. -->
|
||||
need to allow refocusing the title.
|
||||
|
||||
Also, we override the a11y title of the dialog in code. If you change the text in id/url or id/title,
|
||||
update the code! -->
|
||||
<RelativeLayout
|
||||
android:id="@+id/info_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -6,6 +6,7 @@ package org.mozilla.gecko.activitystream.homepanel.menu;
|
|||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.design.widget.BottomSheetBehavior;
|
||||
import android.support.design.widget.BottomSheetDialog;
|
||||
import android.support.design.widget.NavigationView;
|
||||
|
@ -16,6 +17,7 @@ import android.view.MenuItem;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.widget.TextView;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.activitystream.ActivityStreamTelemetry;
|
||||
|
@ -41,6 +43,9 @@ import java.net.URISyntaxException;
|
|||
private final View content;
|
||||
private final View activityView;
|
||||
|
||||
/** A reference, that represents the page domain, that allows a return value from an async task. */
|
||||
private String[] pageDomainTextReference = new String[] { "" };
|
||||
|
||||
public BottomSheetContextMenu(final Context context,
|
||||
final ActivityStreamTelemetry.Extras.Builder telemetryExtraBuilder,
|
||||
final MenuMode mode,
|
||||
|
@ -68,14 +73,15 @@ import java.net.URISyntaxException;
|
|||
|
||||
final String pageTitle = item.getTitle();
|
||||
final String sheetPageTitle = !TextUtils.isEmpty(pageTitle) ? pageTitle : item.getUrl();
|
||||
((TextView) content.findViewById(R.id.title)).setText(sheetPageTitle);
|
||||
final TextView titleView = (TextView) content.findViewById(R.id.title);
|
||||
titleView.setText(sheetPageTitle);
|
||||
|
||||
final TextView pageDomainView = (TextView) content.findViewById(R.id.url);
|
||||
final URI itemURI;
|
||||
try {
|
||||
itemURI = new URI(item.getUrl());
|
||||
final UpdatePageDomainAsyncTask updateDomainAsyncTask = new UpdatePageDomainAsyncTask(context, pageDomainView,
|
||||
itemURI);
|
||||
itemURI, pageDomainTextReference);
|
||||
updateDomainAsyncTask.execute();
|
||||
} catch (final URISyntaxException e) {
|
||||
// Invalid URI: not much processing we can do. Like the async task, the page title view sets itself to the
|
||||
|
@ -83,6 +89,8 @@ import java.net.URISyntaxException;
|
|||
pageDomainView.setText("");
|
||||
}
|
||||
|
||||
overrideInitialAccessibilityAnnouncement(pageDomainView, titleView, sheetPageTitle, item.getUrl());
|
||||
|
||||
// Copy layouted parameters from the Highlights / TopSites items to ensure consistency
|
||||
final StreamOverridablePageIconLayout pageIconLayout =
|
||||
(StreamOverridablePageIconLayout) content.findViewById(R.id.page_icon_layout);
|
||||
|
@ -101,6 +109,56 @@ import java.net.URISyntaxException;
|
|||
super.postInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the announcement made when the dialog first appears with Talkback enabled.
|
||||
*
|
||||
* By default, the dialog will find the first TextView (the page domain) and speak its contents as the initial
|
||||
* announcement. However, in order to uniquely identify a site, we need both the page domain and the page title: we
|
||||
* override the announcement with that content.
|
||||
*
|
||||
* Caveat: the page domain is retrieved asynchronously so this becomes tricky. In theory, we could block the UI
|
||||
* thread for the page domain and with the current implementation, it'd be fine:
|
||||
* - It's async only because the first time this method is called, it reads a file from disk.
|
||||
* Otherwise, it's unnecessary.
|
||||
* - This method is guaranteed to have already been called because about:home shows before this context menu can show
|
||||
*
|
||||
* But the implementation could change and it seemed incorrect to block showing this context menu for
|
||||
* *all* users solely for a11y text that can be estimated.
|
||||
*/
|
||||
private void overrideInitialAccessibilityAnnouncement(final View pageDomainView, final View pageTitleView,
|
||||
final String pageTitle, final String urlStr) {
|
||||
final View.AccessibilityDelegate initialAnnouncementDelegate = new View.AccessibilityDelegate() {
|
||||
@Override
|
||||
public void onPopulateAccessibilityEvent(final View hostView, final AccessibilityEvent event) {
|
||||
// The page domain is retrieved with an async operation and the return value is stored here.
|
||||
final String shortenedHost = pageDomainTextReference[0];
|
||||
|
||||
final String finalHost;
|
||||
if (!TextUtils.isEmpty(shortenedHost)) {
|
||||
finalHost = shortenedHost;
|
||||
} else if (TextUtils.isEmpty(urlStr)) {
|
||||
// There's no url so we can't do any better.
|
||||
finalHost = "";
|
||||
} else {
|
||||
// The async page domain isn't completed yet so we'll do a best approximation.
|
||||
final Uri uri = Uri.parse(urlStr);
|
||||
final String host = uri.getHost();
|
||||
finalHost = !TextUtils.isEmpty(host) ? host : urlStr;
|
||||
}
|
||||
|
||||
final String announcementText = finalHost + ", " + pageTitle;
|
||||
event.getText().add(announcementText);
|
||||
super.onPopulateAccessibilityEvent(hostView, event);
|
||||
}
|
||||
};
|
||||
|
||||
// The dialog finds the first available TextView and announces its text as the accessibility title. The
|
||||
// pageDomainView is first but since the title is completed asynchronously, it may not have text yet, and
|
||||
// may be an invalid first TextView, we have to set the listener on both the first and second TextViews.
|
||||
pageDomainView.setAccessibilityDelegate(initialAnnouncementDelegate);
|
||||
pageTitleView.setAccessibilityDelegate(initialAnnouncementDelegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuItem getItemByID(int id) {
|
||||
return navigationView.getMenu().findItem(id);
|
||||
|
@ -169,10 +227,13 @@ import java.net.URISyntaxException;
|
|||
/** Updates the given TextView's text to the page domain. */
|
||||
private static class UpdatePageDomainAsyncTask extends URIUtils.GetFormattedDomainAsyncTask {
|
||||
private final WeakReference<TextView> pageDomainViewWeakReference;
|
||||
private final String[] pageDomainTextReference;
|
||||
|
||||
private UpdatePageDomainAsyncTask(final Context context, final TextView pageDomainView, final URI uri) {
|
||||
private UpdatePageDomainAsyncTask(final Context context, final TextView pageDomainView, final URI uri,
|
||||
final String[] pageDomainTextReference) {
|
||||
super(context, uri, true, 0); // baseDomain.
|
||||
this.pageDomainViewWeakReference = new WeakReference<>(pageDomainView);
|
||||
this.pageDomainTextReference = pageDomainTextReference;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -195,6 +256,7 @@ import java.net.URISyntaxException;
|
|||
updateText = !TextUtils.isEmpty(normalizedHost) ? normalizedHost : "";
|
||||
}
|
||||
|
||||
pageDomainTextReference[0] = updateText;
|
||||
pageDomainView.setText(updateText);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче