diff --git a/src/svgcanvas/path-actions.js b/src/svgcanvas/path-actions.js index 39e40878..db99df0e 100644 --- a/src/svgcanvas/path-actions.js +++ b/src/svgcanvas/path-actions.js @@ -17,9 +17,6 @@ import { assignAttributes, getElem, getRotationAngle, snapToGrid, isNullish, getBBox as utilsGetBBox } from './utilities.js'; -import { - isWebkit -} from '../common/browser.js'; let pathActionsContext_ = null; let editorContext_ = null; @@ -61,22 +58,24 @@ export const convertPath = function (pth, toRel) { let x2 = seg.x2 || 0; let y2 = seg.y2 || 0; - const type = seg.pathSegType; - const pathMap = pathActionsContext_.getPathMap(); - let letter = pathMap[type][toRel ? 'toLowerCase' : 'toUpperCase'](); + // const type = seg.pathSegType; + // const pathMap = pathActionsContext_.getPathMap(); + // let letter = pathMap[type][toRel ? 'toLowerCase' : 'toUpperCase'](); + let letter = seg.pathSegTypeAsLetter; - switch (type) { - case 1: // z,Z closepath (Z/z) + switch (letter) { + case 'z': // z,Z closepath (Z/z) + case 'Z': d += 'z'; if (lastM && !toRel) { curx = lastM[0]; cury = lastM[1]; } break; - case 12: // absolute horizontal line (H) + case 'H': // absolute horizontal line (H) x -= curx; // Fallthrough - case 13: // relative horizontal line (h) + case 'h': // relative horizontal line (h) if (toRel) { y = 0; curx += x; @@ -90,10 +89,10 @@ export const convertPath = function (pth, toRel) { // Convert to "line" for easier editing d += pathDSegment(letter, [ [ x, y ] ]); break; - case 14: // absolute vertical line (V) + case 'V': // absolute vertical line (V) y -= cury; // Fallthrough - case 15: // relative vertical line (v) + case 'v': // relative vertical line (v) if (toRel) { x = 0; cury += y; @@ -107,71 +106,81 @@ export const convertPath = function (pth, toRel) { // Convert to "line" for easier editing d += pathDSegment(letter, [ [ x, y ] ]); break; - case 2: // absolute move (M) - case 4: // absolute line (L) - case 18: // absolute smooth quad (T) - case 10: // absolute elliptical arc (A) + case 'M': // absolute move (M) + case 'L': // absolute line (L) + case 'T': // absolute smooth quad (T) x -= curx; y -= cury; // Fallthrough - case 5: // relative line (l) - case 3: // relative move (m) - case 19: // relative smooth quad (t) + case 'l': // relative line (l) + case 'm': // relative move (m) + case 't': // relative smooth quad (t) if (toRel) { curx += x; cury += y; + letter = letter.toLowerCase(); } else { x += curx; y += cury; curx = x; cury = y; + letter = letter.toUpperCase(); } - if (type === 2 || type === 3) { lastM = [ curx, cury ]; } + if (letter === 'm' || letter === 'M') { lastM = [ curx, cury ]; } d += pathDSegment(letter, [ [ x, y ] ]); break; - case 6: // absolute cubic (C) + case 'C': // absolute cubic (C) x -= curx; x1 -= curx; x2 -= curx; y -= cury; y1 -= cury; y2 -= cury; // Fallthrough - case 7: // relative cubic (c) + case 'c': // relative cubic (c) if (toRel) { curx += x; cury += y; + letter = 'c'; } else { x += curx; x1 += curx; x2 += curx; y += cury; y1 += cury; y2 += cury; curx = x; cury = y; + letter = 'C'; } d += pathDSegment(letter, [ [ x1, y1 ], [ x2, y2 ], [ x, y ] ]); break; - case 8: // absolute quad (Q) + case 'Q': // absolute quad (Q) x -= curx; x1 -= curx; y -= cury; y1 -= cury; // Fallthrough - case 9: // relative quad (q) + case 'q': // relative quad (q) if (toRel) { curx += x; cury += y; + letter = 'q'; } else { x += curx; x1 += curx; y += cury; y1 += cury; curx = x; cury = y; + letter = 'Q'; } d += pathDSegment(letter, [ [ x1, y1 ], [ x, y ] ]); break; - // Fallthrough - case 11: // relative elliptical arc (a) + case 'A': + x -= curx; + y -= cury; + // fallthrough + case 'a': // relative elliptical arc (a) if (toRel) { curx += x; cury += y; + letter = 'a'; } else { x += curx; y += cury; curx = x; cury = y; + letter = 'A'; } d += pathDSegment(letter, [ [ seg.r1, seg.r2 ] ], [ seg.angle, @@ -179,19 +188,21 @@ export const convertPath = function (pth, toRel) { (seg.sweepFlag ? 1 : 0) ], [ x, y ]); break; - case 16: // absolute smooth cubic (S) + case 'S': // absolute smooth cubic (S) x -= curx; x2 -= curx; y -= cury; y2 -= cury; // Fallthrough - case 17: // relative smooth cubic (s) + case 's': // relative smooth cubic (s) if (toRel) { curx += x; cury += y; + letter = 's'; } else { x += curx; x2 += curx; y += cury; y2 += cury; curx = x; cury = y; + letter = 'S'; } d += pathDSegment(letter, [ [ x2, y2 ], [ x, y ] ]); break; @@ -1027,8 +1038,8 @@ export const pathActionsMethod = (function () { list.appendItem(newseg); list.appendItem(closer); } else { - pathActionsContext_.insertItemBefore(elem, closer, openPt); - pathActionsContext_.insertItemBefore(elem, newseg, openPt); + list.insertItemBefore(closer, openPt); + list.insertItemBefore(newseg, openPt); } path.init().selectPt(openPt + 1); @@ -1074,7 +1085,7 @@ export const pathActionsMethod = (function () { let num = (index - lastM) - 1; while (num--) { - pathActionsContext_.insertItemBefore(elem, list.getItem(lastM), zSeg); + list.insertItemBefore(list.getItem(lastM), zSeg); } const pt = list.getItem(lastM); @@ -1213,24 +1224,22 @@ export const pathActionsMethod = (function () { let lastM; for (let i = 0; i < len; ++i) { const item = segList.getItem(i); - if (item.pathSegType === 2) { + if (item.pathSegType === 2) { // 2 => M segment type (move to) lastM = item; } - if (item.pathSegType === 1) { + if (item.pathSegType === 1) { // 1 => Z segment type (close path) const prev = segList.getItem(i - 1); if (prev.x !== lastM.x || prev.y !== lastM.y) { // Add an L segment here const newseg = elem.createSVGPathSegLinetoAbs(lastM.x, lastM.y); - pathActionsContext_.insertItemBefore(elem, newseg, i); + segList.insertItemBefore(newseg, i); // Can this be done better? pathActionsMethod.fixEnd(elem); break; } } } - editorContext_ = pathActionsContext_.getEditorContext(); - if (isWebkit()) { editorContext_.resetD(elem); } }, // Can't seem to use `@borrows` here, so using `@see` /** diff --git a/src/svgcanvas/path-method.js b/src/svgcanvas/path-method.js index 1c5c439c..17767a8c 100644 --- a/src/svgcanvas/path-method.js +++ b/src/svgcanvas/path-method.js @@ -15,9 +15,6 @@ import { assignAttributes, getRotationAngle, isNullish, getElem } from './utilities.js'; -import { - supportsPathInsertItemBefore, supportsPathReplaceItem, isWebkit -} from '../common/browser.js'; let pathMethodsContext_ = null; let editorContext_ = null; @@ -31,35 +28,6 @@ export const init = function (pathMethodsContext) { pathMethodsContext_ = pathMethodsContext; }; -/** -* @function module:path.insertItemBefore -* @param {Element} elem -* @param {Segment} newseg -* @param {Integer} index -* @returns {void} -*/ -export const insertItemBeforeMethod = function (elem, newseg, index) { - // Support insertItemBefore on paths for FF2 - const list = elem.pathSegList; - - if (supportsPathInsertItemBefore()) { - list.insertItemBefore(newseg, index); - return; - } - const len = list.numberOfItems; - const arr = []; - for (let i = 0; i < len; i++) { - const curSeg = list.getItem(i); - arr.push(curSeg); - } - list.clear(); - for (let i = 0; i < len; i++) { - if (i === index) { // index + 1 - list.appendItem(newseg); - } - list.appendItem(arr[i]); - } -}; /* eslint-disable max-len */ /** * @function module:path.ptObjToArr @@ -324,25 +292,7 @@ export const replacePathSegMethod = function (type, index, pts, elem) { const func = 'createSVGPathSeg' + pathFuncs[type]; const seg = pth[func](...pts); - if (supportsPathReplaceItem()) { - pth.pathSegList.replaceItem(seg, index); - } else { - const segList = pth.pathSegList; - const len = segList.numberOfItems; - const arr = []; - for (let i = 0; i < len; i++) { - const curSeg = segList.getItem(i); - arr.push(curSeg); - } - segList.clear(); - for (let i = 0; i < len; i++) { - if (i === index) { - segList.appendItem(seg); - } else { - segList.appendItem(arr[i]); - } - } - } + pth.pathSegList.replaceItem(seg, index); }; /** * @function module:path.getSegSelector @@ -775,8 +725,8 @@ export class Path { break; } } - - insertItemBeforeMethod(this.elem, newseg, index); + const list = this.elem.pathSegList; + list.insertItemBefore(newseg, index); } /** @@ -1005,7 +955,6 @@ export class Path { * @returns {void} */ endChanges (text) { - if (isWebkit()) { editorContext_.resetD(this.elem); } const cmd = new ChangeElementCommand(this.elem, { d: this.last_d }, text); editorContext_.endChanges({ cmd, elem: this.elem }); } diff --git a/src/svgcanvas/path.js b/src/svgcanvas/path.js index f5399591..3f2bb1f9 100644 --- a/src/svgcanvas/path.js +++ b/src/svgcanvas/path.js @@ -14,7 +14,7 @@ import { getBBox as utilsGetBBox } from './utilities.js'; import { - init as pathMethodInit, insertItemBeforeMethod, ptObjToArrMethod, getGripPtMethod, + init as pathMethodInit, ptObjToArrMethod, getGripPtMethod, getPointFromGripMethod, addPointGripMethod, getGripContainerMethod, addCtrlGripMethod, getCtrlLineMethod, getPointGripMethod, getControlPointsMethod, replacePathSegMethod, getSegSelectorMethod, Path @@ -103,11 +103,6 @@ let editorContext_ = null; * If the event is "changed", an array of `Element`s is passed; if "selected", a single-item array of `Element` is passed. * @returns {void} */ -/** - * @function module:path.EditorContext#resetD - * @param {SVGPathElement} p - * @returns {void} -*/ /** * Note: This doesn't round to an integer necessarily. * @function module:path.EditorContext#round @@ -263,14 +258,6 @@ pathMethodInit( } ); -/** -* @function module:path.insertItemBefore -* @param {Element} elem -* @param {Segment} newseg -* @param {Integer} index -* @returns {void} -*/ -export const insertItemBefore = insertItemBeforeMethod; /* eslint-disable max-len */ /** * @function module:path.ptObjToArr @@ -801,7 +788,6 @@ pathActionsInit( addCtrlGrip, getCtrlLine, replacePathSeg, - insertItemBefore, getPointFromGrip, getGripPt, getPath_, diff --git a/src/svgcanvas/selection.js b/src/svgcanvas/selection.js index 40e71bf6..4fcde8b0 100644 --- a/src/svgcanvas/selection.js +++ b/src/svgcanvas/selection.js @@ -324,12 +324,14 @@ export const groupSvgElem = function (elem) { * @returns {void} */ export const prepareSvg = function (newDoc) { + svgCanvas.sanitizeSvg(newDoc.documentElement); // convert paths into absolute commands const paths = [ ...newDoc.getElementsByTagNameNS(NS.SVG, 'path') ]; paths.forEach((path) => { - path.setAttribute('d', svgCanvas.pathActions.convertPath(path)); + const convertedPath = svgCanvas.pathActions.convertPath(path); + path.setAttribute('d', convertedPath); svgCanvas.pathActions.fixEnd(path); }); }; diff --git a/src/svgcanvas/svgcanvas.js b/src/svgcanvas/svgcanvas.js index 5549a060..9ee3140e 100644 --- a/src/svgcanvas/svgcanvas.js +++ b/src/svgcanvas/svgcanvas.js @@ -9,7 +9,7 @@ */ import { Canvg as canvg } from 'canvg'; -import 'pathseg'; +import 'pathseg'; // SVGPathSeg Polyfill (see https://github.com/progers/pathseg) import * as pathModule from './path.js'; import * as hstry from './history.js'; @@ -668,16 +668,6 @@ class SvgCanvas { * @see module:path.pathActions */ canvas.pathActions = pathActions; - /** -* @type {module:path.EditorContext#resetD} -*/ - function resetD(p) { - if (typeof pathActions.convertPath === 'function') { - p.setAttribute('d', pathActions.convertPath(p)); - } else if (typeof pathActions.convertPaths === 'function') { - p.setAttribute('d', pathActions.convertPaths(p)); - } - } pathModule.init( /** * @implements {module:path.EditorContext} @@ -686,7 +676,6 @@ class SvgCanvas { selectorManager, // Ok since not changing canvas, // Ok since not changing call, - resetD, round, clearSelection, addToSelection,