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 'use strict'; | |
6 | |
7 | |
8 /** | |
9 * SelectAlbumDialog contains a message, a list box, an ok button, and a | |
10 * cancel button. | |
11 * Operates on a list of objects representing albums: { name, url, create }. | |
12 * If user chooses to create a new album, result will be a fake album with | |
13 * |create == true|. | |
14 * | |
15 * @param {HTMLElement} parentNode Node to be parent for this dialog. | |
16 * @constructor | |
17 */ | |
18 function SelectAlbumDialog(parentNode) { | |
19 this.parentNode_ = parentNode; | |
20 this.document_ = parentNode.ownerDocument; | |
21 | |
22 this.container_ = this.document_.createElement('div'); | |
23 this.container_.className = 'select-album-dialog-container'; | |
24 this.container_.addEventListener('keydown', | |
25 this.onContainerKeyDown_.bind(this)); | |
26 | |
27 this.shield_ = this.document_.createElement('div'); | |
28 this.shield_.className = 'select-album-dialog-shield'; | |
29 this.container_.appendChild(this.shield_); | |
30 | |
31 this.frame_ = this.document_.createElement('div'); | |
32 this.frame_.className = 'select-album-dialog-frame'; | |
33 this.container_.appendChild(this.frame_); | |
34 | |
35 this.caption_ = this.document_.createElement('div'); | |
36 this.caption_.className = 'select-album-dialog-caption'; | |
37 this.frame_.appendChild(this.caption_); | |
38 | |
39 this.list_ = new cr.ui.List(); | |
40 this.list_.classList.add('select-album-list'); | |
41 this.frame_.appendChild(this.list_); | |
42 | |
43 this.dataModel_ = this.list_.dataModel = new cr.ui.ArrayDataModel([]); | |
44 this.selectionModel_ = this.list_.selectionModel = | |
45 new cr.ui.ListSingleSelectionModel(); | |
46 this.selectionModel_.addEventListener('change', | |
47 this.onSelectionChanged_.bind(this)); | |
48 | |
49 // TODO(dgozman): add shades at top and bottom of the list. | |
50 // List has max-height defined at css, so that list grows automatically, | |
51 // but doesn't exceed predefined size. | |
52 this.list_.autoExpands = true; | |
53 this.list_.activateItemAtIndex = this.activateItemAtIndex_.bind(this); | |
54 // Binding stuff doesn't work with constructors, so we have to create | |
55 // closure here. | |
56 var self = this; | |
57 this.list_.itemConstructor = function(item) { | |
58 return self.renderItem(item); | |
59 }; | |
60 | |
61 var buttons = this.document_.createElement('div'); | |
62 buttons.className = 'select-album-dialog-buttons'; | |
63 this.frame_.appendChild(buttons); | |
64 | |
65 this.okButton_ = this.document_.createElement('button'); | |
66 this.okButton_.className = 'no-icon'; | |
67 this.okButton_.addEventListener('click', this.onOkClick_.bind(this)); | |
68 buttons.appendChild(this.okButton_); | |
69 | |
70 this.cancelButton_ = this.document_.createElement('button'); | |
71 this.cancelButton_.className = 'no-icon'; | |
72 this.cancelButton_.textContent = | |
73 loadTimeData.getString('PHOTO_IMPORT_CANCEL_BUTTON'); | |
74 this.cancelButton_.addEventListener('click', this.onCancelClick_.bind(this)); | |
75 buttons.appendChild(this.cancelButton_); | |
76 | |
77 this.nameEdit_ = this.document_.createElement('input'); | |
78 this.nameEdit_.setAttribute('type', 'text'); | |
79 this.nameEdit_.className = 'name'; | |
80 this.nameEdit_.addEventListener('input', | |
81 this.updateOkButtonEnabled_.bind(this)); | |
82 } | |
83 | |
84 SelectAlbumDialog.prototype = { | |
85 __proto__: cr.ui.dialogs.BaseDialog.prototype | |
86 }; | |
87 | |
88 /** | |
89 * Renders item for list. | |
90 * @param {Object} item Item to render. | |
91 * @return {HTMLLIElement} Rendered item. | |
92 */ | |
93 SelectAlbumDialog.prototype.renderItem = function(item) { | |
94 var result = this.document_.createElement('li'); | |
95 | |
96 var frame = this.document_.createElement('div'); | |
97 frame.className = 'img-frame'; | |
98 result.appendChild(frame); | |
99 | |
100 var box = this.document_.createElement('div'); | |
101 box.className = 'img-container'; | |
102 frame.appendChild(box); | |
103 | |
104 if (item.create) { | |
105 result.appendChild(this.nameEdit_); | |
106 this.nameEdit_.value = item.name; | |
107 } else { | |
108 var name = this.document_.createElement('div'); | |
109 name.className = 'name'; | |
110 name.textContent = item.name; | |
111 result.appendChild(name); | |
112 } | |
113 | |
114 cr.defineProperty(result, 'lead', cr.PropertyKind.BOOL_ATTR); | |
115 cr.defineProperty(result, 'selected', cr.PropertyKind.BOOL_ATTR); | |
116 | |
117 new ThumbnailLoader(item.url).load(box, ThumbnailLoader.FillMode.FILL); | |
118 | |
119 return result; | |
120 }; | |
121 | |
122 /** | |
123 * Shows dialog. | |
124 * | |
125 * @param {string} message Message in dialog caption. | |
126 * @param {Array} items Albums to render in list. | |
127 * @param {string} defaultNewName Default name of the new album. | |
128 * @param {string} okCaption Text on the ok button. | |
129 * @param {function} onOk Callback function. | |
130 */ | |
131 SelectAlbumDialog.prototype.show = function( | |
132 message, items, defaultNewName, okCaption, onOk) { | |
133 | |
134 this.onOk_ = onOk; | |
135 this.okButton_.textContent = okCaption; | |
136 this.caption_.textContent = message; | |
137 | |
138 // Fake item to create new album. | |
139 var newAlbum = { | |
140 create: true, | |
141 name: defaultNewName, | |
142 url: chrome.extension.getURL('../../images/photo/new_album.png') | |
143 }; | |
144 | |
145 this.list_.startBatchUpdates(); | |
146 this.dataModel_.splice(0, this.dataModel_.length); | |
147 this.dataModel_.push(newAlbum); | |
148 for (var i = 0; i < items.length; i++) { | |
149 this.dataModel_.push(items[i]); | |
150 } | |
151 this.selectionModel_.selectedIndex = 0; | |
152 this.list_.endBatchUpdates(); | |
153 | |
154 this.parentNode_.appendChild(this.container_); | |
155 }; | |
156 | |
157 /** | |
158 * Hides dialog. | |
159 */ | |
160 SelectAlbumDialog.prototype.hide = function() { | |
161 this.parentNode_.removeChild(this.container_); | |
162 }; | |
163 | |
164 /** | |
165 * List activation handler. Closes dialog and calls 'ok' callback. | |
166 * | |
167 * @param {number} index Activated index. | |
168 * @private | |
169 */ | |
170 SelectAlbumDialog.prototype.activateItemAtIndex_ = function(index) { | |
171 if (this.okButton_.disabled) return; | |
172 this.hide(); | |
173 var album = this.dataModel_.item(index); | |
174 if (index == 0) | |
175 album.name = this.nameEdit_.value; | |
176 this.onOk_(album); | |
177 }; | |
178 | |
179 /** | |
180 * Closes dialog and invokes callback with currently-selected item. | |
181 * @private | |
182 */ | |
183 SelectAlbumDialog.prototype.onOkClick_ = function() { | |
184 this.activateItemAtIndex_(this.selectionModel_.selectedIndex); | |
185 }; | |
186 | |
187 /** | |
188 * Closes dialog. | |
189 * @private | |
190 */ | |
191 SelectAlbumDialog.prototype.onCancelClick_ = function() { | |
192 this.hide(); | |
193 }; | |
194 | |
195 /** | |
196 * Event handler for keydown event. | |
197 * @param {Event} event The event. | |
198 * @private | |
199 */ | |
200 SelectAlbumDialog.prototype.onContainerKeyDown_ = function(event) { | |
201 // Handle Escape. | |
202 if (event.keyCode == 27) { | |
203 this.onCancelClick_(event); | |
204 event.preventDefault(); | |
205 } else if (event.keyCode == 13) { | |
206 this.onOkClick_(); | |
207 event.preventDefault(); | |
208 } | |
209 }; | |
210 | |
211 /** | |
212 * Event handler for selection change. | |
213 * @param {Event} event The event. | |
214 * @private | |
215 */ | |
216 SelectAlbumDialog.prototype.onSelectionChanged_ = function(event) { | |
217 if (this.selectionModel_.selectedIndex == 0) { | |
218 setTimeout(this.nameEdit_.focus.bind(this.nameEdit_), 0); | |
219 } else { | |
220 this.nameEdit_.blur(); | |
221 this.list_.focus(); | |
222 } | |
223 this.updateOkButtonEnabled_(); | |
224 }; | |
225 | |
226 /** | |
227 * Updates ok button. | |
228 * @private | |
229 */ | |
230 SelectAlbumDialog.prototype.updateOkButtonEnabled_ = function() { | |
231 this.okButton_.disabled = this.selectionModel_.selectedIndex == 0 && | |
232 this.nameEdit_.value == ''; | |
233 }; | |
OLD | NEW |