Merge pull request #646 from SVG-Edit/fix-path

Fix path
master
JFH 2021-09-20 09:50:52 +02:00 committed by GitHub
commit 31ce3f3c6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 69 additions and 297 deletions

View File

@ -67,7 +67,7 @@ exports[`use all parts of svg-edit > check tool_path_change_node_xy #0`] = `
fill="#FF0000"
stroke="#000000"
stroke-width="5"
d="M75,75L150,100L125,200L75,75z"
d="M 75 75 L 150 100 L 125 200 L 75 75 z"
id="svg_1"
fill-opacity="1"
stroke-opacity="1"
@ -94,7 +94,7 @@ exports[`use all parts of svg-edit > check tool_path_change_seg_type #0`] = `
fill="#FF0000"
stroke="#000000"
stroke-width="5"
d="M75,75L150,100L125,200C235.33333,330.33333 91.66667,116.66667 75,75z"
d="M 75 75 L 150 100 L 125 200 C 235.33333333333331 330.33333333333337 91.66666666666667 116.66666666666666 75 75 z"
id="svg_1"
fill-opacity="1"
stroke-opacity="1"
@ -121,7 +121,7 @@ exports[`use all parts of svg-edit > check tool_path_change_clone_node #0`] = `
fill="#FF0000"
stroke="#000000"
stroke-width="5"
d="M201,246L150,100L125,200C180.16666,265.16666 297.83333,415.33333 273.625,373C249.41667,330.66667 209.33334,266.83334 201,246z"
d="M 201 246 L 150 100 L 125 200 C 180.16666666666666 265.1666666666667 297.8333333333333 415.33333333333337 273.625 373 C 249.41666666666669 330.66666666666663 209.33333333333334 266.8333333333333 201 246 z"
id="svg_1"
fill-opacity="1"
stroke-opacity="1"
@ -148,7 +148,7 @@ exports[`use all parts of svg-edit > check tool_path_openclose #0`] = `
fill="#FF0000"
stroke="#000000"
stroke-width="5"
d="M201,246L150,100L125,200C180.16666,265.16666 297.83333,415.33333 273.625,373C249.41667,330.66667 209.33334,266.83334 201,246z"
d="M 201 246 L 150 100 L 125 200 C 180.16666666666666 265.1666666666667 297.8333333333333 415.33333333333337 273.625 373 C 249.41666666666669 330.66666666666663 209.33333333333334 266.8333333333333 201 246 z"
id="svg_1"
fill-opacity="1"
stroke-opacity="1"

View File

@ -1,3 +1,4 @@
import 'pathseg';
import { NS } from '../../../instrumented/common/namespaces.js';
import * as draw from '../../../instrumented/svgcanvas/draw.js';
import * as units from '../../../instrumented/common/units.js';

View File

