Bug 1370278 - used `getTransformToAncestor` in Grid Inspector highlighter; r=pbro
☠☠ backed out by 0d4fe81a5f81 ☠ ☠
authorMatteo Ferretti <mferretti@mozilla.com>
Thu, 08 Jun 2017 19:46:41 +0200
changeset 411248 b61c6809644c0f97872971957842f59736e6851d
parent 411247 df6304204f6a3a2e22d92c47b4ddd48bffd6697a
child 411249 fc905fca340af6f85a9ba95cd024572d6708f7ad
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspbro
bugs1370278
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1370278 - used `getTransformToAncestor` in Grid Inspector highlighter; r=pbro Used the new chrome-only API to obtain the transformation matrix of the current node, relative to the inspected window's root element. That also includes all the transformations from the element's ancestor; plus the method is more robust and we can simplify the current code, removing also some hack. MozReview-Commit-ID: 35rs34RSMYA
devtools/server/actors/highlighters/css-grid.js
devtools/shared/layout/dom-matrix-2d.js
--- a/devtools/server/actors/highlighters/css-grid.js
+++ b/devtools/server/actors/highlighters/css-grid.js
@@ -12,27 +12,26 @@ const {
   createNode,
   createSVGNode,
   moveInfobar,
 } = require("./utils/markup");
 const {
   getCurrentZoom,
   getDisplayPixelRatio,
   setIgnoreLayoutChanges,
-  getNodeBounds,
   getViewportDimensions,
 } = require("devtools/shared/layout/utils");
 const {
   identity,
   apply,
   translate,
   multiply,
   scale,
+  isIdentity,
   getNodeTransformationMatrix,
-  getNodeTransformOrigin
 } = require("devtools/shared/layout/dom-matrix-2d");
 const { stringifyGridFragments } = require("devtools/server/actors/utils/css-grid-utils");
 const { LocalizationHelper } = require("devtools/shared/l10n");
 
 const LAYOUT_STRINGS_URI = "devtools/client/locales/layout.properties";
 const LAYOUT_L10N = new LocalizationHelper(LAYOUT_STRINGS_URI);
 
 const CSS_GRID_ENABLED_PREF = "layout.css.grid.enabled";
@@ -1042,51 +1041,41 @@ CssGridHighlighter.prototype = extend(Au
    *   5. Any CSS transformation applied directly to the element (only 2D
    *      transformation; the 3D transformation are flattened, see `dom-matrix-2d` module
    *      for further details.)
    *
    *  The transformations of the element's ancestors are not currently computed (see
    *  bug 1355675).
    */
   updateCurrentMatrix() {
-    let origin = getNodeTransformOrigin(this.currentNode);
-    let bounds = getNodeBounds(this.win, this.currentNode);
-    let nodeMatrix = getNodeTransformationMatrix(this.currentNode);
     let computedStyle = this.currentNode.ownerGlobal.getComputedStyle(this.currentNode);
 
     let paddingTop = parseFloat(computedStyle.paddingTop);
     let paddingLeft = parseFloat(computedStyle.paddingLeft);
     let borderTop = parseFloat(computedStyle.borderTopWidth);
     let borderLeft = parseFloat(computedStyle.borderLeftWidth);
 
-    // Subtract padding and border values to compensate for top/left being moved by
-    // padding and / or borders.
-    let ox = origin[0] - paddingLeft - borderLeft;
-    let oy = origin[1] - paddingTop - borderTop;
+    let nodeMatrix = getNodeTransformationMatrix(this.currentNode,
+      this.win.document.documentElement);
 
     let m = identity();
 
-    // First, we scale based on the display's current pixel ratio.
-    m = multiply(m, scale(getDisplayPixelRatio(this.win)));
-    // Then we translate the origin to the node's top left corner.
-    m = multiply(m, translate(bounds.p1.x, bounds.p1.y));
-    // And scale based on the current zoom factor.
-    m = multiply(m, scale(getCurrentZoom(this.win)));
-    // Then translate the origin based on the node's padding and border values.
+    // First, we scale based on the device pixel ratio.
+    m = multiply(m, scale(this.win.devicePixelRatio));
+    // Then, we apply the current node's transformation matrix, relative to the
+    // inspected window's root element, but only if it's not a identity matrix.
+    if (isIdentity(nodeMatrix)) {
+      this.hasNodeTransformations = false;
+    } else {
+      m = multiply(m, nodeMatrix);
+      this.hasNodeTransformations = true;
+    }
+
+    // Finally, we translate the origin based on the node's padding and border values.
     m = multiply(m, translate(paddingLeft + borderLeft, paddingTop + borderTop));
-    // Finally, we can apply the current node's transformation matrix, taking in account
-    // the `transform-origin` property and the node's top and left padding.
-    if (nodeMatrix) {
-      m = multiply(m, translate(ox, oy));
-      m = multiply(m, nodeMatrix);
-      m = multiply(m, translate(-ox, -oy));
-      this.hasNodeTransformations = true;
-    } else {
-      this.hasNodeTransformations = false;
-    }
 
     this.currentMatrix = m;
   },
 
   getFirstRowLinePos(fragment) {
     return fragment.rows.lines[0].start;
   },
 
