blob: 936f9a7f1bed9680325b85ccd4b2c235ebf22164 [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';
/** @suppress {duplicate} */
var remoting = remoting || {};
/** @constructor */
remoting.MessageWindowOptions = function() {
/** @type {string} */
this.title = '';
/** @type {string} */
this.message = '';
/** @type {string} */
this.buttonLabel = '';
/** @type {string} */
this.cancelButtonLabel = '';
/** @type {function(number):void} */
this.onResult = function() {};
/** @type {number} */
this.duration = 0;
/** @type {string} */
this.infobox = '';
/** @type {?function():void} */
this.onTimeout = function() {};
/** @type {string} */
this.htmlFile = '';
/** @type {string} */
this.frame = '';
/** @type {number} */
this.minimumWidth = 0;
};
/**
* Create a new message window.
*
* @param {remoting.MessageWindowOptions} options Message window create options
* @constructor
*/
remoting.MessageWindow = function(options) {
var title = options.title;
var message = options.message;
var okButtonLabel = options.buttonLabel;
var cancelButtonLabel = options.cancelButtonLabel;
var onResult = options.onResult;
var duration = 0;
if (options.duration) {
duration = options.duration;
}
var infobox = '';
if (options.infobox) {
infobox = options.infobox;
}
var onTimeout = options.onTimeout;
/** @type {number} */
this.id_ = remoting.messageWindowManager.addMessageWindow(this);
/** @type {?function(number):void} */
this.onResult_ = onResult;
/** @type {Window} */
this.window_ = null;
/** @type {number} */
this.timer_ = 0;
/** @type {Array<function():void>} */
this.pendingWindowOperations_ = [];
/**
* Callback to call when the timeout expires.
* @type {?function():void}
*/
this.onTimeout_ = onTimeout;
var message_struct = {
command: 'show',
id: this.id_,
title: title,
message: message,
infobox: infobox,
buttonLabel: okButtonLabel,
cancelButtonLabel: cancelButtonLabel,
showSpinner: (duration != 0)
};
var windowAttributes = {
bounds: {
width: options.minimumWidth || 400,
height: 100,
top: undefined,
left: undefined
},
resizable: false,
frame: options.frame || 'chrome'
};
/** @type {remoting.MessageWindow} */
var that = this;
/** @param {chrome.app.window.AppWindow} appWindow */
var onCreate = function(appWindow) {
that.setWindow_(/** @type {Window} */(appWindow.contentWindow));
var onLoad = function() {
appWindow.contentWindow.postMessage(message_struct, '*');
};
appWindow.contentWindow.addEventListener('load', onLoad, false);
};
var htmlFile = options.htmlFile || 'message_window.html';
chrome.app.window.create(
remoting.MessageWindow.htmlFilePrefix + htmlFile,
windowAttributes, onCreate);
if (duration != 0) {
this.timer_ = window.setTimeout(this.onTimeoutHandler_.bind(this),
duration);
}
};
/**
* This string is prepended to the htmlFile when message windows are created.
* Normally, this should be left empty, but the shared module needs to specify
* this so that the shared HTML files can be found when running in the
* context of the app stub.
* @type {string}
*/
remoting.MessageWindow.htmlFilePrefix = "";
/**
* Called when the timer runs out. This in turn calls the window's
* timeout handler (if any).
*/
remoting.MessageWindow.prototype.onTimeoutHandler_ = function() {
this.close();
if (this.onTimeout_) {
this.onTimeout_();
}
};
/**
* Update the message being shown in the window. This should only be called
* after the window has been shown.
*
* @param {string} message The message.
*/
remoting.MessageWindow.prototype.updateMessage = function(message) {
if (!this.window_) {
this.pendingWindowOperations_.push(this.updateMessage.bind(this, message));
return;
}
var message_struct = {
command: 'update_message',
message: message
};
this.window_.postMessage(message_struct, '*');
};
/**
* Close the message box and unregister it with the window manager.
*/
remoting.MessageWindow.prototype.close = function() {
if (!this.window_) {
this.pendingWindowOperations_.push(this.close.bind(this));
return;
}
if (this.timer_) {
window.clearTimeout(this.timer_);
}
this.timer_ = 0;
// Unregister the window with the window manager.
// After this call, events sent to this window will no longer trigger the
// onResult callback.
remoting.messageWindowManager.deleteMessageWindow(this.id_);
this.window_.close();
this.window_ = null;
};
/**
* Dispatch a message box result to the registered callback.
*
* @param {number} result The dialog result.
*/
remoting.MessageWindow.prototype.handleResult = function(result) {
if (this.onResult_) {
this.onResult_(result);
}
}
/**
* Set the window handle and run any pending operations that require it.
*
* @param {Window} window
* @private
*/
remoting.MessageWindow.prototype.setWindow_ = function(window) {
console.assert(this.window_ == null, 'Duplicate call to setWindow_().');
this.window_ = window;
for (var i = 0; i < this.pendingWindowOperations_.length; ++i) {
var pendingOperation = this.pendingWindowOperations_[i];
pendingOperation();
}
this.pendingWindowOperations_ = [];
};
/**
* Static method to create and show a confirm message box.
*
* @param {string} title The title of the message box.
* @param {string} message The message.
* @param {string} okButtonLabel The text for the primary button.
* @param {string} cancelButtonLabel The text for the secondary button.
* @param {function(number):void} onResult The callback to invoke when the
* user closes the message window.
* @return {remoting.MessageWindow}
*/
remoting.MessageWindow.showConfirmWindow = function(
title, message, okButtonLabel, cancelButtonLabel, onResult) {
var options = /** @type {remoting.MessageWindowOptions} */ ({
title: title,
message: message,
buttonLabel: okButtonLabel,
cancelButtonLabel: cancelButtonLabel,
onResult: onResult
});
return new remoting.MessageWindow(options);
};
/**
* Static method to create and show a simple message box.
*
* @param {string} title The title of the message box.
* @param {string} message The message.
* @param {string} buttonLabel The text for the primary button.
* @param {function(number):void} onResult The callback to invoke when the
* user closes the message window.
* @return {remoting.MessageWindow}
*/
remoting.MessageWindow.showMessageWindow = function(
title, message, buttonLabel, onResult) {
var options = /** @type {remoting.MessageWindowOptions} */ ({
title: title,
message: message,
buttonLabel: buttonLabel,
onResult: onResult
});
return new remoting.MessageWindow(options);
};
/**
* Static method to create and show an error message box with an "OK" button.
* The app will close when the user dismisses the message window.
*
* @param {string} title The title of the message box.
* @param {string} message The message.
* @return {remoting.MessageWindow}
*/
remoting.MessageWindow.showErrorMessage = function(title, message) {
var options = /** @type {remoting.MessageWindowOptions} */ ({
title: title,
message: message,
buttonLabel: chrome.i18n.getMessage(/*i18n-content*/'OK'),
onResult: remoting.MessageWindow.quitApp
});
return new remoting.MessageWindow(options);
};
/**
* Cancel the current connection and close all app windows.
*
* @param {number} result The dialog result.
*/
remoting.MessageWindow.quitApp = function(result) {
remoting.messageWindowManager.closeAllMessageWindows();
window.close();
};