Bug 1411645 - Shapes highlighter: resize on one axis in transform mode for polygon and ellipse. r=pbro

MozReview-Commit-ID: 9Td88QCRPQg

--HG--
extra : rebase_source : b5aaa71335964aad5d60a3bd7b623d9ec64341e6
This commit is contained in:
Mike Park 2017-11-01 11:19:13 -04:00
Родитель 0438db5068
Коммит 47961d34b3
4 изменённых файлов: 158 добавлений и 14 удалений

Просмотреть файл

@ -84,6 +84,7 @@ skip-if = os == "mac" # Full keyboard navigation on OSX only works if Full Keybo
[browser_inspector_highlighter-cssshape_04.js]
[browser_inspector_highlighter-cssshape_05.js]
[browser_inspector_highlighter-cssshape_06.js]
[browser_inspector_highlighter-cssshape_07.js]
[browser_inspector_highlighter-cssshape_iframe_01.js]
[browser_inspector_highlighter-csstransform_01.js]
[browser_inspector_highlighter-csstransform_02.js]

Просмотреть файл

@ -0,0 +1,117 @@
/* 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";
// Test that shapes are updated correctly for scaling on one axis in transform mode.
const TEST_URL = URL_ROOT + "doc_inspector_highlighter_cssshapes.html";
const HIGHLIGHTER_TYPE = "ShapesHighlighter";
const SHAPE_IDS = ["#polygon-transform", "#ellipse"];
add_task(function* () {
let inspector = yield openInspectorForURL(TEST_URL);
let helper = yield getHighlighterHelperFor(HIGHLIGHTER_TYPE)(inspector);
let {testActor} = inspector;
yield testOneDimScale(testActor, helper);
helper.finalize();
});
function* testOneDimScale(testActor, helper) {
for (let shape of SHAPE_IDS) {
info(`Displaying ${shape}`);
yield helper.show(shape, {mode: "cssClipPath", transformMode: true});
let { mouse } = helper;
let { top, left, width, height } = yield getBoundingBoxInPx(testActor, helper, shape);
// if the top or left edges are not visible, move the shape so it is.
if (top < 0 || left < 0) {
let x = left + width / 2;
let y = top + height / 2;
let dx = Math.max(0, -left);
let dy = Math.max(0, -top);
yield mouse.down(x, y, shape);
yield mouse.move(x + dx, y + dy, shape);
yield mouse.up(x + dx, y + dy, shape);
yield testActor.reflow();
left += dx;
top += dy;
}
let dx = width / 10;
let dy = height / 10;
info("Scaling from w");
yield mouse.down(left, top + height / 2, shape);
yield mouse.move(left + dx, top + height / 2, shape);
yield mouse.up(left + dx, top + height / 2, shape);
yield testActor.reflow();
let wBB = yield getBoundingBoxInPx(testActor, helper, shape);
is(wBB.top, top, `${shape} top not moved down after w scale`);
isnot(wBB.left, left, `${shape} left moved right after w scale`);
isnot(wBB.width, width, `${shape} width reduced after w scale`);
is(wBB.height, height, `${shape} height not reduced after w scale`);
info("Scaling from e");
yield mouse.down(wBB.left + wBB.width, wBB.top + wBB.height / 2, shape);
yield mouse.move(wBB.left + wBB.width - dx, wBB.top + wBB.height / 2, shape);
yield mouse.up(wBB.left + wBB.width - dx, wBB.top + wBB.height / 2, shape);
yield testActor.reflow();
let eBB = yield getBoundingBoxInPx(testActor, helper, shape);
is(eBB.top, wBB.top, `${shape} top not moved down after e scale`);
is(eBB.left, wBB.left, `${shape} left not moved right after e scale`);
isnot(eBB.width, wBB.width, `${shape} width reduced after e scale`);
is(eBB.height, wBB.height, `${shape} height not reduced after e scale`);
info("Scaling from s");
yield mouse.down(eBB.left + eBB.width / 2, eBB.top + eBB.height, shape);
yield mouse.move(eBB.left + eBB.width / 2, eBB.top + eBB.height - dy, shape);
yield mouse.up(eBB.left + eBB.width / 2, eBB.top + eBB.height - dy, shape);
yield testActor.reflow();
let sBB = yield getBoundingBoxInPx(testActor, helper, shape);
is(sBB.top, eBB.top, `${shape} top not moved down after w scale`);
is(sBB.left, eBB.left, `${shape} left not moved right after w scale`);
is(sBB.width, eBB.width, `${shape} width not reduced after w scale`);
isnot(sBB.height, eBB.height, `${shape} height reduced after w scale`);
info("Scaling from n");
yield mouse.down(sBB.left + sBB.width / 2, sBB.top, shape);
yield mouse.move(sBB.left + sBB.width / 2, sBB.top + dy, shape);
yield mouse.up(sBB.left + sBB.width / 2, sBB.top + dy, shape);
yield testActor.reflow();
let nBB = yield getBoundingBoxInPx(testActor, helper, shape);
isnot(nBB.top, sBB.top, `${shape} top moved down after n scale`);
is(nBB.left, sBB.left, `${shape} left not moved right after n scale`);
is(nBB.width, sBB.width, `${shape} width reduced after n scale`);
isnot(nBB.height, sBB.height, `${shape} height not reduced after n scale`);
}
}
function* getBoundingBoxInPx(testActor, helper, shape = "#polygon") {
let bbTop = parseFloat(yield helper.getElementAttribute("shapes-bounding-box", "y"));
let bbLeft = parseFloat(yield helper.getElementAttribute("shapes-bounding-box", "x"));
let bbWidth = parseFloat(yield helper.getElementAttribute("shapes-bounding-box",
"width"));
let bbHeight = parseFloat(yield helper.getElementAttribute("shapes-bounding-box",
"height"));
let quads = yield testActor.getAllAdjustedQuads(shape);
let { width, height } = quads.content[0].bounds;
let computedStyle = yield helper.highlightedNode.getComputedStyle();
let paddingTop = parseFloat(computedStyle["padding-top"].value);
let paddingLeft = parseFloat(computedStyle["padding-left"].value);
return {
top: paddingTop + height * bbTop / 100,
left: paddingLeft + width * bbLeft / 100,
width: width * bbWidth / 100,
height: height * bbHeight / 100
};
}

Просмотреть файл

@ -526,31 +526,39 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
let { width, height } = this.zoomAdjustedDimensions;
// How much points on each axis should be translated before scaling
let transX = (type === "scale-se" || type === "scale-ne") ?
let transX = (type === "scale-se" || type === "scale-ne" || type === "scale-e") ?
minX / 100 * width : maxX / 100 * width;
let transY = (type === "scale-se" || type === "scale-sw") ?
let transY = (type === "scale-se" || type === "scale-sw" || type === "scale-s") ?
minY / 100 * height : maxY / 100 * height;
let { percentX, percentY } = this.convertPageCoordsToPercent(x, y);
let { percentX: percentPageX,
percentY: percentPageY } = this.convertPageCoordsToPercent(pageX, pageY);
// distance from original click to current mouse position, in %
let distanceX = (type === "scale-se" || type === "scale-ne") ?
let distanceX = (type === "scale-se" || type === "scale-ne" || type === "scale-e") ?
percentPageX - percentX : percentX - percentPageX;
let distanceY = (type === "scale-se" || type === "scale-sw") ?
let distanceY = (type === "scale-se" || type === "scale-sw" || type === "scale-s") ?
percentPageY - percentY : percentY - percentPageY;
// scale = 1 + proportion of distance to bounding box width/height of shape
let scaleX = 1 + distanceX / (maxX - minX);
let scaleY = 1 + distanceY / (maxY - minY);
let scale = (scaleX + scaleY) / 2;
let axis = "xy";
if (type === "scale-e" || type === "scale-w") {
scale = scaleX;
axis = "x";
} else if (type === "scale-n" || type === "scale-s") {
scale = scaleY;
axis = "y";
}
if (this.shapeType === "polygon") {
this._scalePolygon(pageX, pageY, transX, transY, scale);
this._scalePolygon(pageX, pageY, transX, transY, scale, axis);
} else if (this.shapeType === "circle") {
this._scaleCircle(pageX, pageY, transX, transY, scale);
} else if (this.shapeType === "ellipse") {
this._scaleEllipse(pageX, pageY, transX, transY, scale);
this._scaleEllipse(pageX, pageY, transX, transY, scale, axis);
} else if (this.shapeType === "inset") {
this._scaleInset(pageX, pageY, transX, transY, scale);
}
@ -564,15 +572,16 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
* @param {Number} transX the number of pixels to translate on the x axis before scaling
* @param {Number} transY the number of pixels to translate on the y axis before scaling
* @param {Number} scale the proportion to scale by
* @param {String} axis the axis to scale on. "x", "y", or "xy" for both.
*/
_scalePolygon(pageX, pageY, transX, transY, scale) {
_scalePolygon(pageX, pageY, transX, transY, scale, axis) {
let { pointsInfo } = this[_dragging];
let polygonDef = (this.fillRule) ? `${this.fillRule}, ` : "";
polygonDef += pointsInfo.map(point => {
let { unitX, unitY, valueX, valueY, ratioX, ratioY } = point;
let [newX, newY] = scalePoint(valueX, valueY, transX * ratioX,
transY * ratioY, scale);
transY * ratioY, scale, axis);
return `${newX}${unitX} ${newY}${unitY}`;
}).join(", ");
polygonDef = (this.geometryBox) ? `polygon(${polygonDef}) ${this.geometryBox}` :
@ -613,13 +622,14 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
* @param {Number} transX the number of pixels to translate on the x axis before scaling
* @param {Number} transY the number of pixels to translate on the y axis before scaling
* @param {Number} scale the proportion to scale by
* @param {String} axis the axis to scale on. "x", "y", or "xy" for both.
*/
_scaleEllipse(pageX, pageY, transX, transY, scale) {
_scaleEllipse(pageX, pageY, transX, transY, scale, axis) {
let { unitX, unitY, unitRX, unitRY, valueX, valueY,
ratioX, ratioY, ratioRX, ratioRY } = this[_dragging];
let [newCx, newCy] = scalePoint(valueX, valueY, transX * ratioX,
transY * ratioY, scale);
transY * ratioY, scale, axis);
// As part of scaling, the center is translated to be tangent to the lines y=0 & x=0.
// To get the new radii, we scale the new center back to that point and get the
// distances to the line x=0 and y=0.
@ -1082,6 +1092,10 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
{ pointName: "scale-ne", x: maxX, y: minY, cursor: "nesw-resize" },
{ pointName: "scale-sw", x: minX, y: maxY, cursor: "nesw-resize" },
{ pointName: "scale-nw", x: minX, y: minY, cursor: "nwse-resize" },
{ pointName: "scale-n", x: centerX, y: minY, cursor: "ns-resize" },
{ pointName: "scale-s", x: centerX, y: maxY, cursor: "ns-resize" },
{ pointName: "scale-e", x: maxX, y: centerY, cursor: "ew-resize" },
{ pointName: "scale-w", x: minX, y: centerY, cursor: "ew-resize" }
];
for (let { pointName, x, y, cursor } of points) {
@ -1226,7 +1240,7 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
let centerX = (minX + maxX) / 2;
let centerY = (minY + maxY) / 2;
const points = [
let points = [
{ point: "translate", x: centerX, y: centerY },
{ point: "scale-se", x: maxX, y: maxY },
{ point: "scale-ne", x: maxX, y: minY },
@ -1234,6 +1248,13 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
{ point: "scale-nw", x: minX, y: minY },
];
if (this.shapeType === "polygon" || this.shapeType === "ellipse") {
points.push({ point: "scale-n", x: centerX, y: minY },
{ point: "scale-s", x: centerX, y: maxY },
{ point: "scale-e", x: maxX, y: centerY },
{ point: "scale-w", x: minX, y: centerY });
}
for (let { point, x, y } of points) {
if (pageX >= x - clickRadiusX && pageX <= x + clickRadiusX &&
pageY >= y - clickRadiusY && pageY <= y + clickRadiusY) {
@ -1879,6 +1900,10 @@ class ShapesHighlighter extends AutoRefreshHighlighter {
let centerY = (minY + maxY) / 2;
let markerPoints = [[centerX, centerY], [minX, minY],
[maxX, minY], [minX, maxY], [maxX, maxY]];
if (this.shapeType === "polygon" || this.shapeType === "ellipse") {
markerPoints.push([minX, centerY], [maxX, centerY],
[centerX, minY], [centerX, maxY]);
}
this._drawMarkers(markerPoints, width, height, zoom);
if (this.shapeType === "polygon") {

Просмотреть файл

@ -130,11 +130,12 @@ const roundTo = (value, exp) => {
* @param {Number} transX the amount to translate the x coord by
* @param {Number} transY the amount ot translate the y coord by
* @param {Number} scale the scaling factor
* @param {String} axis the axis to scale on. "x", "y", or "xy" for both.
* @returns {Array} of the form [newX, newY], containing the coord pair after scaling.
*/
const scalePoint = (x, y, transX, transY, scale) => {
let newX = (x - transX) * scale + transX;
let newY = (y - transY) * scale + transY;
const scalePoint = (x, y, transX, transY, scale, axis = "xy") => {
let newX = (axis === "y") ? x : (x - transX) * scale + transX;
let newY = (axis === "x") ? y : (y - transY) * scale + transY;
return [newX, newY];
};