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 * DefaultActionDialog contains a message, a list box, an ok button, and a 10 * cancel button. 11 * This dialog should be used as action picker for file operations. 12 */ 13cr.define('cr.filebrowser', function() { 14 15 /** 16 * Creates dialog in DOM tree. 17 * 18 * @param {HTMLElement} parentNode Node to be parent for this dialog. 19 * @constructor 20 * @extends {FileManagerDialogBase} 21 */ 22 function DefaultActionDialog(parentNode) { 23 FileManagerDialogBase.call(this, parentNode); 24 25 this.frame_.id = 'default-action-dialog'; 26 27 this.list_ = new cr.ui.List(); 28 this.list_.id = 'default-actions-list'; 29 this.frame_.insertBefore(this.list_, this.text_.nextSibling); 30 31 this.selectionModel_ = this.list_.selectionModel = 32 new cr.ui.ListSingleSelectionModel(); 33 this.dataModel_ = this.list_.dataModel = new cr.ui.ArrayDataModel([]); 34 35 // List has max-height defined at css, so that list grows automatically, 36 // but doesn't exceed predefined size. 37 this.list_.autoExpands = true; 38 this.list_.activateItemAtIndex = this.activateItemAtIndex_.bind(this); 39 // Use 'click' instead of 'change' for keyboard users. 40 this.list_.addEventListener('click', this.onSelected_.bind(this)); 41 42 this.initialFocusElement_ = this.list_; 43 44 var self = this; 45 46 // Binding stuff doesn't work with constructors, so we have to create 47 // closure here. 48 this.list_.itemConstructor = function(item) { 49 return self.renderItem(item); 50 }; 51 } 52 53 DefaultActionDialog.prototype = { 54 __proto__: FileManagerDialogBase.prototype 55 }; 56 57 /** 58 * @override 59 */ 60 DefaultActionDialog.prototype.onInputFocus = function() { 61 this.list_.select(); 62 }; 63 64 /** 65 * Renders item for list. 66 * @param {Object} item Item to render. 67 */ 68 DefaultActionDialog.prototype.renderItem = function(item) { 69 var result = this.document_.createElement('li'); 70 71 var div = this.document_.createElement('div'); 72 div.textContent = item.label; 73 74 if (item.iconType) { 75 div.setAttribute('file-type-icon', item.iconType); 76 } else if (item.iconUrl) { 77 div.style.backgroundImage = 'url(' + item.iconUrl + ')'; 78 } 79 80 if (item.class) 81 div.classList.add(item.class); 82 83 result.appendChild(div); 84 85 cr.defineProperty(result, 'lead', cr.PropertyKind.BOOL_ATTR); 86 cr.defineProperty(result, 'selected', cr.PropertyKind.BOOL_ATTR); 87 88 return result; 89 }; 90 91 /** 92 * Shows dialog. 93 * 94 * @param {string} title Title in dialog caption. 95 * @param {string} message Message in dialog caption. 96 * @param {Array.<Object>} items Items to render in the list. 97 * @param {number} defaultIndex Item to select by default. 98 * @param {function(Object)} onSelectedItem Callback which is called when an 99 * item is selected. 100 */ 101 DefaultActionDialog.prototype.show = function(title, message, items, 102 defaultIndex, onSelectedItem) { 103 104 this.onSelectedItemCallback_ = onSelectedItem; 105 106 var show = FileManagerDialogBase.prototype.showTitleAndTextDialog.call( 107 this, title, message); 108 109 if (!show) { 110 console.error('DefaultActionDialog can\'t be shown.'); 111 return; 112 } 113 114 if (!message) { 115 this.text_.setAttribute('hidden', 'hidden'); 116 } else { 117 this.text_.removeAttribute('hidden'); 118 } 119 120 this.list_.startBatchUpdates(); 121 this.dataModel_.splice(0, this.dataModel_.length); 122 for (var i = 0; i < items.length; i++) { 123 this.dataModel_.push(items[i]); 124 } 125 this.selectionModel_.selectedIndex = defaultIndex; 126 this.list_.endBatchUpdates(); 127 }; 128 129 /** 130 * List activation handler. Closes dialog and calls 'ok' callback. 131 * @param {number} index Activated index. 132 */ 133 DefaultActionDialog.prototype.activateItemAtIndex_ = function(index) { 134 this.hide(); 135 this.onSelectedItemCallback_(this.dataModel_.item(index)); 136 }; 137 138 /** 139 * Closes dialog and invokes callback with currently-selected item. 140 */ 141 DefaultActionDialog.prototype.onSelected_ = function() { 142 if (this.selectionModel_.selectedIndex !== -1) 143 this.activateItemAtIndex_(this.selectionModel_.selectedIndex); 144 }; 145 146 /** 147 * @override 148 */ 149 DefaultActionDialog.prototype.onContainerKeyDown_ = function(event) { 150 // Handle Escape. 151 if (event.keyCode == 27) { 152 this.hide(); 153 event.preventDefault(); 154 } else if (event.keyCode == 32 || event.keyCode == 13) { 155 this.onSelected_(); 156 event.preventDefault(); 157 } 158 }; 159 160 return {DefaultActionDialog: DefaultActionDialog}; 161}); 162