Chromium Code Reviews| Index: remoting/webapp/window_frame.js |
| diff --git a/remoting/webapp/window_frame.js b/remoting/webapp/window_frame.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b4f3d740af7454f9bf96036788dc5e9b7e628356 |
| --- /dev/null |
| +++ b/remoting/webapp/window_frame.js |
| @@ -0,0 +1,175 @@ |
| +// 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. |
| + |
| +/** |
| + * @fileoverview |
| + * Apps v2 custom title bar implementation |
| + */ |
| + |
| +'use strict'; |
| + |
| +/** @suppress {duplicate} */ |
| +var remoting = remoting || {}; |
| + |
| +/** |
| + * @param {HTMLElement} titleBar The root node of the title-bar DOM hierarchy. |
| + * @constructor |
| + */ |
| +remoting.WindowFrame = function(titleBar) { |
| + /** |
| + * @type {boolean} |
| + * @private |
| + */ |
| + this.isConnected_ = false; |
| + |
| + /** |
| + * @type {HTMLElement} |
| + * @private |
| + */ |
| + this.titleBar_ = titleBar; |
| + |
| + /** |
| + * @type {HTMLElement} |
| + * @private |
| + */ |
| + this.hoverTarget_ = /** @type {HTMLElement} */ |
| + (titleBar.querySelector('.window-controls-hover-target')); |
| + base.debug.assert(this.hoverTarget_ != null); |
| + |
| + /** |
| + * @type {HTMLElement} |
| + * @private |
| + */ |
| + this.maximizeRestoreControl_ = /** @type {HTMLElement} */ |
| + (titleBar.querySelector('.window-maximize-restore')); |
| + base.debug.assert(this.maximizeRestoreControl_ != null); |
| + |
| + /** |
| + * @type {Array.<{cls:string, fn: function()}>} |
| + */ |
| + var handlers = [ |
| + { cls: 'window-disconnect', fn: this.disconnectSession_.bind(this) }, |
| + { cls: 'window-maximize-restore', |
| + fn: this.maximizeOrRestoreWindow_.bind(this) }, |
| + { cls: 'window-minimize', fn: this.minimizeWindow_.bind(this) }, |
| + { cls: 'window-close', fn: window.close.bind(window) }, |
| + { cls: 'window-controls-stub', fn: this.toggleWindowControls_.bind(this) } |
| + ]; |
| + for (var i = 0; i < handlers.length; ++i) { |
| + var element = titleBar.querySelector('.' + handlers[i].cls); |
| + base.debug.assert(element != null); |
| + element.addEventListener('click', handlers[i].fn, false); |
| + } |
| + |
| + // Ensure that tool-tips are always correct. |
| + this.updateMaximizeOrRestoreIconTitle_(); |
| + chrome.app.window.current().onMaximized.addListener( |
| + this.updateMaximizeOrRestoreIconTitle_.bind(this)); |
| + chrome.app.window.current().onRestored.addListener( |
| + this.updateMaximizeOrRestoreIconTitle_.bind(this)); |
| + chrome.app.window.current().onFullscreened.addListener( |
| + this.updateMaximizeOrRestoreIconTitle_.bind(this)); |
| +}; |
| + |
| +/** |
| + * @param {boolean} isConnected True if there is a connection active. |
| + */ |
| +remoting.WindowFrame.prototype.setConnected = function(isConnected) { |
| + this.isConnected_ = isConnected; |
| + if (this.isConnected_) { |
| + document.body.classList.add('connected'); |
| + } else { |
| + document.body.classList.remove('connected'); |
| + } |
| + this.updateMaximizeOrRestoreIconTitle_(); |
| +}; |
| + |
| +/** |
| + * @return {{width: number, height: number}} The size of the window, ignoring |
| + * the title-bar and window borders, if visible. |
| + */ |
| +remoting.WindowFrame.prototype.getClientArea = function() { |
| + if (chrome.app.window.current().isFullscreen()) { |
| + return { 'height': window.innerHeight, 'width': window.innerWidth }; |
| + } else { |
| + var kBorderWidth = 1; |
| + var titleHeight = this.titleBar_.clientHeight; |
| + return { |
| + 'height': window.innerHeight - titleHeight - 2 * kBorderWidth, |
| + 'width': window.innerWidth - 2 * kBorderWidth |
| + }; |
| + } |
| +}; |
| + |
| +/** |
| + * @private |
| + */ |
| +remoting.WindowFrame.prototype.disconnectSession_ = function() { |
| + // When the user disconnects, exit full-screen mode. This should not be |
|
kelvinp
2014/05/07 18:44:11
Nit: Do we have a bug number? We should file one
Jamie
2014/05/07 19:31:15
I agree, but I don't have a minimal repro yet. I w
|
| + // necessary, as we do the same thing in client_session.js when the plugin |
| + // is removed. However, there seems to be a bug in chrome.AppWindow.restore |
| + // that causes it to get stuck in full-screen mode without this. |
| + if (chrome.app.window.current().isFullscreen()) { |
| + chrome.app.window.current().restore(); |
| + chrome.app.window.current().restore(); |
| + } |
| + remoting.disconnect(); |
| +}; |
| + |
| +/** |
| + * @private |
| + */ |
| +remoting.WindowFrame.prototype.maximizeOrRestoreWindow_ = function() { |
| + /** @type {boolean} */ |
| + var restore = |
| + chrome.app.window.current().isFullscreen() || |
| + chrome.app.window.current().isMaximized(); |
| + if (restore) { |
| + // Restore twice: once to exit full-screen and once to exit maximized. |
| + // If the app is not full-screen, or went full-screen without first |
| + // being maximized, then the second restore has no effect. |
| + chrome.app.window.current().restore(); |
| + chrome.app.window.current().restore(); |
| + } else { |
| + chrome.app.window.current().maximize(); |
| + } |
| +}; |
| + |
| +/** |
| + * @private |
| + */ |
| +remoting.WindowFrame.prototype.minimizeWindow_ = function() { |
| + chrome.app.window.current().minimize(); |
| +}; |
| + |
| +/** |
| + * @private |
| + */ |
| +remoting.WindowFrame.prototype.toggleWindowControls_ = function() { |
| + this.hoverTarget_.classList.toggle('opened'); |
| +}; |
| + |
| +/** |
| + * Update the tool-top for the maximize/full-screen/restore icon to reflect |
| + * its current behaviour. |
| + * |
| + * @private |
| + */ |
| +remoting.WindowFrame.prototype.updateMaximizeOrRestoreIconTitle_ = function() { |
| + /** @type {string} */ |
| + var tag = ''; |
| + if (chrome.app.window.current().isFullscreen()) { |
| + tag = /*i18n-content*/'EXIT_FULL_SCREEN'; |
| + } else if (chrome.app.window.current().isMaximized()) { |
| + tag = /*i18n-content*/'RESTORE_WINDOW'; |
| + } else if (this.isConnected_) { |
| + tag = /*i18n-content*/'FULL_SCREEN'; |
| + } else { |
| + tag = /*i18n-content*/'MAXIMIZE_WINDOW'; |
| + } |
| + this.maximizeRestoreControl_.title = l10n.getTranslationOrError(tag); |
| +}; |
| + |
| +/** @type {remoting.WindowFrame} */ |
| +remoting.windowFrame = null; |