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; |