blob: a57684a662b3ea3460a9a0d67c73d5cf03843d27 [file] [log] [blame]
// Copyright 2014 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';
/**
* @constructor
*/
function MessageWindowImpl() {
/**
* Used to prevent multiple responses due to the closeWindow handler.
*
* @type {boolean}
* @private
*/
this.sentReply_ = false;
window.addEventListener('message', this.onMessage_.bind(this), false);
};
/**
* @param {Window} parentWindow The id of the window that showed the message.
* @param {string} messageId The identifier of the message, as supplied by the
* parent.
* @param {number} result 0 if window was closed without pressing a button;
* otherwise the index of the button pressed (e.g., 1 = primary).
* @private
*/
MessageWindowImpl.prototype.sendReply_ = function(
parentWindow, messageId, result) {
// Only forward the first reply that we receive.
if (!this.sentReply_) {
var message = {
command: 'messageWindowResult',
id: messageId,
result: result
};
parentWindow.postMessage(message, '*');
this.sentReply_ = true;
} else {
// Make sure that the reply we're ignoring is from the window close.
base.debug.assert(result == 0);
}
};
/**
* Size the window to its content vertically.
* @private
*/
MessageWindowImpl.prototype.updateSize_ = function() {
var borderY = window.outerHeight - window.innerHeight;
window.resizeTo(window.outerWidth, document.body.clientHeight + borderY);
};
/**
* Initializes the button with the label and the click handler.
* Hides the button if the label is null or undefined.
*
* @param{HTMLElement} button
* @param{?string} label
* @param{Function} clickHandler
* @private
*/
MessageWindowImpl.prototype.initButton_ =
function(button, label, clickHandler) {
if (label) {
button.innerText = label;
button.addEventListener('click', clickHandler, false);
}
button.hidden = !Boolean(label);
};
/**
* Event-handler callback, invoked when the parent window supplies the
* message content.
*
* @param{Event} event
* @private
*/
MessageWindowImpl.prototype.onMessage_ = function(event) {
switch (event.data['command']) {
case 'show':
// Validate the message.
var messageId = /** @type {number} */ (event.data['id']);
var title = /** @type {string} */ (event.data['title']);
var message = /** @type {string} */ (event.data['message']);
var infobox = /** @type {string} */ (event.data['infobox']);
var buttonLabel = /** @type {string} */ (event.data['buttonLabel']);
/** @type {string} */
var cancelButtonLabel = (event.data['cancelButtonLabel']);
var showSpinner = /** @type {boolean} */ (event.data['showSpinner']);
if (typeof(messageId) != 'number' ||
typeof(title) != 'string' ||
typeof(message) != 'string' ||
typeof(infobox) != 'string' ||
typeof(buttonLabel) != 'string' ||
typeof(showSpinner) != 'boolean') {
console.log('Bad show message:', event.data);
break;
}
// Set the dialog text.
var button = document.getElementById('button-primary');
var cancelButton = document.getElementById('button-secondary');
var messageDiv = document.getElementById('message');
var infoboxDiv = document.getElementById('infobox');
document.getElementById('title').innerText = title;
document.querySelector('title').innerText = title;
messageDiv.innerHTML = message;
if (showSpinner) {
messageDiv.classList.add('waiting');
messageDiv.classList.add('prominent');
}
if (infobox != '') {
infoboxDiv.innerText = infobox;
} else {
infoboxDiv.hidden = true;
}
this.initButton_(
button,
buttonLabel,
this.sendReply_.bind(this, event.source, messageId, 1));
this.initButton_(
cancelButton,
cancelButtonLabel,
this.sendReply_.bind(this, event.source, messageId, 0));
var buttonToFocus = (cancelButtonLabel) ? cancelButton : button;
buttonToFocus.focus();
// Add a close handler in case the window is closed without clicking one
// of the buttons. This will send a 0 as the result.
// Note that when a button is pressed, this will result in sendReply_
// being called multiple times (once for the button, once for close).
chrome.app.window.current().onClosed.addListener(
this.sendReply_.bind(this, event.source, messageId, 0));
this.updateSize_();
chrome.app.window.current().show();
break;
case 'update_message':
var message = /** @type {string} */ (event.data['message']);
if (typeof(message) != 'string') {
console.log('Bad update_message message:', event.data);
break;
}
var messageDiv = document.getElementById('message');
messageDiv.innerText = message;
this.updateSize_();
break;
default:
console.error('Unexpected message:', event.data);
}
};
var messageWindow = new MessageWindowImpl();