remove svgtransform polyfill now widely supported
parent
e2d91ea248
commit
0d2c344fee
|
@ -1,14 +1,10 @@
|
|||
import { NS } from '../../../instrumented/common/namespaces.js';
|
||||
import * as transformlist from '../../../instrumented/svgcanvas/svgtransformlist.js';
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
|
||||
import * as hstory from '../../../instrumented/svgcanvas/history.js';
|
||||
|
||||
describe('history', function () {
|
||||
// TODO(codedread): Write tests for handling history events.
|
||||
|
||||
// Mocked out methods.
|
||||
transformlist.changeRemoveElementFromListMap(() => { /* empty fn */ });
|
||||
|
||||
utilities.mock({
|
||||
getHref () { return '#foo'; },
|
||||
setHref () { /* empty fn */ },
|
||||
|
|
|
@ -1,330 +0,0 @@
|
|||
import { NS } from '../../../instrumented/common/namespaces.js';
|
||||
import * as transformlist from '../../../instrumented/svgcanvas/svgtransformlist.js';
|
||||
import { disableSupportsNativeTransformLists } from '../../../instrumented/common/browser.js';
|
||||
|
||||
import almostEqualsPlugin from '../../support/assert-almostEquals.js';
|
||||
import expectOutOfBoundsExceptionPlugin from '../../support/assert-expectOutOfBoundsException.js';
|
||||
|
||||
chai.use(almostEqualsPlugin);
|
||||
chai.use(expectOutOfBoundsExceptionPlugin);
|
||||
|
||||
describe('svgtransformlist', function () {
|
||||
disableSupportsNativeTransformLists();
|
||||
|
||||
let svgroot; let svgcontent; let rect; let circle;
|
||||
|
||||
/**
|
||||
* Set up tests, adding elements.
|
||||
* @returns {void}
|
||||
*/
|
||||
beforeEach(() => {
|
||||
document.body.textContent = '';
|
||||
svgroot = document.createElement('div');
|
||||
svgroot.id = 'svgroot';
|
||||
svgroot.style.visibility = 'hidden';
|
||||
document.body.append(svgroot);
|
||||
|
||||
svgcontent = document.createElementNS(NS.SVG, 'svg');
|
||||
svgroot.append(svgcontent);
|
||||
rect = document.createElementNS(NS.SVG, 'rect');
|
||||
svgcontent.append(rect);
|
||||
rect.id = 'r';
|
||||
circle = document.createElementNS(NS.SVG, 'circle');
|
||||
svgcontent.append(circle);
|
||||
circle.id = 'c';
|
||||
});
|
||||
|
||||
/**
|
||||
* Tear down tests, emptying SVG root, and resetting list map.
|
||||
* @returns {void}
|
||||
*/
|
||||
afterEach(() => {
|
||||
transformlist.resetListMap();
|
||||
while (svgroot.hasChildNodes()) {
|
||||
svgroot.firstChild.remove();
|
||||
}
|
||||
});
|
||||
|
||||
it('Test svgedit.transformlist package', function () {
|
||||
assert.ok(transformlist);
|
||||
assert.ok(transformlist.getTransformList);
|
||||
});
|
||||
|
||||
it('Test svgedit.transformlist.getTransformList() function', function () {
|
||||
const rxform = transformlist.getTransformList(rect);
|
||||
const cxform = transformlist.getTransformList(circle);
|
||||
|
||||
assert.ok(rxform);
|
||||
assert.ok(cxform);
|
||||
assert.equal(typeof rxform, typeof {});
|
||||
assert.equal(typeof cxform, typeof {});
|
||||
});
|
||||
|
||||
it('Test SVGTransformList.numberOfItems property', function () {
|
||||
const rxform = transformlist.getTransformList(rect);
|
||||
|
||||
assert.equal(typeof rxform.numberOfItems, typeof 0);
|
||||
assert.equal(rxform.numberOfItems, 0);
|
||||
});
|
||||
|
||||
it('Test SVGTransformList.initialize()', function () {
|
||||
const rxform = transformlist.getTransformList(rect);
|
||||
const cxform = transformlist.getTransformList(circle);
|
||||
|
||||
const t = svgcontent.createSVGTransform();
|
||||
assert.ok(t);
|
||||
assert.ok(rxform.initialize);
|
||||
assert.equal(typeof rxform.initialize, typeof function () { /* empty fn */ });
|
||||
rxform.initialize(t);
|
||||
assert.equal(rxform.numberOfItems, 1);
|
||||
assert.equal(cxform.numberOfItems, 0);
|
||||
|
||||
// If a transform was already in a transform list, this should
|
||||
// remove it from its old list and add it to this list.
|
||||
cxform.initialize(t);
|
||||
// This also fails in Firefox native.
|
||||
// assert.equal(rxform.numberOfItems, 0, 'Did not remove transform from list before initializing another transformlist');
|
||||
assert.equal(cxform.numberOfItems, 1);
|
||||
});
|
||||
|
||||
it('Test SVGTransformList.appendItem() and getItem()', function () {
|
||||
const rxform = transformlist.getTransformList(rect);
|
||||
const cxform = transformlist.getTransformList(circle);
|
||||
|
||||
const t1 = svgcontent.createSVGTransform();
|
||||
const t2 = svgcontent.createSVGTransform();
|
||||
const t3 = svgcontent.createSVGTransform();
|
||||
|
||||
assert.ok(rxform.appendItem);
|
||||
assert.ok(rxform.getItem);
|
||||
assert.equal(typeof rxform.appendItem, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof rxform.getItem, typeof function () { /* empty fn */ });
|
||||
|
||||
rxform.appendItem(t1);
|
||||
rxform.appendItem(t2);
|
||||
rxform.appendItem(t3);
|
||||
|
||||
assert.equal(rxform.numberOfItems, 3);
|
||||
const rxf = rxform.getItem(0);
|
||||
assert.equal(rxf, t1);
|
||||
assert.equal(rxform.getItem(1), t2);
|
||||
assert.equal(rxform.getItem(2), t3);
|
||||
|
||||
assert.expectOutOfBoundsException(rxform, 'getItem', -1);
|
||||
assert.expectOutOfBoundsException(rxform, 'getItem', 3);
|
||||
cxform.appendItem(t1);
|
||||
// These also fail in Firefox native.
|
||||
// assert.equal(rxform.numberOfItems, 2, 'Did not remove a transform from a list before appending it to a new transformlist');
|
||||
// assert.equal(rxform.getItem(0), t2, 'Found the wrong transform in a transformlist');
|
||||
// assert.equal(rxform.getItem(1), t3, 'Found the wrong transform in a transformlist');
|
||||
|
||||
assert.equal(cxform.numberOfItems, 1);
|
||||
assert.equal(cxform.getItem(0), t1);
|
||||
});
|
||||
|
||||
it('Test SVGTransformList.removeItem()', function () {
|
||||
const rxform = transformlist.getTransformList(rect);
|
||||
|
||||
const t1 = svgcontent.createSVGTransform();
|
||||
const t2 = svgcontent.createSVGTransform();
|
||||
assert.ok(rxform.removeItem);
|
||||
assert.equal(typeof rxform.removeItem, typeof function () { /* empty fn */ });
|
||||
rxform.appendItem(t1);
|
||||
rxform.appendItem(t2);
|
||||
|
||||
const removedTransform = rxform.removeItem(0);
|
||||
assert.equal(rxform.numberOfItems, 1);
|
||||
assert.equal(removedTransform, t1);
|
||||
assert.equal(rxform.getItem(0), t2);
|
||||
|
||||
assert.expectOutOfBoundsException(rxform, 'removeItem', -1);
|
||||
assert.expectOutOfBoundsException(rxform, 'removeItem', 1);
|
||||
});
|
||||
|
||||
it('Test SVGTransformList.replaceItem()', function () {
|
||||
const rxform = transformlist.getTransformList(rect);
|
||||
const cxform = transformlist.getTransformList(circle);
|
||||
|
||||
assert.ok(rxform.replaceItem);
|
||||
assert.equal(typeof rxform.replaceItem, typeof function () { /* empty fn */ });
|
||||
|
||||
const t1 = svgcontent.createSVGTransform();
|
||||
const t2 = svgcontent.createSVGTransform();
|
||||
const t3 = svgcontent.createSVGTransform();
|
||||
|
||||
rxform.appendItem(t1);
|
||||
rxform.appendItem(t2);
|
||||
cxform.appendItem(t3);
|
||||
|
||||
const newItem = rxform.replaceItem(t3, 0);
|
||||
assert.equal(rxform.numberOfItems, 2);
|
||||
assert.equal(newItem, t3);
|
||||
assert.equal(rxform.getItem(0), t3);
|
||||
assert.equal(rxform.getItem(1), t2);
|
||||
// Fails in Firefox native
|
||||
// assert.equal(cxform.numberOfItems, 0);
|
||||
|
||||
// test replaceItem within a list
|
||||
rxform.appendItem(t1);
|
||||
rxform.replaceItem(t1, 0);
|
||||
// Fails in Firefox native
|
||||
// assert.equal(rxform.numberOfItems, 2);
|
||||
assert.equal(rxform.getItem(0), t1);
|
||||
assert.equal(rxform.getItem(1), t2);
|
||||
});
|
||||
|
||||
it('Test SVGTransformList.insertItemBefore()', function () {
|
||||
const rxform = transformlist.getTransformList(rect);
|
||||
const cxform = transformlist.getTransformList(circle);
|
||||
|
||||
assert.ok(rxform.insertItemBefore);
|
||||
assert.equal(typeof rxform.insertItemBefore, typeof function () { /* empty fn */ });
|
||||
|
||||
const t1 = svgcontent.createSVGTransform();
|
||||
const t2 = svgcontent.createSVGTransform();
|
||||
const t3 = svgcontent.createSVGTransform();
|
||||
|
||||
rxform.appendItem(t1);
|
||||
rxform.appendItem(t2);
|
||||
cxform.appendItem(t3);
|
||||
|
||||
const newItem = rxform.insertItemBefore(t3, 0);
|
||||
assert.equal(rxform.numberOfItems, 3);
|
||||
assert.equal(newItem, t3);
|
||||
assert.equal(rxform.getItem(0), t3);
|
||||
assert.equal(rxform.getItem(1), t1);
|
||||
assert.equal(rxform.getItem(2), t2);
|
||||
// Fails in Firefox native
|
||||
// assert.equal(cxform.numberOfItems, 0);
|
||||
|
||||
rxform.insertItemBefore(t2, 1);
|
||||
// Fails in Firefox native (they make copies of the transforms)
|
||||
// assert.equal(rxform.numberOfItems, 3);
|
||||
assert.equal(rxform.getItem(0), t3);
|
||||
assert.equal(rxform.getItem(1), t2);
|
||||
assert.equal(rxform.getItem(2), t1);
|
||||
});
|
||||
|
||||
it('Test SVGTransformList.init() for translate(200,100)', function () {
|
||||
rect.setAttribute('transform', 'translate(200,100)');
|
||||
|
||||
const rxform = transformlist.getTransformList(rect);
|
||||
assert.equal(rxform.numberOfItems, 1);
|
||||
|
||||
const translate = rxform.getItem(0);
|
||||
assert.equal(translate.type, 2);
|
||||
|
||||
const m = translate.matrix;
|
||||
assert.equal(m.a, 1);
|
||||
assert.equal(m.b, 0);
|
||||
assert.equal(m.c, 0);
|
||||
assert.equal(m.d, 1);
|
||||
assert.equal(m.e, 200);
|
||||
assert.equal(m.f, 100);
|
||||
});
|
||||
|
||||
it('Test SVGTransformList.init() for scale(4)', function () {
|
||||
rect.setAttribute('transform', 'scale(4)');
|
||||
|
||||
const rxform = transformlist.getTransformList(rect);
|
||||
assert.equal(rxform.numberOfItems, 1);
|
||||
|
||||
const scale = rxform.getItem(0);
|
||||
assert.equal(scale.type, 3);
|
||||
|
||||
const m = scale.matrix;
|
||||
assert.equal(m.a, 4);
|
||||
assert.equal(m.b, 0);
|
||||
assert.equal(m.c, 0);
|
||||
assert.equal(m.d, 4);
|
||||
assert.equal(m.e, 0);
|
||||
assert.equal(m.f, 0);
|
||||
});
|
||||
|
||||
it('Test SVGTransformList.init() for scale(4,3)', function () {
|
||||
rect.setAttribute('transform', 'scale(4,3)');
|
||||
|
||||
const rxform = transformlist.getTransformList(rect);
|
||||
assert.equal(rxform.numberOfItems, 1);
|
||||
|
||||
const scale = rxform.getItem(0);
|
||||
assert.equal(scale.type, 3);
|
||||
|
||||
const m = scale.matrix;
|
||||
assert.equal(m.a, 4);
|
||||
assert.equal(m.b, 0);
|
||||
assert.equal(m.c, 0);
|
||||
assert.equal(m.d, 3);
|
||||
assert.equal(m.e, 0);
|
||||
assert.equal(m.f, 0);
|
||||
});
|
||||
|
||||
it('Test SVGTransformList.init() for rotate(45)', function () {
|
||||
rect.setAttribute('transform', 'rotate(45)');
|
||||
|
||||
const rxform = transformlist.getTransformList(rect);
|
||||
assert.equal(rxform.numberOfItems, 1);
|
||||
|
||||
const rotate = rxform.getItem(0);
|
||||
assert.equal(rotate.type, 4);
|
||||
assert.equal(rotate.angle, 45);
|
||||
|
||||
const m = rotate.matrix;
|
||||
assert.almostEquals(1 / Math.sqrt(2), m.a);
|
||||
assert.almostEquals(1 / Math.sqrt(2), m.b);
|
||||
assert.almostEquals(-1 / Math.sqrt(2), m.c);
|
||||
assert.almostEquals(1 / Math.sqrt(2), m.d);
|
||||
assert.equal(m.e, 0);
|
||||
assert.equal(m.f, 0);
|
||||
});
|
||||
|
||||
it('Test SVGTransformList.init() for rotate(45, 100, 200)', function () {
|
||||
rect.setAttribute('transform', 'rotate(45, 100, 200)');
|
||||
|
||||
const rxform = transformlist.getTransformList(rect);
|
||||
assert.equal(rxform.numberOfItems, 1);
|
||||
|
||||
const rotate = rxform.getItem(0);
|
||||
assert.equal(rotate.type, 4);
|
||||
assert.equal(rotate.angle, 45);
|
||||
|
||||
const m = rotate.matrix;
|
||||
assert.almostEquals(m.a, 1 / Math.sqrt(2));
|
||||
assert.almostEquals(m.b, 1 / Math.sqrt(2));
|
||||
assert.almostEquals(m.c, -1 / Math.sqrt(2));
|
||||
assert.almostEquals(m.d, 1 / Math.sqrt(2));
|
||||
|
||||
const r = svgcontent.createSVGMatrix();
|
||||
r.a = 1 / Math.sqrt(2); r.b = 1 / Math.sqrt(2);
|
||||
r.c = -1 / Math.sqrt(2); r.d = 1 / Math.sqrt(2);
|
||||
|
||||
const t = svgcontent.createSVGMatrix();
|
||||
t.e = -100; t.f = -200;
|
||||
|
||||
const t_ = svgcontent.createSVGMatrix();
|
||||
t_.e = 100; t_.f = 200;
|
||||
|
||||
const result = t_.multiply(r).multiply(t);
|
||||
|
||||
assert.almostEquals(m.e, result.e);
|
||||
assert.almostEquals(m.f, result.f);
|
||||
});
|
||||
|
||||
it('Test SVGTransformList.init() for matrix(1, 2, 3, 4, 5, 6)', function () {
|
||||
rect.setAttribute('transform', 'matrix(1,2,3,4,5,6)');
|
||||
|
||||
const rxform = transformlist.getTransformList(rect);
|
||||
assert.equal(rxform.numberOfItems, 1);
|
||||
|
||||
const mt = rxform.getItem(0);
|
||||
assert.equal(mt.type, 1);
|
||||
|
||||
const m = mt.matrix;
|
||||
assert.equal(m.a, 1);
|
||||
assert.equal(m.b, 2);
|
||||
assert.equal(m.c, 3);
|
||||
assert.equal(m.d, 4);
|
||||
assert.equal(m.e, 5);
|
||||
assert.equal(m.f, 6);
|
||||
});
|
||||
});
|
|
@ -3,7 +3,6 @@ import 'pathseg';
|
|||
|
||||
import { NS } from '../../../instrumented/common/namespaces.js';
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
|
||||
import * as transformlist from '../../../instrumented/svgcanvas/svgtransformlist.js';
|
||||
import * as math from '../../../instrumented/svgcanvas/math.js';
|
||||
import * as path from '../../../instrumented/svgcanvas/path.js';
|
||||
import setAssertionMethods from '../../support/assert-close.js';
|
||||
|
@ -39,7 +38,7 @@ describe('utilities bbox', function () {
|
|||
const mockPathActions = {
|
||||
resetOrientation (pth) {
|
||||
if (utilities.isNullish(pth) || pth.nodeName !== 'path') { return false; }
|
||||
const tlist = transformlist.getTransformList(pth);
|
||||
const tlist = pth.transform.baseVal;
|
||||
const m = math.transformListToTransform(tlist).matrix;
|
||||
tlist.clear();
|
||||
pth.removeAttribute('transform');
|
||||
|
@ -84,8 +83,6 @@ describe('utilities bbox', function () {
|
|||
});
|
||||
sandbox.append(svgroot);
|
||||
|
||||
// We're reusing ID's so we need to do this for transforms.
|
||||
transformlist.resetListMap();
|
||||
path.init(null);
|
||||
mockaddSVGElementFromJsonCallCount = 0;
|
||||
});
|
||||
|
|
|
@ -3,7 +3,6 @@ import 'pathseg';
|
|||
|
||||
import { NS } from '../../../instrumented/common/namespaces.js';
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
|
||||
import * as transformlist from '../../../instrumented/svgcanvas/svgtransformlist.js';
|
||||
import * as math from '../../../instrumented/svgcanvas/math.js';
|
||||
|
||||
describe('utilities performance', function () {
|
||||
|
@ -118,7 +117,7 @@ describe('utilities performance', function () {
|
|||
const mockPathActions = {
|
||||
resetOrientation (path) {
|
||||
if (utilities.isNullish(path) || path.nodeName !== 'path') { return false; }
|
||||
const tlist = transformlist.getTransformList(path);
|
||||
const tlist = path.transform.baseVal;
|
||||
const m = math.transformListToTransform(tlist).matrix;
|
||||
tlist.clear();
|
||||
path.removeAttribute('transform');
|
||||
|
|
|
@ -11,7 +11,6 @@ import 'pathseg';
|
|||
import { NS } from './namespaces.js';
|
||||
|
||||
const { userAgent } = navigator;
|
||||
const svg = document.createElementNS(NS.SVG, 'svg');
|
||||
|
||||
// Note: Browser sniffing should only be used if no other detection method is possible
|
||||
const isWebkit_ = userAgent.includes('AppleWebKit');
|
||||
|
@ -99,26 +98,6 @@ const supportsNonScalingStroke_ = (function () {
|
|||
return rect.style.vectorEffect === 'non-scaling-stroke';
|
||||
}());
|
||||
|
||||
let supportsNativeSVGTransformLists_ = (function () {
|
||||
const rect = document.createElementNS(NS.SVG, 'rect');
|
||||
const rxform = rect.transform.baseVal;
|
||||
const t1 = svg.createSVGTransform();
|
||||
rxform.appendItem(t1);
|
||||
const r1 = rxform.getItem(0);
|
||||
const isSVGTransform = (o) => {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/SVGTransform
|
||||
return o && typeof o === 'object' && typeof o.setMatrix === 'function' && 'angle' in o;
|
||||
};
|
||||
return isSVGTransform(r1) && isSVGTransform(t1) &&
|
||||
r1.type === t1.type && r1.angle === t1.angle &&
|
||||
r1.matrix.a === t1.matrix.a &&
|
||||
r1.matrix.b === t1.matrix.b &&
|
||||
r1.matrix.c === t1.matrix.c &&
|
||||
r1.matrix.d === t1.matrix.d &&
|
||||
r1.matrix.e === t1.matrix.e &&
|
||||
r1.matrix.f === t1.matrix.f;
|
||||
}());
|
||||
|
||||
// Public API
|
||||
|
||||
/**
|
||||
|
@ -184,17 +163,3 @@ export const supportsGoodTextCharPos = () => supportsGoodTextCharPos_;
|
|||
*/
|
||||
export const supportsNonScalingStroke = () => supportsNonScalingStroke_;
|
||||
|
||||
/**
|
||||
* @function module:browser.supportsNativeTransformLists
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const supportsNativeTransformLists = () => supportsNativeSVGTransformLists_;
|
||||
|
||||
/**
|
||||
* Set `supportsNativeSVGTransformLists_` to `false` (for unit testing).
|
||||
* @function module:browser.disableSupportsNativeTransformLists
|
||||
* @returns {void}
|
||||
*/
|
||||
export const disableSupportsNativeTransformLists = () => {
|
||||
supportsNativeSVGTransformLists_ = false;
|
||||
};
|
||||
|
|
|
@ -456,7 +456,7 @@ export default {
|
|||
if (elem && dataStorage.has(elem, 'c_start')) {
|
||||
// Remove the "translate" transform given to move
|
||||
svgCanvas.removeFromSelection([ elem ]);
|
||||
svgCanvas.getTransformList(elem).clear();
|
||||
elem.transform.baseVal.clear();
|
||||
}
|
||||
}
|
||||
if (connections.length) {
|
||||
|
|
|
@ -94,8 +94,6 @@ export default {
|
|||
|
||||
canv.recalculateDimensions(curShape);
|
||||
|
||||
canv.getTransformList(curShape);
|
||||
|
||||
lastBBox = curShape.getBBox();
|
||||
|
||||
return {
|
||||
|
@ -112,7 +110,7 @@ export default {
|
|||
const x = opts.mouse_x / zoom;
|
||||
const y = opts.mouse_y / zoom;
|
||||
|
||||
const tlist = canv.getTransformList(curShape);
|
||||
const tlist = curShape.transform.baseVal;
|
||||
const box = curShape.getBBox();
|
||||
const left = box.x; const top = box.y;
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import {
|
|||
import {
|
||||
transformPoint, transformListToTransform, matrixMultiply, transformBox
|
||||
} from './math.js';
|
||||
import { getTransformList } from './svgtransformlist.js';
|
||||
|
||||
// this is how we map paths to our preferred relative segment types
|
||||
const pathMap = [
|
||||
|
@ -103,7 +102,7 @@ export const remapElement = function (selected, changes, m) {
|
|||
changes.y = Number.parseFloat(changes.y) + tNew.f;
|
||||
} else {
|
||||
// we just absorb all matrices into the element and don't do any remapping
|
||||
const chlist = getTransformList(selected);
|
||||
const chlist = selected.transform.baseVal;
|
||||
const mt = editorContext_.getSVGRoot().createSVGTransform();
|
||||
mt.setMatrix(matrixMultiply(transformListToTransform(chlist).matrix, m));
|
||||
chlist.clear();
|
||||
|
@ -120,7 +119,7 @@ export const remapElement = function (selected, changes, m) {
|
|||
// Allow images to be inverted (give them matrix when flipped)
|
||||
if (elName === 'image' && (m.a < 0 || m.d < 0)) {
|
||||
// Convert to matrix
|
||||
const chlist = getTransformList(selected);
|
||||
const chlist = selected.transform.baseVal;
|
||||
const mt = editorContext_.getSVGRoot().createSVGTransform();
|
||||
mt.setMatrix(matrixMultiply(transformListToTransform(chlist).matrix, m));
|
||||
chlist.clear();
|
||||
|
|
|
@ -14,9 +14,6 @@ import {
|
|||
import {
|
||||
transformPoint, hasMatrixTransform, getMatrix, snapToAngle
|
||||
} from './math.js';
|
||||
import {
|
||||
getTransformList
|
||||
} from './svgtransformlist.js';
|
||||
import { supportsNonScalingStroke } from '../common/browser.js';
|
||||
import * as draw from './draw.js';
|
||||
import * as pathModule from './path.js';
|
||||
|
@ -144,7 +141,7 @@ export const mouseMoveEvent = function (evt) {
|
|||
// update the dummy transform in our transform list
|
||||
// to be a translate
|
||||
const xform = svgRoot.createSVGTransform();
|
||||
tlist = getTransformList(selected);
|
||||
tlist = selected.transform.baseVal;
|
||||
// Note that if Webkit and there's no ID for this
|
||||
// element, the dummy transform may have gotten lost.
|
||||
// This results in unexpected behaviour
|
||||
|
@ -209,7 +206,7 @@ export const mouseMoveEvent = function (evt) {
|
|||
// we track the resize bounding box and translate/scale the selected element
|
||||
// while the mouse is down, when mouse goes up, we use this to recalculate
|
||||
// the shape's coordinates
|
||||
tlist = getTransformList(selected);
|
||||
tlist = selected.transform.baseVal;
|
||||
const hasMatrix = hasMatrixTransform(tlist);
|
||||
box = hasMatrix ? eventContext_.getInitBbox() : utilsGetBBox(selected);
|
||||
let left = box.x;
|
||||
|
@ -1019,7 +1016,7 @@ export const mouseDownEvent = function (evt) {
|
|||
|
||||
eventContext_.setStartTransform(mouseTarget.getAttribute('transform'));
|
||||
|
||||
const tlist = getTransformList(mouseTarget);
|
||||
const tlist = mouseTarget.transform.baseVal;
|
||||
switch (eventContext_.getCurrentMode()) {
|
||||
case 'select':
|
||||
eventContext_.setStarted(true);
|
||||
|
@ -1046,7 +1043,7 @@ export const mouseDownEvent = function (evt) {
|
|||
// a transform to use for its translate
|
||||
for (const selectedElement of selectedElements()) {
|
||||
if (isNullish(selectedElement)) { continue; }
|
||||
const slist = getTransformList(selectedElement);
|
||||
const slist = selectedElement.transform.baseVal;
|
||||
if (slist.numberOfItems) {
|
||||
slist.insertItemBefore(svgRoot.createSVGTransform(), 0);
|
||||
} else {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
import { getHref, setHref, getRotationAngle, isNullish } from './utilities.js';
|
||||
import { removeElementFromListMap } from './svgtransformlist.js';
|
||||
|
||||
/**
|
||||
* Group: Undo/Redo history management.
|
||||
|
@ -215,6 +214,7 @@ export class InsertElementCommand extends Command {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* History command for an element removed from the DOM.
|
||||
* @implements {module:history.HistoryCommand}
|
||||
|
@ -232,9 +232,6 @@ export class RemoveElementCommand extends Command {
|
|||
this.text = text || ('Delete ' + elem.tagName);
|
||||
this.nextSibling = oldNextSibling;
|
||||
this.parent = oldParent;
|
||||
|
||||
// special hack for webkit: remove this element's entry in the svgTransformLists map
|
||||
removeElementFromListMap(elem);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -245,7 +242,7 @@ export class RemoveElementCommand extends Command {
|
|||
*/
|
||||
apply (handler) {
|
||||
super.apply(handler, () => {
|
||||
removeElementFromListMap(this.elem);
|
||||
this.removeElementFromListMap();
|
||||
this.parent = this.elem.parentNode;
|
||||
this.elem.remove();
|
||||
});
|
||||
|
@ -259,7 +256,6 @@ export class RemoveElementCommand extends Command {
|
|||
*/
|
||||
unapply (handler) {
|
||||
super.unapply(handler, () => {
|
||||
removeElementFromListMap(this.elem);
|
||||
if (isNullish(this.nextSibling) && window.console) {
|
||||
console.error('Reference element was lost');
|
||||
}
|
||||
|
@ -385,8 +381,6 @@ export class ChangeElementCommand extends Command {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Remove transformlist to prevent confusion that causes bugs like 575.
|
||||
removeElementFromListMap(this.elem);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
*/
|
||||
|
||||
import { NS } from '../common/namespaces.js';
|
||||
import { getTransformList } from './svgtransformlist.js';
|
||||
|
||||
// Constants
|
||||
const NEAR_ZERO = 1e-14;
|
||||
|
@ -178,7 +177,7 @@ export const transformListToTransform = function (tlist, min, max) {
|
|||
* @returns {SVGMatrix} The matrix object associated with the element's transformlist
|
||||
*/
|
||||
export const getMatrix = function (elem) {
|
||||
const tlist = getTransformList(elem);
|
||||
const tlist = elem.transform.baseVal;
|
||||
return transformListToTransform(tlist).matrix;
|
||||
};
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
import { NS } from '../common/namespaces.js';
|
||||
import { shortFloat } from '../common/units.js';
|
||||
import { getTransformList } from './svgtransformlist.js';
|
||||
import { ChangeElementCommand, BatchCommand } from './history.js';
|
||||
import {
|
||||
transformPoint, snapToAngle, rectsIntersect,
|
||||
|
@ -879,7 +878,7 @@ export const pathActionsMethod = (function () {
|
|||
*/
|
||||
resetOrientation (pth) {
|
||||
if (isNullish(pth) || pth.nodeName !== 'path') { return false; }
|
||||
const tlist = getTransformList(pth);
|
||||
const tlist = pth.transform.baseVal;
|
||||
const m = transformListToTransform(tlist).matrix;
|
||||
tlist.clear();
|
||||
pth.removeAttribute('transform');
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
* @copyright 2011 Alexis Deveria, 2011 Jeff Schiller
|
||||
*/
|
||||
|
||||
import { getTransformList } from './svgtransformlist.js';
|
||||
import { shortFloat } from '../common/units.js';
|
||||
import { transformPoint } from './math.js';
|
||||
import {
|
||||
|
@ -526,7 +525,7 @@ export const recalcRotatedPath = function () {
|
|||
|
||||
// now we must set the new transform to be rotated around the new center
|
||||
const Rnc = editorContext_.getSVGRoot().createSVGTransform();
|
||||
const tlist = getTransformList(currentPath);
|
||||
const tlist = currentPath.transform.baseVal;
|
||||
Rnc.setRotate((angle * 180.0 / Math.PI), newcx, newcy);
|
||||
tlist.replaceItem(Rnc, 0);
|
||||
};
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
import { NS } from '../common/namespaces.js';
|
||||
import { convertToNum } from '../common/units.js';
|
||||
import { isWebkit } from '../common/browser.js';
|
||||
import { getTransformList } from './svgtransformlist.js';
|
||||
import { getRotationAngle, getHref, getBBox, getRefElem, isNullish } from './utilities.js';
|
||||
import { BatchCommand, ChangeElementCommand } from './history.js';
|
||||
import { remapElement } from './coords.js';
|
||||
|
@ -57,7 +56,7 @@ export const init = function (editorContext) {
|
|||
*/
|
||||
export const updateClipPath = function (attr, tx, ty) {
|
||||
const path = getRefElem(attr).firstChild;
|
||||
const cpXform = getTransformList(path);
|
||||
const cpXform = path.transform.baseVal;
|
||||
const newxlate = context_.getSVGRoot().createSVGTransform();
|
||||
newxlate.setTranslate(tx, ty);
|
||||
|
||||
|
@ -74,17 +73,10 @@ export const updateClipPath = function (attr, tx, ty) {
|
|||
* @returns {Command} Undo command object with the resulting change
|
||||
*/
|
||||
export const recalculateDimensions = function (selected) {
|
||||
if (isNullish(selected)) { return null; }
|
||||
|
||||
// Firefox Issue - 1081
|
||||
if (selected.nodeName === 'svg' && navigator.userAgent.includes('Firefox/20')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!selected) return null;
|
||||
const svgroot = context_.getSVGRoot();
|
||||
const dataStorage = context_.getDataStorage();
|
||||
const tlist = getTransformList(selected);
|
||||
|
||||
const tlist = selected.transform.baseVal;
|
||||
// remove any unnecessary transforms
|
||||
if (tlist && tlist.numberOfItems > 0) {
|
||||
let k = tlist.numberOfItems;
|
||||
|
@ -307,7 +299,7 @@ export const recalculateDimensions = function (selected) {
|
|||
tx = 0;
|
||||
ty = 0;
|
||||
if (child.nodeType === 1) {
|
||||
const childTlist = getTransformList(child);
|
||||
const childTlist = child.transform.baseVal;
|
||||
|
||||
// some children might not have a transform (<metadata>, <defs>, etc)
|
||||
if (!childTlist) { continue; }
|
||||
|
@ -387,7 +379,7 @@ export const recalculateDimensions = function (selected) {
|
|||
// if (href == getHref(useElem)) {
|
||||
// const usexlate = svgroot.createSVGTransform();
|
||||
// usexlate.setTranslate(-tx,-ty);
|
||||
// getTransformList(useElem).insertItemBefore(usexlate,0);
|
||||
// useElem.transform.baseVal.insertItemBefore(usexlate,0);
|
||||
// batchCmd.addSubCommand( recalculateDimensions(useElem) );
|
||||
// }
|
||||
// }
|
||||
|
@ -441,7 +433,7 @@ export const recalculateDimensions = function (selected) {
|
|||
oldStartTransform = context_.getStartTransform();
|
||||
context_.setStartTransform(child.getAttribute('transform'));
|
||||
|
||||
const childTlist = getTransformList(child);
|
||||
const childTlist = child.transform?.baseVal;
|
||||
// some children might not have a transform (<metadata>, <defs>, etc)
|
||||
if (childTlist) {
|
||||
const newxlate = svgroot.createSVGTransform();
|
||||
|
@ -463,7 +455,7 @@ export const recalculateDimensions = function (selected) {
|
|||
if (href === getHref(useElem)) {
|
||||
const usexlate = svgroot.createSVGTransform();
|
||||
usexlate.setTranslate(-tx, -ty);
|
||||
getTransformList(useElem).insertItemBefore(usexlate, 0);
|
||||
useElem.transform.baseVal.insertItemBefore(usexlate, 0);
|
||||
batchCmd.addSubCommand(recalculateDimensions(useElem));
|
||||
}
|
||||
}
|
||||
|
@ -485,7 +477,7 @@ export const recalculateDimensions = function (selected) {
|
|||
if (child.nodeType === 1) {
|
||||
oldStartTransform = context_.getStartTransform();
|
||||
context_.setStartTransform(child.getAttribute('transform'));
|
||||
const childTlist = getTransformList(child);
|
||||
const childTlist = child.transform.baseVal;
|
||||
|
||||
if (!childTlist) { continue; }
|
||||
|
||||
|
@ -566,7 +558,7 @@ export const recalculateDimensions = function (selected) {
|
|||
if (child.nodeType === 1) {
|
||||
oldStartTransform = context_.getStartTransform();
|
||||
context_.setStartTransform(child.getAttribute('transform'));
|
||||
const childTlist = getTransformList(child);
|
||||
const childTlist = child.transform.baseVal;
|
||||
const newxlate = svgroot.createSVGTransform();
|
||||
newxlate.setTranslate(tx, ty);
|
||||
if (childTlist.numberOfItems) {
|
||||
|
@ -649,7 +641,7 @@ export const recalculateDimensions = function (selected) {
|
|||
if (attrVal === 'userSpaceOnUse') {
|
||||
// Update the userSpaceOnUse element
|
||||
m = transformListToTransform(tlist).matrix;
|
||||
const gtlist = getTransformList(paint);
|
||||
const gtlist = paint.transform.baseVal;
|
||||
const gmatrix = transformListToTransform(gtlist).matrix;
|
||||
m = matrixMultiply(m, gmatrix);
|
||||
const mStr = 'matrix(' + [ m.a, m.b, m.c, m.d, m.e, m.f ].join(',') + ')';
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
import { isTouch, isWebkit } from '../common/browser.js'; // , isOpera
|
||||
import { getRotationAngle, getBBox, getStrokedBBox, isNullish } from './utilities.js';
|
||||
import { transformListToTransform, transformBox, transformPoint } from './math.js';
|
||||
import { getTransformList } from './svgtransformlist.js';
|
||||
|
||||
let svgFactory_;
|
||||
let config_;
|
||||
|
@ -124,7 +123,7 @@ export class Selector {
|
|||
}
|
||||
|
||||
// loop and transform our bounding box until we reach our first rotation
|
||||
const tlist = getTransformList(selected);
|
||||
const tlist = selected.transform.baseVal;
|
||||
const m = transformListToTransform(tlist).matrix;
|
||||
|
||||
// This should probably be handled somewhere else, but for now
|
||||
|
|
|
@ -16,9 +16,6 @@ import {
|
|||
import {
|
||||
transformPoint, matrixMultiply, transformListToTransform
|
||||
} from './math.js';
|
||||
import {
|
||||
getTransformList
|
||||
} from './svgtransformlist.js';
|
||||
import {
|
||||
recalculateDimensions
|
||||
} from './recalculate.js';
|
||||
|
@ -171,7 +168,7 @@ export const moveSelectedElements = function (dx, dy, undoable = true) {
|
|||
const selected = selectedElements[i];
|
||||
if (!isNullish(selected)) {
|
||||
const xform = elementContext_.getSVGRoot().createSVGTransform();
|
||||
const tlist = getTransformList(selected);
|
||||
const tlist = selected.transform.baseVal;
|
||||
|
||||
// dx and dy could be arrays
|
||||
if (Array.isArray(dx)) {
|
||||
|
@ -503,7 +500,7 @@ export const pushGroupProperty = function (g, undoable) {
|
|||
const len = children.length;
|
||||
const xform = g.getAttribute('transform');
|
||||
|
||||
const glist = getTransformList(g);
|
||||
const glist = g.transform.baseVal;
|
||||
const m = transformListToTransform(glist).matrix;
|
||||
|
||||
const batchCmd = new BatchCommand('Push group properties');
|
||||
|
@ -576,7 +573,7 @@ export const pushGroupProperty = function (g, undoable) {
|
|||
}
|
||||
}
|
||||
|
||||
let chtlist = getTransformList(elem);
|
||||
let chtlist = elem.transform?.baseVal;
|
||||
|
||||
// Don't process gradient transforms
|
||||
if (elem.tagName.includes('Gradient')) { chtlist = null; }
|
||||
|
@ -717,7 +714,7 @@ export const convertToGroup = function (elem) {
|
|||
}
|
||||
dataStorage.remove(elem, 'gsvg');
|
||||
|
||||
const tlist = getTransformList(elem);
|
||||
const tlist = elem.transform.baseVal;
|
||||
const xform = elementContext_.getSVGRoot().createSVGTransform();
|
||||
xform.setTranslate(pt.x, pt.y);
|
||||
tlist.appendItem(xform);
|
||||
|
|
|
@ -10,9 +10,6 @@ import {
|
|||
isNullish, getBBox as utilsGetBBox, getStrokedBBoxDefaultVisible
|
||||
} from './utilities.js';
|
||||
import { transformPoint, transformListToTransform, rectsIntersect } from './math.js';
|
||||
import {
|
||||
getTransformList
|
||||
} from './svgtransformlist.js';
|
||||
import * as hstry from './history.js';
|
||||
import { getClosest } from '../editor/components/jgraduate/Util.js';
|
||||
|
||||
|
@ -353,7 +350,7 @@ export const setRotationAngle = function (val, preventUndo) {
|
|||
const oldTransform = elem.getAttribute('transform');
|
||||
const bbox = utilsGetBBox(elem);
|
||||
const cx = bbox.x + bbox.width / 2; const cy = bbox.y + bbox.height / 2;
|
||||
const tlist = getTransformList(elem);
|
||||
const tlist = elem.transform.baseVal;
|
||||
|
||||
// only remove the real rotational transform if present (i.e. at index=0)
|
||||
if (tlist.numberOfItems > 0) {
|
||||
|
@ -411,7 +408,6 @@ export const recalculateAllSelectedDimensions = function () {
|
|||
let i = selectedElements().length;
|
||||
while (i--) {
|
||||
const elem = selectedElements()[i];
|
||||
// if (getRotationAngle(elem) && !hasMatrixTransform(getTransformList(elem))) { continue; }
|
||||
const cmd = svgCanvas.recalculateDimensions(elem);
|
||||
if (cmd) {
|
||||
batchCmd.addSubCommand(cmd);
|
||||
|
|
|
@ -17,7 +17,6 @@ import {
|
|||
import {
|
||||
transformPoint, transformListToTransform
|
||||
} from './math.js';
|
||||
import { resetListMap } from './svgtransformlist.js';
|
||||
import {
|
||||
convertUnit, shortFloat, convertToNum
|
||||
} from '../common/units.js';
|
||||
|
@ -491,8 +490,6 @@ export const setSvgString = function (xmlString, preventUndo) {
|
|||
// reset zoom
|
||||
svgContext_.setCurrentZoom(1);
|
||||
|
||||
// reset transform lists
|
||||
resetListMap();
|
||||
svgCanvas.clearSelection();
|
||||
pathModule.clearData();
|
||||
svgContext_.getSVGRoot().append(svgCanvas.selectorManager.selectorParentGroup);
|
||||
|
|
|
@ -87,9 +87,6 @@ import {
|
|||
import {
|
||||
isChrome, isWebkit
|
||||
} from '../common/browser.js'; // , supportsEditableText
|
||||
import {
|
||||
getTransformList, SVGTransformList as SVGEditTransformList
|
||||
} from './svgtransformlist.js';
|
||||
import {
|
||||
remapElement,
|
||||
init as coordsInit
|
||||
|
@ -151,7 +148,6 @@ if (window.opera) {
|
|||
* @borrows module:utilities.getRefElem as #getRefElem
|
||||
* @borrows module:utilities.assignAttributes as #assignAttributes
|
||||
*
|
||||
* @borrows module:SVGTransformList.getTransformList as #getTransformList
|
||||
* @borrows module:math.matrixMultiply as #matrixMultiply
|
||||
* @borrows module:math.hasMatrixTransform as #hasMatrixTransform
|
||||
* @borrows module:math.transformListToTransform as #transformListToTransform
|
||||
|
@ -372,7 +368,6 @@ class SvgCanvas {
|
|||
*/
|
||||
const addSVGElementFromJson = this.addSVGElementFromJson = addSVGElementsFromJson;
|
||||
|
||||
canvas.getTransformList = getTransformList;
|
||||
canvas.matrixMultiply = matrixMultiply;
|
||||
canvas.hasMatrixTransform = hasMatrixTransform;
|
||||
canvas.transformListToTransform = transformListToTransform;
|
||||
|
@ -2756,7 +2751,6 @@ class SvgCanvas {
|
|||
NS,
|
||||
preventClickDefault,
|
||||
RemoveElementCommand,
|
||||
SVGEditTransformList,
|
||||
text2xml,
|
||||
transformBox,
|
||||
transformPoint,
|
||||
|
|
|
@ -1,393 +0,0 @@
|
|||
/**
|
||||
* Partial polyfill of `SVGTransformList`
|
||||
* @module SVGTransformList
|
||||
*
|
||||
* @license MIT
|
||||
*
|
||||
* @copyright 2010 Alexis Deveria, 2010 Jeff Schiller
|
||||
*/
|
||||
|
||||
import { NS } from '../common/namespaces.js';
|
||||
import { supportsNativeTransformLists } from '../common/browser.js';
|
||||
|
||||
const svgroot = document.createElementNS(NS.SVG, 'svg');
|
||||
|
||||
/**
|
||||
* Helper function to convert `SVGTransform` to a string.
|
||||
* @param {SVGTransform} xform
|
||||
* @returns {string}
|
||||
*/
|
||||
function transformToString (xform) {
|
||||
const m = xform.matrix;
|
||||
let text = '';
|
||||
switch (xform.type) {
|
||||
case 1: // MATRIX
|
||||
text = 'matrix(' + [ m.a, m.b, m.c, m.d, m.e, m.f ].join(',') + ')';
|
||||
break;
|
||||
case 2: // TRANSLATE
|
||||
text = 'translate(' + m.e + ',' + m.f + ')';
|
||||
break;
|
||||
case 3: // SCALE
|
||||
text = (m.a === m.d) ? `scale(${m.a})` : `scale(${m.a},${m.d})`;
|
||||
break;
|
||||
case 4: { // ROTATE
|
||||
let cx = 0;
|
||||
let cy = 0;
|
||||
// this prevents divide by zero
|
||||
if (xform.angle !== 0) {
|
||||
const K = 1 - m.a;
|
||||
cy = (K * m.f + m.b * m.e) / (K * K + m.b * m.b);
|
||||
cx = (m.e - m.b * cy) / K;
|
||||
}
|
||||
text = 'rotate(' + xform.angle + ' ' + cx + ',' + cy + ')';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map of SVGTransformList objects.
|
||||
*/
|
||||
let listMap_ = {};
|
||||
|
||||
/**
|
||||
* @interface module:SVGTransformList.SVGEditTransformList
|
||||
* @property {Integer} numberOfItems unsigned long
|
||||
*/
|
||||
/**
|
||||
* @function module:SVGTransformList.SVGEditTransformList#clear
|
||||
* @returns {void}
|
||||
*/
|
||||
/**
|
||||
* @function module:SVGTransformList.SVGEditTransformList#initialize
|
||||
* @param {SVGTransform} newItem
|
||||
* @returns {SVGTransform}
|
||||
*/
|
||||
/**
|
||||
* DOES NOT THROW DOMException, INDEX_SIZE_ERR.
|
||||
* @function module:SVGTransformList.SVGEditTransformList#getItem
|
||||
* @param {Integer} index unsigned long
|
||||
* @returns {SVGTransform}
|
||||
*/
|
||||
/**
|
||||
* DOES NOT THROW DOMException, INDEX_SIZE_ERR.
|
||||
* @function module:SVGTransformList.SVGEditTransformList#insertItemBefore
|
||||
* @param {SVGTransform} newItem
|
||||
* @param {Integer} index unsigned long
|
||||
* @returns {SVGTransform}
|
||||
*/
|
||||
/**
|
||||
* DOES NOT THROW DOMException, INDEX_SIZE_ERR.
|
||||
* @function module:SVGTransformList.SVGEditTransformList#replaceItem
|
||||
* @param {SVGTransform} newItem
|
||||
* @param {Integer} index unsigned long
|
||||
* @returns {SVGTransform}
|
||||
*/
|
||||
/**
|
||||
* DOES NOT THROW DOMException, INDEX_SIZE_ERR.
|
||||
* @function module:SVGTransformList.SVGEditTransformList#removeItem
|
||||
* @param {Integer} index unsigned long
|
||||
* @returns {SVGTransform}
|
||||
*/
|
||||
/**
|
||||
* @function module:SVGTransformList.SVGEditTransformList#appendItem
|
||||
* @param {SVGTransform} newItem
|
||||
* @returns {SVGTransform}
|
||||
*/
|
||||
/**
|
||||
* NOT IMPLEMENTED.
|
||||
* @ignore
|
||||
* @function module:SVGTransformList.SVGEditTransformList#createSVGTransformFromMatrix
|
||||
* @param {SVGMatrix} matrix
|
||||
* @returns {SVGTransform}
|
||||
*/
|
||||
/**
|
||||
* NOT IMPLEMENTED.
|
||||
* @ignore
|
||||
* @function module:SVGTransformList.SVGEditTransformList#consolidate
|
||||
* @returns {SVGTransform}
|
||||
*/
|
||||
|
||||
/**
|
||||
* SVGTransformList implementation for Webkit.
|
||||
* These methods do not currently raise any exceptions.
|
||||
* These methods also do not check that transforms are being inserted. This is basically
|
||||
* implementing as much of SVGTransformList that we need to get the job done.
|
||||
* @implements {module:SVGTransformList.SVGEditTransformList}
|
||||
*/
|
||||
export class SVGTransformList {
|
||||
/**
|
||||
* @param {Element} elem
|
||||
* @returns {SVGTransformList}
|
||||
*/
|
||||
constructor (elem) {
|
||||
this._elem = elem || null;
|
||||
this._xforms = [];
|
||||
// TODO: how do we capture the undo-ability in the changed transform list?
|
||||
this._update = function () {
|
||||
let tstr = '';
|
||||
// /* const concatMatrix = */ svgroot.createSVGMatrix();
|
||||
for (let i = 0; i < this.numberOfItems; ++i) {
|
||||
const xform = this._list.getItem(i);
|
||||
tstr += transformToString(xform) + ' ';
|
||||
}
|
||||
this._elem.setAttribute('transform', tstr);
|
||||
};
|
||||
this._list = this;
|
||||
this._init = function () {
|
||||
// Transform attribute parser
|
||||
let str = this._elem.getAttribute('transform');
|
||||
if (!str) { return; }
|
||||
|
||||
// TODO: Add skew support in future
|
||||
const re = /\s*((scale|matrix|rotate|translate)\s*\(.*?\))\s*,?\s*/;
|
||||
// const re = /\s*(?<xform>(?:scale|matrix|rotate|translate)\s*\(.*?\))\s*,?\s*/;
|
||||
let m = true;
|
||||
while (m) {
|
||||
m = str.match(re);
|
||||
str = str.replace(re, '');
|
||||
if (m && m[1]) {
|
||||
const x = m[1];
|
||||
const bits = x.split(/\s*\(/);
|
||||
const name = bits[0];
|
||||
const valBits = bits[1].match(/\s*(.*?)\s*\)/);
|
||||
valBits[1] = valBits[1].replace(/(\d)-/g, '$1 -');
|
||||
const valArr = valBits[1].split(/[, ]+/);
|
||||
const letters = 'abcdef'.split('');
|
||||
/*
|
||||
if (m && m.groups.xform) {
|
||||
const x = m.groups.xform;
|
||||
const [name, bits] = x.split(/\s*\(/);
|
||||
const valBits = bits.match(/\s*(?<nonWhitespace>.*?)\s*\)/);
|
||||
valBits.groups.nonWhitespace = valBits.groups.nonWhitespace.replace(
|
||||
/(?<digit>\d)-/g, '$<digit> -'
|
||||
);
|
||||
const valArr = valBits.groups.nonWhitespace.split(/[, ]+/);
|
||||
const letters = [...'abcdef'];
|
||||
*/
|
||||
const mtx = svgroot.createSVGMatrix();
|
||||
Object.values(valArr).forEach(function (item, i) {
|
||||
valArr[i] = Number.parseFloat(item);
|
||||
if (name === 'matrix') {
|
||||
mtx[letters[i]] = valArr[i];
|
||||
}
|
||||
});
|
||||
const xform = svgroot.createSVGTransform();
|
||||
const fname = 'set' + name.charAt(0).toUpperCase() + name.slice(1);
|
||||
const values = name === 'matrix' ? [ mtx ] : valArr;
|
||||
|
||||
if (name === 'scale' && values.length === 1) {
|
||||
values.push(values[0]);
|
||||
} else if (name === 'translate' && values.length === 1) {
|
||||
values.push(0);
|
||||
} else if (name === 'rotate' && values.length === 1) {
|
||||
values.push(0, 0);
|
||||
}
|
||||
xform[fname](...values);
|
||||
this._list.appendItem(xform);
|
||||
}
|
||||
}
|
||||
};
|
||||
this._removeFromOtherLists = function (item) {
|
||||
if (item) {
|
||||
// Check if this transform is already in a transformlist, and
|
||||
// remove it if so.
|
||||
Object.values(listMap_).some((tl) => {
|
||||
for (let i = 0, len = tl._xforms.length; i < len; ++i) {
|
||||
if (tl._xforms[i] === item) {
|
||||
tl.removeItem(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.numberOfItems = 0;
|
||||
}
|
||||
/**
|
||||
* @returns {void}
|
||||
*/
|
||||
clear () {
|
||||
this.numberOfItems = 0;
|
||||
this._xforms = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SVGTransform} newItem
|
||||
* @returns {void}
|
||||
*/
|
||||
initialize (newItem) {
|
||||
this.numberOfItems = 1;
|
||||
this._removeFromOtherLists(newItem);
|
||||
this._xforms = [ newItem ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Integer} index unsigned long
|
||||
* @throws {Error}
|
||||
* @returns {SVGTransform}
|
||||
*/
|
||||
getItem (index) {
|
||||
if (index < this.numberOfItems && index >= 0) {
|
||||
return this._xforms[index];
|
||||
}
|
||||
const err = new Error('DOMException with code=INDEX_SIZE_ERR');
|
||||
err.code = 1;
|
||||
throw err;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SVGTransform} newItem
|
||||
* @param {Integer} index unsigned long
|
||||
* @returns {SVGTransform}
|
||||
*/
|
||||
insertItemBefore (newItem, index) {
|
||||
let retValue = null;
|
||||
if (index >= 0) {
|
||||
if (index < this.numberOfItems) {
|
||||
this._removeFromOtherLists(newItem);
|
||||
const newxforms = new Array(this.numberOfItems + 1);
|
||||
// TODO: use array copying and slicing
|
||||
let i;
|
||||
for (i = 0; i < index; ++i) {
|
||||
newxforms[i] = this._xforms[i];
|
||||
}
|
||||
newxforms[i] = newItem;
|
||||
for (let j = i + 1; i < this.numberOfItems; ++j, ++i) {
|
||||
newxforms[j] = this._xforms[i];
|
||||
}
|
||||
this.numberOfItems++;
|
||||
this._xforms = newxforms;
|
||||
retValue = newItem;
|
||||
this._list._update();
|
||||
} else {
|
||||
retValue = this._list.appendItem(newItem);
|
||||
}
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SVGTransform} newItem
|
||||
* @param {Integer} index unsigned long
|
||||
* @returns {SVGTransform}
|
||||
*/
|
||||
replaceItem (newItem, index) {
|
||||
let retValue = null;
|
||||
if (index < this.numberOfItems && index >= 0) {
|
||||
this._removeFromOtherLists(newItem);
|
||||
this._xforms[index] = newItem;
|
||||
retValue = newItem;
|
||||
this._list._update();
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Integer} index unsigned long
|
||||
* @throws {Error}
|
||||
* @returns {SVGTransform}
|
||||
*/
|
||||
removeItem (index) {
|
||||
if (index < this.numberOfItems && index >= 0) {
|
||||
const retValue = this._xforms[index];
|
||||
const newxforms = new Array(this.numberOfItems - 1);
|
||||
let i;
|
||||
for (i = 0; i < index; ++i) {
|
||||
newxforms[i] = this._xforms[i];
|
||||
}
|
||||
for (let j = i; j < this.numberOfItems - 1; ++j, ++i) {
|
||||
newxforms[j] = this._xforms[i + 1];
|
||||
}
|
||||
this.numberOfItems--;
|
||||
this._xforms = newxforms;
|
||||
this._list._update();
|
||||
return retValue;
|
||||
}
|
||||
const err = new Error('DOMException with code=INDEX_SIZE_ERR');
|
||||
err.code = 1;
|
||||
throw err;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SVGTransform} newItem
|
||||
* @returns {SVGTransform}
|
||||
*/
|
||||
appendItem (newItem) {
|
||||
this._removeFromOtherLists(newItem);
|
||||
this._xforms.push(newItem);
|
||||
this.numberOfItems++;
|
||||
this._list._update();
|
||||
return newItem;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function module:SVGTransformList.resetListMap
|
||||
* @returns {void}
|
||||
*/
|
||||
export const resetListMap = function () {
|
||||
listMap_ = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes transforms of the given element from the map.
|
||||
* @function module:SVGTransformList.removeElementFromListMap
|
||||
* @param {Element} elem - a DOM Element
|
||||
* @returns {void}
|
||||
*/
|
||||
export let removeElementFromListMap = function (elem) {
|
||||
if (elem.id && listMap_[elem.id]) {
|
||||
delete listMap_[elem.id];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an object that behaves like a `SVGTransformList` for the given DOM element.
|
||||
* @function module:SVGTransformList.getTransformList
|
||||
* @param {Element} elem - DOM element to get a transformlist from
|
||||
* @todo The polyfill should have `SVGAnimatedTransformList` and this should use it
|
||||
* @returns {SVGAnimatedTransformList|SVGTransformList}
|
||||
*/
|
||||
export const getTransformList = function (elem) {
|
||||
if (!supportsNativeTransformLists()) {
|
||||
const id = elem.id || 'temp';
|
||||
let t = listMap_[id];
|
||||
if (!t || id === 'temp') {
|
||||
listMap_[id] = new SVGTransformList(elem);
|
||||
listMap_[id]._init();
|
||||
t = listMap_[id];
|
||||
}
|
||||
return t;
|
||||
}
|
||||
if (elem.transform) {
|
||||
return elem.transform.baseVal;
|
||||
}
|
||||
if (elem.gradientTransform) {
|
||||
return elem.gradientTransform.baseVal;
|
||||
}
|
||||
if (elem.patternTransform) {
|
||||
return elem.patternTransform.baseVal;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* @callback module:SVGTransformList.removeElementFromListMap
|
||||
* @param {Element} elem
|
||||
* @returns {void}
|
||||
*/
|
||||
/**
|
||||
* Replace `removeElementFromListMap` for unit-testing.
|
||||
* @function module:SVGTransformList.changeRemoveElementFromListMap
|
||||
* @param {module:SVGTransformList.removeElementFromListMap} cb Passed a single argument `elem`
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
export const changeRemoveElementFromListMap = function (cb) {
|
||||
removeElementFromListMap = cb;
|
||||
};
|
|
@ -15,9 +15,6 @@ import {
|
|||
import {
|
||||
transformPoint, transformListToTransform
|
||||
} from './math.js';
|
||||
import {
|
||||
getTransformList
|
||||
} from './svgtransformlist.js';
|
||||
|
||||
const {
|
||||
UndoManager, HistoryEventTypes
|
||||
|
@ -251,7 +248,7 @@ export const changeSelectedAttributeNoUndoMethod = function (attr, newValue, ele
|
|||
// we need to update the rotational transform attribute
|
||||
const angle = getRotationAngle(elem);
|
||||
if (angle !== 0 && attr !== 'transform') {
|
||||
const tlist = getTransformList(elem);
|
||||
const tlist = elem.transform.baseVal;
|
||||
let n = tlist.numberOfItems;
|
||||
while (n--) {
|
||||
const xform = tlist.getItem(n);
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
import { NS } from '../common/namespaces.js';
|
||||
import { getTransformList } from './svgtransformlist.js';
|
||||
import { setUnitAttr, getTypeMap } from '../common/units.js';
|
||||
import {
|
||||
hasMatrixTransform, transformListToTransform, transformBox
|
||||
|
@ -907,7 +906,7 @@ export const convertToPath = function (
|
|||
|
||||
// Reorient if it has a matrix
|
||||
if (eltrans) {
|
||||
const tlist = getTransformList(path);
|
||||
const tlist = path.transform.baseVal;
|
||||
if (hasMatrixTransform(tlist)) {
|
||||
pathActions.resetOrientation(path);
|
||||
}
|
||||
|
@ -978,7 +977,7 @@ export const getBBoxWithTransform = function (elem, addSVGElementFromJson, pathA
|
|||
return null;
|
||||
}
|
||||
|
||||
const tlist = getTransformList(elem);
|
||||
const tlist = elem.transform.baseVal;
|
||||
const angle = getRotationAngleFromTransformList(tlist);
|
||||
const hasMatrixXForm = hasMatrixTransform(tlist);
|
||||
|
||||
|
@ -1170,7 +1169,7 @@ export const getRotationAngleFromTransformList = function (tlist, toRad) {
|
|||
export let getRotationAngle = function (elem, toRad) {
|
||||
const selected = elem || editorContext_.getSelectedElements()[0];
|
||||
// find the rotation transform (if any) and set it
|
||||
const tlist = getTransformList(selected);
|
||||
const tlist = selected.transform.baseVal;
|
||||
return getRotationAngleFromTransformList(tlist, toRad);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue