1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 cr.define('options', function() {
6 /** @const */ var List = cr.ui.List;
7 /** @const */ var ListItem = cr.ui.ListItem;
10 * Creates a deletable list item, which has a button that will trigger a call
11 * to deleteItemAtIndex(index) in the list.
13 * @extends {cr.ui.ListItem}
15 var DeletableItem = cr.ui.define('li');
17 DeletableItem.prototype = {
18 __proto__: ListItem.prototype,
21 * The element subclasses should populate with content.
25 contentElement_: null,
28 * The close button element.
32 closeButtonElement_: null,
35 * Whether or not this item can be deleted.
42 decorate: function() {
43 ListItem.prototype.decorate.call(this);
45 this.classList.add('deletable-item');
47 this.contentElement_ = /** @type {HTMLElement} */(
48 this.ownerDocument.createElement('div'));
49 this.appendChild(this.contentElement_);
51 this.closeButtonElement_ = /** @type {HTMLElement} */(
52 this.ownerDocument.createElement('button'));
53 this.closeButtonElement_.className =
54 'raw-button row-delete-button custom-appearance';
55 this.closeButtonElement_.addEventListener('mousedown',
56 this.handleMouseDownUpOnClose_);
57 this.closeButtonElement_.addEventListener('mouseup',
58 this.handleMouseDownUpOnClose_);
59 this.closeButtonElement_.addEventListener('focus',
60 this.handleFocus_.bind(this));
61 this.closeButtonElement_.tabIndex = -1;
62 this.closeButtonElement_.title =
63 loadTimeData.getString('deletableItemDeleteButtonTitle');
64 this.appendChild(this.closeButtonElement_);
68 * Returns the element subclasses should add content to.
69 * @return {HTMLElement} The element subclasses should popuplate.
71 get contentElement() {
72 return this.contentElement_;
76 * Returns the close button element.
77 * @return {HTMLElement} The close |<button>| element.
79 get closeButtonElement() {
80 return this.closeButtonElement_;
83 /* Gets/sets the deletable property. An item that is not deletable doesn't
84 * show the delete button (although space is still reserved for it).
87 return this.deletable_;
89 set deletable(value) {
90 this.deletable_ = value;
91 this.closeButtonElement_.disabled = !value;
95 * Called when a focusable child element receives focus. Selects this item
96 * in the list selection model.
99 handleFocus_: function() {
100 // This handler is also fired when the child receives focus as a result of
101 // the item getting selected by the customized mouse/keyboard handling in
102 // SelectionController. Take care not to destroy a potential multiple
103 // selection in this case.
107 var list = this.parentNode;
108 var index = list.getIndexOfListItem(this);
109 list.selectionModel.selectedIndex = index;
110 list.selectionModel.anchorIndex = index;
114 * Don't let the list have a crack at the event. We don't want clicking the
115 * close button to change the selection of the list or to focus on the close
117 * @param {Event} e The mouse down/up event object.
120 handleMouseDownUpOnClose_: function(e) {
121 if (e.target.disabled)
130 * @extends {cr.ui.List}
132 var DeletableItemList = cr.ui.define('list');
134 DeletableItemList.prototype = {
135 __proto__: List.prototype,
138 decorate: function() {
139 List.prototype.decorate.call(this);
140 this.addEventListener('click', this.handleClick);
141 this.addEventListener('keydown', this.handleKeyDown_);
145 * Callback for onclick events.
146 * @param {Event} e The click event object.
149 handleClick: function(e) {
153 var target = e.target;
154 if (target.classList.contains('row-delete-button')) {
155 var listItem = this.getListItemAncestor(
156 /** @type {HTMLElement} */(target));
157 var idx = this.getIndexOfListItem(listItem);
158 this.deleteItemAtIndex(idx);
163 * Callback for keydown events.
164 * @param {Event} e The keydown event object.
167 handleKeyDown_: function(e) {
168 // Map delete (and backspace on Mac) to item deletion (unless focus is
169 // in an input field, where it's intended for text editing).
170 if ((e.keyCode == 46 || (e.keyCode == 8 && cr.isMac)) &&
171 e.target.tagName != 'INPUT') {
172 this.deleteSelectedItems_();
173 // Prevent the browser from going back.
179 * Deletes all the currently selected items that are deletable.
182 deleteSelectedItems_: function() {
183 var selected = this.selectionModel.selectedIndexes;
184 // Reverse through the list of selected indexes to maintain the
185 // correct index values after deletion.
186 for (var j = selected.length - 1; j >= 0; j--) {
187 var index = selected[j];
188 if (this.getListItemByIndex(index).deletable)
189 this.deleteItemAtIndex(index);
194 * Called when an item should be deleted; subclasses are responsible for
196 * @param {number} index The index of the item that is being deleted.
198 deleteItemAtIndex: function(index) {
203 DeletableItemList: DeletableItemList,
204 DeletableItem: DeletableItem,