Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / remoting / webapp / base / js / window_shape.js
blob871c6476b9ca8d1ebde6433bec7043a974534980
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  * Class handling setting of the local app window shape to account for windows
8  * on the remote desktop, as well as any client-side UI.
9  */
11 'use strict';
13 /** @suppress {duplicate} */
14 var remoting = remoting || {};
16 /** @constructor */
17 remoting.WindowShape = function() {
18   /** @private {Array<{left: number, top: number,
19                        width: number, height: number}>} */
20   this.desktopRects_ = [];
22   /** @private {Array<remoting.WindowShape.ClientUI>} */
23   this.clientUIs_ = [];
26 /**
27  * @return {boolean} True if setShape is available and implemented for the
28  *     current platform.
29  */
30 remoting.WindowShape.isSupported = function() {
31   return base.isAppsV2() &&
32       typeof(chrome.app.window.current().setShape) != 'undefined' &&
33       !remoting.platformIsMac();
36 /**
37  * Adds a client-side UI.
38  *
39  * @param {remoting.WindowShape.ClientUI} callback
40  */
41 remoting.WindowShape.prototype.registerClientUI = function(callback) {
42   if (this.clientUIs_.indexOf(callback) === -1) {
43     this.clientUIs_.push(callback);
44     this.updateClientWindowShape();
45   }
48 /**
49  * Removes a client-side UI.
50  *
51  * @param {remoting.WindowShape.ClientUI} callback
52  */
53 remoting.WindowShape.prototype.unregisterClientUI = function(callback) {
54   var index = this.clientUIs_.indexOf(callback);
55   this.clientUIs_.splice(index, 1);
56   this.updateClientWindowShape();
59 /**
60  * Center aligns a DOM element to the desktop shape.
61  *
62  * @param {HTMLElement} element
63  */
64 remoting.WindowShape.prototype.centerToDesktop = function(element) {
65   var desktop = {
66     left: Number.MAX_VALUE,
67     right: Number.MIN_VALUE,
68     top: Number.MAX_VALUE,
69     bottom: Number.MIN_VALUE
70   };
72   // If there is no desktop window, center it to the current viewport.
73   if (this.desktopRects_.length === 0) {
74     desktop.left = 0;
75     desktop.right = window.innerWidth;
76     desktop.top = 0;
77     desktop.bottom = window.innerHeight;
78   } else {
79     // Compute the union of the bounding rects of all desktop windows.
80     this.desktopRects_.forEach(function(
81         /**{left: number, top: number, width: number, height: number}*/ rect) {
82       desktop.left = Math.min(rect.left, desktop.left);
83       desktop.right = Math.max(rect.left + rect.width, desktop.right);
84       desktop.top = Math.min(rect.top, desktop.top);
85       desktop.bottom = Math.max(rect.top + rect.height, desktop.bottom);
86     });
87   }
89   // Center the element to the desktop window bounding rect.
90   var rect = element.getBoundingClientRect();
91   var left = (desktop.right - desktop.left - rect.width) / 2 + desktop.left;
92   var top = (desktop.bottom - desktop.top - rect.height) / 2 + desktop.top;
93   element.style.left = Math.round(left) + 'px';
94   element.style.top = Math.round(top) + 'px';
95   this.updateClientWindowShape();
98 /**
99  * Sets the region associated with the remote desktop windows.
101  * @param {Array<{left: number, top: number, width: number, height: number}>}
102  *     rects
103  */
104 remoting.WindowShape.prototype.setDesktopRects = function(rects) {
105   this.desktopRects_ = rects;
106   this.updateClientWindowShape();
110  * Updates the client window shape.
111  */
112 remoting.WindowShape.prototype.updateClientWindowShape = function() {
113   if (!remoting.WindowShape.isSupported()) {
114     return;
115   }
117   var rects = this.desktopRects_.slice();
118   for (var i = 0; i < this.clientUIs_.length; ++i) {
119     this.clientUIs_[i].addToRegion(rects);
120   }
121   for (var i = 0; i < rects.length; ++i) {
122     var rect = /** @type {ClientRect} */ (rects[i]);
123     var left = Math.floor(rect.left);
124     var right = Math.ceil(rect.left + rect.width);
125     var top = Math.floor(rect.top);
126     var bottom = Math.ceil(rect.top + rect.height);
127     rects[i] = { left: left,
128                  top: top,
129                  width: right - left,
130                  height: bottom - top };
131   }
132   chrome.app.window.current().setShape({rects: rects});
137  * @interface
138  */
139 remoting.WindowShape.ClientUI = function () {
143  * Adds the context menu's bounding rectangle to the specified region.
145  * @param {Array<{left: number, top: number, width: number, height: number}>}
146  *     rects
147  */
148 remoting.WindowShape.ClientUI.prototype.addToRegion = function(rects) {};