OLD | NEW |
(Empty) | |
| 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 /** |
| 8 * @constructor |
| 9 */ |
| 10 function MessageWindowImpl() { |
| 11 /** |
| 12 * Used to prevent multiple responses due to the closeWindow handler. |
| 13 * |
| 14 * @type {boolean} |
| 15 * @private |
| 16 */ |
| 17 this.sentReply_ = false; |
| 18 |
| 19 window.addEventListener('message', this.onMessage_.bind(this), false); |
| 20 }; |
| 21 |
| 22 /** |
| 23 * @param {Window} parentWindow The id of the window that showed the message. |
| 24 * @param {string} messageId The identifier of the message, as supplied by the |
| 25 * parent. |
| 26 * @param {number} result 0 if window was closed without pressing a button; |
| 27 * otherwise the index of the button pressed (e.g., 1 = primary). |
| 28 * @private |
| 29 */ |
| 30 MessageWindowImpl.prototype.sendReply_ = function( |
| 31 parentWindow, messageId, result) { |
| 32 // Only forward the first reply that we receive. |
| 33 if (!this.sentReply_) { |
| 34 var message = { |
| 35 command: 'messageWindowResult', |
| 36 id: messageId, |
| 37 result: result |
| 38 }; |
| 39 parentWindow.postMessage(message, '*'); |
| 40 this.sentReply_ = true; |
| 41 } else { |
| 42 // Make sure that the reply we're ignoring is from the window close. |
| 43 base.debug.assert(result == 0); |
| 44 } |
| 45 }; |
| 46 |
| 47 /** |
| 48 * Size the window to its content vertically. |
| 49 * @private |
| 50 */ |
| 51 MessageWindowImpl.prototype.updateSize_ = function() { |
| 52 var borderY = window.outerHeight - window.innerHeight; |
| 53 window.resizeTo(window.outerWidth, document.body.clientHeight + borderY); |
| 54 }; |
| 55 |
| 56 /** |
| 57 * Initializes the button with the label and the click handler. |
| 58 * Hides the button if the label is null or undefined. |
| 59 * |
| 60 * @param{HTMLElement} button |
| 61 * @param{?string} label |
| 62 * @param{Function} clickHandler |
| 63 * @private |
| 64 */ |
| 65 MessageWindowImpl.prototype.initButton_ = |
| 66 function(button, label, clickHandler) { |
| 67 if (label) { |
| 68 button.innerText = label; |
| 69 button.addEventListener('click', clickHandler, false); |
| 70 } |
| 71 button.hidden = !Boolean(label); |
| 72 }; |
| 73 |
| 74 /** |
| 75 * Event-handler callback, invoked when the parent window supplies the |
| 76 * message content. |
| 77 * |
| 78 * @param{Event} event |
| 79 * @private |
| 80 */ |
| 81 MessageWindowImpl.prototype.onMessage_ = function(event) { |
| 82 switch (event.data['command']) { |
| 83 case 'show': |
| 84 // Validate the message. |
| 85 var messageId = /** @type {number} */ (event.data['id']); |
| 86 var title = /** @type {string} */ (event.data['title']); |
| 87 var message = /** @type {string} */ (event.data['message']); |
| 88 var infobox = /** @type {string} */ (event.data['infobox']); |
| 89 var buttonLabel = /** @type {string} */ (event.data['buttonLabel']); |
| 90 /** @type {string} */ |
| 91 var cancelButtonLabel = (event.data['cancelButtonLabel']); |
| 92 var showSpinner = /** @type {boolean} */ (event.data['showSpinner']); |
| 93 if (typeof(messageId) != 'number' || |
| 94 typeof(title) != 'string' || |
| 95 typeof(message) != 'string' || |
| 96 typeof(infobox) != 'string' || |
| 97 typeof(buttonLabel) != 'string' || |
| 98 typeof(showSpinner) != 'boolean') { |
| 99 console.log('Bad show message:', event.data); |
| 100 break; |
| 101 } |
| 102 |
| 103 // Set the dialog text. |
| 104 var button = document.getElementById('button-primary'); |
| 105 var cancelButton = document.getElementById('button-secondary'); |
| 106 var messageDiv = document.getElementById('message'); |
| 107 var infoboxDiv = document.getElementById('infobox'); |
| 108 document.getElementById('title').innerText = title; |
| 109 document.querySelector('title').innerText = title; |
| 110 messageDiv.innerText = message; |
| 111 if (showSpinner) { |
| 112 messageDiv.classList.add('waiting'); |
| 113 messageDiv.classList.add('prominent'); |
| 114 } |
| 115 if (infobox != '') { |
| 116 infoboxDiv.innerText = infobox; |
| 117 } else { |
| 118 infoboxDiv.hidden = true; |
| 119 } |
| 120 |
| 121 this.initButton_( |
| 122 button, |
| 123 buttonLabel, |
| 124 this.sendReply_.bind(this, event.source, messageId, 1)); |
| 125 |
| 126 this.initButton_( |
| 127 cancelButton, |
| 128 cancelButtonLabel, |
| 129 this.sendReply_.bind(this, event.source, messageId, 0)); |
| 130 |
| 131 var buttonToFocus = (cancelButtonLabel) ? cancelButton : button; |
| 132 buttonToFocus.focus(); |
| 133 |
| 134 // Add a close handler in case the window is closed without clicking one |
| 135 // of the buttons. This will send a 0 as the result. |
| 136 // Note that when a button is pressed, this will result in sendReply_ |
| 137 // being called multiple times (once for the button, once for close). |
| 138 chrome.app.window.current().onClosed.addListener( |
| 139 this.sendReply_.bind(this, event.source, messageId, 0)); |
| 140 |
| 141 this.updateSize_(); |
| 142 chrome.app.window.current().show(); |
| 143 break; |
| 144 |
| 145 case 'update_message': |
| 146 var message = /** @type {string} */ (event.data['message']); |
| 147 if (typeof(message) != 'string') { |
| 148 console.log('Bad update_message message:', event.data); |
| 149 break; |
| 150 } |
| 151 |
| 152 var messageDiv = document.getElementById('message'); |
| 153 messageDiv.innerText = message; |
| 154 |
| 155 this.updateSize_(); |
| 156 break; |
| 157 |
| 158 default: |
| 159 console.error('Unexpected message:', event.data); |
| 160 } |
| 161 }; |
| 162 |
| 163 var messageWindow = new MessageWindowImpl(); |
OLD | NEW |