Commit 44bb8fab authored by rbpotter's avatar rbpotter Committed by Commit Bot

Web UI: Split KeyboardShortcutList into a separate file

Split KeyboardShortcut and KeyboardShortcutList out of command.js, and
update them to use es6 class syntax.

These classes do not contain any ui and do not depend on cr.ui.define()
so should be straightforward to migrate to Polymer 3, unlike
cr.ui.Command itself. Moving them to a separate file allows the
FindShortcutBehavior and the bookmarks CommandManager to depend on
only keyboard_shortcut_list.js and not on command.js.

Bug: 1022213
Change-Id: I5478f7ac5820f5316ff8a07d047bdf20f76210cc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1907773
Commit-Queue: Rebekah Potter <rbpotter@chromium.org>
Reviewed-by: default avatarLuciano Pacheco <lucmult@chromium.org>
Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#714770}
parent 7f3661fd
...@@ -134,7 +134,7 @@ js_library("command_manager") { ...@@ -134,7 +134,7 @@ js_library("command_manager") {
"//ui/webui/resources/cr_elements/cr_toast:cr_toast_manager", "//ui/webui/resources/cr_elements/cr_toast:cr_toast_manager",
"//ui/webui/resources/js:cr", "//ui/webui/resources/js:cr",
"//ui/webui/resources/js:load_time_data", "//ui/webui/resources/js:load_time_data",
"//ui/webui/resources/js/cr/ui:command", "//ui/webui/resources/js/cr/ui:keyboard_shortcut_list",
] ]
externs_list = [ "$externs_path/bookmark_manager_private.js" ] externs_list = [ "$externs_path/bookmark_manager_private.js" ]
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<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/cr_lazy_render/cr_lazy_render.html"> <link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html">
<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/ui/command.html"> <link rel="import" href="chrome://resources/html/cr/ui/keyboard_shortcut_list.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
<link rel="import" href="browser_proxy.html"> <link rel="import" href="browser_proxy.html">
<link rel="import" href="dialog_focus_manager.html"> <link rel="import" href="dialog_focus_manager.html">
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
// src="../../../../../../ui/webui/resources/js/cr/ui/list_selection_controller.js"> // src="../../../../../../ui/webui/resources/js/cr/ui/list_selection_controller.js">
// <include src="../../../../../../ui/webui/resources/js/cr/ui/list.js"> // <include src="../../../../../../ui/webui/resources/js/cr/ui/list.js">
// <include src="../../../../../../ui/webui/resources/js/cr/ui/grid.js"> // <include src="../../../../../../ui/webui/resources/js/cr/ui/grid.js">
// <include
// src="../../../../../../ui/webui/resources/js/cr/ui/keyboard_shortcut_list.js">
// <include src="../../../../../../ui/webui/resources/js/cr/ui/command.js"> // <include src="../../../../../../ui/webui/resources/js/cr/ui/command.js">
// <include // <include
// src="../../../../../../ui/webui/resources/js/cr/ui/position_util.js"> // src="../../../../../../ui/webui/resources/js/cr/ui/position_util.js">
......
...@@ -32,6 +32,7 @@ found in the LICENSE file. ...@@ -32,6 +32,7 @@ found in the LICENSE file.
<script src="../../../../../ui/webui/resources/js/cr/ui/list_selection_controller.js"></script> <script src="../../../../../ui/webui/resources/js/cr/ui/list_selection_controller.js"></script>
<script src="../../../../../ui/webui/resources/js/cr/ui/list.js"></script> <script src="../../../../../ui/webui/resources/js/cr/ui/list.js"></script>
<script src="../../../../../ui/webui/resources/js/cr/ui/grid.js"></script> <script src="../../../../../ui/webui/resources/js/cr/ui/grid.js"></script>
<script src="../../../../../ui/webui/resources/js/cr/ui/keyboard_shortcut_list.js"></script>
<script src="../../../../../ui/webui/resources/js/cr/ui/command.js"></script> <script src="../../../../../ui/webui/resources/js/cr/ui/command.js"></script>
<script src="../../../../../ui/webui/resources/js/cr/ui/position_util.js"></script> <script src="../../../../../ui/webui/resources/js/cr/ui/position_util.js"></script>
<script src="../../../../../ui/webui/resources/js/cr/ui/menu_item.js"></script> <script src="../../../../../ui/webui/resources/js/cr/ui/menu_item.js"></script>
......
...@@ -26,6 +26,7 @@ js_library("apps_page") { ...@@ -26,6 +26,7 @@ js_library("apps_page") {
"//ui/webui/resources/js/cr/ui/context_menu_handler.js", "//ui/webui/resources/js/cr/ui/context_menu_handler.js",
"//ui/webui/resources/js/cr/ui/drag_wrapper.js", "//ui/webui/resources/js/cr/ui/drag_wrapper.js",
"//ui/webui/resources/js/cr/ui/focus_manager.js", "//ui/webui/resources/js/cr/ui/focus_manager.js",
"//ui/webui/resources/js/cr/ui/keyboard_shortcut_list.js",
"//ui/webui/resources/js/cr/ui/menu.js", "//ui/webui/resources/js/cr/ui/menu.js",
"//ui/webui/resources/js/cr/ui/menu_button.js", "//ui/webui/resources/js/cr/ui/menu_button.js",
"//ui/webui/resources/js/cr/ui/menu_item.js", "//ui/webui/resources/js/cr/ui/menu_item.js",
......
...@@ -185,6 +185,7 @@ IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, CommandTest) { ...@@ -185,6 +185,7 @@ IN_PROC_BROWSER_TEST_F(WebUIResourceBrowserTest, CommandTest) {
AddLibrary(IDR_WEBUI_JS_ASSERT); AddLibrary(IDR_WEBUI_JS_ASSERT);
AddLibrary(IDR_WEBUI_JS_CR); AddLibrary(IDR_WEBUI_JS_CR);
AddLibrary(IDR_WEBUI_JS_CR_UI); AddLibrary(IDR_WEBUI_JS_CR_UI);
AddLibrary(IDR_WEBUI_JS_CR_UI_KEYBOARD_SHORTCUT_LIST);
AddLibrary(IDR_WEBUI_JS_CR_UI_COMMAND); AddLibrary(IDR_WEBUI_JS_CR_UI_COMMAND);
LoadFile(base::FilePath(FILE_PATH_LITERAL("command_test.html"))); LoadFile(base::FilePath(FILE_PATH_LITERAL("command_test.html")));
} }
......
...@@ -64,6 +64,8 @@ ...@@ -64,6 +64,8 @@
// //
// <include src="../../../../webui/resources/js/cr/ui/grid.js"> // <include src="../../../../webui/resources/js/cr/ui/grid.js">
// //
// <include
// src="../../../../webui/resources/js/cr/ui/keyboard_shortcut_list.js">
// <include src="../../../../webui/resources/js/cr/ui/command.js"> // <include src="../../../../webui/resources/js/cr/ui/command.js">
// <include src="../../../../webui/resources/js/cr/ui/position_util.js"> // <include src="../../../../webui/resources/js/cr/ui/position_util.js">
// <include src="../../../../webui/resources/js/cr/ui/menu_item.js"> // <include src="../../../../webui/resources/js/cr/ui/menu_item.js">
......
<link rel="import" href="../../../html/cr/ui.html"> <link rel="import" href="../../../html/cr/ui.html">
<link rel="import" href="../../../html/cr/ui/keyboard_shortcut_list.html">
<script src="../../../js/cr/ui/command.js"></script> <script src="../../../js/cr/ui/command.js"></script>
<link rel="import" href="../../../html/cr.html">
<script src="../../../js/cr/ui/keyboard_shortcut_list.js"></script>
<link rel="import" href="../html/assert.html"> <link rel="import" href="../html/assert.html">
<link rel="import" href="../html/cr.html"> <link rel="import" href="../html/cr.html">
<link rel="import" href="../html/cr/ui/command.html"> <link rel="import" href="../html/cr/ui/keyboard_shortcut_list.html">
<link rel="import" href="../html/util.html"> <link rel="import" href="../html/util.html">
<script src="../js/find_shortcut_behavior.js"></script> <script src="../js/find_shortcut_behavior.js"></script>
...@@ -133,7 +133,7 @@ js_library("find_shortcut_behavior") { ...@@ -133,7 +133,7 @@ js_library("find_shortcut_behavior") {
":assert", ":assert",
":cr", ":cr",
":util", ":util",
"cr/ui:command", "cr/ui:keyboard_shortcut_list",
] ]
} }
......
...@@ -25,6 +25,7 @@ js_type_check("ui_resources") { ...@@ -25,6 +25,7 @@ js_type_check("ui_resources") {
":focus_row", ":focus_row",
":focus_row_behavior", ":focus_row_behavior",
":focus_without_ink", ":focus_without_ink",
":keyboard_shortcut_list",
":list", ":list",
":list_item", ":list_item",
":list_selection_controller", ":list_selection_controller",
...@@ -64,6 +65,7 @@ js_library("bubble") { ...@@ -64,6 +65,7 @@ js_library("bubble") {
js_library("command") { js_library("command") {
deps = [ deps = [
":keyboard_shortcut_list",
"..:ui", "..:ui",
"../..:cr", "../..:cr",
] ]
...@@ -142,6 +144,12 @@ js_library("grid") { ...@@ -142,6 +144,12 @@ js_library("grid") {
] ]
} }
js_library("keyboard_shortcut_list") {
deps = [
"../..:cr",
]
}
js_library("list") { js_library("list") {
deps = [ deps = [
":array_data_model", ":array_data_model",
......
...@@ -16,86 +16,6 @@ ...@@ -16,86 +16,6 @@
*/ */
cr.define('cr.ui', function() { cr.define('cr.ui', function() {
/**
* This is used to identify keyboard shortcuts.
* @param {string} shortcut The text used to describe the keys for this
* keyboard shortcut.
* @constructor
*/
function KeyboardShortcut(shortcut) {
this.useKeyCode_ = false;
this.mods_ = {};
shortcut.split('|').forEach((part) => {
const partLc = part.toLowerCase();
switch (partLc) {
case 'alt':
case 'ctrl':
case 'meta':
case 'shift':
this.mods_[partLc + 'Key'] = true;
break;
default:
if (this.key_) {
throw Error('Invalid shortcut');
}
this.key_ = part;
// For single key alpha shortcuts use event.keyCode rather than
// event.key to match how chrome handles shortcuts and allow
// non-english language input to work.
if (part.match(/^[a-z]$/)) {
this.useKeyCode_ = true;
this.keyCode_ = part.toUpperCase().charCodeAt(0);
}
}
});
}
KeyboardShortcut.prototype = {
/**
* Whether the keyboard shortcut object matches a keyboard event.
* @param {!Event} e The keyboard event object.
* @return {boolean} Whether we found a match or not.
*/
matchesEvent: function(e) {
if ((this.useKeyCode_ && e.keyCode == this.keyCode_) ||
e.key == this.key_) {
// All keyboard modifiers need to match.
const mods = this.mods_;
return ['altKey', 'ctrlKey', 'metaKey', 'shiftKey'].every(function(k) {
return e[k] == !!mods[k];
});
}
return false;
}
};
/**
* A list of keyboard shortcuts which all perform one command.
* @param {string} shortcuts Text-based representation of one or more keyboard
* shortcuts, separated by spaces.
* @constructor
*/
function KeyboardShortcutList(shortcuts) {
this.shortcuts_ = shortcuts.split(/\s+/).map(function(shortcut) {
return new KeyboardShortcut(shortcut);
});
}
KeyboardShortcutList.prototype = {
/**
* Returns true if any of the keyboard shortcuts in the list matches a
* keyboard event.
* @param {!Event} e
* @return {boolean}
*/
matchesEvent: function(e) {
return this.shortcuts_.some(function(keyboardShortcut) {
return keyboardShortcut.matchesEvent(e);
});
},
};
/** /**
* Creates a new command element. * Creates a new command element.
* @constructor * @constructor
...@@ -169,7 +89,7 @@ cr.define('cr.ui', function() { ...@@ -169,7 +89,7 @@ cr.define('cr.ui', function() {
set shortcut(shortcut) { set shortcut(shortcut) {
const oldShortcut = this.shortcut_; const oldShortcut = this.shortcut_;
if (shortcut !== oldShortcut) { if (shortcut !== oldShortcut) {
this.keyboardShortcuts_ = new KeyboardShortcutList(shortcut); this.keyboardShortcuts_ = new cr.ui.KeyboardShortcutList(shortcut);
// Set this after the keyboardShortcuts_ since that might throw. // Set this after the keyboardShortcuts_ since that might throw.
this.shortcut_ = shortcut; this.shortcut_ = shortcut;
...@@ -357,6 +277,5 @@ cr.define('cr.ui', function() { ...@@ -357,6 +277,5 @@ cr.define('cr.ui', function() {
return { return {
Command: Command, Command: Command,
CanExecuteEvent: CanExecuteEvent, CanExecuteEvent: CanExecuteEvent,
KeyboardShortcutList: KeyboardShortcutList,
}; };
}); });
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
cr.define('cr.ui', function() {
/** This is used to identify keyboard shortcuts. */
class KeyboardShortcut {
/**
* @param {string} shortcut The text used to describe the keys for this
* keyboard shortcut.
*/
constructor(shortcut) {
/** @private {boolean} */
this.useKeyCode_ = false;
/** @private {Object} */
this.mods_ = {};
/** @private {?string} */
this.key_ = null;
/** @private {?number} */
this.keyCode_ = null;
shortcut.split('|').forEach((part) => {
const partLc = part.toLowerCase();
switch (partLc) {
case 'alt':
case 'ctrl':
case 'meta':
case 'shift':
this.mods_[partLc + 'Key'] = true;
break;
default:
if (this.key_) {
throw Error('Invalid shortcut');
}
this.key_ = part;
// For single key alpha shortcuts use event.keyCode rather than
// event.key to match how chrome handles shortcuts and allow
// non-english language input to work.
if (part.match(/^[a-z]$/)) {
this.useKeyCode_ = true;
this.keyCode_ = part.toUpperCase().charCodeAt(0);
}
}
});
}
/**
* Whether the keyboard shortcut object matches a keyboard event.
* @param {!Event} e The keyboard event object.
* @return {boolean} Whether we found a match or not.
*/
matchesEvent(e) {
if ((this.useKeyCode_ && e.keyCode == this.keyCode_) ||
e.key == this.key_) {
// All keyboard modifiers need to match.
const mods = this.mods_;
return ['altKey', 'ctrlKey', 'metaKey', 'shiftKey'].every(function(k) {
return e[k] == !!mods[k];
});
}
return false;
}
}
/** A list of keyboard shortcuts which all perform one command. */
class KeyboardShortcutList {
/**
* @param {string} shortcuts Text-based representation of one or more
* keyboard shortcuts, separated by spaces.
*/
constructor(shortcuts) {
this.shortcuts_ = shortcuts.split(/\s+/).map(function(shortcut) {
return new KeyboardShortcut(shortcut);
});
}
/**
* Returns true if any of the keyboard shortcuts in the list matches a
* keyboard event.
* @param {!Event} e
* @return {boolean}
*/
matchesEvent(e) {
return this.shortcuts_.some(function(keyboardShortcut) {
return keyboardShortcut.matchesEvent(e);
});
}
}
// Export
return {
KeyboardShortcutList: KeyboardShortcutList,
};
});
...@@ -246,6 +246,9 @@ without changes to the corresponding grd file. --> ...@@ -246,6 +246,9 @@ without changes to the corresponding grd file. -->
<structure name="IDR_WEBUI_HTML_CR_UI_FOCUS_ROW" <structure name="IDR_WEBUI_HTML_CR_UI_FOCUS_ROW"
file="html/cr/ui/focus_row.html" type="chrome_html" file="html/cr/ui/focus_row.html" type="chrome_html"
compress="gzip" /> compress="gzip" />
<structure name="IDR_WEBUI_HTML_CR_UI_KEYBOARD_SHORTCUT_LIST"
file="html/cr/ui/keyboard_shortcut_list.html"
type="chrome_html" compress="gzip" />
<structure name="IDR_WEBUI_HTML_CR_UI_LIST" <structure name="IDR_WEBUI_HTML_CR_UI_LIST"
file="html/cr/ui/list.html" file="html/cr/ui/list.html"
type="chrome_html" compress="gzip" /> type="chrome_html" compress="gzip" />
...@@ -361,6 +364,9 @@ without changes to the corresponding grd file. --> ...@@ -361,6 +364,9 @@ without changes to the corresponding grd file. -->
<structure name="IDR_WEBUI_JS_CR_UI_FOCUS_ROW" <structure name="IDR_WEBUI_JS_CR_UI_FOCUS_ROW"
file="js/cr/ui/focus_row.js" type="chrome_html" file="js/cr/ui/focus_row.js" type="chrome_html"
compress="gzip" /> compress="gzip" />
<structure name="IDR_WEBUI_JS_CR_UI_KEYBOARD_SHORTCUT_LIST"
file="js/cr/ui/keyboard_shortcut_list.js" type="chrome_html"
compress="gzip" />
<structure name="IDR_WEBUI_JS_CR_UI_LIST" <structure name="IDR_WEBUI_JS_CR_UI_LIST"
file="js/cr/ui/list.js" type="chrome_html" compress="gzip" /> file="js/cr/ui/list.js" type="chrome_html" compress="gzip" />
<structure name="IDR_WEBUI_JS_CR_UI_LIST_ITEM" <structure name="IDR_WEBUI_JS_CR_UI_LIST_ITEM"
......
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