This is an automated email from the ASF dual-hosted git repository.

Harbs pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git


The following commit(s) were added to refs/heads/develop by this push:
     new 6888a851d8 Add DisplayUtils class and corresponding tests for bounding 
box calculations
6888a851d8 is described below

commit 6888a851d80d1bad4b29e278bc8bc99f538d4341
Author: Harbs <[email protected]>
AuthorDate: Mon Jul 13 09:59:30 2026 +0300

    Add DisplayUtils class and corresponding tests for bounding box calculations
---
 .../royale/org/apache/royale/utils/DisplayUtils.as |  19 ++-
 .../src/test/royale/flexUnitTests/CoreTester.as    |   1 +
 .../test/royale/flexUnitTests/DisplayUtilsTest.as  | 184 +++++++++++++++++++++
 3 files changed, 198 insertions(+), 6 deletions(-)

diff --git 
a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/DisplayUtils.as
 
b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/DisplayUtils.as
index e3894ea45b..6800eb6ba2 100644
--- 
a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/DisplayUtils.as
+++ 
b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/DisplayUtils.as
@@ -38,7 +38,7 @@ package org.apache.royale.utils
                import org.apache.royale.core.ITransformHost;
        }
        /**
-        *  The SpriteUtils class is a collection of static functions that are 
useful
+        *  The DisplayUtils class is a collection of static functions that are 
useful
         *  for geometric operations on visible objects.
         *  
         *  @langversion 3.0
@@ -50,9 +50,17 @@ package org.apache.royale.utils
        {
 
                /**
-                *  Gets the bounding box of an object relative to the screen 
ignoring any scrolling.
+                *  Gets the axis-aligned bounding box of an object in the 
top-level visible
+                *  coordinate space. On SWF, this is the stage coordinate 
space. On JS, this
+                *  is the browser layout viewport coordinate space returned by
+                *  <code>getBoundingClientRect()</code>. Scrolling the 
document or an ancestor
+                *  changes the returned position relative to the viewport.
                 * 
                 *  @param obj The object to test.
+                *  @param boundsBeforeTransform Optional untransformed local 
bounds. On JS,
+                *  these bounds are transformed into viewport coordinates for 
SVG elements.
+                *
+                *  @return The object's axis-aligned bounds in the top-level 
visible coordinate space.
                 *  
                 *  @langversion 3.0
                 *  @playerversion Flash 10.2
@@ -76,8 +84,6 @@ package org.apache.royale.utils
                                        var r:Object = (obj.element as 
HTMLElement).getBoundingClientRect();
                                        bounds = new Rectangle(r.left, r.top, 
r.right - r.left, r.bottom - r.top);
                                }
-                               bounds.x -= window.pageXOffset;
-                               bounds.y -= window.pageYOffset;
                                if (obj.element is SVGElement)
                                {
                                        var m:org.apache.royale.geom.Matrix = 
getTransormMatrix(obj);
@@ -99,7 +105,8 @@ package org.apache.royale.utils
                }
                
                /**
-                *  Gets a composition all transform matrices applied to an 
IUIBase. Currently only works for SVG on JS side.
+                *  Gets the composition of all transform matrices applied to 
an IUIBase.
+                *  Currently only works for SVG elements on JS.
                 * 
                 *  @param obj The object to test.
                 *  
@@ -128,7 +135,7 @@ package org.apache.royale.utils
                }
 
                /**
-                *  Evaluates the bounding box of two objects to see if thier 
bounding boxes overlap.
+                *  Evaluates the bounding boxes of two objects to see if they 
overlap.
                 * 
                 *  @param obj1 The object to test.
                 *  @param obj2 The object to test against.
diff --git 
a/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as 
b/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
index b95cb19307..d37bb7e970 100644
--- a/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
+++ b/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
@@ -44,6 +44,7 @@ package flexUnitTests
         public var stringUtilsTest:StringUtilsTest;
         public var sanitizerTest:SanitizeTest;
         public var eventsTest:EventsTest;
+        public var displayUtilsTest:DisplayUtilsTest;
         public var objectUtilTests:ObjectUtilsTest;
         public var functionalTests:FunctionalTests;
         public var taskTests:TaskTests;
diff --git 
a/frameworks/projects/Core/src/test/royale/flexUnitTests/DisplayUtilsTest.as 
b/frameworks/projects/Core/src/test/royale/flexUnitTests/DisplayUtilsTest.as
new file mode 100644
index 0000000000..1fbbd85679
--- /dev/null
+++ b/frameworks/projects/Core/src/test/royale/flexUnitTests/DisplayUtilsTest.as
@@ -0,0 +1,184 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package flexUnitTests
+{
+    import org.apache.royale.core.UIBase;
+    import org.apache.royale.geom.Rectangle;
+    import org.apache.royale.test.asserts.*;
+    import org.apache.royale.utils.DisplayUtils;
+
+    public class DisplayUtilsTest
+    {
+        private var target:UIBase;
+
+        COMPILE::JS
+        private var fixture:HTMLElement;
+
+        COMPILE::JS
+        private var originalScrollX:Number;
+
+        COMPILE::JS
+        private var originalScrollY:Number;
+
+        [Before]
+        public function setUp():void
+        {
+            COMPILE::JS
+            {
+                originalScrollX = window.pageXOffset;
+                originalScrollY = window.pageYOffset;
+                window.scrollTo(0, 0);
+
+                fixture = document.createElement("div") as HTMLElement;
+                fixture.style.position = "absolute";
+                fixture.style.left = "0px";
+                fixture.style.top = "0px";
+                fixture.style.width = "1px";
+                fixture.style.height = "3000px";
+                document.body.appendChild(fixture);
+
+                target = new UIBase();
+                target.element.style.position = "absolute";
+                target.element.style.left = "37px";
+                target.element.style.top = "600px";
+                target.element.style.width = "80px";
+                target.element.style.height = "40px";
+                fixture.appendChild(target.element);
+            }
+        }
+
+        [After]
+        public function tearDown():void
+        {
+            COMPILE::JS
+            {
+                window.scrollTo(originalScrollX, originalScrollY);
+                document.body.removeChild(fixture);
+                fixture = null;
+                target = null;
+            }
+        }
+
+        [Test]
+        public function testScreenBoundsAtPageOffsetZero():void
+        {
+            COMPILE::JS
+            {
+                var clientBounds:Object = 
target.element.getBoundingClientRect();
+                var bounds:Rectangle = 
DisplayUtils.getScreenBoundingRect(target);
+
+                assertRectangleMatchesClientBounds(bounds, clientBounds);
+            }
+        }
+
+        [Test]
+        public function testScreenBoundsAfterDocumentScroll():void
+        {
+            COMPILE::JS
+            {
+                var before:Rectangle = 
DisplayUtils.getScreenBoundingRect(target);
+                window.scrollTo(0, 200);
+                var clientBounds:Object = 
target.element.getBoundingClientRect();
+                var after:Rectangle = 
DisplayUtils.getScreenBoundingRect(target);
+
+                assertRectangleMatchesClientBounds(after, clientBounds);
+                assertNear(before.top - 200, after.top, "Document scrolling 
should move viewport bounds");
+            }
+        }
+
+        [Test]
+        public function testScreenBoundsInsideScrollingContainer():void
+        {
+            COMPILE::JS
+            {
+                var scroller:HTMLElement = document.createElement("div") as 
HTMLElement;
+                scroller.style.position = "absolute";
+                scroller.style.left = "150px";
+                scroller.style.top = "100px";
+                scroller.style.width = "200px";
+                scroller.style.height = "100px";
+                scroller.style.overflow = "auto";
+                fixture.appendChild(scroller);
+
+                target.element.style.left = "20px";
+                target.element.style.top = "300px";
+                scroller.appendChild(target.element);
+                var before:Rectangle = 
DisplayUtils.getScreenBoundingRect(target);
+
+                scroller.scrollTop = 120;
+                var clientBounds:Object = 
target.element.getBoundingClientRect();
+                var after:Rectangle = 
DisplayUtils.getScreenBoundingRect(target);
+
+                assertRectangleMatchesClientBounds(after, clientBounds);
+                assertNear(before.top - 120, after.top, "Ancestor scrolling 
should move viewport bounds");
+            }
+        }
+
+        [Test]
+        public function testBoundsBeforeTransformIsUsed():void
+        {
+            COMPILE::JS
+            {
+                var suppliedBounds:Rectangle = new Rectangle(10, 20, 30, 40);
+                var bounds:Rectangle = 
DisplayUtils.getScreenBoundingRect(target, suppliedBounds);
+
+                assertStrictlyEquals(suppliedBounds, bounds);
+                assertEquals(10, bounds.left);
+                assertEquals(20, bounds.top);
+                assertEquals(40, bounds.right);
+                assertEquals(60, bounds.bottom);
+            }
+        }
+
+        [Test]
+        public function testObjectsOverlapUsesViewportBounds():void
+        {
+            COMPILE::JS
+            {
+                var other:UIBase = new UIBase();
+                other.element.style.position = "absolute";
+                other.element.style.left = "100px";
+                other.element.style.top = "620px";
+                other.element.style.width = "40px";
+                other.element.style.height = "40px";
+                fixture.appendChild(other.element);
+
+                assertTrue(DisplayUtils.objectsOverlap(target, other));
+
+                other.element.style.left = "200px";
+                assertFalse(DisplayUtils.objectsOverlap(target, other));
+            }
+        }
+
+        COMPILE::JS
+        private function assertRectangleMatchesClientBounds(bounds:Rectangle, 
clientBounds:Object):void
+        {
+            assertNear(clientBounds.left, bounds.left, "Incorrect left 
viewport coordinate");
+            assertNear(clientBounds.top, bounds.top, "Incorrect top viewport 
coordinate");
+            assertNear(clientBounds.right, bounds.right, "Incorrect right 
viewport coordinate");
+            assertNear(clientBounds.bottom, bounds.bottom, "Incorrect bottom 
viewport coordinate");
+        }
+
+        COMPILE::JS
+        private function assertNear(expected:Number, actual:Number, 
message:String):void
+        {
+            assertTrue(Math.abs(expected - actual) < 0.01, message + ": 
expected " + expected + " but was " + actual);
+        }
+    }
+}
\ No newline at end of file

Reply via email to