--- a/devtools/shared/layout/dom-matrix-2d.js
+++ b/devtools/shared/layout/dom-matrix-2d.js
@@ -100,58 +100,44 @@ exports.multiply = multiply;
  */
 const apply = (M, P) => [
   M[0] * P[0] + M[1] * P[1] + M[2],
   M[3] * P[0] + M[4] * P[1] + M[5],
 ];
 exports.apply = apply;
 
 /**
- * Returns the transformation origin point for the given node.
+ * Returns `true` if the given matrix is a identity matrix.
  *
- * @param {DOMNode} node
- *        The node.
- * @return {Array}
- *        The transformation origin point.
+ * @param {Array} M
+ *        The matrix to check
+ * @return {Boolean}
+ *        `true` if the matrix passed is a identity matrix, `false` otherwise.
  */
-function getNodeTransformOrigin(node) {
-  let origin = node.ownerGlobal.getComputedStyle(node).transformOrigin;
-
-  return origin.split(/ /).map(parseFloat);
-}
-exports.getNodeTransformOrigin = getNodeTransformOrigin;
+const isIdentity = (M) =>
+  M[0] === 1 && M[1] === 0 && M[2] === 0 &&
+  M[3] === 0 && M[4] === 1 && M[5] === 0 &&
+  M[6] === 0 && M[7] === 0 && M[8] === 1;
+exports.isIdentity = isIdentity;
 
 /**
- * Returns the transformation matrix for the given node.
+ * Returns the transformation matrix for the given node, relative to the ancestor passed
+ * as second argument.
+ * If no ancestor is specified, it will returns the transformation matrix relative to the
+ * node's parent element.
  *
  * @param {DOMNode} node
  *        The node.
- * @return {Array}
+ * @param {DOMNode} ancestor
+ *        The ancestor of the node given.
+ ** @return {Array}
  *        The transformation matrix.
  */
-function getNodeTransformationMatrix(node) {
-  let t = node.ownerGlobal.getComputedStyle(node).transform;
-
-  if (t === "none") {
-    return null;
-  }
-
-  // We're assuming is a 2d matrix.
-  let m = t.substring(t.indexOf("(") + 1, t.length - 1).split(/,\s*/).map(Number);
-  let [a, b, c, d, e, f] = m;
-
-  // If the length is 16, it's a 3d matrix: in that case we'll extrapolate only the values
-  // we need for the 2D transformation; this cover the scenario where 3D CSS properties
-  // are used only for HW acceleration on 2D transformation.
-  if (m.length === 16) {
-    c = m[4];
-    d = m[5];
-    e = m[12];
-    f = m[13];
-  }
+function getNodeTransformationMatrix(node, ancestor = node.parentElement) {
+  let { a, b, c, d, e, f } = node.getTransformToAncestor(ancestor);
 
   return [
     a, c, e,
     b, d, f,
     0, 0, 1
   ];
 }