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
40    this.initialFocusElement_ = this.list_;
41
42    var self = this;
43
44    // Binding stuff doesn't work with constructors, so we have to create
45    // closure here.
46    this.list_.itemConstructor = function(item) {
47      return self.renderItem(item);
48    };
49  }
50
51  DefaultActionDialog.prototype = {
52    __proto__: FileManagerDialogBase.prototype
53  };
54
55  /**
56   * @override
57   */
58  DefaultActionDialog.prototype.onInputFocus = function() {
59    this.list_.select();
60  };
61
62  /**
63   * Renders item for list.
64   * @param {Object} item Item to render.
65   */
66  DefaultActionDialog.prototype.renderItem = function(item) {
67    var result = this.document_.createElement('li');
68
69    var div = this.document_.createElement('div');
70    div.textContent = item.label;
71
72    if (item.iconType) {
73      div.setAttribute('file-type-icon', item.iconType);
74    } else if (item.iconUrl) {
75      div.style.backgroundImage = 'url(' + item.iconUrl + ')';
76    }
77
78    if (item.class)
79      div.classList.add(item.class);
80
81    result.appendChild(div);
82
83    cr.defineProperty(result, 'lead', cr.PropertyKind.BOOL_ATTR);
84    cr.defineProperty(result, 'selected', cr.PropertyKind.BOOL_ATTR);
85
86    return result;
87  };
88
89  /**
90   * Shows dialog.
91   *
92   * @param {string} title Title in dialog caption.
93   * @param {string} message Message in dialog caption.
94   * @param {Array.<Object>} items Items to render in the list.
95   * @param {number} defaultIndex Item to select by default.
96   * @param {function(Object=)} opt_onOk OK callback with the selected item.
97   * @param {function()=} opt_onCancel Cancel callback.
98   */
99  DefaultActionDialog.prototype.show = function(title, message, items,
100      defaultIndex, opt_onOk, opt_onCancel) {
101
102    var show = FileManagerDialogBase.prototype.showOkCancelDialog.call(
103        this, title, message, opt_onOk, opt_onCancel);
104
105    if (!show) {
106      console.error('DefaultActionDialog can\'t be shown.');
107      return;
108    }
109
110    if (!message) {
111      this.text_.setAttribute('hidden', 'hidden');
112    } else {
113      this.text_.removeAttribute('hidden');
114    }
115
116    this.list_.startBatchUpdates();
117    this.dataModel_.splice(0, this.dataModel_.length);
118    for (var i = 0; i < items.length; i++) {
119      this.dataModel_.push(items[i]);
120    }
121    this.selectionModel_.selectedIndex = defaultIndex;
122    this.list_.endBatchUpdates();
123  };
124
125  /**
126   * List activation handler. Closes dialog and calls 'ok' callback.
127   * @param {number} index Activated index.
128   */
129  DefaultActionDialog.prototype.activateItemAtIndex_ = function(index) {
130    this.hide();
131    this.onOk_(this.dataModel_.item(index));
132  };
133
134  /**
135   * Closes dialog and invokes callback with currently-selected item.
136   * @override
137   */
138  DefaultActionDialog.prototype.onOkClick_ = function() {
139    this.activateItemAtIndex_(this.selectionModel_.selectedIndex);
140  };
141
142  /**
143   * @override
144   */
145  DefaultActionDialog.prototype.onContainerKeyDown_ = function(event) {
146    // Handle Escape.
147    if (event.keyCode == 27) {
148      this.onCancelClick_(event);
149      event.preventDefault();
150    } else if (event.keyCode == 32 || event.keyCode == 13) {
151      this.onOkClick_();
152      event.preventDefault();
153    }
154  };
155
156  return {DefaultActionDialog: DefaultActionDialog};
157});
158