From d46ecf53ea0c58e61515ce2d6b6b04a823f5502b Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Thu, 28 Jan 2021 20:58:34 +0000 Subject: [PATCH] Bug 1685801: Part 10 - Move BrowserUtils.getElementBounding*Rect to a separate module. r=mccr8 They won't be used in most processes. Differential Revision: https://phabricator.services.mozilla.com/D101490 --- browser/actors/FormValidationChild.jsm | 6 +- toolkit/actors/AutoCompleteChild.jsm | 6 +- toolkit/actors/DateTimePickerChild.jsm | 6 +- toolkit/actors/SelectChild.jsm | 6 +- toolkit/modules/BrowserUtils.jsm | 76 ----------------------- toolkit/modules/LayoutUtils.jsm | 86 ++++++++++++++++++++++++++ toolkit/modules/moz.build | 1 + 7 files changed, 99 insertions(+), 88 deletions(-) create mode 100644 toolkit/modules/LayoutUtils.jsm diff --git a/browser/actors/FormValidationChild.jsm b/browser/actors/FormValidationChild.jsm index 180e79fc93ae..787aec54e723 100644 --- a/browser/actors/FormValidationChild.jsm +++ b/browser/actors/FormValidationChild.jsm @@ -10,8 +10,8 @@ var EXPORTED_SYMBOLS = ["FormValidationChild"]; -const { BrowserUtils } = ChromeUtils.import( - "resource://gre/modules/BrowserUtils.jsm" +const { LayoutUtils } = ChromeUtils.import( + "resource://gre/modules/LayoutUtils.jsm" ); const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); @@ -154,7 +154,7 @@ class FormValidationChild extends JSWindowActorChild { panelData.message = this._validationMessage; - panelData.screenRect = BrowserUtils.getElementBoundingScreenRect(aElement); + panelData.screenRect = LayoutUtils.getElementBoundingScreenRect(aElement); // We want to show the popup at the middle of checkbox and radio buttons // and where the content begin for the other elements. diff --git a/toolkit/actors/AutoCompleteChild.jsm b/toolkit/actors/AutoCompleteChild.jsm index b860d10c21f0..a10dd9c0fe58 100644 --- a/toolkit/actors/AutoCompleteChild.jsm +++ b/toolkit/actors/AutoCompleteChild.jsm @@ -11,8 +11,8 @@ const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.defineModuleGetter( this, - "BrowserUtils", - "resource://gre/modules/BrowserUtils.jsm" + "LayoutUtils", + "resource://gre/modules/LayoutUtils.jsm" ); ChromeUtils.defineModuleGetter( @@ -136,7 +136,7 @@ class AutoCompleteChild extends JSWindowActorChild { return; } - let rect = BrowserUtils.getElementBoundingScreenRect(element); + let rect = LayoutUtils.getElementBoundingScreenRect(element); let window = element.ownerGlobal; let dir = window.getComputedStyle(element).direction; let results = this.getResultsFromController(input); diff --git a/toolkit/actors/DateTimePickerChild.jsm b/toolkit/actors/DateTimePickerChild.jsm index 0bfce7f0a7d6..7a3a7d7c6225 100644 --- a/toolkit/actors/DateTimePickerChild.jsm +++ b/toolkit/actors/DateTimePickerChild.jsm @@ -5,8 +5,8 @@ const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.defineModuleGetter( this, - "BrowserUtils", - "resource://gre/modules/BrowserUtils.jsm" + "LayoutUtils", + "resource://gre/modules/LayoutUtils.jsm" ); var EXPORTED_SYMBOLS = ["DateTimePickerChild"]; @@ -78,7 +78,7 @@ class DateTimePickerChild extends JSWindowActorChild { * relative to the left/top of the content area. */ getBoundingContentRect(aElement) { - return BrowserUtils.getElementBoundingScreenRect(aElement); + return LayoutUtils.getElementBoundingScreenRect(aElement); } getTimePickerPref() { diff --git a/toolkit/actors/SelectChild.jsm b/toolkit/actors/SelectChild.jsm index 54a60d178b87..5b96a02a0e8b 100644 --- a/toolkit/actors/SelectChild.jsm +++ b/toolkit/actors/SelectChild.jsm @@ -12,8 +12,8 @@ const { XPCOMUtils } = ChromeUtils.import( ChromeUtils.defineModuleGetter( this, - "BrowserUtils", - "resource://gre/modules/BrowserUtils.jsm" + "LayoutUtils", + "resource://gre/modules/LayoutUtils.jsm" ); ChromeUtils.defineModuleGetter( this, @@ -173,7 +173,7 @@ SelectContentHelper.prototype = { }, _getBoundingContentRect() { - return BrowserUtils.getElementBoundingScreenRect(this.element); + return LayoutUtils.getElementBoundingScreenRect(this.element); }, _buildOptionList() { diff --git a/toolkit/modules/BrowserUtils.jsm b/toolkit/modules/BrowserUtils.jsm index 9b3f33789d2b..08f4fb6d9ee5 100644 --- a/toolkit/modules/BrowserUtils.jsm +++ b/toolkit/modules/BrowserUtils.jsm @@ -91,82 +91,6 @@ var BrowserUtils = { ); }, - /** - * For a given DOM element, returns its position in "screen" - * coordinates. In a content process, the coordinates returned will - * be relative to the left/top of the tab. In the chrome process, - * the coordinates are relative to the user's screen. - */ - getElementBoundingScreenRect(aElement) { - return this.getElementBoundingRect(aElement, true); - }, - - /** - * For a given DOM element, returns its position as an offset from the topmost - * window. In a content process, the coordinates returned will be relative to - * the left/top of the topmost content area. If aInScreenCoords is true, - * screen coordinates will be returned instead. - */ - getElementBoundingRect(aElement, aInScreenCoords) { - let rect = aElement.getBoundingClientRect(); - let win = aElement.ownerGlobal; - - let x = rect.left; - let y = rect.top; - - // We need to compensate for any iframes that might shift things - // over. We also need to compensate for zooming. - let parentFrame = win.frameElement; - while (parentFrame) { - win = parentFrame.ownerGlobal; - let cstyle = win.getComputedStyle(parentFrame); - - let framerect = parentFrame.getBoundingClientRect(); - x += - framerect.left + - parseFloat(cstyle.borderLeftWidth) + - parseFloat(cstyle.paddingLeft); - y += - framerect.top + - parseFloat(cstyle.borderTopWidth) + - parseFloat(cstyle.paddingTop); - - parentFrame = win.frameElement; - } - - rect = { - left: x, - top: y, - width: rect.width, - height: rect.height, - }; - rect = win.windowUtils.transformRectLayoutToVisual( - rect.left, - rect.top, - rect.width, - rect.height - ); - - if (aInScreenCoords) { - rect = { - left: rect.left + win.mozInnerScreenX, - top: rect.top + win.mozInnerScreenY, - width: rect.width, - height: rect.height, - }; - } - - let fullZoom = win.windowUtils.fullZoom; - rect = { - left: rect.left * fullZoom, - top: rect.top * fullZoom, - width: rect.width * fullZoom, - height: rect.height * fullZoom, - }; - - return rect; - }, - onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab) { // Don't modify non-default targets or targets that aren't in top-level app // tab docshells (isAppTab will be false for app tab subframes). diff --git a/toolkit/modules/LayoutUtils.jsm b/toolkit/modules/LayoutUtils.jsm new file mode 100644 index 000000000000..e644bd453c4c --- /dev/null +++ b/toolkit/modules/LayoutUtils.jsm @@ -0,0 +1,86 @@ +/* -*- mode: js; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +var EXPORTED_SYMBOLS = ["LayoutUtils"]; + +var LayoutUtils = { + /** + * For a given DOM element, returns its position in "screen" + * coordinates. In a content process, the coordinates returned will + * be relative to the left/top of the tab. In the chrome process, + * the coordinates are relative to the user's screen. + */ + getElementBoundingScreenRect(aElement) { + return this.getElementBoundingRect(aElement, true); + }, + + /** + * For a given DOM element, returns its position as an offset from the topmost + * window. In a content process, the coordinates returned will be relative to + * the left/top of the topmost content area. If aInScreenCoords is true, + * screen coordinates will be returned instead. + */ + getElementBoundingRect(aElement, aInScreenCoords) { + let rect = aElement.getBoundingClientRect(); + let win = aElement.ownerGlobal; + + let x = rect.left; + let y = rect.top; + + // We need to compensate for any iframes that might shift things + // over. We also need to compensate for zooming. + let parentFrame = win.frameElement; + while (parentFrame) { + win = parentFrame.ownerGlobal; + let cstyle = win.getComputedStyle(parentFrame); + + let framerect = parentFrame.getBoundingClientRect(); + x += + framerect.left + + parseFloat(cstyle.borderLeftWidth) + + parseFloat(cstyle.paddingLeft); + y += + framerect.top + + parseFloat(cstyle.borderTopWidth) + + parseFloat(cstyle.paddingTop); + + parentFrame = win.frameElement; + } + + rect = { + left: x, + top: y, + width: rect.width, + height: rect.height, + }; + rect = win.windowUtils.transformRectLayoutToVisual( + rect.left, + rect.top, + rect.width, + rect.height + ); + + if (aInScreenCoords) { + rect = { + left: rect.left + win.mozInnerScreenX, + top: rect.top + win.mozInnerScreenY, + width: rect.width, + height: rect.height, + }; + } + + let fullZoom = win.windowUtils.fullZoom; + rect = { + left: rect.left * fullZoom, + top: rect.top * fullZoom, + width: rect.width * fullZoom, + height: rect.height * fullZoom, + }; + + return rect; + }, +}; diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build index afb2598448a6..88676f6f303f 100644 --- a/toolkit/modules/moz.build +++ b/toolkit/modules/moz.build @@ -192,6 +192,7 @@ EXTRA_JS_MODULES += [ "Integration.jsm", "JSONFile.jsm", "KeywordUtils.jsm", + "LayoutUtils.jsm", "Log.jsm", "NewTabUtils.jsm", "NLP.jsm",