Bug 1334496 - Part 1 - Add an autofocus option to PopupNotifications.show. r=Paolo

MozReview-Commit-ID: DrJOjUWJJOD

--HG--
extra : rebase_source : 75f395dcadd1134fe7ca6169533ffaa4c65a1485
This commit is contained in:
Johann Hofmann 2017-02-17 14:56:23 +01:00
Родитель 5bfaab2025
Коммит d9c8f7d70b
2 изменённых файлов: 66 добавлений и 10 удалений

Просмотреть файл

@ -8,7 +8,8 @@ function test() {
ok(PopupNotifications, "PopupNotifications object exists");
ok(PopupNotifications.panel, "PopupNotifications panel exists");
setup();
// Force tabfocus for all elements on OSX.
SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]}).then(setup);
}
var tests = [
@ -53,7 +54,6 @@ var tests = [
// Test that the space key on an anchor element focuses an active notification
{ id: "Test#3",
*run() {
yield SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]});
this.notifyObj = new BasicNotification(this.id);
this.notifyObj.anchorID = "geo-notification-icon";
this.notifyObj.addOptions({
@ -76,8 +76,6 @@ var tests = [
// and that the notification is focused on selection.
{ id: "Test#4",
*run() {
yield SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]});
let notifyObj1 = new BasicNotification(this.id);
notifyObj1.id += "_1";
notifyObj1.anchorID = "default-notification-icon";
@ -132,4 +130,46 @@ var tests = [
goNext();
},
},
// Test that passing the autofocus option will focus an opened notification.
{ id: "Test#5",
*run() {
this.notifyObj = new BasicNotification(this.id);
this.notifyObj.anchorID = "geo-notification-icon";
this.notifyObj.addOptions({
autofocus: true,
});
this.notification = showNotification(this.notifyObj);
},
*onShown(popup) {
checkPopup(popup, this.notifyObj);
// Initial focus on open is null because a panel itself
// can not be focused, next tab focus will be inside the panel.
is(Services.focus.focusedElement, null);
EventUtils.synthesizeKey("VK_TAB", {});
is(Services.focus.focusedElement, popup.childNodes[0].closebutton);
dismissNotification(popup);
},
*onHidden() {
// Focus the urlbar to check that it stays focused.
gURLBar.focus();
// Show another notification and make sure it's not autofocused.
let notifyObj = new BasicNotification(this.id);
notifyObj.id += "_2";
notifyObj.anchorID = "default-notification-icon";
let opened = waitForNotificationPanel();
let notification = showNotification(notifyObj);
let popup = yield opened;
checkPopup(popup, notifyObj);
// Check that the urlbar is still focused.
is(Services.focus.focusedElement, gURLBar.inputField);
this.notification.remove();
notification.remove();
}
},
];

Просмотреть файл

@ -246,15 +246,15 @@ this.PopupNotifications = function PopupNotifications(tabbrowser, panel,
}
let doc = this.window.document;
let activeElement = doc.activeElement;
let focusedElement = Services.focus.focusedElement;
// If the chrome window has a focused element, let it handle the ESC key instead.
if (!activeElement ||
activeElement == doc.body ||
activeElement == this.tabbrowser.selectedBrowser ||
if (!focusedElement ||
focusedElement == doc.body ||
focusedElement == this.tabbrowser.selectedBrowser ||
// Ignore focused elements inside the notification.
getNotificationFromElement(activeElement) == notification ||
notification.contains(activeElement)) {
getNotificationFromElement(focusedElement) == notification ||
notification.contains(focusedElement)) {
this._onButtonEvent(aEvent, "secondarybuttoncommand", notification);
}
};
@ -354,6 +354,8 @@ PopupNotifications.prototype = {
* dismissed: Whether the notification should be added as a dismissed
* notification. Dismissed notifications can be activated
* by clicking on their anchorElement.
* autofocus: Whether the notification should be autofocused on
* showing, stealing focus from any other focused element.
* eventCallback:
* Callback to be invoked when the notification changes
* state. The callback's first argument is a string
@ -465,6 +467,14 @@ PopupNotifications.prototype = {
if (isActiveBrowser) {
if (isActiveWindow) {
// Autofocus if the notification requests focus.
if (options && !options.dismissed && options.autofocus) {
this.panel.removeAttribute("noautofocus");
} else {
this.panel.setAttribute("noautofocus", "true");
}
// show panel now
this._update(notifications, new Set([notification.anchorElement]), true);
} else {
@ -1318,6 +1328,12 @@ PopupNotifications.prototype = {
return;
}
// We may have removed the "noautofocus" attribute before showing the panel
// if the notification specified it wants to autofocus on first show.
// When the panel is closed, we have to restore the attribute to its default
// value, so we don't autofocus it if it's subsequently opened from a different code path.
this.panel.setAttribute("noautofocus", "true");
// Handle the case where the panel was closed programmatically.
if (this._ignoreDismissal) {
this._ignoreDismissal.resolve();