OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 List = cr.ui.List; | |
7 const 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_.classList.add('raw-button'); | |
50 this.closeButtonElement_.classList.add('close-button'); | |
51 this.closeButtonElement_.addEventListener('mousedown', | |
52 this.handleMouseDownUpOnClose_); | |
53 this.closeButtonElement_.addEventListener('mouseup', | |
54 this.handleMouseDownUpOnClose_); | |
55 this.appendChild(this.closeButtonElement_); | |
56 }, | |
57 | |
58 /** | |
59 * Returns the element subclasses should add content to. | |
60 * @return {HTMLElement} The element subclasses should popuplate. | |
61 */ | |
62 get contentElement() { | |
63 return this.contentElement_; | |
64 }, | |
65 | |
66 /* Gets/sets the deletable property. An item that is not deletable doesn't | |
67 * show the delete button (although space is still reserved for it). | |
68 */ | |
69 get deletable() { | |
70 return this.deletable_; | |
71 }, | |
72 set deletable(value) { | |
73 this.deletable_ = value; | |
74 this.closeButtonElement_.disabled = !value; | |
75 }, | |
76 | |
77 /** | |
78 * Don't let the list have a crack at the event. We don't want clicking the | |
79 * close button to change the selection of the list. | |
80 * @param {Event} e The mouse down/up event object. | |
81 * @private | |
82 */ | |
83 handleMouseDownUpOnClose_: function(e) { | |
84 if (!e.target.disabled) | |
85 e.stopPropagation(); | |
86 }, | |
87 }; | |
88 | |
89 var DeletableItemList = cr.ui.define('list'); | |
90 | |
91 DeletableItemList.prototype = { | |
92 __proto__: List.prototype, | |
93 | |
94 /** @inheritDoc */ | |
95 decorate: function() { | |
96 List.prototype.decorate.call(this); | |
97 this.addEventListener('click', this.handleClick_); | |
98 this.addEventListener('keydown', this.handleKeyDown_); | |
99 }, | |
100 | |
101 /** | |
102 * Callback for onclick events. | |
103 * @param {Event} e The click event object. | |
104 * @private | |
105 */ | |
106 handleClick_: function(e) { | |
107 if (this.disabled) | |
108 return; | |
109 | |
110 var target = e.target; | |
111 if (target.classList.contains('close-button')) { | |
112 var listItem = this.getListItemAncestor(target); | |
113 var selected = this.selectionModel.selectedIndexes; | |
114 | |
115 // Check if the list item that contains the close button being clicked | |
116 // is not in the list of selected items. Only delete this item in that | |
117 // case. | |
118 var idx = this.getIndexOfListItem(listItem); | |
119 if (selected.indexOf(idx) == -1) { | |
120 this.deleteItemAtIndex(idx); | |
121 } else { | |
122 this.deleteSelectedItems_(); | |
123 } | |
124 } | |
125 }, | |
126 | |
127 /** | |
128 * Callback for keydown events. | |
129 * @param {Event} e The keydown event object. | |
130 * @private | |
131 */ | |
132 handleKeyDown_: function(e) { | |
133 // Map delete (and backspace on Mac) to item deletion (unless focus is | |
134 // in an input field, where it's intended for text editing). | |
135 if ((e.keyCode == 46 || (e.keyCode == 8 && cr.isMac)) && | |
136 e.target.tagName != 'INPUT') { | |
137 this.deleteSelectedItems_(); | |
138 // Prevent the browser from going back. | |
139 e.preventDefault(); | |
140 } | |
141 }, | |
142 | |
143 /** | |
144 * Deletes all the currently selected items that are deletable. | |
145 * @private | |
146 */ | |
147 deleteSelectedItems_: function() { | |
148 var selected = this.selectionModel.selectedIndexes; | |
149 // Reverse through the list of selected indexes to maintain the | |
150 // correct index values after deletion. | |
151 for (var j = selected.length - 1; j >= 0; j--) { | |
152 var index = selected[j]; | |
153 if (this.getListItemByIndex(index).deletable) | |
154 this.deleteItemAtIndex(index); | |
155 } | |
156 }, | |
157 | |
158 /** | |
159 * Called when an item should be deleted; subclasses are responsible for | |
160 * implementing. | |
161 * @param {number} index The index of the item that is being deleted. | |
162 */ | |
163 deleteItemAtIndex: function(index) { | |
164 }, | |
165 }; | |
166 | |
167 return { | |
168 DeletableItemList: DeletableItemList, | |
169 DeletableItem: DeletableItem, | |
170 }; | |
171 }); | |
OLD | NEW |