Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9793)

Unified Diff: chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_controller.js

Issue 8396001: Add sample extension that allows setting plugin-specific content settings. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: update docs Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_controller.js
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_controller.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_controller.js
new file mode 100644
index 0000000000000000000000000000000000000000..35101d1e715e5f83a4d76f1d5dd6a39582e45a85
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/extensions/plugin_settings/domui/js/cr/ui/list_selection_controller.js
@@ -0,0 +1,289 @@
+// Copyright (c) 2010 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() {
+ /**
+ * Creates a selection controller that is to be used with lists. This is
+ * implemented for vertical lists but changing the behavior for horizontal
+ * lists or icon views is a matter of overriding {@code getIndexBefore},
+ * {@code getIndexAfter}, {@code getIndexAbove} as well as
+ * {@code getIndexBelow}.
+ *
+ * @param {cr.ui.ListSelectionModel} selectionModel The selection model to
+ * interact with.
+ *
+ * @constructor
+ * @extends {!cr.EventTarget}
+ */
+ function ListSelectionController(selectionModel) {
+ this.selectionModel_ = selectionModel;
+ }
+
+ ListSelectionController.prototype = {
+
+ /**
+ * The selection model we are interacting with.
+ * @type {cr.ui.ListSelectionModel}
+ */
+ get selectionModel() {
+ return this.selectionModel_;
+ },
+
+ /**
+ * Returns the index below (y axis) the given element.
+ * @param {number} index The index to get the index below.
+ * @return {number} The index below or -1 if not found.
+ */
+ getIndexBelow: function(index) {
+ if (index == this.getLastIndex())
+ return -1;
+ return index + 1;
+ },
+
+ /**
+ * Returns the index above (y axis) the given element.
+ * @param {number} index The index to get the index above.
+ * @return {number} The index below or -1 if not found.
+ */
+ getIndexAbove: function(index) {
+ return index - 1;
+ },
+
+ /**
+ * Returns the index before (x axis) the given element. This returns -1
+ * by default but override this for icon view and horizontal selection
+ * models.
+ *
+ * @param {number} index The index to get the index before.
+ * @return {number} The index before or -1 if not found.
+ */
+ getIndexBefore: function(index) {
+ return -1;
+ },
+
+ /**
+ * Returns the index after (x axis) the given element. This returns -1
+ * by default but override this for icon view and horizontal selection
+ * models.
+ *
+ * @param {number} index The index to get the index after.
+ * @return {number} The index after or -1 if not found.
+ */
+ getIndexAfter: function(index) {
+ return -1;
+ },
+
+ /**
+ * Returns the next list index. This is the next logical and should not
+ * depend on any kind of layout of the list.
+ * @param {number} index The index to get the next index for.
+ * @return {number} The next index or -1 if not found.
+ */
+ getNextIndex: function(index) {
+ if (index == this.getLastIndex())
+ return -1;
+ return index + 1;
+ },
+
+ /**
+ * Returns the prevous list index. This is the previous logical and should
+ * not depend on any kind of layout of the list.
+ * @param {number} index The index to get the previous index for.
+ * @return {number} The previous index or -1 if not found.
+ */
+ getPreviousIndex: function(index) {
+ return index - 1;
+ },
+
+ /**
+ * @return {number} The first index.
+ */
+ getFirstIndex: function() {
+ return 0;
+ },
+
+ /**
+ * @return {number} The last index.
+ */
+ getLastIndex: function() {
+ return this.selectionModel.length - 1;
+ },
+
+ /**
+ * Called by the view when the user does a mousedown or mouseup on the list.
+ * @param {!Event} e The browser mousedown event.
+ * @param {number} index The index that was under the mouse pointer, -1 if
+ * none.
+ */
+ handleMouseDownUp: function(e, index) {
+ var sm = this.selectionModel;
+ var anchorIndex = sm.anchorIndex;
+ var isDown = e.type == 'mousedown';
+
+ sm.beginChange();
+
+ if (index == -1) {
+ // On Mac we always clear the selection if the user clicks a blank area.
+ // On Windows, we only clear the selection if neither Shift nor Ctrl are
+ // pressed.
+ if (cr.isMac) {
+ sm.leadIndex = sm.anchorIndex = -1;
+ if (sm.multiple)
+ sm.unselectAll();
+ } else if (!isDown && !e.shiftKey && !e.ctrlKey)
+ // Keep anchor and lead indexes. Note that this is intentionally
+ // different than on the Mac.
+ if (sm.multiple)
+ sm.unselectAll();
+ } else {
+ if (sm.multiple && (cr.isMac ? e.metaKey :
+ (e.ctrlKey && !e.shiftKey))) {
+ // Selection is handled at mouseUp on windows/linux, mouseDown on mac.
+ if (cr.isMac? isDown : !isDown) {
+ // Toggle the current one and make it anchor index.
+ sm.setIndexSelected(index, !sm.getIndexSelected(index));
+ sm.leadIndex = index;
+ sm.anchorIndex = index;
+ }
+ } else if (e.shiftKey && anchorIndex != -1 && anchorIndex != index) {
+ // Shift is done in mousedown.
+ if (isDown) {
+ sm.unselectAll();
+ sm.leadIndex = index;
+ if (sm.multiple)
+ sm.selectRange(anchorIndex, index);
+ else
+ sm.setIndexSelected(index, true);
+ }
+ } else {
+ // Right click for a context menu needs to not clear the selection.
+ var isRightClick = e.button == 2;
+
+ // If the index is selected this is handled in mouseup.
+ var indexSelected = sm.getIndexSelected(index);
+ if ((indexSelected && !isDown || !indexSelected && isDown) &&
+ !(indexSelected && isRightClick)) {
+ sm.unselectAll();
+ sm.setIndexSelected(index, true);
+ sm.leadIndex = index;
+ sm.anchorIndex = index;
+ }
+ }
+ }
+
+ sm.endChange();
+ },
+
+ /**
+ * Called by the view when it receives a keydown event.
+ * @param {Event} e The keydown event.
+ */
+ handleKeyDown: function(e) {
+ const SPACE_KEY_CODE = 32;
+ var tagName = e.target.tagName;
+ // If focus is in an input field of some kind, only handle navigation keys
+ // that aren't likely to conflict with input interaction (e.g., text
+ // editing, or changing the value of a checkbox or select).
+ if (tagName == 'INPUT') {
+ var inputType = e.target.type;
+ // Just protect space (for toggling) for checkbox and radio.
+ if (inputType == 'checkbox' || inputType == 'radio') {
+ if (e.keyCode == SPACE_KEY_CODE)
+ return;
+ // Protect all but the most basic navigation commands in anything else.
+ } else if (e.keyIdentifier != 'Up' && e.keyIdentifier != 'Down') {
+ return;
+ }
+ }
+ // Similarly, don't interfere with select element handling.
+ if (tagName == 'SELECT')
+ return;
+
+ var sm = this.selectionModel;
+ var newIndex = -1;
+ var leadIndex = sm.leadIndex;
+ var prevent = true;
+
+ // Ctrl/Meta+A
+ if (sm.multiple && e.keyCode == 65 &&
+ (cr.isMac && e.metaKey || !cr.isMac && e.ctrlKey)) {
+ sm.selectAll();
+ e.preventDefault();
+ return;
+ }
+
+ // Space
+ if (e.keyCode == SPACE_KEY_CODE) {
+ if (leadIndex != -1) {
+ var selected = sm.getIndexSelected(leadIndex);
+ if (e.ctrlKey || !selected) {
+ sm.setIndexSelected(leadIndex, !selected || !sm.multiple);
+ return;
+ }
+ }
+ }
+
+ switch (e.keyIdentifier) {
+ case 'Home':
+ newIndex = this.getFirstIndex();
+ break;
+ case 'End':
+ newIndex = this.getLastIndex();
+ break;
+ case 'Up':
+ newIndex = leadIndex == -1 ?
+ this.getLastIndex() : this.getIndexAbove(leadIndex);
+ break;
+ case 'Down':
+ newIndex = leadIndex == -1 ?
+ this.getFirstIndex() : this.getIndexBelow(leadIndex);
+ break;
+ case 'Left':
+ newIndex = leadIndex == -1 ?
+ this.getLastIndex() : this.getIndexBefore(leadIndex);
+ break;
+ case 'Right':
+ newIndex = leadIndex == -1 ?
+ this.getFirstIndex() : this.getIndexAfter(leadIndex);
+ break;
+ default:
+ prevent = false;
+ }
+
+ if (newIndex != -1) {
+ sm.beginChange();
+
+ sm.leadIndex = newIndex;
+ if (e.shiftKey) {
+ var anchorIndex = sm.anchorIndex;
+ if (sm.multiple)
+ sm.unselectAll();
+ if (anchorIndex == -1) {
+ sm.setIndexSelected(newIndex, true);
+ sm.anchorIndex = newIndex;
+ } else {
+ sm.selectRange(anchorIndex, newIndex);
+ }
+ } else if (e.ctrlKey && !cr.isMac) {
+ // Setting the lead index is done above.
+ // Mac does not allow you to change the lead.
+ } else {
+ if (sm.multiple)
+ sm.unselectAll();
+ sm.setIndexSelected(newIndex, true);
+ sm.anchorIndex = newIndex;
+ }
+
+ sm.endChange();
+
+ if (prevent)
+ e.preventDefault();
+ }
+ }
+ };
+
+ return {
+ ListSelectionController: ListSelectionController
+ };
+});

Powered by Google App Engine
This is Rietveld 408576698