--- a/devtools/shared/layout/utils.js
+++ b/devtools/shared/layout/utils.js
@@ -2,30 +2,29 @@
* 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";
const { Ci, Cc } = require("chrome");
const { memoize } = require("sdk/lang/functional");
-loader.lazyRequireGetter(this, "setIgnoreLayoutChanges",
- "devtools/server/actors/layout", true);
+loader.lazyRequireGetter(this, "setIgnoreLayoutChanges", "devtools/server/actors/layout", true);
exports.setIgnoreLayoutChanges = (...args) =>
this.setIgnoreLayoutChanges(...args);
/**
* Returns the `DOMWindowUtils` for the window given.
*
* @param {DOMWindow} win
* @returns {DOMWindowUtils}
*/
const utilsFor = memoize(
- (win) => win.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils)
+ win => win.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils)
);
/**
* like win.top, but goes through mozbrowsers and mozapps iframes.
*
* @param {DOMWindow} win
* @return {DOMWindow}
*/
@@ -33,17 +32,18 @@ function getTopWindow(win) {
let docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
if (!docShell.isMozBrowserOrApp) {
return win.top;
}
- let topDocShell = docShell.getSameTypeRootTreeItemIgnoreBrowserAndAppBoundaries();
+ let topDocShell =
+ docShell.getSameTypeRootTreeItemIgnoreBrowserAndAppBoundaries();
return topDocShell
? topDocShell.contentViewer.DOMDocument.defaultView
: null;
}
exports.getTopWindow = getTopWindow;
@@ -93,17 +93,18 @@ function getParentWindow(win) {
let docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
if (!docShell.isMozBrowserOrApp) {
return win.parent;
}
- let parentDocShell = docShell.getSameTypeParentIgnoreBrowserAndAppBoundaries();
+ let parentDocShell =
+ docShell.getSameTypeParentIgnoreBrowserAndAppBoundaries();
return parentDocShell
? parentDocShell.contentViewer.DOMDocument.defaultView
: null;
}
exports.getParentWindow = getParentWindow;
@@ -135,21 +136,20 @@ function getFrameOffsets(boundaryWindow,
let xOffset = 0;
let yOffset = 0;
let frameWin = node.ownerDocument.defaultView;
let scale = getCurrentZoom(node);
if (boundaryWindow === null) {
boundaryWindow = getTopWindow(frameWin);
} else if (typeof boundaryWindow === "undefined") {
- throw new Error("No `boundaryWindow` given. Use `null` for the default one.");
+ throw new Error("No boundaryWindow given. Use null for the default one.");
}
while (frameWin !== boundaryWindow) {
-
let frameElement = getFrameElement(frameWin);
if (!frameElement) {
break;
}
// We are in an iframe.
// We take into account the parent iframe position and its
// offset (borders and padding).
@@ -244,38 +244,38 @@ exports.getAdjustedQuads = getAdjustedQu
/**
* Compute the absolute position and the dimensions of a node, relativalely
* to the root window.
* @param {DOMWindow} boundaryWindow
* The window where to stop to iterate. If `null` is given, the top
* window is used.
- * @param {DOMNode} aNode
+ * @param {DOMNode} node
* a DOM element to get the bounds for
- * @param {DOMWindow} aContentWindow
+ * @param {DOMWindow} contentWindow
* the content window holding the node
* @return {Object}
* A rect object with the {top, left, width, height} properties
*/
-function getRect(boundaryWindow, aNode, aContentWindow) {
- let frameWin = aNode.ownerDocument.defaultView;
- let clientRect = aNode.getBoundingClientRect();
+function getRect(boundaryWindow, node, contentWindow) {
+ let frameWin = node.ownerDocument.defaultView;
+ let clientRect = node.getBoundingClientRect();
if (boundaryWindow === null) {
boundaryWindow = getTopWindow(frameWin);
} else if (typeof boundaryWindow === "undefined") {
- throw new Error("No `boundaryWindow` given. Use `null` for the default one.");
+ throw new Error("No boundaryWindow given. Use null for the default one.");
}
// Go up in the tree of frames to determine the correct rectangle.
// clientRect is read-only, we need to be able to change properties.
let rect = {
- top: clientRect.top + aContentWindow.pageYOffset,
- left: clientRect.left + aContentWindow.pageXOffset,
+ top: clientRect.top + contentWindow.pageYOffset,
+ left: clientRect.left + contentWindow.pageXOffset,
width: clientRect.width,
height: clientRect.height
};
// We iterate through all the parent windows.
while (frameWin !== boundaryWindow) {
let frameElement = getFrameElement(frameWin);
if (!frameElement) {
@@ -291,33 +291,33 @@ function getRect(boundaryWindow, aNode,
rect.top += frameRect.top + offsetTop;
rect.left += frameRect.left + offsetLeft;
frameWin = getParentWindow(frameWin);
}
return rect;
-};
+}
exports.getRect = getRect;
/**
* Get the 4 bounding points for a node taking iframes into account.
* Note that for transformed nodes, this will return the untransformed bound.
*
* @param {DOMWindow} boundaryWindow
* The window where to stop to iterate. If `null` is given, the top
* window is used.
* @param {DOMNode} node
* @return {Object}
* An object with p1,p2,p3,p4 properties being {x,y} objects
*/
function getNodeBounds(boundaryWindow, node) {
if (!node) {
- return;
+ return null;
}
let scale = getCurrentZoom(node);
// Find out the offset of the node in its current frame
let offsetLeft = 0;
let offsetTop = 0;
let el = node;
@@ -360,102 +360,102 @@ function getNodeBounds(boundaryWindow, n
}
exports.getNodeBounds = getNodeBounds;
/**
* Same as doing iframe.contentWindow but works with all types of container
* elements that act like frames (e.g. <embed>), where 'contentWindow' isn't a
* property that can be accessed.
* This uses the inIDeepTreeWalker instead.
- * @param {DOMNode} aFrame
+ * @param {DOMNode} frame
* @return {Window}
*/
-function safelyGetContentWindow(aFrame) {
- if (aFrame.contentWindow) {
- return aFrame.contentWindow;
+function safelyGetContentWindow(frame) {
+ if (frame.contentWindow) {
+ return frame.contentWindow;
}
let walker = Cc["@mozilla.org/inspector/deep-tree-walker;1"]
.createInstance(Ci.inIDeepTreeWalker);
walker.showSubDocuments = true;
walker.showDocumentsAsNodes = true;
- walker.init(aFrame, Ci.nsIDOMNodeFilter.SHOW_ALL);
- walker.currentNode = aFrame;
+ walker.init(frame, Ci.nsIDOMNodeFilter.SHOW_ALL);
+ walker.currentNode = frame;
let document = walker.nextNode();
if (!document || !document.defaultView) {
- throw new Error("Couldn't get the content window inside aFrame " + aFrame);
+ throw new Error("Couldn't get the content window inside frame " + frame);
}
return document.defaultView;
}
/**
* Returns a frame's content offset (frame border + padding).
* Note: this function shouldn't need to exist, had the platform provided a
* suitable API for determining the offset between the frame's content and
* its bounding client rect. Bug 626359 should provide us with such an API.
*
- * @param {DOMNode} aFrame
+ * @param {DOMNode} frame
* The frame.
* @return {Array} [offsetTop, offsetLeft]
* offsetTop is the distance from the top of the frame and the top of
* the content document.
* offsetLeft is the distance from the left of the frame and the left
* of the content document.
*/
-function getFrameContentOffset(aFrame) {
- let style = safelyGetContentWindow(aFrame).getComputedStyle(aFrame, null);
+function getFrameContentOffset(frame) {
+ let style = safelyGetContentWindow(frame).getComputedStyle(frame, null);
// In some cases, the computed style is null
if (!style) {
return [0, 0];
}
- let paddingTop = parseInt(style.getPropertyValue("padding-top"));
- let paddingLeft = parseInt(style.getPropertyValue("padding-left"));
+ let paddingTop = parseInt(style.getPropertyValue("padding-top"), 10);
+ let paddingLeft = parseInt(style.getPropertyValue("padding-left"), 10);
- let borderTop = parseInt(style.getPropertyValue("border-top-width"));
- let borderLeft = parseInt(style.getPropertyValue("border-left-width"));
+ let borderTop = parseInt(style.getPropertyValue("border-top-width"), 10);
+ let borderLeft = parseInt(style.getPropertyValue("border-left-width"), 10);
return [borderTop + paddingTop, borderLeft + paddingLeft];
}
/**
* Find an element from the given coordinates. This method descends through
* frames to find the element the user clicked inside frames.
*
- * @param {DOMDocument} aDocument
+ * @param {DOMDocument} document
* The document to look into.
- * @param {Number} aX
- * @param {Number} aY
+ * @param {Number} x
+ * @param {Number} y
* @return {DOMNode}
* the element node found at the given coordinates, or null if no node
* was found
*/
-function getElementFromPoint(aDocument, aX, aY) {
- let node = aDocument.elementFromPoint(aX, aY);
+function getElementFromPoint(document, x, y) {
+ let node = document.elementFromPoint(x, y);
if (node && node.contentDocument) {
if (node instanceof Ci.nsIDOMHTMLIFrameElement) {
let rect = node.getBoundingClientRect();
// Gap between the frame and its content window.
let [offsetTop, offsetLeft] = getFrameContentOffset(node);
- aX -= rect.left + offsetLeft;
- aY -= rect.top + offsetTop;
+ x -= rect.left + offsetLeft;
+ y -= rect.top + offsetTop;
- if (aX < 0 || aY < 0) {
+ if (x < 0 || y < 0) {
// Didn't reach the content document, still over the frame.
return node;
}
}
if (node instanceof Ci.nsIDOMHTMLIFrameElement ||
node instanceof Ci.nsIDOMHTMLFrameElement) {
- let subnode = getElementFromPoint(node.contentDocument, aX, aY);
+ let subnode = getElementFromPoint(node.contentDocument, x, y);
if (subnode) {
node = subnode;
}
}
}
return node;
}
exports.getElementFromPoint = getElementFromPoint;
@@ -465,35 +465,37 @@ exports.getElementFromPoint = getElement
*
* @param {DOMNode} elem
* The element that needs to appear in the viewport.
* @param {Boolean} centered
* true if you want it centered, false if you want it to appear on the
* top of the viewport. It is true by default, and that is usually what
* you want.
*/
-function scrollIntoViewIfNeeded(elem, centered=true) {
+function scrollIntoViewIfNeeded(elem, centered = true) {
let win = elem.ownerDocument.defaultView;
let clientRect = elem.getBoundingClientRect();
// The following are always from the {top, bottom}
// of the viewport, to the {top, …} of the box.
// Think of them as geometrical vectors, it helps.
// The origin is at the top left.
let topToBottom = clientRect.bottom;
let bottomToTop = clientRect.top - win.innerHeight;
- let yAllowed = true; // We allow one translation on the y axis.
+ // We allow one translation on the y axis.
+ let yAllowed = true;
// Whatever `centered` is, the behavior is the same if the box is
// (even partially) visible.
if ((topToBottom > 0 || !centered) && topToBottom <= elem.offsetHeight) {
win.scrollBy(0, topToBottom - elem.offsetHeight);
yAllowed = false;
- } else if ((bottomToTop < 0 || !centered) && bottomToTop >= -elem.offsetHeight) {
+ } else if ((bottomToTop < 0 || !centered) &&
+ bottomToTop >= -elem.offsetHeight) {
win.scrollBy(0, bottomToTop + elem.offsetHeight);
yAllowed = false;
}
// If we want it centered, and the box is completely hidden,
// then we center it explicitly.
if (centered) {
if (yAllowed && (topToBottom <= 0 || bottomToTop >= 0)) {
@@ -504,25 +506,27 @@ function scrollIntoViewIfNeeded(elem, ce
}
}
exports.scrollIntoViewIfNeeded = scrollIntoViewIfNeeded;
/**
* Check if a node and its document are still alive
* and attached to the window.
*
- * @param {DOMNode} aNode
+ * @param {DOMNode} node
* @return {Boolean}
*/
-function isNodeConnected(aNode) {
+function isNodeConnected(node) {
+ if (!node.ownerDocument || !node.ownerDocument.defaultView) {
+ return false;
+ }
+
try {
- let connected = (aNode.ownerDocument && aNode.ownerDocument.defaultView &&
- !(aNode.compareDocumentPosition(aNode.ownerDocument.documentElement) &
- aNode.DOCUMENT_POSITION_DISCONNECTED));
- return connected;
+ return !(node.compareDocumentPosition(node.ownerDocument.documentElement) &
+ node.DOCUMENT_POSITION_DISCONNECTED);
} catch (e) {
// "can't access dead object" error
return false;
}
}
exports.isNodeConnected = isNodeConnected;
/**
@@ -650,18 +654,23 @@ exports.isShadowAnonymous = isShadowAnon
* nsIDOMWindowUtils instance to avoid querying it every time.
*
* @param {DOMNode|DOMWindow}
* The node for which the zoom factor should be calculated, or its
* owner window.
* @return {Number}
*/
function getCurrentZoom(node) {
- let win = node instanceof Ci.nsIDOMNode ? node.ownerDocument.defaultView :
- node instanceof Ci.nsIDOMWindow ? node : null;
+ let win = null;
+
+ if (node instanceof Ci.nsIDOMNode) {
+ win = node.ownerDocument.defaultView;
+ } else if (node instanceof Ci.nsIDOMWindow) {
+ win = node;
+ }
if (!win) {
throw new Error("Unable to get the zoom from the given argument.");
}
return utilsFor(win).fullZoom;
}
exports.getCurrentZoom = getCurrentZoom;