blob: 402fd6e18773a29a8818324c387174cf270fac7c [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
/**
* SelectAlbumDialog contains a message, a list box, an ok button, and a
* cancel button.
* Operates on a list of objects representing albums: { name, url, create }.
* If user chooses to create a new album, result will be a fake album with
* |create == true|.
*
* @param {HTMLElement} parentNode Node to be parent for this dialog.
* @constructor
*/
function SelectAlbumDialog(parentNode) {
this.parentNode_ = parentNode;
this.document_ = parentNode.ownerDocument;
this.container_ = this.document_.createElement('div');
this.container_.className = 'select-album-dialog-container';
this.container_.addEventListener('keydown',
this.onContainerKeyDown_.bind(this));
this.shield_ = this.document_.createElement('div');
this.shield_.className = 'select-album-dialog-shield';
this.container_.appendChild(this.shield_);
this.frame_ = this.document_.createElement('div');
this.frame_.className = 'select-album-dialog-frame';
this.container_.appendChild(this.frame_);
this.caption_ = this.document_.createElement('div');
this.caption_.className = 'select-album-dialog-caption';
this.frame_.appendChild(this.caption_);
this.list_ = new cr.ui.List();
this.list_.classList.add('select-album-list');
this.frame_.appendChild(this.list_);
this.dataModel_ = this.list_.dataModel = new cr.ui.ArrayDataModel([]);
this.selectionModel_ = this.list_.selectionModel =
new cr.ui.ListSingleSelectionModel();
this.selectionModel_.addEventListener('change',
this.onSelectionChanged_.bind(this));
// TODO(dgozman): add shades at top and bottom of the list.
// List has max-height defined at css, so that list grows automatically,
// but doesn't exceed predefined size.
this.list_.autoExpands = true;
this.list_.activateItemAtIndex = this.activateItemAtIndex_.bind(this);
// Binding stuff doesn't work with constructors, so we have to create
// closure here.
var self = this;
this.list_.itemConstructor = function(item) {
return self.renderItem(item);
};
var buttons = this.document_.createElement('div');
buttons.className = 'select-album-dialog-buttons';
this.frame_.appendChild(buttons);
this.okButton_ = this.document_.createElement('button');
this.okButton_.className = 'no-icon';
this.okButton_.addEventListener('click', this.onOkClick_.bind(this));
buttons.appendChild(this.okButton_);
this.cancelButton_ = this.document_.createElement('button');
this.cancelButton_.className = 'no-icon';
this.cancelButton_.textContent =
loadTimeData.getString('PHOTO_IMPORT_CANCEL_BUTTON');
this.cancelButton_.addEventListener('click', this.onCancelClick_.bind(this));
buttons.appendChild(this.cancelButton_);
this.nameEdit_ = this.document_.createElement('input');
this.nameEdit_.setAttribute('type', 'text');
this.nameEdit_.className = 'name';
this.nameEdit_.addEventListener('input',
this.updateOkButtonEnabled_.bind(this));
}
SelectAlbumDialog.prototype = {
__proto__: cr.ui.dialogs.BaseDialog.prototype
};
/**
* Renders item for list.
* @param {Object} item Item to render.
* @return {HTMLLIElement} Rendered item.
*/
SelectAlbumDialog.prototype.renderItem = function(item) {
var result = this.document_.createElement('li');
var frame = this.document_.createElement('div');
frame.className = 'img-frame';
result.appendChild(frame);
var box = this.document_.createElement('div');
box.className = 'img-container';
frame.appendChild(box);
if (item.create) {
result.appendChild(this.nameEdit_);
this.nameEdit_.value = item.name;
} else {
var name = this.document_.createElement('div');
name.className = 'name';
name.textContent = item.name;
result.appendChild(name);
}
cr.defineProperty(result, 'lead', cr.PropertyKind.BOOL_ATTR);
cr.defineProperty(result, 'selected', cr.PropertyKind.BOOL_ATTR);
new ThumbnailLoader(item.url).load(box, ThumbnailLoader.FillMode.FILL);
return result;
};
/**
* Shows dialog.
*
* @param {string} message Message in dialog caption.
* @param {Array} items Albums to render in list.
* @param {string} defaultNewName Default name of the new album.
* @param {string} okCaption Text on the ok button.
* @param {function} onOk Callback function.
*/
SelectAlbumDialog.prototype.show = function(
message, items, defaultNewName, okCaption, onOk) {
this.onOk_ = onOk;
this.okButton_.textContent = okCaption;
this.caption_.textContent = message;
// Fake item to create new album.
var newAlbum = {
create: true,
name: defaultNewName,
url: chrome.extension.getURL('../../images/photo/new_album.png')
};
this.list_.startBatchUpdates();
this.dataModel_.splice(0, this.dataModel_.length);
this.dataModel_.push(newAlbum);
for (var i = 0; i < items.length; i++) {
this.dataModel_.push(items[i]);
}
this.selectionModel_.selectedIndex = 0;
this.list_.endBatchUpdates();
this.parentNode_.appendChild(this.container_);
};
/**
* Hides dialog.
*/
SelectAlbumDialog.prototype.hide = function() {
this.parentNode_.removeChild(this.container_);
};
/**
* List activation handler. Closes dialog and calls 'ok' callback.
*
* @param {number} index Activated index.
* @private
*/
SelectAlbumDialog.prototype.activateItemAtIndex_ = function(index) {
if (this.okButton_.disabled) return;
this.hide();
var album = this.dataModel_.item(index);
if (index == 0)
album.name = this.nameEdit_.value;
this.onOk_(album);
};
/**
* Closes dialog and invokes callback with currently-selected item.
* @private
*/
SelectAlbumDialog.prototype.onOkClick_ = function() {
this.activateItemAtIndex_(this.selectionModel_.selectedIndex);
};
/**
* Closes dialog.
* @private
*/
SelectAlbumDialog.prototype.onCancelClick_ = function() {
this.hide();
};
/**
* Event handler for keydown event.
* @param {Event} event The event.
* @private
*/
SelectAlbumDialog.prototype.onContainerKeyDown_ = function(event) {
// Handle Escape.
if (event.keyCode == 27) {
this.onCancelClick_(event);
event.preventDefault();
} else if (event.keyCode == 13) {
this.onOkClick_();
event.preventDefault();
}
};
/**
* Event handler for selection change.
* @param {Event} event The event.
* @private
*/
SelectAlbumDialog.prototype.onSelectionChanged_ = function(event) {
if (this.selectionModel_.selectedIndex == 0) {
setTimeout(this.nameEdit_.focus.bind(this.nameEdit_), 0);
} else {
this.nameEdit_.blur();
this.list_.focus();
}
this.updateOkButtonEnabled_();
};
/**
* Updates ok button.
* @private
*/
SelectAlbumDialog.prototype.updateOkButtonEnabled_ = function() {
this.okButton_.disabled = this.selectionModel_.selectedIndex == 0 &&
this.nameEdit_.value == '';
};