mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-07 16:28:38 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
243
devtools/server/actors/highlighters/css-transform.js
Normal file
243
devtools/server/actors/highlighters/css-transform.js
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
/* 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";
|
||||
|
||||
const { extend } = require("sdk/core/heritage");
|
||||
const { AutoRefreshHighlighter } = require("./auto-refresh");
|
||||
const {
|
||||
CanvasFrameAnonymousContentHelper, getComputedStyle,
|
||||
createSVGNode, createNode } = require("./utils/markup");
|
||||
const { setIgnoreLayoutChanges,
|
||||
getNodeBounds } = require("devtools/shared/layout/utils");
|
||||
|
||||
// The minimum distance a line should be before it has an arrow marker-end
|
||||
const ARROW_LINE_MIN_DISTANCE = 10;
|
||||
|
||||
var MARKER_COUNTER = 1;
|
||||
|
||||
/**
|
||||
* The CssTransformHighlighter is the class that draws an outline around a
|
||||
* transformed element and an outline around where it would be if untransformed
|
||||
* as well as arrows connecting the 2 outlines' corners.
|
||||
*/
|
||||
function CssTransformHighlighter(highlighterEnv) {
|
||||
AutoRefreshHighlighter.call(this, highlighterEnv);
|
||||
|
||||
this.markup = new CanvasFrameAnonymousContentHelper(this.highlighterEnv,
|
||||
this._buildMarkup.bind(this));
|
||||
}
|
||||
|
||||
CssTransformHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
|
||||
typeName: "CssTransformHighlighter",
|
||||
|
||||
ID_CLASS_PREFIX: "css-transform-",
|
||||
|
||||
_buildMarkup: function () {
|
||||
let container = createNode(this.win, {
|
||||
attributes: {
|
||||
"class": "highlighter-container"
|
||||
}
|
||||
});
|
||||
|
||||
// The root wrapper is used to unzoom the highlighter when needed.
|
||||
let rootWrapper = createNode(this.win, {
|
||||
parent: container,
|
||||
attributes: {
|
||||
"id": "root",
|
||||
"class": "root"
|
||||
},
|
||||
prefix: this.ID_CLASS_PREFIX
|
||||
});
|
||||
|
||||
let svg = createSVGNode(this.win, {
|
||||
nodeType: "svg",
|
||||
parent: rootWrapper,
|
||||
attributes: {
|
||||
"id": "elements",
|
||||
"hidden": "true",
|
||||
"width": "100%",
|
||||
"height": "100%"
|
||||
},
|
||||
prefix: this.ID_CLASS_PREFIX
|
||||
});
|
||||
|
||||
// Add a marker tag to the svg root for the arrow tip
|
||||
this.markerId = "arrow-marker-" + MARKER_COUNTER;
|
||||
MARKER_COUNTER++;
|
||||
let marker = createSVGNode(this.win, {
|
||||
nodeType: "marker",
|
||||
parent: svg,
|
||||
attributes: {
|
||||
"id": this.markerId,
|
||||
"markerWidth": "10",
|
||||
"markerHeight": "5",
|
||||
"orient": "auto",
|
||||
"markerUnits": "strokeWidth",
|
||||
"refX": "10",
|
||||
"refY": "5",
|
||||
"viewBox": "0 0 10 10"
|
||||
},
|
||||
prefix: this.ID_CLASS_PREFIX
|
||||
});
|
||||
createSVGNode(this.win, {
|
||||
nodeType: "path",
|
||||
parent: marker,
|
||||
attributes: {
|
||||
"d": "M 0 0 L 10 5 L 0 10 z",
|
||||
"fill": "#08C"
|
||||
}
|
||||
});
|
||||
|
||||
let shapesGroup = createSVGNode(this.win, {
|
||||
nodeType: "g",
|
||||
parent: svg
|
||||
});
|
||||
|
||||
// Create the 2 polygons (transformed and untransformed)
|
||||
createSVGNode(this.win, {
|
||||
nodeType: "polygon",
|
||||
parent: shapesGroup,
|
||||
attributes: {
|
||||
"id": "untransformed",
|
||||
"class": "untransformed"
|
||||
},
|
||||
prefix: this.ID_CLASS_PREFIX
|
||||
});
|
||||
createSVGNode(this.win, {
|
||||
nodeType: "polygon",
|
||||
parent: shapesGroup,
|
||||
attributes: {
|
||||
"id": "transformed",
|
||||
"class": "transformed"
|
||||
},
|
||||
prefix: this.ID_CLASS_PREFIX
|
||||
});
|
||||
|
||||
// Create the arrows
|
||||
for (let nb of ["1", "2", "3", "4"]) {
|
||||
createSVGNode(this.win, {
|
||||
nodeType: "line",
|
||||
parent: shapesGroup,
|
||||
attributes: {
|
||||
"id": "line" + nb,
|
||||
"class": "line",
|
||||
"marker-end": "url(#" + this.markerId + ")"
|
||||
},
|
||||
prefix: this.ID_CLASS_PREFIX
|
||||
});
|
||||
}
|
||||
|
||||
return container;
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the nodes. Remove listeners.
|
||||
*/
|
||||
destroy: function () {
|
||||
AutoRefreshHighlighter.prototype.destroy.call(this);
|
||||
this.markup.destroy();
|
||||
},
|
||||
|
||||
getElement: function (id) {
|
||||
return this.markup.getElement(this.ID_CLASS_PREFIX + id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the highlighter on a given node
|
||||
*/
|
||||
_show: function () {
|
||||
if (!this._isTransformed(this.currentNode)) {
|
||||
this.hide();
|
||||
return false;
|
||||
}
|
||||
|
||||
return this._update();
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the supplied node is transformed and not inline
|
||||
*/
|
||||
_isTransformed: function (node) {
|
||||
let style = getComputedStyle(node);
|
||||
return style && (style.transform !== "none" && style.display !== "inline");
|
||||
},
|
||||
|
||||
_setPolygonPoints: function (quad, id) {
|
||||
let points = [];
|
||||
for (let point of ["p1", "p2", "p3", "p4"]) {
|
||||
points.push(quad[point].x + "," + quad[point].y);
|
||||
}
|
||||
this.getElement(id).setAttribute("points", points.join(" "));
|
||||
},
|
||||
|
||||
_setLinePoints: function (p1, p2, id) {
|
||||
let line = this.getElement(id);
|
||||
line.setAttribute("x1", p1.x);
|
||||
line.setAttribute("y1", p1.y);
|
||||
line.setAttribute("x2", p2.x);
|
||||
line.setAttribute("y2", p2.y);
|
||||
|
||||
let dist = Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
|
||||
if (dist < ARROW_LINE_MIN_DISTANCE) {
|
||||
line.removeAttribute("marker-end");
|
||||
} else {
|
||||
line.setAttribute("marker-end", "url(#" + this.markerId + ")");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the highlighter on the current highlighted node (the one that was
|
||||
* passed as an argument to show(node)).
|
||||
* Should be called whenever node size or attributes change
|
||||
*/
|
||||
_update: function () {
|
||||
setIgnoreLayoutChanges(true);
|
||||
|
||||
// Getting the points for the transformed shape
|
||||
let quads = this.currentQuads.border;
|
||||
if (!quads.length ||
|
||||
quads[0].bounds.width <= 0 || quads[0].bounds.height <= 0) {
|
||||
this._hideShapes();
|
||||
return false;
|
||||
}
|
||||
|
||||
let [quad] = quads;
|
||||
|
||||
// Getting the points for the untransformed shape
|
||||
let untransformedQuad = getNodeBounds(this.win, this.currentNode);
|
||||
|
||||
this._setPolygonPoints(quad, "transformed");
|
||||
this._setPolygonPoints(untransformedQuad, "untransformed");
|
||||
for (let nb of ["1", "2", "3", "4"]) {
|
||||
this._setLinePoints(untransformedQuad["p" + nb], quad["p" + nb], "line" + nb);
|
||||
}
|
||||
|
||||
// Adapt to the current zoom
|
||||
this.markup.scaleRootElement(this.currentNode, this.ID_CLASS_PREFIX + "root");
|
||||
|
||||
this._showShapes();
|
||||
|
||||
setIgnoreLayoutChanges(false, this.highlighterEnv.window.document.documentElement);
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide the highlighter, the outline and the infobar.
|
||||
*/
|
||||
_hide: function () {
|
||||
setIgnoreLayoutChanges(true);
|
||||
this._hideShapes();
|
||||
setIgnoreLayoutChanges(false, this.highlighterEnv.window.document.documentElement);
|
||||
},
|
||||
|
||||
_hideShapes: function () {
|
||||
this.getElement("elements").setAttribute("hidden", "true");
|
||||
},
|
||||
|
||||
_showShapes: function () {
|
||||
this.getElement("elements").removeAttribute("hidden");
|
||||
}
|
||||
});
|
||||
exports.CssTransformHighlighter = CssTransformHighlighter;
|
||||
Loading…
Add table
Add a link
Reference in a new issue