Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / remoting / webapp / base / js / message_window.js
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 outerBounds = chrome.app.window.current().outerBounds;
53   var innerBounds = chrome.app.window.current().innerBounds;
54   var borderY = outerBounds.height - innerBounds.height;
55   window.resizeTo(outerBounds.width, document.body.clientHeight + borderY);
56   // Sometimes, resizing the window causes its position to be reset to (0, 0),
57   // so restore it explicitly.
58   window.moveTo(outerBounds.left, outerBounds.top);
59 };
60
61 /**
62  * Initializes the button with the label and the click handler.
63  * Hides the button if the label is null or undefined.
64  *
65  * @param{HTMLElement} button
66  * @param{?string} label
67  * @param{Function} clickHandler
68  * @private
69  */
70 MessageWindowImpl.prototype.initButton_ =
71     function(button, label, clickHandler) {
72   if (label) {
73     button.innerText = label;
74     button.addEventListener('click', clickHandler, false);
75   }
76   button.hidden = !Boolean(label);
77 };
78
79 /**
80  * Event-handler callback, invoked when the parent window supplies the
81  * message content.
82  *
83  * @param{Event} event
84  * @private
85  */
86 MessageWindowImpl.prototype.onMessage_ = function(event) {
87   switch (event.data['command']) {
88     case 'show':
89       // Validate the message.
90       var messageId = /** @type {number} */ (event.data['id']);
91       var title = /** @type {string} */ (event.data['title']);
92       var message = /** @type {string} */ (event.data['message']);
93       var infobox = /** @type {string} */ (event.data['infobox']);
94       var buttonLabel = /** @type {string} */ (event.data['buttonLabel']);
95       /** @type {string} */
96       var cancelButtonLabel = (event.data['cancelButtonLabel']);
97       var showSpinner = /** @type {boolean} */ (event.data['showSpinner']);
98       if (typeof(messageId) != 'number' ||
99           typeof(title) != 'string' ||
100           typeof(message) != 'string' ||
101           typeof(infobox) != 'string' ||
102           typeof(buttonLabel) != 'string' ||
103           typeof(showSpinner) != 'boolean') {
104         console.log('Bad show message:', event.data);
105         break;
106       }
107
108       // Set the dialog text.
109       var button = document.getElementById('button-primary');
110       var cancelButton = document.getElementById('button-secondary');
111       var messageDiv = document.getElementById('message');
112       var infoboxDiv = document.getElementById('infobox');
113
114       document.getElementById('title').innerText = title;
115       document.querySelector('title').innerText = title;
116       messageDiv.innerHTML = message;
117
118       if (showSpinner) {
119         messageDiv.classList.add('waiting');
120         messageDiv.classList.add('prominent');
121       }
122       if (infobox != '') {
123         infoboxDiv.innerText = infobox;
124       } else {
125         infoboxDiv.hidden = true;
126       }
127
128       this.initButton_(
129           button,
130           buttonLabel,
131           this.sendReply_.bind(this, event.source, messageId, 1));
132
133       this.initButton_(
134           cancelButton,
135           cancelButtonLabel,
136           this.sendReply_.bind(this, event.source, messageId, 0));
137
138       var buttonToFocus = (cancelButtonLabel) ? cancelButton : button;
139       buttonToFocus.focus();
140
141       // Add a close handler in case the window is closed without clicking one
142       // of the buttons. This will send a 0 as the result.
143       // Note that when a button is pressed, this will result in sendReply_
144       // being called multiple times (once for the button, once for close).
145       chrome.app.window.current().onClosed.addListener(
146           this.sendReply_.bind(this, event.source, messageId, 0));
147
148       this.updateSize_();
149       chrome.app.window.current().show();
150       break;
151
152     case 'update_message':
153       var message = /** @type {string} */ (event.data['message']);
154       if (typeof(message) != 'string') {
155         console.log('Bad update_message message:', event.data);
156         break;
157       }
158
159       var messageDiv = document.getElementById('message');
160       messageDiv.innerText = message;
161
162       this.updateSize_();
163       break;
164
165     default:
166       console.error('Unexpected message:', event.data);
167   }
168 };
169
170 var messageWindow = new MessageWindowImpl();