Backed out changeset b61c6809644c (bug 1370278) for failing chrome test test_dom_matrix_2d.html with 'getNodeTransformOrigin is not a function'. r=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Thu, 08 Jun 2017 20:58:32 +0200
changeset 411254 0d4fe81a5f816b5bf67bca874431a2857b52f247
parent 411253 d20646799abb8ab802873017464461bd1a526804
child 411255 cba06bfa1e8878ff28cb8072f760e6698bb974bc
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)
reviewersbackout
bugs1370278
milestone55.0a1
backs outb61c6809644c0f97872971957842f59736e6851d
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
Backed out changeset b61c6809644c (bug 1370278) for failing chrome test test_dom_matrix_2d.html with 'getNodeTransformOrigin is not a function'. r=backout
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,26 +12,27 @@ 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";
@@ -1041,42 +1042,52 @@ 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);
 
-    let nodeMatrix = getNodeTransformationMatrix(this.currentNode,
-      this.win.document.documentElement);
+    // 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 m = identity();
 
-    // 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;
+    // 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.
+    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 {
-      m = multiply(m, nodeMatrix);
-      this.hasNodeTransformations = true;
+      this.hasNodeTransformations = false;
     }
 
-    // Finally, we translate the origin based on the node's padding and border values.
-    m = multiply(m, translate(paddingLeft + borderLeft, paddingTop + borderTop));
-
     this.currentMatrix = m;
   },
 
   getFirstRowLinePos(fragment) {
     return fragment.rows.lines[0].start;
   },
 
   getLastRowLinePos(fragment) {
--- a/devtools/shared/layout/dom-matrix-2d.js
+++ b/devtools/shared/layout/dom-matrix-2d.js
@@ -100,44 +100,58 @@ 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 `true` if the given matrix is a identity matrix.
+ * Returns the transformation origin point for the given node.
  *
- * @param {Array} M
- *        The matrix to check
- * @return {Boolean}
- *        `true` if the matrix passed is a identity matrix, `false` otherwise.
+ * @param {DOMNode} node
+ *        The node.
+ * @return {Array}
+ *        The transformation origin point.
  */
-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;
+function getNodeTransformOrigin(node) {
+  let origin = node.ownerGlobal.getComputedStyle(node).transformOrigin;
+
+  return origin.split(/ /).map(parseFloat);
+}
+exports.getNodeTransformOrigin = getNodeTransformOrigin;
 
 /**
- * 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.
+ * Returns the transformation matrix for the given node.
  *
  * @param {DOMNode} node
  *        The node.
- * @param {DOMNode} ancestor
- *        The ancestor of the node given.
- ** @return {Array}
+ * @return {Array}
  *        The transformation matrix.
  */
-function getNodeTransformationMatrix(node, ancestor = node.parentElement) {
-  let { a, b, c, d, e, f } = node.getTransformToAncestor(ancestor);
+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];
+  }
 
   return [
     a, c, e,
     b, d, f,
     0, 0, 1
   ];
 }