| 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 |