Update V8 to version 3.30.4 (based on bleeding_edge revision r24443)
[chromium-blink-merge.git] / remoting / webapp / window_frame.js
blob75ecf49ba99cec864023009bf0de541f53ff2eaa
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.
5 /**
6 * @fileoverview
7 * Apps v2 custom title bar implementation
8 */
10 'use strict';
12 /** @suppress {duplicate} */
13 var remoting = remoting || {};
15 /**
16 * @param {HTMLElement} titleBar The root node of the title-bar DOM hierarchy.
17 * @constructor
19 remoting.WindowFrame = function(titleBar) {
20 /**
21 * @type {remoting.ClientSession}
22 * @private
24 this.clientSession_ = null;
26 /**
27 * @type {HTMLElement}
28 * @private
30 this.titleBar_ = titleBar;
32 /**
33 * @type {HTMLElement}
34 * @private
36 this.title_ = /** @type {HTMLElement} */
37 (titleBar.querySelector('.window-title'));
38 base.debug.assert(this.title_ != null);
40 /**
41 * @type {HTMLElement}
42 * @private
44 this.maximizeRestoreControl_ = /** @type {HTMLElement} */
45 (titleBar.querySelector('.window-maximize-restore'));
46 base.debug.assert(this.maximizeRestoreControl_ != null);
48 var optionsButton = titleBar.querySelector('.window-options');
49 base.debug.assert(optionsButton != null);
50 this.optionMenuButton_ = new remoting.MenuButton(
51 optionsButton,
52 this.onShowOptionsMenu_.bind(this),
53 this.onHideOptionsMenu_.bind(this));
55 /**
56 * @type {HTMLElement}
57 * @private
59 this.optionsMenuList_ = /** @type {HTMLElement} */
60 (optionsButton.querySelector('.window-options-menu'));
61 base.debug.assert(this.optionsMenuList_ != null);
63 /**
64 * @type {Array.<{cls:string, fn: function()}>}
66 var handlers = [
67 { cls: 'window-disconnect', fn: this.disconnectSession_.bind(this) },
68 { cls: 'window-maximize-restore',
69 fn: this.maximizeOrRestoreWindow_.bind(this) },
70 { cls: 'window-minimize', fn: this.minimizeWindow_.bind(this) },
71 { cls: 'window-close', fn: window.close.bind(window) },
72 { cls: 'window-controls-stub', fn: this.toggleWindowControls_.bind(this) }
74 for (var i = 0; i < handlers.length; ++i) {
75 var element = titleBar.querySelector('.' + handlers[i].cls);
76 base.debug.assert(element != null);
77 element.addEventListener('click', handlers[i].fn, false);
80 // Ensure that tool-tips are always correct.
81 this.handleWindowStateChange_();
82 chrome.app.window.current().onMaximized.addListener(
83 this.handleWindowStateChange_.bind(this));
84 chrome.app.window.current().onRestored.addListener(
85 this.handleWindowStateChange_.bind(this));
86 chrome.app.window.current().onFullscreened.addListener(
87 this.handleWindowStateChange_.bind(this));
88 chrome.app.window.current().onFullscreened.addListener(
89 this.showWindowControlsPreview_.bind(this));
92 /**
93 * @return {remoting.OptionsMenu}
95 remoting.WindowFrame.prototype.createOptionsMenu = function() {
96 return new remoting.OptionsMenu(
97 this.titleBar_.querySelector('.menu-send-ctrl-alt-del'),
98 this.titleBar_.querySelector('.menu-send-print-screen'),
99 this.titleBar_.querySelector('.menu-resize-to-client'),
100 this.titleBar_.querySelector('.menu-shrink-to-fit'),
101 this.titleBar_.querySelector('.menu-new-connection'),
102 this.titleBar_.querySelector('.window-fullscreen'),
103 this.titleBar_.querySelector('.menu-start-stop-recording'));
107 * @param {remoting.ClientSession} clientSession The client session, or null if
108 * there is no connection.
110 remoting.WindowFrame.prototype.setClientSession = function(clientSession) {
111 this.clientSession_ = clientSession;
112 var windowTitle = document.head.querySelector('title');
113 if (this.clientSession_) {
114 this.title_.innerText = clientSession.getHostDisplayName();
115 windowTitle.innerText = clientSession.getHostDisplayName() + ' - ' +
116 chrome.i18n.getMessage(/*i18n-content*/'PRODUCT_NAME');
117 } else {
118 this.title_.innerHTML = '&nbsp;';
119 windowTitle.innerText =
120 chrome.i18n.getMessage(/*i18n-content*/'PRODUCT_NAME');
122 this.handleWindowStateChange_();
126 * @return {{width: number, height: number}} The size of the window, ignoring
127 * the title-bar and window borders, if visible.
129 remoting.WindowFrame.prototype.getClientArea = function() {
130 if (chrome.app.window.current().isFullscreen()) {
131 return { 'height': window.innerHeight, 'width': window.innerWidth };
132 } else {
133 var kBorderWidth = 1;
134 var titleHeight = this.titleBar_.clientHeight;
135 return {
136 'height': window.innerHeight - titleHeight - 2 * kBorderWidth,
137 'width': window.innerWidth - 2 * kBorderWidth
143 * @private
145 remoting.WindowFrame.prototype.disconnectSession_ = function() {
146 // When the user disconnects, exit full-screen mode. This should not be
147 // necessary, as we do the same thing in client_session.js when the plugin
148 // is removed. However, there seems to be a bug in chrome.AppWindow.restore
149 // that causes it to get stuck in full-screen mode without this.
150 if (chrome.app.window.current().isFullscreen()) {
151 chrome.app.window.current().restore();
153 remoting.disconnect();
157 * @private
159 remoting.WindowFrame.prototype.maximizeOrRestoreWindow_ = function() {
160 /** @type {boolean} */
161 var restore =
162 chrome.app.window.current().isFullscreen() ||
163 chrome.app.window.current().isMaximized();
164 if (restore) {
165 chrome.app.window.current().restore();
166 } else {
167 chrome.app.window.current().maximize();
172 * @private
174 remoting.WindowFrame.prototype.minimizeWindow_ = function() {
175 chrome.app.window.current().minimize();
179 * @private
181 remoting.WindowFrame.prototype.toggleWindowControls_ = function() {
182 this.titleBar_.classList.toggle('opened');
186 * Update the tool-top for the maximize/full-screen/restore icon to reflect
187 * its current behaviour.
189 * @private
191 remoting.WindowFrame.prototype.handleWindowStateChange_ = function() {
192 // Set the title for the maximize/restore/full-screen button
193 /** @type {string} */
194 var tag = '';
195 if (chrome.app.window.current().isFullscreen()) {
196 tag = /*i18n-content*/'EXIT_FULL_SCREEN';
197 } else if (chrome.app.window.current().isMaximized()) {
198 tag = /*i18n-content*/'RESTORE_WINDOW';
199 } else {
200 tag = /*i18n-content*/'MAXIMIZE_WINDOW';
202 this.maximizeRestoreControl_.title = l10n.getTranslationOrError(tag);
204 // Ensure that the options menu aligns correctly for the side of the window
205 // it occupies.
206 if (chrome.app.window.current().isFullscreen()) {
207 this.optionsMenuList_.classList.add('right-align');
208 } else {
209 this.optionsMenuList_.classList.remove('right-align');
214 * Callback invoked when the options menu is shown.
215 * @private
217 remoting.WindowFrame.prototype.onShowOptionsMenu_ = function() {
218 remoting.optionsMenu.onShow();
219 this.titleBar_.classList.add('menu-opened');
223 * Callback invoked when the options menu is shown.
224 * @private
226 remoting.WindowFrame.prototype.onHideOptionsMenu_ = function() {
227 this.titleBar_.classList.remove('menu-opened');
231 * Show the window controls for a few seconds
233 * @private
235 remoting.WindowFrame.prototype.showWindowControlsPreview_ = function() {
237 * @type {HTMLElement}
239 var target = this.titleBar_;
240 var kPreviewTimeoutMs = 3000;
241 var hidePreview = function() {
242 target.classList.remove('preview');
244 target.classList.add('preview');
245 window.setTimeout(hidePreview, kPreviewTimeoutMs);
249 /** @type {remoting.WindowFrame} */
250 remoting.windowFrame = null;