@ -1,5 +1,4 @@
/* eslint-disable max-len */
import * as browser from '../../../instrumented/common/browser.js';
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
import { NS } from '../../../instrumented/common/namespaces.js';
@ -161,19 +160,6 @@ describe('utilities', function () {
assert.equal(utilities.getUrlFromAttr('url("#foo")'), '#foo');
});
it('Test getPathBBox', function () {
if (browser.supportsPathBBox()) {
return;
}
const doc = utilities.text2xml('<svg></svg>');
const path = doc.createElementNS(NS.SVG, 'path');
path.setAttribute('d', 'm0,0l5,0l0,5l-5,0l0,-5z');
const bb = utilities.getPathBBox(path);
assert.equal(typeof bb, 'object', 'BBox returned object');
assert.ok(bb.x && !isNaN(bb.x));
assert.ok(bb.y && !isNaN(bb.y));
});
it('Test getPathDFromSegments', function () {
const { getPathDFromSegments } = utilities;
@ -226,7 +212,6 @@ describe('utilities', function () {
});
svgroot.append(elem);
const closeEnough = /M0,4 C0,2.3\d* 0.9\d*,1 2,1 L8,1 C9.0\d*,1 10,2.3\d* 10,4 L10,9 C10,10.6\d* 9.0\d*,12 8,12 L2,12 C0.9\d*,12 0,10.6\d* 0,9 L0,4 Z/;
console.log(getPathDFromElement(elem), closeEnough);
assert.equal(closeEnough.test(getPathDFromElement(elem)), true);
elem.remove();

View File

@ -6,8 +6,6 @@
* @copyright 2010 Jeff Schiller, 2010 Alexis Deveria
*/
import 'pathseg';
import { NS } from './namespaces.js';
const { userAgent } = navigator;
@ -19,31 +17,6 @@ const isChrome_ = userAgent.includes('Chrome/');
const isMac_ = userAgent.includes('Macintosh');
const isTouch_ = 'ontouchstart' in window;
// segList functions (for FF1.5 and 2.0)
const supportsPathReplaceItem_ = (function () {
const path = document.createElementNS(NS.SVG, 'path');
path.setAttribute('d', 'M0,0 10,10');
const seglist = path.pathSegList;
const seg = path.createSVGPathSegLinetoAbs(5, 5);
try {
seglist.replaceItem(seg, 1);
return true;
}catch (err) {/* empty */}
return false;
}());
const supportsPathInsertItemBefore_ = (function () {
const path = document.createElementNS(NS.SVG, 'path');
path.setAttribute('d', 'M0,0 10,10');
const seglist = path.pathSegList;
const seg = path.createSVGPathSegLinetoAbs(5, 5);
try {
seglist.insertItemBefore(seg, 1);
return true;
}catch (err) {/* empty */}
return false;
}());
// text character positioning (for IE9 and now Chrome)
const supportsGoodTextCharPos_ = (function () {
const svgroot = document.createElementNS(NS.SVG, 'svg');
@ -64,17 +37,6 @@ const supportsGoodTextCharPos_ = (function () {
}
}());
const supportsPathBBox_ = (function () {
const svgcontent = document.createElementNS(NS.SVG, 'svg');
document.documentElement.append(svgcontent);
const path = document.createElementNS(NS.SVG, 'path');
path.setAttribute('d', 'M0,0 C0,0 10,10 10,0');
svgcontent.append(path);
const bbox = path.getBBox();
svgcontent.remove();
return (bbox.height > 4 && bbox.height < 5);
}());
// Support for correct bbox sizing on groups with horizontal/vertical lines
const supportsHVLineContainerBBox_ = (function () {
const svgcontent = document.createElementNS(NS.SVG, 'svg');
@ -127,24 +89,6 @@ export const isMac = () => isMac_;
*/
export const isTouch = () => isTouch_;
/**
* @function module:browser.supportsPathReplaceItem
* @returns {boolean}
*/
export const supportsPathReplaceItem = () => supportsPathReplaceItem_;
/**
* @function module:browser.supportsPathInsertItemBefore
* @returns {boolean}
*/
export const supportsPathInsertItemBefore = () => supportsPathInsertItemBefore_;
/**
* @function module:browser.supportsPathBBox
* @returns {boolean}
*/
export const supportsPathBBox = () => supportsPathBBox_;
/**
* @function module:browser.supportsHVLineContainerBBox
* @returns {boolean}

View File

@ -365,7 +365,8 @@ class Editor extends EditorStartup {
const { workarea } = this;
const cnvs = $id("svgcanvas");
let w = parseFloat(getComputedStyle(workarea, null).width.replace("px", "")); let h = parseFloat(getComputedStyle(workarea, null).height.replace("px", ""));
let w = parseFloat(getComputedStyle(workarea, null).width.replace("px", ""));
let h = parseFloat(getComputedStyle(workarea, null).height.replace("px", ""));
const wOrig = w; const hOrig = h;
const oldCtr = {
x: workarea.scrollLeft + wOrig / 2,

View File

@ -48,8 +48,7 @@ Array.prototype.forEach.call(atags, function (aEle) {
post({ href, data });
return data;
})
// eslint-disable-next-line no-console
.catch( (error) => console.log(error));
.catch( (error) => console.error(error));
}
return false;
});

View File

@ -82,14 +82,6 @@ export default {
}
});
/*
// Make sure shape uses absolute values
if ((/[a-z]/).test(currentD)) {
currentD = curLib.data[curShapeId] = canv.pathActions.convertPath(curShape);
curShape.setAttribute('d', currentD);
canv.pathActions.fixEnd(curShape);
}
*/
curShape.setAttribute('transform', 'translate(' + x + ',' + y + ') scale(0.005) translate(' + -x + ',' + -y + ')');
canv.recalculateDimensions(curShape);

View File

@ -11,7 +11,7 @@ class LayersPanel {
* @param {PlainObject} editor
*/
constructor(editor) {
this.updateContextPanel = editor.topPanel.updateContextPanel;
this.updateContextPanel = editor.topPanel.updateContextPanel.bind(editor.topPanel);
this.editor = editor;
}

View File

@ -782,8 +782,7 @@ class TopPanel {
editor.svgCanvas.setMode('select');
editor.svgCanvas.selectOnly(editor.svgCanvas.getSelectedElems(), true);
}, (error) => {
// eslint-disable-next-line no-console
console.log("error =", error);
console.error("error =", error);
seAlert(editor.i18next.t('tools.no_embed'));
editor.svgCanvas.deleteSelectedElements();
});

View File

@ -44,7 +44,6 @@ export const setBlurNoUndo = function (val) {
blurContext_.changeSelectedAttributeNoUndoMethod('filter', 'url(#' + elem.id + '_blur)');
}
if (blurContext_.isWebkit()) {
// console.log('e', elem);
elem.removeAttribute('filter');
elem.setAttribute('filter', 'url(#' + elem.id + '_blur)');
}

View File

@ -1,5 +1,3 @@
import { isWebkit } from '../common/browser.js';
import { convertPath } from './path.js';
import { preventClickDefault } from './utilities.js';
/**
@ -19,13 +17,6 @@ export const copyElem = function (el, getNextId) {
newEl.removeAttribute('id');
newEl.id = getNextId();
// Opera's "d" value needs to be reset for Opera/Win/non-EN
// Also needed for webkit (else does not keep curved segments on clone)
if (isWebkit() && el.nodeName === 'path') {
const fixedD = convertPath(el);
newEl.setAttribute('d', fixedD);
}
// now create copies of all children
el.childNodes.forEach(function(child){
switch (child.nodeType) {

View File

@ -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`
/**

View File

@ -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 });
}

View File

@ -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_,

View File

@ -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);
});
};

View File

@ -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,

View File

@ -12,13 +12,10 @@ import {
hasMatrixTransform, transformListToTransform, transformBox
} from './math.js';
import {
isWebkit, supportsHVLineContainerBBox, supportsPathBBox
isWebkit, supportsHVLineContainerBBox
} from '../common/browser.js';
import { getClosest, mergeDeep } from '../editor/components/jgraduate/Util.js';
// String used to encode base64.
const KEYSTR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
// Much faster than running getBBox() every time
const visElems = 'a,circle,ellipse,foreignObject,g,image,line,path,polygon,polyline,rect,svg,text,tspan,use,clipPath';
const visElemsArr = visElems.split(',');
@ -137,41 +134,7 @@ export const toXml = function (str) {
export function encode64(input) {
// base64 strings are 4/3 larger than the original string
input = encodeUTF8(input); // convert non-ASCII characters
// input = convertToXMLReferences(input);
if (window.btoa) {
return window.btoa(input); // Use native if available
}
const output = new Array(Math.floor((input.length + 2) / 3) * 4);
let i = 0;
let p = 0;
do {
const chr1 = input.charCodeAt(i++);
const chr2 = input.charCodeAt(i++);
const chr3 = input.charCodeAt(i++);
/* eslint-disable no-bitwise */
const enc1 = chr1 >> 2;
const enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
let enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
let enc4 = chr3 & 63;
/* eslint-enable no-bitwise */
if (Number.isNaN(chr2)) {
enc3 = 64;
enc4 = 64;
} else if (Number.isNaN(chr3)) {
enc4 = 64;
}
output[p++] = KEYSTR.charAt(enc1);
output[p++] = KEYSTR.charAt(enc2);
output[p++] = KEYSTR.charAt(enc3);
output[p++] = KEYSTR.charAt(enc4);
} while (i < input.length);
return output.join('');
return window.btoa(input); // Use native if available
}
/**
@ -181,38 +144,7 @@ export function encode64(input) {
* @returns {string} Decoded output
*/
export function decode64(input) {
if (window.atob) {
return decodeUTF8(window.atob(input));
}
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
input = input.replace(/[^A-Za-z\d+/=]/g, '');
let output = '';
let i = 0;
do {
const enc1 = KEYSTR.indexOf(input.charAt(i++));
const enc2 = KEYSTR.indexOf(input.charAt(i++));
const enc3 = KEYSTR.indexOf(input.charAt(i++));
const enc4 = KEYSTR.indexOf(input.charAt(i++));
/* eslint-disable no-bitwise */
const chr1 = (enc1 << 2) | (enc2 >> 4);
const chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
const chr3 = ((enc3 & 3) << 6) | enc4;
/* eslint-enable no-bitwise */
output += String.fromCharCode(chr1);
if (enc3 !== 64) {
output += String.fromCharCode(chr2);
}
if (enc4 !== 64) {
output += String.fromCharCode(chr3);
}
} while (i < input.length);
return decodeUTF8(output);
return decodeUTF8(window.atob(input));
}
/**
@ -315,17 +247,13 @@ export const text2xml = function (sXML) {
let out; let dXML;
try {
dXML = (window.DOMParser) ? new DOMParser() : new window.ActiveXObject('Microsoft.XMLDOM');
dXML = new DOMParser();
dXML.async = false;
} catch (e) {
throw new Error('XML Parser could not be instantiated');
}
try {
if (dXML.loadXML) {
out = (dXML.loadXML(sXML)) ? dXML : false;
} else {
out = dXML.parseFromString(sXML, 'text/xml');
}
out = dXML.parseFromString(sXML, 'text/xml');
} catch (e2) { throw new Error('Error parsing XML string'); }
return out;
};
@ -618,9 +546,7 @@ export const getBBox = function (elem) {
}
break;
case 'path':
if (!supportsPathBBox()) {
ret = getPathBBox(selected);
} else if (selected.getBBox) {
if (selected.getBBox) {
ret = selected.getBBox();
}
break;