From 798e9d28c596f61df149f767ec66e0755116e95d Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 29 Jan 2015 23:47:17 -0800 Subject: [PATCH] GUAC-958: Simplify resize handling (use directive). Only install resize handler after object loads. --- .../app/client/directives/guacClient.js | 4 +- .../app/client/directives/guacThumbnail.js | 17 +-- .../main/webapp/app/client/styles/display.css | 12 -- .../app/client/templates/guacClient.html | 5 +- .../app/client/templates/guacThumbnail.html | 5 +- .../app/element/directives/guacResize.js | 117 ++++++++++++++++++ .../app/element/styles/resize-sensor.css | 33 +++++ .../{client => element}/templates/blank.html | 0 .../main/webapp/app/osk/directives/guacOsk.js | 17 +-- .../src/main/webapp/app/osk/styles/osk.css | 12 -- .../main/webapp/app/osk/templates/blank.html | 22 ---- .../webapp/app/osk/templates/guacOsk.html | 6 +- 12 files changed, 160 insertions(+), 90 deletions(-) create mode 100644 guacamole/src/main/webapp/app/element/directives/guacResize.js create mode 100644 guacamole/src/main/webapp/app/element/styles/resize-sensor.css rename guacamole/src/main/webapp/app/{client => element}/templates/blank.html (100%) delete mode 100644 guacamole/src/main/webapp/app/osk/templates/blank.html diff --git a/guacamole/src/main/webapp/app/client/directives/guacClient.js b/guacamole/src/main/webapp/app/client/directives/guacClient.js index 033f2e485..595be8d57 100644 --- a/guacamole/src/main/webapp/app/client/directives/guacClient.js +++ b/guacamole/src/main/webapp/app/client/directives/guacClient.js @@ -339,7 +339,7 @@ angular.module('client').directive('guacClient', [function guacClient() { }); // If the element is resized, attempt to resize client - resizeSensor.contentDocument.defaultView.addEventListener('resize', function mainElementResized() { + $scope.mainElementResized = function mainElementResized() { // Send new display size, if changed if (client && display) { @@ -355,7 +355,7 @@ angular.module('client').directive('guacClient', [function guacClient() { $scope.$evalAsync(updateDisplayScale); - }); + }; // Watch for changes to mouse emulation mode // Send all received mouse events to the client diff --git a/guacamole/src/main/webapp/app/client/directives/guacThumbnail.js b/guacamole/src/main/webapp/app/client/directives/guacThumbnail.js index 06e99a5d2..fc1e9650c 100644 --- a/guacamole/src/main/webapp/app/client/directives/guacThumbnail.js +++ b/guacamole/src/main/webapp/app/client/directives/guacThumbnail.js @@ -89,18 +89,11 @@ angular.module('client').directive('guacThumbnail', [function guacThumbnail() { */ var main = $element[0]; - /** - * The element which functions as a detector for size changes. - * - * @type Element - */ - var resizeSensor = $element.find('.resize-sensor')[0]; - /** * Updates the scale of the attached Guacamole.Client based on current window * size and "auto-fit" setting. */ - var updateDisplayScale = function updateDisplayScale() { + $scope.updateDisplayScale = function updateDisplayScale() { if (!display) return; @@ -159,15 +152,11 @@ angular.module('client').directive('guacThumbnail', [function guacThumbnail() { thumbnail.height = height; $scope.thumbnail = thumbnail.toDataURL("image/png"); - $scope.$evalAsync(updateDisplayScale); + // Init display scale + $scope.$evalAsync($scope.updateDisplayScale); }); - // If the element is resized, attempt to resize client - resizeSensor.contentDocument.defaultView.addEventListener('resize', function mainElementResized() { - $scope.$apply(updateDisplayScale); - }); - }] }; }]); \ No newline at end of file diff --git a/guacamole/src/main/webapp/app/client/styles/display.css b/guacamole/src/main/webapp/app/client/styles/display.css index 41b635915..04b8dc3de 100644 --- a/guacamole/src/main/webapp/app/client/styles/display.css +++ b/guacamole/src/main/webapp/app/client/styles/display.css @@ -38,18 +38,6 @@ div.main { font-size: 0px; } -.resize-sensor { - height: 100%; - width: 100%; - position: absolute; - left: 0; - top: 0; - overflow: hidden; - border: none; - opacity: 0; - z-index: -1; -} - div.displayOuter { height: 100%; width: 100%; diff --git a/guacamole/src/main/webapp/app/client/templates/guacClient.html b/guacamole/src/main/webapp/app/client/templates/guacClient.html index 3cc71b887..0642b1774 100644 --- a/guacamole/src/main/webapp/app/client/templates/guacClient.html +++ b/guacamole/src/main/webapp/app/client/templates/guacClient.html @@ -1,4 +1,4 @@ -
+
- -
\ No newline at end of file diff --git a/guacamole/src/main/webapp/app/client/templates/guacThumbnail.html b/guacamole/src/main/webapp/app/client/templates/guacThumbnail.html index 58558b2e2..1dd1c61fc 100644 --- a/guacamole/src/main/webapp/app/client/templates/guacThumbnail.html +++ b/guacamole/src/main/webapp/app/client/templates/guacThumbnail.html @@ -1,4 +1,4 @@ -
+
- - -
diff --git a/guacamole/src/main/webapp/app/element/directives/guacResize.js b/guacamole/src/main/webapp/app/element/directives/guacResize.js new file mode 100644 index 000000000..b9aeb3417 --- /dev/null +++ b/guacamole/src/main/webapp/app/element/directives/guacResize.js @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2015 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * A directive which calls a given callback when its associated element is + * resized. This will modify the internal DOM tree of the associated element, + * and the associated element MUST have position (for example, + * "position: relative"). + */ +angular.module('element').directive('guacResize', ['$document', function guacResize($document) { + + return { + restrict: 'A', + + link: function linkGuacResize($scope, $element, $attrs) { + + /** + * The function to call whenever the associated element is + * resized. The function will be passed the width and height of + * the element, in pixels. + * + * @type Function + */ + var guacResize = $scope.$eval($attrs.guacResize); + + /** + * The element which will monitored for size changes. + * + * @type Element + */ + var element = $element[0]; + + /** + * The resize sensor - an HTML object element. + * + * @type HTMLObjectElement + */ + var resizeSensor = $document[0].createElement('object'); + + /** + * The width of the associated element, in pixels. + * + * @type Number + */ + var lastWidth = element.offsetWidth; + + /** + * The height of the associated element, in pixels. + * + * @type Number + */ + var lastHeight = element.offsetHeight; + + /** + * Checks whether the size of the associated element has changed + * and, if so, calls the resize callback with the new width and + * height as parameters. + */ + var checkSize = function checkSize() { + + // Call callback only if size actually changed + if (element.offsetWidth !== lastWidth + || element.offsetHeight !== lastHeight) { + + // Call resize callback, if defined + if (guacResize) { + $scope.$apply(function elementSizeChanged() { + guacResize(element.offsetWidth, element.offsetHeight); + }); + } + + // Update stored size + lastWidth = element.offsetWidth; + lastHeight = element.offsetHeight; + + } + + }; + + // Register event listener once window object exists + resizeSensor.onload = function resizeSensorReady() { + resizeSensor.contentDocument.defaultView.addEventListener('resize', checkSize); + checkSize(); + }; + + // Load blank contents + resizeSensor.className = 'resize-sensor'; + resizeSensor.type = 'text/html'; + resizeSensor.data = 'app/element/templates/blank.html'; + + // Add resize sensor to associated element + element.insertBefore(resizeSensor, element.firstChild); + + } // end guacResize link function + + }; + +}]); diff --git a/guacamole/src/main/webapp/app/element/styles/resize-sensor.css b/guacamole/src/main/webapp/app/element/styles/resize-sensor.css new file mode 100644 index 000000000..2f260af4c --- /dev/null +++ b/guacamole/src/main/webapp/app/element/styles/resize-sensor.css @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2015 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +.resize-sensor { + height: 100%; + width: 100%; + position: absolute; + left: 0; + top: 0; + overflow: hidden; + border: none; + opacity: 0; + z-index: -1; +} diff --git a/guacamole/src/main/webapp/app/client/templates/blank.html b/guacamole/src/main/webapp/app/element/templates/blank.html similarity index 100% rename from guacamole/src/main/webapp/app/client/templates/blank.html rename to guacamole/src/main/webapp/app/element/templates/blank.html diff --git a/guacamole/src/main/webapp/app/osk/directives/guacOsk.js b/guacamole/src/main/webapp/app/osk/directives/guacOsk.js index edb8fd94d..decb06f8d 100644 --- a/guacamole/src/main/webapp/app/osk/directives/guacOsk.js +++ b/guacamole/src/main/webapp/app/osk/directives/guacOsk.js @@ -57,18 +57,8 @@ angular.module('osk').directive('guacOsk', [function guacOsk() { */ var main = $element[0]; - /** - * The element which functions as a detector for size changes. - * - * @type Element - */ - var resizeSensor = $element.find('.resize-sensor')[0]; - - /** - * Event listener which resizes the current keyboard, if any, such - * that it fits within available space. - */ - var resizeListener = function resizeListener() { + // Size keyboard to same size as main element + $scope.keyboardResized = function keyboardResized() { // Resize keyboard, if defined if (keyboard) @@ -105,9 +95,6 @@ angular.module('osk').directive('guacOsk', [function guacOsk() { $rootScope.$broadcast('guacSyntheticKeyup', keysym); }; - // Resize keyboard whenever element changes size - resizeSensor.contentDocument.defaultView.addEventListener('resize', resizeListener); - } }); // end layout scope watch diff --git a/guacamole/src/main/webapp/app/osk/styles/osk.css b/guacamole/src/main/webapp/app/osk/styles/osk.css index fba5c3f97..ad131bed4 100644 --- a/guacamole/src/main/webapp/app/osk/styles/osk.css +++ b/guacamole/src/main/webapp/app/osk/styles/osk.css @@ -24,18 +24,6 @@ position: relative; } -.osk .resize-sensor { - height: 100%; - width: 100%; - position: absolute; - left: 0; - top: 0; - overflow: hidden; - border: none; - opacity: 0; - z-index: -1; -} - .guac-keyboard { display: inline-block; width: 100%; diff --git a/guacamole/src/main/webapp/app/osk/templates/blank.html b/guacamole/src/main/webapp/app/osk/templates/blank.html deleted file mode 100644 index 62b9f6aa2..000000000 --- a/guacamole/src/main/webapp/app/osk/templates/blank.html +++ /dev/null @@ -1,22 +0,0 @@ - - diff --git a/guacamole/src/main/webapp/app/osk/templates/guacOsk.html b/guacamole/src/main/webapp/app/osk/templates/guacOsk.html index f1e3be270..097d1b38a 100644 --- a/guacamole/src/main/webapp/app/osk/templates/guacOsk.html +++ b/guacamole/src/main/webapp/app/osk/templates/guacOsk.html @@ -1,4 +1,4 @@ -
+
- - - -