| // 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(); |
| }; |