OLD | NEW |
| (Empty) |
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. | |
4 | |
5 cr.define('options', function() { | |
6 /** @const */ var List = cr.ui.List; | |
7 /** @const */ var ListItem = cr.ui.ListItem; | |
8 | |
9 /** | |
10 * Creates a deletable list item, which has a button that will trigger a call | |
11 * to deleteItemAtIndex(index) in the list. | |
12 */ | |
13 var DeletableItem = cr.ui.define('li'); | |
14 | |
15 DeletableItem.prototype = { | |
16 __proto__: ListItem.prototype, | |
17 | |
18 /** | |
19 * The element subclasses should populate with content. | |
20 * @type {HTMLElement} | |
21 * @private | |
22 */ | |
23 contentElement_: null, | |
24 | |
25 /** | |
26 * The close button element. | |
27 * @type {HTMLElement} | |
28 * @private | |
29 */ | |
30 closeButtonElement_: null, | |
31 | |
32 /** | |
33 * Whether or not this item can be deleted. | |
34 * @type {boolean} | |
35 * @private | |
36 */ | |
37 deletable_: true, | |
38 | |
39 /** @inheritDoc */ | |
40 decorate: function() { | |
41 ListItem.prototype.decorate.call(this); | |
42 | |
43 this.classList.add('deletable-item'); | |
44 | |
45 this.contentElement_ = this.ownerDocument.createElement('div'); | |
46 this.appendChild(this.contentElement_); | |
47 | |
48 this.closeButtonElement_ = this.ownerDocument.createElement('button'); | |
49 this.closeButtonElement_.className = | |
50 'raw-button row-delete-button custom-appearance'; | |
51 this.closeButtonElement_.addEventListener('mousedown', | |
52 this.handleMouseDownUpOnClose_); | |
53 this.closeButtonElement_.addEventListener('mouseup', | |
54 this.handleMouseDownUpOnClose_); | |
55 this.closeButtonElement_.addEventListener('focus', | |
56 this.handleFocus_.bind(this)); | |
57 this.appendChild(this.closeButtonElement_); | |
58 }, | |
59 | |
60 /** | |
61 * Returns the element subclasses should add content to. | |
62 * @return {HTMLElement} The element subclasses should popuplate. | |
63 */ | |
64 get contentElement() { | |
65 return this.contentElement_; | |
66 }, | |
67 | |
68 /** | |
69 * Returns the close button element. | |
70 * @return {HTMLElement} The close |<button>| element. | |
71 */ | |
72 get closeButtonElement() { | |
73 return this.closeButtonElement_; | |
74 }, | |
75 | |
76 /* Gets/sets the deletable property. An item that is not deletable doesn't | |
77 * show the delete button (although space is still reserved for it). | |
78 */ | |
79 get deletable() { | |
80 return this.deletable_; | |
81 }, | |
82 set deletable(value) { | |
83 this.deletable_ = value; | |
84 this.closeButtonElement_.disabled = !value; | |
85 }, | |
86 | |
87 /** | |
88 * Called when a focusable child element receives focus. Selects this item | |
89 * in the list selection model. | |
90 * @private | |
91 */ | |
92 handleFocus_: function() { | |
93 var list = this.parentNode; | |
94 var index = list.getIndexOfListItem(this); | |
95 list.selectionModel.selectedIndex = index; | |
96 list.selectionModel.anchorIndex = index; | |
97 }, | |
98 | |
99 /** | |
100 * Don't let the list have a crack at the event. We don't want clicking the | |
101 * close button to change the selection of the list. | |
102 * @param {Event} e The mouse down/up event object. | |
103 * @private | |
104 */ | |
105 handleMouseDownUpOnClose_: function(e) { | |
106 if (!e.target.disabled) | |
107 e.stopPropagation(); | |
108 }, | |
109 }; | |
110 | |
111 var DeletableItemList = cr.ui.define('list'); | |
112 | |
113 DeletableItemList.prototype = { | |
114 __proto__: List.prototype, | |
115 | |
116 /** @inheritDoc */ | |
117 decorate: function() { | |
118 List.prototype.decorate.call(this); | |
119 this.addEventListener('click', this.handleClick_); | |
120 this.addEventListener('keydown', this.handleKeyDown_); | |
121 }, | |
122 | |
123 /** | |
124 * Callback for onclick events. | |
125 * @param {Event} e The click event object. | |
126 * @private | |
127 */ | |
128 handleClick_: function(e) { | |
129 if (this.disabled) | |
130 return; | |
131 | |
132 var target = e.target; | |
133 if (target.classList.contains('row-delete-button')) { | |
134 var listItem = this.getListItemAncestor(target); | |
135 var selected = this.selectionModel.selectedIndexes; | |
136 | |
137 // Check if the list item that contains the close button being clicked | |
138 // is not in the list of selected items. Only delete this item in that | |
139 // case. | |
140 var idx = this.getIndexOfListItem(listItem); | |
141 if (selected.indexOf(idx) == -1) { | |
142 this.deleteItemAtIndex(idx); | |
143 } else { | |
144 this.deleteSelectedItems_(); | |
145 } | |
146 } | |
147 }, | |
148 | |
149 /** | |
150 * Callback for keydown events. | |
151 * @param {Event} e The keydown event object. | |
152 * @private | |
153 */ | |
154 handleKeyDown_: function(e) { | |
155 // Map delete (and backspace on Mac) to item deletion (unless focus is | |
156 // in an input field, where it's intended for text editing). | |
157 if ((e.keyCode == 46 || (e.keyCode == 8 && cr.isMac)) && | |
158 e.target.tagName != 'INPUT') { | |
159 this.deleteSelectedItems_(); | |
160 // Prevent the browser from going back. | |
161 e.preventDefault(); | |
162 } | |
163 }, | |
164 | |
165 /** | |
166 * Deletes all the currently selected items that are deletable. | |
167 * @private | |
168 */ | |
169 deleteSelectedItems_: function() { | |
170 var selected = this.selectionModel.selectedIndexes; | |
171 // Reverse through the list of selected indexes to maintain the | |
172 // correct index values after deletion. | |
173 for (var j = selected.length - 1; j >= 0; j--) { | |
174 var index = selected[j]; | |
175 if (this.getListItemByIndex(index).deletable) | |
176 this.deleteItemAtIndex(index); | |
177 } | |
178 }, | |
179 | |
180 /** | |
181 * Called when an item should be deleted; subclasses are responsible for | |
182 * implementing. | |
183 * @param {number} index The index of the item that is being deleted. | |
184 */ | |
185 deleteItemAtIndex: function(index) { | |
186 }, | |
187 }; | |
188 | |
189 return { | |
190 DeletableItemList: DeletableItemList, | |
191 DeletableItem: DeletableItem, | |
192 }; | |
193 }); | |
OLD | NEW |