1 // Copyright 2014 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 /** @suppress {duplicate} */ 8 var remoting = remoting || {}; 9 10 /** 11 * Create a new message window. 12 * 13 * @param {Object} options Message window create options 14 * @constructor 15 */ 16 remoting.MessageWindow = function(options) { 17 var title = /** @type {string} */ (options.title); 18 var message = /** @type {string} */ (options.message); 19 var okButtonLabel = /** @type {string} */ (options.buttonLabel); 20 var cancelButtonLabel = /** @type {string} */ (options.cancelButtonLabel); 21 var onResult = /** @type {function(number):void} */(options.onResult); 22 /** @type {number} */ 23 var duration = 0; 24 if (/** @type {number?} */(options.duration)) { 25 duration = /** @type {number} */(options.duration); 26 } 27 /** @type {string} */ 28 var infobox = ''; 29 if (/** @type {string?} */(options.infobox)) { 30 infobox = /** @type {string} */(options.infobox); 31 } 32 var onTimeout = /** @type {?function():void} */ (options.onTimeout); 33 34 /** @type {number} */ 35 this.id_ = remoting.MessageWindowManager.addMessageWindow(this); 36 37 /** @type {?function(number):void} */ 38 this.onResult_ = onResult; 39 40 /** @type {Window} */ 41 this.window_ = null; 42 43 /** @type {number} */ 44 this.timer_ = 0; 45 46 /** @type {Array.<function():void>} */ 47 this.pendingWindowOperations_ = []; 48 49 /** 50 * Callback to call when the timeout expires. 51 * @type {?function():void} 52 */ 53 this.onTimeout_ = onTimeout; 54 55 var message_struct = { 56 command: 'show', 57 id: this.id_, 58 title: title, 59 message: message, 60 infobox: infobox, 61 buttonLabel: okButtonLabel, 62 cancelButtonLabel: cancelButtonLabel, 63 showSpinner: (duration != 0) 64 }; 65 66 var windowAttributes = { 67 bounds: { 68 width: 400, 69 height: 100 70 }, 71 resizable: false 72 }; 73 74 /** @type {remoting.MessageWindow} */ 75 var that = this; 76 77 /** @param {AppWindow} appWindow */ 78 var onCreate = function(appWindow) { 79 that.setWindow_(/** @type {Window} */(appWindow.contentWindow)); 80 var onLoad = function() { 81 appWindow.contentWindow.postMessage(message_struct, '*'); 82 }; 83 appWindow.contentWindow.addEventListener('load', onLoad, false); 84 }; 85 86 chrome.app.window.create('message_window.html', windowAttributes, onCreate); 87 88 if (duration != 0) { 89 this.timer_ = window.setTimeout(this.onTimeoutHandler_.bind(this), 90 duration); 91 } 92 }; 93 94 /** 95 * Called when the timer runs out. This in turn calls the window's 96 * timeout handler (if any). 97 */ 98 remoting.MessageWindow.prototype.onTimeoutHandler_ = function() { 99 this.close(); 100 if (this.onTimeout_) { 101 this.onTimeout_(); 102 } 103 }; 104 105 /** 106 * Update the message being shown in the window. This should only be called 107 * after the window has been shown. 108 * 109 * @param {string} message The message. 110 */ 111 remoting.MessageWindow.prototype.updateMessage = function(message) { 112 if (!this.window_) { 113 this.pendingWindowOperations_.push(this.updateMessage.bind(this, message)); 114 return; 115 } 116 117 var message_struct = { 118 command: 'update_message', 119 message: message 120 }; 121 this.window_.postMessage(message_struct, '*'); 122 }; 123 124 /** 125 * Close the message box and unregister it with the window manager. 126 */ 127 remoting.MessageWindow.prototype.close = function() { 128 if (!this.window_) { 129 this.pendingWindowOperations_.push(this.close.bind(this)); 130 return; 131 } 132 133 if (this.timer_) { 134 window.clearTimeout(this.timer_); 135 } 136 this.timer_ = 0; 137 138 // Unregister the window with the window manager. 139 // After this call, events sent to this window will no longer trigger the 140 // onResult callback. 141 remoting.MessageWindowManager.deleteMessageWindow(this.id_); 142 this.window_.close(); 143 this.window_ = null; 144 }; 145 146 /** 147 * Dispatch a message box result to the registered callback. 148 * 149 * @param {number} result The dialog result. 150 */ 151 remoting.MessageWindow.prototype.handleResult = function(result) { 152 if (this.onResult_) { 153 this.onResult_(result); 154 } 155 } 156 157 /** 158 * Set the window handle and run any pending operations that require it. 159 * 160 * @param {Window} window 161 * @private 162 */ 163 remoting.MessageWindow.prototype.setWindow_ = function(window) { 164 base.debug.assert(this.window_ == null); 165 this.window_ = window; 166 for (var i = 0; i < this.pendingWindowOperations_.length; ++i) { 167 var pendingOperation = this.pendingWindowOperations_[i]; 168 pendingOperation(); 169 } 170 this.pendingWindowOperations_ = []; 171 }; 172 173 /** 174 * Static method to create and show a confirm message box. 175 * 176 * @param {string} title The title of the message box. 177 * @param {string} message The message. 178 * @param {string} okButtonLabel The text for the primary button. 179 * @param {string} cancelButtonLabel The text for the secondary button. 180 * @param {function(number):void} onResult The callback to invoke when the 181 * user closes the message window. 182 * @return {remoting.MessageWindow} 183 */ 184 remoting.MessageWindow.showConfirmWindow = function( 185 title, message, okButtonLabel, cancelButtonLabel, onResult) { 186 var options = { 187 title: title, 188 message: message, 189 buttonLabel: okButtonLabel, 190 cancelButtonLabel: cancelButtonLabel, 191 onResult: onResult 192 }; 193 return new remoting.MessageWindow(options); 194 }; 195 196 /** 197 * Static method to create and show a simple message box. 198 * 199 * @param {string} title The title of the message box. 200 * @param {string} message The message. 201 * @param {string} buttonLabel The text for the primary button. 202 * @param {function(number):void} onResult The callback to invoke when the 203 * user closes the message window. 204 * @return {remoting.MessageWindow} 205 */ 206 remoting.MessageWindow.showMessageWindow = function( 207 title, message, buttonLabel, onResult) { 208 var options = { 209 title: title, 210 message: message, 211 buttonLabel: buttonLabel, 212 onResult: onResult 213 }; 214 return new remoting.MessageWindow(options); 215 }; 216 217 /** 218 * Static method to create and show an error message box with an "OK" button. 219 * The app will close when the user dismisses the message window. 220 * 221 * @param {string} title The title of the message box. 222 * @param {string} message The message. 223 * @return {remoting.MessageWindow} 224 */ 225 remoting.MessageWindow.showErrorMessage = function(title, message) { 226 var options = { 227 title: title, 228 message: message, 229 buttonLabel: chrome.i18n.getMessage(/**i18n-content*/'OK'), 230 onResult: remoting.MessageWindow.quitApp 231 }; 232 return new remoting.MessageWindow(options); 233 }; 234 235 /** 236 * Static method to create and show a timed message box. 237 * 238 * @param {string} title The title of the message box. 239 * @param {string} message The message. 240 * @param {string} infobox Additional information to be displayed in an infobox, 241 * or the empty string if there is no additional information. 242 * @param {string} buttonLabel The text for the primary button. 243 * @param {function(number):void} onResult The callback to invoke when the 244 * user closes the message window. 245 * @param {number} duration Time for wait before calling onTime 246 * @param {?function():void} onTimeout Callback function. 247 * @return {remoting.MessageWindow} 248 */ 249 remoting.MessageWindow.showTimedMessageWindow = function( 250 title, message, infobox, buttonLabel, onResult, duration, onTimeout) { 251 var options = { 252 title: title, 253 message: message, 254 infobox: infobox, 255 buttonLabel: buttonLabel, 256 onResult: onResult, 257 duration: duration, 258 onTimeout: onTimeout 259 }; 260 return new remoting.MessageWindow(options); 261 }; 262 263 /** 264 * Cancel the current connection and close all app windows. 265 * 266 * @param {number} result The dialog result. 267 */ 268 remoting.MessageWindow.quitApp = function(result) { 269 remoting.MessageWindowManager.closeAllMessageWindows(); 270 window.close(); 271 }; 272