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 * Whether or not the close button can ever be navigated to using the
47 closeButtonFocusAllowed
: false,
50 decorate: function() {
51 ListItem
.prototype.decorate
.call(this);
53 this.classList
.add('deletable-item');
55 this.contentElement_
= /** @type {HTMLElement} */(
56 this.ownerDocument
.createElement('div'));
57 this.appendChild(this.contentElement_
);
59 this.closeButtonElement_
= /** @type {HTMLElement} */(
60 this.ownerDocument
.createElement('button'));
61 this.closeButtonElement_
.className
=
62 'raw-button row-delete-button custom-appearance';
63 this.closeButtonElement_
.addEventListener('mousedown',
64 this.handleMouseDownUpOnClose_
);
65 this.closeButtonElement_
.addEventListener('mouseup',
66 this.handleMouseDownUpOnClose_
);
67 this.closeButtonElement_
.addEventListener('focus',
68 this.handleFocus
.bind(this));
69 this.closeButtonElement_
.tabIndex
= -1;
70 this.closeButtonElement_
.title
=
71 loadTimeData
.getString('deletableItemDeleteButtonTitle');
72 this.appendChild(this.closeButtonElement_
);
76 * Returns the element subclasses should add content to.
77 * @return {HTMLElement} The element subclasses should popuplate.
79 get contentElement() {
80 return this.contentElement_
;
84 * Returns the close button element.
85 * @return {HTMLElement} The close |<button>| element.
87 get closeButtonElement() {
88 return this.closeButtonElement_
;
91 /* Gets/sets the deletable property. An item that is not deletable doesn't
92 * show the delete button (although space is still reserved for it).
95 return this.deletable_
;
97 set deletable(value
) {
98 this.deletable_
= value
;
99 this.closeButtonElement_
.disabled
= !value
;
103 * Called when a focusable child element receives focus. Selects this item
104 * in the list selection model.
107 handleFocus: function() {
108 // This handler is also fired when the child receives focus as a result of
109 // the item getting selected by the customized mouse/keyboard handling in
110 // SelectionController. Take care not to destroy a potential multiple
111 // selection in this case.
115 var list
= this.parentNode
;
116 var index
= list
.getIndexOfListItem(this);
117 list
.selectionModel
.selectedIndex
= index
;
118 list
.selectionModel
.anchorIndex
= index
;
122 * Don't let the list have a crack at the event. We don't want clicking the
123 * close button to change the selection of the list or to focus on the close
125 * @param {Event} e The mouse down/up event object.
128 handleMouseDownUpOnClose_: function(e
) {
129 if (e
.target
.disabled
)
138 * @extends {cr.ui.List}
140 var DeletableItemList
= cr
.ui
.define('list');
142 DeletableItemList
.prototype = {
143 __proto__
: List
.prototype,
146 decorate: function() {
147 List
.prototype.decorate
.call(this);
148 this.addEventListener('click', this.handleClick
);
149 this.addEventListener('keydown', this.handleKeyDown_
);
153 * Callback for onclick events.
154 * @param {Event} e The click event object.
157 handleClick: function(e
) {
161 var target
= e
.target
;
162 if (target
.classList
.contains('row-delete-button')) {
163 var listItem
= this.getListItemAncestor(
164 /** @type {HTMLElement} */(target
));
165 var idx
= this.getIndexOfListItem(listItem
);
166 this.deleteItemAtIndex(idx
);
171 * Callback for keydown events.
172 * @param {Event} e The keydown event object.
175 handleKeyDown_: function(e
) {
176 // Map delete (and backspace on Mac) to item deletion (unless focus is
177 // in an input field, where it's intended for text editing).
178 if ((e
.keyCode
== 46 || (e
.keyCode
== 8 && cr
.isMac
)) &&
179 e
.target
.tagName
!= 'INPUT') {
180 this.deleteSelectedItems_();
181 // Prevent the browser from going back.
187 * Deletes all the currently selected items that are deletable.
190 deleteSelectedItems_: function() {
191 var selected
= this.selectionModel
.selectedIndexes
;
192 // Reverse through the list of selected indexes to maintain the
193 // correct index values after deletion.
194 for (var j
= selected
.length
- 1; j
>= 0; j
--) {
195 var index
= selected
[j
];
196 if (this.getListItemByIndex(index
).deletable
)
197 this.deleteItemAtIndex(index
);
202 * Called when an item should be deleted; subclasses are responsible for
204 * @param {number} index The index of the item that is being deleted.
206 deleteItemAtIndex: function(index
) {
211 DeletableItemList
: DeletableItemList
,
212 DeletableItem
: DeletableItem
,