Commit 3d5ded22 authored by Kyle Milka's avatar Kyle Milka Committed by Commit Bot

Support tab navigation for custom backgrounds UI

Allow users to interact with the custom backgrounds UI with
only the keyboard.

Bug: 851173
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: Ic442995e2a68d147942ad7625ea0e8a202e40137
Reviewed-on: https://chromium-review.googlesource.com/1097576
Commit-Queue: Kyle Milka <kmilka@chromium.org>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567316}
parent 4c9d0845
......@@ -94,7 +94,7 @@
#bg-sel-menu-overlay {
background-color: rgba(255, 255, 255, .75);
display: none;
border: none;
height: 100%;
left: 0;
position: fixed;
......
......@@ -7,6 +7,18 @@
let customBackgrounds = {};
/**
* Enum for key codes.
* @enum {int}
* @const
*/
customBackgrounds.KEYCODES = {
BACKSPACE: 8,
ENTER: 13,
ESC: 27,
TAB: 9,
};
/**
* Enum for HTML element ids.
* @enum {string}
......@@ -20,6 +32,7 @@ customBackgrounds.IDS = {
DEFAULT_WALLPAPERS_TEXT: 'edit-bg-default-wallpapers-text',
DONE: 'bg-sel-footer-done',
EDIT_BG: 'edit-bg',
EDIT_BG_DIALOG: 'edit-bg-dialog',
EDIT_BG_GEAR: 'edit-bg-gear',
EDIT_BG_OVERLAY: 'edit-bg-overlay',
MENU: 'bg-sel-menu',
......@@ -81,11 +94,11 @@ customBackgrounds.resetSelectionDialog = function() {
* dialog.
*/
customBackgrounds.showCollectionSelectionDialog = function() {
var doneButton = $(customBackgrounds.IDS.DONE);
var tileContainer = $(customBackgrounds.IDS.TILES);
var overlay = $(customBackgrounds.IDS.OVERLAY);
overlay.classList.add(customBackgrounds.CLASSES.SHOW_OVERLAY);
if (!overlay.open)
overlay.showModal();
// Create dialog header
$(customBackgrounds.IDS.TITLE).textContent =
......@@ -100,15 +113,19 @@ customBackgrounds.showCollectionSelectionDialog = function() {
var tile = document.createElement('div');
tile.classList.add(customBackgrounds.CLASSES.COLLECTION_TILE);
tile.style.backgroundImage = 'url(' + coll[i].previewImageUrl + ')';
tile.id = 'coll_tile_' + i;
tile.dataset.id = coll[i].collectionId;
tile.dataset.name = coll[i].collectionName;
tile.tabIndex = 0;
var title = document.createElement('div');
title.classList.add(customBackgrounds.CLASSES.COLLECTION_TITLE);
title.textContent = tile.dataset.name;
tile.onclick = function(event) {
var tile = this;
var tileInteraction = function(event) {
var tile = event.target;
if (tile.classList.contains(customBackgrounds.CLASSES.COLLECTION_TITLE))
tile = tile.parentNode;
// Load images for selected collection
var imgElement = $('ntp-images-loader');
......@@ -118,7 +135,7 @@ customBackgrounds.showCollectionSelectionDialog = function() {
var imgScript = document.createElement('script');
imgScript.id = 'ntp-images-loader';
imgScript.src = 'chrome-search://local-ntp/ntp-background-images.js?' +
'collection_id=' + this.dataset.id;
'collection_id=' + tile.dataset.id;
document.body.appendChild(imgScript);
imgScript.onload = function() {
......@@ -127,23 +144,32 @@ customBackgrounds.showCollectionSelectionDialog = function() {
coll_img[0].collectionId == tile.dataset.id) {
customBackgrounds.showImageSelectionDialog(tile.dataset.name);
} else {
overlay.classList.remove(customBackgrounds.CLASSES.SHOW_OVERLAY);
overlay.close();
customBackgrounds.resetSelectionDialog();
}
};
};
tile.onclick = tileInteraction;
tile.onkeyup = function(event) {
if (event.keyCode === customBackgrounds.KEYCODES.ENTER) {
tileInteraction(event);
}
};
tile.appendChild(title);
tileContainer.appendChild(tile);
}
$(customBackgrounds.IDS.DONE).tabIndex = -1;
// Create dialog footer
$(customBackgrounds.IDS.DONE).textContent =
configData.translatedStrings.selectionDone;
overlay.onclick = function(event) {
if (event.target == overlay) {
overlay.classList.remove(customBackgrounds.CLASSES.SHOW_OVERLAY);
overlay.close();
customBackgrounds.resetSelectionDialog();
}
};
......@@ -155,8 +181,6 @@ customBackgrounds.showCollectionSelectionDialog = function() {
* data should previous have been loaded into coll_img via
* chrome-search://local-ntp/ntp-background-images.js?collection_id=<collection_id>
* @param {string} dialogTitle The title to be displayed at the top of the
* @param {string} prevDialogTitle The title for the previous dialog, needed
* when the back button is clicked.
*/
customBackgrounds.showImageSelectionDialog = function(dialogTitle) {
var backButton = $(customBackgrounds.IDS.BACK);
......@@ -178,8 +202,9 @@ customBackgrounds.showImageSelectionDialog = function(dialogTitle) {
tile.style.backgroundImage = 'url(' + coll_img[i].thumbnailImageUrl + ')';
tile.id = 'img_tile_' + i;
tile.dataset.url = coll_img[i].imageUrl;
tile.tabIndex = 0;
tile.onclick = function(event) {
var tileInteraction = function(event) {
var tile = event.target;
if (selectedTile) {
selectedTile.classList.remove(
......@@ -194,9 +219,20 @@ customBackgrounds.showImageSelectionDialog = function(dialogTitle) {
.classList.add(customBackgrounds.CLASSES.DONE_AVAILABLE);
};
tile.onclick = tileInteraction;
tile.onkeyup = function(event) {
if (event.keyCode === customBackgrounds.KEYCODES.ENTER) {
tileInteraction(event);
doneButton.focus();
}
};
tileContainer.appendChild(tile);
}
$('img_tile_0').focus();
doneButton.tabIndex = 0;
dailyRefresh.onclick = function(event) {
if (selectedTile) {
selectedTile.classList.remove(
......@@ -207,27 +243,53 @@ customBackgrounds.showImageSelectionDialog = function(dialogTitle) {
.classList.add(customBackgrounds.CLASSES.DONE_AVAILABLE);
};
doneButton.onclick = function(event) {
var setBackground = function(event) {
if (!selectedTile)
return;
overlay.classList.remove(customBackgrounds.CLASSES.SHOW_OVERLAY);
overlay.close();
window.chrome.embeddedSearch.newTabPage.setBackgroundURL(
selectedTile.dataset.url);
customBackgrounds.resetSelectionDialog();
};
doneButton.onclick = setBackground;
doneButton.onkeyup = function(event) {
if (event.keyCode === customBackgrounds.KEYCODES.ENTER) {
setBackground(event);
$(customBackgrounds.IDS.EDIT_BG).focus();
}
};
backButton.onclick = function(event) {
customBackgrounds.resetSelectionDialog();
customBackgrounds.showCollectionSelectionDialog();
};
};
/**
* Load the NTPBackgroundCollections script. It'll create a global
* variable name "coll" which is a dict of background collections data.
* TODO(kmilka): add error UI as part of crbug.com/848981.
* @private
*/
customBackgrounds.loadCollections = function() {
var collElement = $('ntp-collection-loader');
if (collElement) {
collElement.parentNode.removeChild(collElement);
}
var collScript = document.createElement('script');
collScript.id = 'ntp-collection-loader';
collScript.src = 'chrome-search://local-ntp/ntp-background-collections.js';
document.body.appendChild(collScript);
};
/**
* Display dialog with various options for custom background source.
*/
customBackgrounds.initCustomBackgrounds = function() {
var editDialogOverlay = $(customBackgrounds.IDS.EDIT_BG_OVERLAY);
var editDialog = $(customBackgrounds.IDS.EDIT_BG_DIALOG);
$(customBackgrounds.IDS.CONNECT_GOOGLE_PHOTOS_TEXT).textContent =
configData.translatedStrings.connectGooglePhotos;
......@@ -242,33 +304,99 @@ customBackgrounds.initCustomBackgrounds = function() {
$(customBackgrounds.IDS.REFRESH_TEXT).textContent =
configData.translatedStrings.dailyRefresh;
$(customBackgrounds.IDS.EDIT_BG_GEAR).onclick = function() {
$(customBackgrounds.IDS.CONNECT_GOOGLE_PHOTOS).hidden = true;
$(customBackgrounds.IDS.DEFAULT_WALLPAPERS).hidden = false;
$(customBackgrounds.IDS.UPLOAD_IMAGE).hidden = true;
$(customBackgrounds.IDS.DEFAULT_WALLPAPERS).onclick = function() {
$(customBackgrounds.IDS.EDIT_BG_OVERLAY)
.classList.remove(customBackgrounds.CLASSES.SHOW_OVERLAY);
if (typeof coll != 'undefined') {
customBackgrounds.showCollectionSelectionDialog(
configData.translatedStrings.selectChromeWallpaper);
}
};
// Control tab cycling through background options.
$(customBackgrounds.IDS.DEFAULT_WALLPAPERS).onkeydown = function(event) {
if (event.keyCode == customBackgrounds.KEYCODES.TAB) {
event.preventDefault();
$(customBackgrounds.IDS.RESTORE_DEFAULT).focus();
}
};
$(customBackgrounds.IDS.RESTORE_DEFAULT).onclick = function() {
$(customBackgrounds.IDS.EDIT_BG_OVERLAY)
.classList.remove(customBackgrounds.CLASSES.SHOW_OVERLAY);
window.chrome.embeddedSearch.newTabPage.setBackgroundURL('');
};
$(customBackgrounds.IDS.RESTORE_DEFAULT).onkeydown = function(event) {
if (event.keyCode == customBackgrounds.KEYCODES.TAB) {
event.preventDefault();
$(customBackgrounds.IDS.DEFAULT_WALLPAPERS).focus();
}
};
editDialogOverlay.classList.add(customBackgrounds.CLASSES.SHOW_OVERLAY);
$(customBackgrounds.IDS.RESTORE_DEFAULT).onfocus = function() {
if (this.hidden) {
$(customBackgrounds.IDS.DEFAULT_WALLPAPERS).focus();
}
};
var editBackgroundInteraction = function(event) {
customBackgrounds.loadCollections();
$(customBackgrounds.IDS.EDIT_BG_OVERLAY)
.classList.add(customBackgrounds.CLASSES.SHOW_OVERLAY);
$(customBackgrounds.IDS.DEFAULT_WALLPAPERS).focus();
};
$(customBackgrounds.IDS.EDIT_BG).onclick = editBackgroundInteraction;
$(customBackgrounds.IDS.EDIT_BG).onkeyup = function(event) {
if (event.keyCode === customBackgrounds.KEYCODES.ENTER) {
editBackgroundInteraction(event);
}
};
var editDialogOverlayInteraction = function(event) {
editDialogOverlay.classList.remove(customBackgrounds.CLASSES.SHOW_OVERLAY);
$(customBackgrounds.IDS.EDIT_BG).focus();
};
editDialogOverlay.onclick = function(event) {
if (event.target == editDialogOverlay) {
editDialogOverlay.classList.remove(
customBackgrounds.CLASSES.SHOW_OVERLAY);
if (event.target == editDialogOverlay)
editDialogOverlayInteraction(event);
};
editDialogOverlay.onkeyup = function(event) {
if (event.keyCode === customBackgrounds.KEYCODES.ESC ||
event.keyCode === customBackgrounds.KEYCODES.BACKSPACE) {
editDialogOverlayInteraction(event);
}
};
var restoreDefaultInteraction = function(event) {
$(customBackgrounds.IDS.EDIT_BG_OVERLAY)
.classList.remove(customBackgrounds.CLASSES.SHOW_OVERLAY);
window.chrome.embeddedSearch.newTabPage.setBackgroundURL('');
$(customBackgrounds.IDS.EDIT_BG).focus();
};
$(customBackgrounds.IDS.RESTORE_DEFAULT).onclick = restoreDefaultInteraction;
$(customBackgrounds.IDS.RESTORE_DEFAULT).onkeyup = function(event) {
if (event.keyCode === customBackgrounds.KEYCODES.ENTER) {
restoreDefaultInteraction(event);
}
};
var defaultWallpapersInteraction = function(event) {
$(customBackgrounds.IDS.EDIT_BG_OVERLAY)
.classList.remove(customBackgrounds.CLASSES.SHOW_OVERLAY);
if (typeof coll != 'undefined') {
customBackgrounds.showCollectionSelectionDialog();
$('coll_tile_0').focus();
}
};
$(customBackgrounds.IDS.DEFAULT_WALLPAPERS).onclick =
defaultWallpapersInteraction;
$(customBackgrounds.IDS.DEFAULT_WALLPAPERS).onkeyup = function(event) {
if (event.keyCode === customBackgrounds.KEYCODES.ENTER) {
defaultWallpapersInteraction(event);
}
};
$(customBackgrounds.IDS.MENU).onkeyup = function(event) {
if (event.keyCode === customBackgrounds.KEYCODES.ESC ||
event.keyCode === customBackgrounds.KEYCODES.BACKSPACE) {
if ($(customBackgrounds.IDS.MENU)
.classList.contains(
customBackgrounds.CLASSES.COLLECTION_DIALOG)) {
$(customBackgrounds.IDS.OVERLAY).close();
$(customBackgrounds.IDS.EDIT_BG).focus();
} else {
customBackgrounds.resetSelectionDialog();
customBackgrounds.showCollectionSelectionDialog();
$('coll_tile_0').focus();
}
}
};
};
......@@ -74,27 +74,27 @@
</div>
<div id="attribution"><div id="attribution-text"></div></div>
<div id="edit-bg" hidden>
<div id="edit-bg" tabindex="0" hidden>
<button id="edit-bg-gear"></button>
</div>
<div id="edit-bg-overlay">
<div id="edit-bg-dialog">
<div id="edit-bg-title"></div>
<div id="edit-bg-google-photos" class="bg-option">
<div id="edit-bg-google-photos" class="bg-option" tabindex="0" hidden>
<div class="bg-option-img"></div>
<div id="edit-bg-google-photos-text" class="bg-option-text"></div>
</div>
<div id="edit-bg-default-wallpapers" class="bg-option">
<div id="edit-bg-default-wallpapers" class="bg-option" tabindex="0">
<div class="bg-option-img"></div>
<div id="edit-bg-default-wallpapers-text" class="bg-option-text">
</div>
</div>
<div id="edit-bg-upload-image" class="bg-option">
<div id="edit-bg-upload-image" class="bg-option" tabindex="0" hidden>
<div class="bg-option-img"></div>
<div id="edit-bg-upload-image-text" class="bg-option-text"></div>
</div>
<div id="edit-bg-restore-default" class="bg-option">
<div id="edit-bg-restore-default" class="bg-option" tabindex="0">
<div class="bg-option-img"></div>
<div id="edit-bg-restore-default-text" class="bg-option-text"></div>
</div>
......@@ -103,7 +103,7 @@
</div>
<div id="bg-sel-menu-overlay">
<dialog id="bg-sel-menu-overlay">
<div id="bg-sel-menu">
<div id="bg-sel-title-bar">
<div id="bg-sel-back"></div>
......@@ -119,7 +119,7 @@
<div id="bg-sel-footer-done"></div>
</div>
</div>
</div>
</dialog>
<dialog id="voice-overlay-dialog" class="overlay-dialog">
<div id="voice-overlay" class="overlay-hidden">
......
......@@ -276,7 +276,6 @@ function getIsThemeDark() {
return luminance >= 128;
}
/**
* Updates the NTP based on the current theme.
* @private
......@@ -307,21 +306,6 @@ function renderTheme() {
if (configData.isGooglePage) {
$('edit-bg').hidden =
!configData.isCustomBackgroundsEnabled || !info.usingDefaultTheme;
$('edit-bg').onclick = function(event) {
var collElement = $('ntp-collection-loader');
if (collElement) {
collElement.parentNode.removeChild(collElement);
}
// Load the NTPBackgroundCollections script. It'll create a global
// variable name "coll" which is a dict of background collections data.
var collScript = document.createElement('script');
collScript.id = 'ntp-collection-loader';
collScript.src =
'chrome-search://local-ntp/ntp-background-collections.js';
document.body.appendChild(collScript);
};
if (configData.isCustomBackgroundsEnabled && info.usingDefaultTheme)
customBackgrounds.initCustomBackgrounds();
}
}
......@@ -825,6 +809,9 @@ function init() {
enableMDIcons();
}
if (configData.isCustomBackgroundsEnabled)
customBackgrounds.initCustomBackgrounds();
// Set up the fakebox (which only exists on the Google NTP).
ntpApiHandle.oninputstart = onInputStart;
ntpApiHandle.oninputcancel = onInputCancel;
......
......@@ -92,7 +92,7 @@
</div>
<div id="bg-sel-menu-overlay">
<dialog id="bg-sel-menu-overlay">
<div id="bg-sel-menu">
<div id="bg-sel-title-bar">
<div id="bg-sel-back"></div>
......@@ -108,7 +108,7 @@
<div id="bg-sel-footer-done"></div>
</div>
</div>
</div>
</dialog>
<dialog id="voice-overlay-dialog" class="overlay-dialog">
<div id="voice-overlay" class="overlay-hidden">
......
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