From 4c8f568c6d293770a06b62bdcb738d14caccf519 Mon Sep 17 00:00:00 2001 From: JFH <20402845+jfhenon@users.noreply.github.com> Date: Sun, 29 Aug 2021 12:52:40 +0200 Subject: [PATCH 1/8] es6 refactor --- src/common/units.js | 6 +-- .../extensions/ext-connector/ext-connector.js | 8 +--- .../ext-overview_window.js | 2 +- src/svgcanvas/coords.js | 43 +++++++++---------- 4 files changed, 25 insertions(+), 34 deletions(-) diff --git a/src/common/units.js b/src/common/units.js index a80a4cb8..60685083 100644 --- a/src/common/units.js +++ b/src/common/units.js @@ -224,14 +224,12 @@ export const convertAttrs = function (element) { const attrs = attrsToConvert[elName]; if (!attrs) { return; } - const len = attrs.length; - for (let i = 0; i < len; i++) { - const attr = attrs[i]; + attrs.forEach( (attr) => { const cur = element.getAttribute(attr); if (cur && !isNaN(cur)) { element.setAttribute(attr, (cur / typeMap_[unit]) + unit); } - } + }); }; /** diff --git a/src/editor/extensions/ext-connector/ext-connector.js b/src/editor/extensions/ext-connector/ext-connector.js index 12fd4289..ddd6a943 100644 --- a/src/editor/extensions/ext-connector/ext-connector.js +++ b/src/editor/extensions/ext-connector/ext-connector.js @@ -136,11 +136,7 @@ export default { } catch (err) { // Should only occur in FF which formats points attr as "n,n n,n", so just split const ptArr = elem.getAttribute('points').split(' '); - for (let i = 0; i < ptArr.length; i++) { - if (i === pos) { - ptArr[i] = x + ',' + y; - } - } + ptArr[pos] = x + ',' + y; elem.setAttribute('points', ptArr.join(' ')); } @@ -208,7 +204,7 @@ export default { let addThis; // Grab the ends const parts = []; - [ 'start', 'end' ].forEach(function (pos, i) { + [ 'start', 'end' ].forEach( (pos, i) => { const key = 'c_' + pos; let part = dataStorage.get(ethis, key); if (part === null || part === undefined) { // Does this ever return nullish values? diff --git a/src/editor/extensions/ext-overview_window/ext-overview_window.js b/src/editor/extensions/ext-overview_window/ext-overview_window.js index 98ec88e0..f7110a02 100644 --- a/src/editor/extensions/ext-overview_window/ext-overview_window.js +++ b/src/editor/extensions/ext-overview_window/ext-overview_window.js @@ -41,7 +41,7 @@ export default { $id("sidepanel_content").insertAdjacentHTML( 'beforeend', propsWindowHtml ); // Define dynamic animation of the view box. - const updateViewBox = function () { + const updateViewBox = () => { const { workarea } = svgEditor; const portHeight = parseFloat(getComputedStyle(workarea, null).height.replace("px", "")); const portWidth = parseFloat(getComputedStyle(workarea, null).width.replace("px", "")); diff --git a/src/svgcanvas/coords.js b/src/svgcanvas/coords.js index 36cae7cd..1c4c5b08 100644 --- a/src/svgcanvas/coords.js +++ b/src/svgcanvas/coords.js @@ -51,11 +51,11 @@ export const init = function (editorContext) { * @type {module:path.EditorContext#remapElement} */ export const remapElement = function (selected, changes, m) { - const remap = function (x, y) { return transformPoint(x, y, m); }; - const scalew = function (w) { return m.a * w; }; - const scaleh = function (h) { return m.d * h; }; + const remap = (x, y) => transformPoint(x, y, m); + const scalew = (w) => m.a * w; + const scaleh = (h) => m.d * h; const doSnapping = editorContext_.getGridSnapping() && selected.parentNode.parentNode.localName === 'svg'; - const finishUp = function () { + const finishUp = () => { if (doSnapping) { Object.entries(changes).forEach(([ o, value ]) => { changes[o] = snapToGrid(value); @@ -65,8 +65,7 @@ export const remapElement = function (selected, changes, m) { }; const box = getBBox(selected); - for (let i = 0; i < 2; i++) { - const type = i === 0 ? 'fill' : 'stroke'; + [ 'fill', 'stroke' ].forEach( (type) => { const attrVal = selected.getAttribute(type); if (attrVal && attrVal.startsWith('url(') && (m.a < 0 || m.d < 0)) { const grad = getRefElem(attrVal); @@ -90,7 +89,7 @@ export const remapElement = function (selected, changes, m) { findDefs().append(newgrad); selected.setAttribute(type, 'url(#' + newgrad.id + ')'); } - } + }); const elName = selected.tagName; if (elName === 'g' || elName === 'text' || elName === 'tspan' || elName === 'use') { @@ -181,20 +180,17 @@ export const remapElement = function (selected, changes, m) { break; } case 'polyline': case 'polygon': { - const len = changes.points.length; - for (let i = 0; i < len; ++i) { - const pt = changes.points[i]; + changes.points.forEach( (pt) => { const { x, y } = remap(pt.x, pt.y); - changes.points[i].x = x; - changes.points[i].y = y; - } + pt.x = x; + pt.y = y; + }); // const len = changes.points.length; let pstr = ''; - for (let i = 0; i < len; ++i) { - const pt = changes.points[i]; + changes.points.forEach( (pt) => { pstr += pt.x + ',' + pt.y + ' '; - } + }); selected.setAttribute('points', pstr); break; } case 'path': { @@ -221,9 +217,12 @@ export const remapElement = function (selected, changes, m) { len = changes.d.length; const firstseg = changes.d[0]; - const currentpt = remap(firstseg.x, firstseg.y); - changes.d[0].x = currentpt.x; - changes.d[0].y = currentpt.y; + let currentpt; + if (len > 0) { + currentpt = remap(firstseg.x, firstseg.y); + changes.d[0].x = currentpt.x; + changes.d[0].y = currentpt.y; + } for (let i = 1; i < len; ++i) { const seg = changes.d[i]; const { type } = seg; @@ -256,9 +255,7 @@ export const remapElement = function (selected, changes, m) { } // for each segment let dstr = ''; - len = changes.d.length; - for (let i = 0; i < len; ++i) { - const seg = changes.d[i]; + changes.d.forEach( (seg) => { const { type } = seg; dstr += pathMap[type]; switch (type) { @@ -297,7 +294,7 @@ export const remapElement = function (selected, changes, m) { dstr += seg.x2 + ',' + seg.y2 + ' ' + seg.x + ',' + seg.y + ' '; break; } - } + }); selected.setAttribute('d', dstr); break; From 8ab88444e1a94bbd06f50296dc302b8ef7cf883e Mon Sep 17 00:00:00 2001 From: JFH <20402845+jfhenon@users.noreply.github.com> Date: Sun, 29 Aug 2021 12:53:06 +0200 Subject: [PATCH 2/8] add generic attributes in whitelist --- src/svgcanvas/sanitize.js | 78 ++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/src/svgcanvas/sanitize.js b/src/svgcanvas/sanitize.js index 90f68bcd..b9bbd828 100644 --- a/src/svgcanvas/sanitize.js +++ b/src/svgcanvas/sanitize.js @@ -19,54 +19,55 @@ const REVERSE_NS = getReverseNS(); * @type {PlainObject} */ /* eslint-disable max-len */ +const svgGenericWhiteList = [ 'class', 'id', 'display', 'transform' ]; const svgWhiteList_ = { // SVG Elements - a: [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'xlink:href', 'xlink:title' ], - circle: [ 'class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'r', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ], - clipPath: [ 'class', 'clipPathUnits', 'id' ], - defs: [ 'id' ], - style: [ 'id', 'type' ], + a: [ 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'mask', 'opacity', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'xlink:href', 'xlink:title' ], + circle: [ 'clip-path', 'clip-rule', 'cx', 'cy', 'enable-background', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'mask', 'opacity', 'r', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage' ], + clipPath: [ 'clipPathUnits', 'id' ], + defs: [], + style: [ 'type' ], desc: [], - ellipse: [ 'class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ], + ellipse: [ 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage' ], feBlend: [ 'in', 'in2' ], - feColorMatrix: [ 'in', 'type', 'value', 'result', 'values', 'id' ], - feComposite: [ 'in', 'id', 'operator', 'result', 'in2' ], - feFlood: [ 'flood-color', 'in', 'id', 'result', 'flood-opacity' ], - feGaussianBlur: [ 'class', 'color-interpolation-filters', 'id', 'in', 'requiredFeatures', 'stdDeviation', 'result' ], + feColorMatrix: [ 'in', 'type', 'value', 'result', 'values' ], + feComposite: [ 'in', 'operator', 'result', 'in2' ], + feFlood: [ 'flood-color', 'in', 'result', 'flood-opacity' ], + feGaussianBlur: [ 'color-interpolation-filters', 'in', 'requiredFeatures', 'stdDeviation', 'result' ], feMerge: [], feMergeNode: [ 'in' ], - feMorphology: [ 'class', 'in', 'operator', 'radius' ], - feOffset: [ 'dx', 'id', 'in', 'dy', 'result' ], - filter: [ 'class', 'color-interpolation-filters', 'filterRes', 'filterUnits', 'height', 'id', 'primitiveUnits', 'requiredFeatures', 'style', 'width', 'x', 'xlink:href', 'y' ], - foreignObject: [ 'class', 'font-size', 'height', 'id', 'opacity', 'requiredFeatures', 'style', 'transform', 'width', 'x', 'y' ], - g: [ 'class', 'clip-path', 'clip-rule', 'id', 'display', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'font-family', 'font-size', 'font-style', 'font-weight', 'text-anchor' ], - image: [ 'class', 'clip-path', 'clip-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'width', 'x', 'xlink:href', 'xlink:title', 'y' ], - line: [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'x1', 'x2', 'y1', 'y2' ], - linearGradient: [ 'class', 'id', 'gradientTransform', 'gradientUnits', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'x1', 'x2', 'xlink:href', 'y1', 'y2' ], - marker: [ 'id', 'class', 'markerHeight', 'markerUnits', 'markerWidth', 'orient', 'preserveAspectRatio', 'refX', 'refY', 'systemLanguage', 'viewBox' ], - mask: [ 'class', 'height', 'id', 'maskContentUnits', 'maskUnits', 'width', 'x', 'y' ], - metadata: [ 'class', 'id' ], - path: [ 'class', 'clip-path', 'clip-rule', 'd', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ], - pattern: [ 'class', 'height', 'id', 'patternContentUnits', 'patternTransform', 'patternUnits', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xlink:href', 'y' ], - polygon: [ 'class', 'clip-path', 'clip-rule', 'id', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'class', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'points', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'sides', 'shape', 'edge', 'point', 'starRadiusMultiplier', 'r', 'radialshift' ], - polyline: [ 'class', 'clip-path', 'clip-rule', 'id', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'points', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'se:connector' ], - radialGradient: [ 'class', 'cx', 'cy', 'fx', 'fy', 'gradientTransform', 'gradientUnits', 'id', 'r', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'xlink:href' ], - rect: [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'width', 'x', 'y' ], - stop: [ 'class', 'id', 'offset', 'requiredFeatures', 'stop-opacity', 'style', 'systemLanguage', 'stop-color', 'gradientUnits', 'gradientTransform' ], - svg: [ 'class', 'clip-path', 'clip-rule', 'filter', 'id', 'height', 'mask', 'preserveAspectRatio', 'requiredFeatures', 'style', 'systemLanguage', 'version', 'viewBox', 'width', 'x', 'xmlns', 'xmlns:se', 'xmlns:xlink', 'xmlns:oi', 'oi:animations', 'y', 'stroke-linejoin', 'fill-rule', 'aria-label', 'stroke-width', 'fill-rule' ], - switch: [ 'class', 'id', 'requiredFeatures', 'systemLanguage' ], - symbol: [ 'class', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'opacity', 'overflow', 'preserveAspectRatio', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'viewBox', 'width', 'height' ], - text: [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'transform', 'x', 'xml:space', 'y' ], - textPath: [ 'class', 'id', 'method', 'requiredFeatures', 'spacing', 'startOffset', 'style', 'systemLanguage', 'transform', 'xlink:href' ], + feMorphology: [ 'in', 'operator', 'radius' ], + feOffset: [ 'dx', 'in', 'dy', 'result' ], + filter: [ 'color-interpolation-filters', 'filterRes', 'filterUnits', 'height', 'primitiveUnits', 'requiredFeatures', 'style', 'width', 'x', 'xlink:href', 'y' ], + foreignObject: [ 'font-size', 'height', 'opacity', 'requiredFeatures', 'style', 'width', 'x', 'y' ], + g: [ 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'font-family', 'font-size', 'font-style', 'font-weight', 'text-anchor' ], + image: [ 'clip-path', 'clip-rule', 'filter', 'height', 'mask', 'opacity', 'requiredFeatures', 'style', 'systemLanguage', 'width', 'x', 'xlink:href', 'xlink:title', 'y' ], + line: [ 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'x1', 'x2', 'y1', 'y2' ], + linearGradient: [ 'gradientTransform', 'gradientUnits', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'x1', 'x2', 'xlink:href', 'y1', 'y2' ], + marker: [ 'markerHeight', 'markerUnits', 'markerWidth', 'orient', 'preserveAspectRatio', 'refX', 'refY', 'systemLanguage', 'viewBox' ], + mask: [ 'height', 'maskContentUnits', 'maskUnits', 'width', 'x', 'y' ], + metadata: [ 'id' ], + path: [ 'clip-path', 'clip-rule', 'd', 'enable-background', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage' ], + pattern: [ 'height', 'patternContentUnits', 'patternTransform', 'patternUnits', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xlink:href', 'y' ], + polygon: [ 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'points', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'sides', 'shape', 'edge', 'point', 'starRadiusMultiplier', 'r', 'radialshift' ], + polyline: [ 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'marker-end', 'marker-mid', 'marker-start', 'mask', 'opacity', 'points', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'se:connector' ], + radialGradient: [ 'cx', 'cy', 'fx', 'fy', 'gradientTransform', 'gradientUnits', 'r', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'xlink:href' ], + rect: [ 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'width', 'x', 'y' ], + stop: [ 'offset', 'requiredFeatures', 'stop-opacity', 'style', 'systemLanguage', 'stop-color', 'gradientUnits', 'gradientTransform' ], + svg: [ 'clip-path', 'clip-rule', 'enable-background', 'filter', 'height', 'mask', 'preserveAspectRatio', 'requiredFeatures', 'style', 'systemLanguage', 'version', 'viewBox', 'width', 'x', 'xmlns', 'xmlns:se', 'xmlns:xlink', 'xmlns:oi', 'oi:animations', 'y', 'stroke-linejoin', 'fill-rule', 'aria-label', 'stroke-width', 'fill-rule', 'xml:space' ], + switch: [ 'requiredFeatures', 'systemLanguage' ], + symbol: [ 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'opacity', 'overflow', 'preserveAspectRatio', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'viewBox', 'width', 'height' ], + text: [ 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'x', 'xml:space', 'y' ], + textPath: [ 'method', 'requiredFeatures', 'spacing', 'startOffset', 'style', 'systemLanguage', 'xlink:href' ], title: [], - tspan: [ 'class', 'clip-path', 'clip-rule', 'dx', 'dy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'rotate', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'textLength', 'transform', 'x', 'xml:space', 'y' ], - use: [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'id', 'mask', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'transform', 'width', 'x', 'xlink:href', 'y' ], + tspan: [ 'clip-path', 'clip-rule', 'dx', 'dy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'mask', 'opacity', 'requiredFeatures', 'rotate', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'textLength', 'x', 'xml:space', 'y' ], + use: [ 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'mask', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'width', 'x', 'xlink:href', 'y', 'overflow' ], // MathML Elements annotation: [ 'encoding' ], 'annotation-xml': [ 'encoding' ], maction: [ 'actiontype', 'other', 'selection' ], - math: [ 'class', 'id', 'display', 'xmlns' ], + math: [ 'xmlns' ], menclose: [ 'notation' ], merror: [], mfrac: [ 'linethickness' ], @@ -96,10 +97,11 @@ const svgWhiteList_ = { semantics: [] }; /* eslint-enable max-len */ - +// add generic attributes to all elements of the whitelist +Object.keys(svgWhiteList_).forEach((element) => svgWhiteList_[element] = [ ...svgWhiteList_[element], ...svgGenericWhiteList ]); // Produce a Namespace-aware version of svgWhitelist const svgWhiteListNS_ = {}; -Object.entries(svgWhiteList_).forEach(function ([ elt, atts ]) { +Object.entries(svgWhiteList_).forEach(([ elt, atts ]) => { const attNS = {}; Object.entries(atts).forEach(function ([ _i, att ]) { if (att.includes(':')) { From e2d91ea24877bbe1ff5469725509d08ed1c6fcca Mon Sep 17 00:00:00 2001 From: JFH <20402845+jfhenon@users.noreply.github.com> Date: Sun, 29 Aug 2021 12:53:46 +0200 Subject: [PATCH 3/8] fix bug with layers transformation --- src/svgcanvas/utilities.js | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/svgcanvas/utilities.js b/src/svgcanvas/utilities.js index cdd2e045..a482daff 100644 --- a/src/svgcanvas/utilities.js +++ b/src/svgcanvas/utilities.js @@ -122,20 +122,6 @@ export const toXml = function (str) { .replace(/'/g, '''); // Note: `'` is XML only }; -/** -* Converts XML entities in a string to single characters. -* @function module:utilities.fromXml -* @example `&` becomes `&` -* @param {string} str - The string to be converted -* @returns {string} The converted string -*/ -export function fromXml(str) { - const p = document.createElement('p'); - // eslint-disable-next-line no-unsanitized/property - p.innerHTML = str; - return p.textContent; -} - // This code was written by Tyler Akins and has been placed in the // public domain. It would be nice if you left this header intact. // Base64 code from Tyler Akins -- http://rumkin.com @@ -1127,7 +1113,7 @@ export const getStrokedBBox = function (elems, addSVGElementFromJson, pathAction export const getVisibleElements = function (parentElement) { if (!parentElement) { const svgcontent = editorContext_.getSVGContent(); - parentElement = svgcontent.children; // Prevent layers from being included + parentElement = svgcontent.children[0]; // Prevent layers from being included } const contentElems = []; From 0d2c344fee11b7f1d4899b9b427c5104166ce698 Mon Sep 17 00:00:00 2001 From: JFH <20402845+jfhenon@users.noreply.github.com> Date: Sun, 29 Aug 2021 14:16:03 +0200 Subject: [PATCH 4/8] remove svgtransform polyfill now widely supported --- cypress/integration/unit/history.js | 4 - cypress/integration/unit/svgtransformlist.js | 330 --------------- cypress/integration/unit/utilities-bbox.js | 5 +- .../integration/unit/utilities-performance.js | 3 +- src/common/browser.js | 35 -- .../extensions/ext-connector/ext-connector.js | 2 +- .../extensions/ext-shapes/ext-shapes.js | 4 +- src/svgcanvas/coords.js | 5 +- src/svgcanvas/event.js | 11 +- src/svgcanvas/history.js | 10 +- src/svgcanvas/math.js | 3 +- src/svgcanvas/path-actions.js | 3 +- src/svgcanvas/path.js | 3 +- src/svgcanvas/recalculate.js | 28 +- src/svgcanvas/select.js | 3 +- src/svgcanvas/selected-elem.js | 11 +- src/svgcanvas/selection.js | 6 +- src/svgcanvas/svg-exec.js | 3 - src/svgcanvas/svgcanvas.js | 6 - src/svgcanvas/svgtransformlist.js | 393 ------------------ src/svgcanvas/undo.js | 5 +- src/svgcanvas/utilities.js | 7 +- 22 files changed, 35 insertions(+), 845 deletions(-) delete mode 100644 cypress/integration/unit/svgtransformlist.js delete mode 100644 src/svgcanvas/svgtransformlist.js diff --git a/cypress/integration/unit/history.js b/cypress/integration/unit/history.js index abf37408..30f4fdca 100644 --- a/cypress/integration/unit/history.js +++ b/cypress/integration/unit/history.js @@ -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 */ }, diff --git a/cypress/integration/unit/svgtransformlist.js b/cypress/integration/unit/svgtransformlist.js deleted file mode 100644 index fed8abdb..00000000 --- a/cypress/integration/unit/svgtransformlist.js +++ /dev/null @@ -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); - }); -}); diff --git a/cypress/integration/unit/utilities-bbox.js b/cypress/integration/unit/utilities-bbox.js index 7b8aa203..29cf87c4 100644 --- a/cypress/integration/unit/utilities-bbox.js +++ b/cypress/integration/unit/utilities-bbox.js @@ -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; }); diff --git a/cypress/integration/unit/utilities-performance.js b/cypress/integration/unit/utilities-performance.js index bc368a40..732f0854 100644 --- a/cypress/integration/unit/utilities-performance.js +++ b/cypress/integration/unit/utilities-performance.js @@ -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'); diff --git a/src/common/browser.js b/src/common/browser.js index fc967925..003a9756 100644 --- a/src/common/browser.js +++ b/src/common/browser.js @@ -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; -}; diff --git a/src/editor/extensions/ext-connector/ext-connector.js b/src/editor/extensions/ext-connector/ext-connector.js index ddd6a943..ebd3394a 100644 --- a/src/editor/extensions/ext-connector/ext-connector.js +++ b/src/editor/extensions/ext-connector/ext-connector.js @@ -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) { diff --git a/src/editor/extensions/ext-shapes/ext-shapes.js b/src/editor/extensions/ext-shapes/ext-shapes.js index a7472f80..246d43c7 100644 --- a/src/editor/extensions/ext-shapes/ext-shapes.js +++ b/src/editor/extensions/ext-shapes/ext-shapes.js @@ -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; diff --git a/src/svgcanvas/coords.js b/src/svgcanvas/coords.js index 1c4c5b08..7d63f49f 100644 --- a/src/svgcanvas/coords.js +++ b/src/svgcanvas/coords.js @@ -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(); diff --git a/src/svgcanvas/event.js b/src/svgcanvas/event.js index b278c525..78acf72e 100644 --- a/src/svgcanvas/event.js +++ b/src/svgcanvas/event.js @@ -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 { diff --git a/src/svgcanvas/history.js b/src/svgcanvas/history.js index 9d533a77..fde9e89e 100644 --- a/src/svgcanvas/history.js +++ b/src/svgcanvas/history.js @@ -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); }); } } diff --git a/src/svgcanvas/math.js b/src/svgcanvas/math.js index 446a11fa..69da0cc3 100644 --- a/src/svgcanvas/math.js +++ b/src/svgcanvas/math.js @@ -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; }; diff --git a/src/svgcanvas/path-actions.js b/src/svgcanvas/path-actions.js index 7087e685..407a947c 100644 --- a/src/svgcanvas/path-actions.js +++ b/src/svgcanvas/path-actions.js @@ -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'); diff --git a/src/svgcanvas/path.js b/src/svgcanvas/path.js index bb285e1c..f5399591 100644 --- a/src/svgcanvas/path.js +++ b/src/svgcanvas/path.js @@ -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); }; diff --git a/src/svgcanvas/recalculate.js b/src/svgcanvas/recalculate.js index 186fb447..74562d3a 100644 --- a/src/svgcanvas/recalculate.js +++ b/src/svgcanvas/recalculate.js @@ -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 (, , 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 (, , 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(',') + ')'; diff --git a/src/svgcanvas/select.js b/src/svgcanvas/select.js index 8b99bfba..3803b3c4 100644 --- a/src/svgcanvas/select.js +++ b/src/svgcanvas/select.js @@ -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 diff --git a/src/svgcanvas/selected-elem.js b/src/svgcanvas/selected-elem.js index 28bf680e..a8511864 100644 --- a/src/svgcanvas/selected-elem.js +++ b/src/svgcanvas/selected-elem.js @@ -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); diff --git a/src/svgcanvas/selection.js b/src/svgcanvas/selection.js index 7435f48d..8aef35ec 100644 --- a/src/svgcanvas/selection.js +++ b/src/svgcanvas/selection.js @@ -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); diff --git a/src/svgcanvas/svg-exec.js b/src/svgcanvas/svg-exec.js index 53de4c22..97ba5a1a 100644 --- a/src/svgcanvas/svg-exec.js +++ b/src/svgcanvas/svg-exec.js @@ -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); diff --git a/src/svgcanvas/svgcanvas.js b/src/svgcanvas/svgcanvas.js index 255df02a..937eb8cf 100644 --- a/src/svgcanvas/svgcanvas.js +++ b/src/svgcanvas/svgcanvas.js @@ -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, diff --git a/src/svgcanvas/svgtransformlist.js b/src/svgcanvas/svgtransformlist.js deleted file mode 100644 index d1761bf2..00000000 --- a/src/svgcanvas/svgtransformlist.js +++ /dev/null @@ -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*(?(?: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*(?.*?)\s*\)/); - valBits.groups.nonWhitespace = valBits.groups.nonWhitespace.replace( - /(?\d)-/g, '$ -' - ); - 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; -}; diff --git a/src/svgcanvas/undo.js b/src/svgcanvas/undo.js index d61e7809..54588398 100644 --- a/src/svgcanvas/undo.js +++ b/src/svgcanvas/undo.js @@ -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); diff --git a/src/svgcanvas/utilities.js b/src/svgcanvas/utilities.js index a482daff..df0c6146 100644 --- a/src/svgcanvas/utilities.js +++ b/src/svgcanvas/utilities.js @@ -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); }; From 6c708ed9748005a711a935a8e3ead5613b73dfd0 Mon Sep 17 00:00:00 2001 From: JFH <20402845+jfhenon@users.noreply.github.com> Date: Sun, 29 Aug 2021 16:05:21 +0200 Subject: [PATCH 5/8] update tests --- .../ui/__snapshots__/scenario2.js.snap | 140 ++++++++-------- .../ui/__snapshots__/scenario4.js.snap | 158 +++++++++--------- .../ui/__snapshots__/scenario5.js.snap | 88 +++++----- cypress/integration/unit/utilities.js | 11 -- src/svgcanvas/undo.js | 16 +- src/svgcanvas/utilities.js | 9 +- 6 files changed, 198 insertions(+), 224 deletions(-) diff --git a/cypress/integration/ui/__snapshots__/scenario2.js.snap b/cypress/integration/ui/__snapshots__/scenario2.js.snap index 241be924..ce009cdd 100644 --- a/cypress/integration/ui/__snapshots__/scenario2.js.snap +++ b/cypress/integration/ui/__snapshots__/scenario2.js.snap @@ -331,68 +331,6 @@ exports[`use all parts of svg-edit > check tool_ellipse_change_rotation #0`] = ` `; -exports[`use all parts of svg-edit > check tool_ellipse_change_blur #0`] = ` - - - Layer 1 - - - - - - - - - - -`; - exports[`use all parts of svg-edit > check tool_ellipse_change_cx_cy_coordinate #0`] = ` check tool_ellipse_change_cx_cy_coordinate > - - + + @@ -510,8 +448,8 @@ exports[`use all parts of svg-edit > check tool_ellipse_change_rx_ry_radius #0`] > - - + + @@ -572,8 +510,8 @@ exports[`use all parts of svg-edit > check tool_ellipse_bring_to_back #0`] = ` > - - + + @@ -634,8 +572,8 @@ exports[`use all parts of svg-edit > check tool_ellipse_bring_to_front #0`] = ` > - - + + @@ -708,6 +646,68 @@ exports[`use all parts of svg-edit > check tool_ellipse_clone #0`] = ` id="svg_4" > + + + + + + +`; + +exports[`use all parts of svg-edit > check tool_ellipse_change_blur #0`] = ` + + + Layer 1 + + + + diff --git a/cypress/integration/ui/__snapshots__/scenario4.js.snap b/cypress/integration/ui/__snapshots__/scenario4.js.snap index 57e732f8..3bad2580 100644 --- a/cypress/integration/ui/__snapshots__/scenario4.js.snap +++ b/cypress/integration/ui/__snapshots__/scenario4.js.snap @@ -280,69 +280,6 @@ exports[`use all parts of svg-edit > check tool_rect_change_rotation #0`] = ` `; -exports[`use all parts of svg-edit > check tool_rect_change_blur #0`] = ` - - - Layer 1 - - - - - - - - - - -`; - exports[`use all parts of svg-edit > check tool_rect_change_opacity #0`] = ` check tool_rect_change_opacity #0`] = ` > - - + + @@ -463,8 +400,8 @@ exports[`use all parts of svg-edit > check tool_fhrect_change_x_y_coordinate #0` > - - + + @@ -526,8 +463,8 @@ exports[`use all parts of svg-edit > check tool_fhrect_change_width_height #0`] > - - + + @@ -600,8 +537,8 @@ exports[`use all parts of svg-edit > check tool_square_clone #0`] = ` > - - + + @@ -674,8 +611,8 @@ exports[`use all parts of svg-edit > check tool_square_bring_to_back #0`] = ` > - - + + @@ -748,8 +685,8 @@ exports[`use all parts of svg-edit > check tool_square_bring_to_front #0`] = ` > - - + + @@ -824,8 +761,8 @@ exports[`use all parts of svg-edit > check tool_square_change_corner_radius #0`] > - - + + @@ -898,8 +835,8 @@ exports[`use all parts of svg-edit > check tool_rect_change_to_path #0`] = ` > - - + + @@ -944,6 +881,69 @@ exports[`use all parts of svg-edit > check tool_rect_delete #0`] = ` ry="25" > + + + + + + +`; + +exports[`use all parts of svg-edit > check tool_rect_change_blur #0`] = ` + + + Layer 1 + + + + diff --git a/cypress/integration/ui/__snapshots__/scenario5.js.snap b/cypress/integration/ui/__snapshots__/scenario5.js.snap index 947b63a5..ab0a001c 100644 --- a/cypress/integration/ui/__snapshots__/scenario5.js.snap +++ b/cypress/integration/ui/__snapshots__/scenario5.js.snap @@ -84,44 +84,6 @@ exports[`use all parts of svg-edit > check tool_line_change_rotation #0`] = ` `; -exports[`use all parts of svg-edit > check tool_line_change_blur #0`] = ` - - - Layer 1 - - - - - - - - -`; - exports[`use all parts of svg-edit > check tool_line_change_opacity #0`] = ` check tool_line_change_opacity #0`] = ` > - - + + @@ -177,8 +139,8 @@ exports[`use all parts of svg-edit > check tool_line_delete #0`] = ` Layer 1 - - + + @@ -245,8 +207,8 @@ exports[`use all parts of svg-edit > check tool_line_clone #0`] = ` - - + + @@ -303,6 +265,44 @@ exports[`use all parts of svg-edit > check tool_fhrect_change_x_y_coordinate #0` > + + + + + + +`; + +exports[`use all parts of svg-edit > check tool_line_change_blur #0`] = ` + + + Layer 1 + + diff --git a/cypress/integration/unit/utilities.js b/cypress/integration/unit/utilities.js index aa70e571..daa7e8db 100644 --- a/cypress/integration/unit/utilities.js +++ b/cypress/integration/unit/utilities.js @@ -113,17 +113,6 @@ describe('utilities', function () { assert.equal(toXml('\'<&>"'), ''<&>"'); }); - it('Test svgedit.utilities.fromXml() function', function () { - const { fromXml } = utilities; - - assert.equal(fromXml('a'), 'a'); - assert.equal(fromXml('ABC_'), 'ABC_'); - assert.equal(fromXml('PB&J'), 'PB&J'); - assert.equal(fromXml('2 < 5'), '2 < 5'); - assert.equal(fromXml('5 > 2'), '5 > 2'); - assert.equal(fromXml('<&>'), '<&>'); - }); - it('Test svgedit.utilities.encode64() function', function () { const { encode64 } = utilities; diff --git a/src/svgcanvas/undo.js b/src/svgcanvas/undo.js index 54588398..00d0d3ae 100644 --- a/src/svgcanvas/undo.js +++ b/src/svgcanvas/undo.js @@ -81,20 +81,6 @@ export const getUndoManager = function () { if (values.stdDeviation) { undoContext_.getCanvas().setBlurOffsets(cmd.elem.parentNode, values.stdDeviation); } - // This is resolved in later versions of webkit, perhaps we should - // have a featured detection for correct 'use' behavior? - // —————————— - // Remove & Re-add hack for Webkit (issue 775) - // if (cmd.elem.tagName === 'use' && isWebkit()) { - // const {elem} = cmd; - // if (!elem.getAttribute('x') && !elem.getAttribute('y')) { - // const parent = elem.parentNode; - // const sib = elem.nextSibling; - // elem.remove(); - // parent.insertBefore(elem, sib); - // // Ok to replace above with this? `sib.before(elem);` - // } - // } if (cmd.elem.tagName === 'text'){ const [ dx, dy ] = [ cmd.newValues.x - cmd.oldValues.x, cmd.newValues.y - cmd.oldValues.y ]; @@ -248,7 +234,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 = elem.transform.baseVal; + const tlist = elem.transform?.baseVal; let n = tlist.numberOfItems; while (n--) { const xform = tlist.getItem(n); diff --git a/src/svgcanvas/utilities.js b/src/svgcanvas/utilities.js index df0c6146..e6348d9b 100644 --- a/src/svgcanvas/utilities.js +++ b/src/svgcanvas/utilities.js @@ -1147,10 +1147,9 @@ export const getStrokedBBoxDefaultVisible = function (elems) { * @param {boolean} toRad - When true returns the value in radians rather than degrees * @returns {Float} The angle in degrees or radians */ -export const getRotationAngleFromTransformList = function (tlist, toRad) { - if (!tlist) { return 0; } // elements have no tlist - const N = tlist.numberOfItems; - for (let i = 0; i < N; ++i) { +export const getRotationAngleFromTransformList = (tlist, toRad) => { + if (!tlist) { return 0; } // element have no tlist + for (let i = 0; i < tlist.numberOfItems; ++i) { const xform = tlist.getItem(i); if (xform.type === 4) { return toRad ? xform.angle * Math.PI / 180.0 : xform.angle; @@ -1169,7 +1168,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 = selected.transform.baseVal; + const tlist = selected.transform?.baseVal; return getRotationAngleFromTransformList(tlist, toRad); }; From a74f5cb4df996224e67e26e09c3b4c751b6972c8 Mon Sep 17 00:00:00 2001 From: JFH <20402845+jfhenon@users.noreply.github.com> Date: Sun, 29 Aug 2021 16:05:32 +0200 Subject: [PATCH 6/8] update dependencies --- package-lock.json | 518 ++++++++++++++++++++++++++-------------------- package.json | 18 +- 2 files changed, 304 insertions(+), 232 deletions(-) diff --git a/package-lock.json b/package-lock.json index a2a1b263..53c4f882 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@babel/polyfill": "7.12.1", "browser-fs-access": "^0.20.4", "canvg": "3.0.7", - "core-js": "3.16.2", + "core-js": "3.16.3", "elix": "15.0.0", "html2canvas": "1.3.2", "i18next": "20.4.0", @@ -36,14 +36,14 @@ "@rollup/plugin-node-resolve": "13.0.4", "@rollup/plugin-replace": "3.0.0", "@rollup/plugin-url": "6.1.0", - "@web/dev-server": "0.1.21", + "@web/dev-server": "0.1.22", "@web/dev-server-rollup": "0.3.9", - "axe-core": "4.3.2", + "axe-core": "4.3.3", "babel-plugin-transform-object-rest-spread": "7.0.0-beta.3", "copyfiles": "2.4.1", - "core-js-bundle": "3.16.2", + "core-js-bundle": "3.16.3", "cp-cli": "2.0.0", - "cypress": "8.3.0", + "cypress": "8.3.1", "cypress-axe": "0.13.0", "cypress-multi-reporters": "1.5.0", "cypress-plugin-snapshots": "1.4.4", @@ -53,12 +53,12 @@ "eslint-plugin-chai-expect": "2.2.0", "eslint-plugin-chai-expect-keywords": "2.1.0", "eslint-plugin-chai-friendly": "0.7.2", - "eslint-plugin-compat": "3.12.0", + "eslint-plugin-compat": "3.13.0", "eslint-plugin-cypress": "2.11.3", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-html": "6.1.2", - "eslint-plugin-import": "2.24.0", - "eslint-plugin-jsdoc": "36.0.7", + "eslint-plugin-import": "2.24.2", + "eslint-plugin-jsdoc": "36.0.8", "eslint-plugin-markdown": "2.2.0", "eslint-plugin-no-unsanitized": "3.1.5", "eslint-plugin-no-use-extend-native": "0.5.0", @@ -77,7 +77,7 @@ "remark-cli": "10.0.0", "remark-lint-ordered-list-marker-value": "3.0.1", "rimraf": "3.0.2", - "rollup": "2.56.2", + "rollup": "2.56.3", "rollup-plugin-copy": "3.4.0", "rollup-plugin-filesize": "9.1.1", "rollup-plugin-node-polyfills": "0.2.1", @@ -2316,9 +2316,9 @@ "dev": true }, "node_modules/@cypress/request": { - "version": "2.88.5", - "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.5.tgz", - "integrity": "sha512-TzEC1XMi1hJkywWpRfD2clreTa/Z+lOrXDCxxBTBPEcY5azdPi56A6Xw+O4tWJnaJH3iIE7G5aDXZC6JgRZLcA==", + "version": "2.88.6", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.6.tgz", + "integrity": "sha512-z0UxBE/+qaESAHY9p9sM2h8Y4XqtsbDCt0/DPOrqA/RZgKi4PkxdpXyK4wCCnSk1xHqWHZZAE+gV6aDAR6+caQ==", "dev": true, "dependencies": { "aws-sign2": "~0.7.0", @@ -2334,13 +2334,12 @@ "isstream": "~0.1.2", "json-stringify-safe": "~5.0.1", "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" + "uuid": "^8.3.2" }, "engines": { "node": ">= 6" @@ -2368,6 +2367,15 @@ "node": ">=0.8" } }, + "node_modules/@cypress/request/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@cypress/xvfb": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", @@ -2394,17 +2402,17 @@ "dev": true }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.10.7.tgz", - "integrity": "sha512-aNKZEoMESDzOBjKxCWrFuG50mcpMeKVBnBNko4+IZZ5t9zXYs8GT1KB0ZaOq1YUsKumDRc6YII/TQm309MJ0KQ==", + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.10.8.tgz", + "integrity": "sha512-3P1JiGL4xaR9PoTKUHa2N/LKwa2/eUdRqGwijMWWgBqbFEqJUVpmaOi2TcjcemrsRMgFLBzQCK4ToPhrSVDiFQ==", "dev": true, "dependencies": { - "comment-parser": "1.2.3", + "comment-parser": "1.2.4", "esquery": "^1.4.0", "jsdoc-type-pratt-parser": "1.1.1" }, "engines": { - "node": "^12.20 || ^14.14.0 || ^16" + "node": "^12 || ^14 || ^16" } }, "node_modules/@eslint/eslintrc": { @@ -3836,16 +3844,16 @@ } }, "node_modules/@web/dev-server": { - "version": "0.1.21", - "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.1.21.tgz", - "integrity": "sha512-au4ALDpojQj16seFYufSlFJCARkHZvC/L2sHsphqsY1lMEB/zLLg4XDpCcyF5t49SfB9glI1c8jgOnyHuofhnw==", + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.1.22.tgz", + "integrity": "sha512-8PZxz2PGK9Ndr0C2LtWHrTzPKkDYTP/IvEMs9nrIebQWxvVjxI/HpvNfli3ivvCtvvcJFI26FvfWaAWDq14GgQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.11", "@rollup/plugin-node-resolve": "^11.0.1", "@types/command-line-args": "^5.0.0", "@web/config-loader": "^0.1.3", - "@web/dev-server-core": "^0.3.12", + "@web/dev-server-core": "^0.3.14", "@web/dev-server-rollup": "^0.3.9", "camelcase": "^6.2.0", "chalk": "^4.1.0", @@ -3866,9 +3874,9 @@ } }, "node_modules/@web/dev-server-core": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.3.13.tgz", - "integrity": "sha512-bGJHPeFRWATNfuL9Pp2LfqhnmqhBCc5eOO5AWQa0X+WQAwHiFo6xZNfsvsnJ1gvxXgsE4jKBAGu9lQRisvFRFA==", + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.3.14.tgz", + "integrity": "sha512-QHWGbkLI7qZVkELd6a7R4llRF9zydwbZagAeiJRvOIIiDhG5Uu9DfAWAQL+RSCb2hqBlEnaVAK4keNffKol4rQ==", "dev": true, "dependencies": { "@types/koa": "^2.11.6", @@ -3876,7 +3884,7 @@ "@web/parse5-utils": "^1.2.0", "chokidar": "^3.4.3", "clone": "^2.1.2", - "es-module-lexer": "^0.4.0", + "es-module-lexer": "^0.7.1", "get-stream": "^6.0.0", "is-stream": "^2.0.0", "isbinaryfile": "^4.0.6", @@ -4868,9 +4876,9 @@ } }, "node_modules/ast-metadata-inferer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.6.0.tgz", - "integrity": "sha512-vI/F+NP0g40QMfufPiWfuKCvFAZPC0o8VxqkizkLxl63SlBHOyUqRPsvcSm+rFyDDi9Uj+9CxWqGb72rdrgghw==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.7.0.tgz", + "integrity": "sha512-OkMLzd8xelb3gmnp6ToFvvsHLtS6CbagTkFQvQ+ZYFe3/AIl9iKikNR9G7pY3GfOR/2Xc222hwBjzI7HLkE76Q==", "dev": true, "dependencies": { "@mdn/browser-compat-data": "^3.3.14" @@ -4948,9 +4956,9 @@ "dev": true }, "node_modules/axe-core": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.2.tgz", - "integrity": "sha512-5LMaDRWm8ZFPAEdzTYmgjjEdj1YnQcpfrVajO/sn/LhbpGp0Y0H64c2hLZI1gRMxfA+w1S71Uc/nHaOXgcCvGg==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.3.tgz", + "integrity": "sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA==", "dev": true, "engines": { "node": ">=4" @@ -5507,16 +5515,16 @@ } }, "node_modules/browserslist": { - "version": "4.16.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.7.tgz", - "integrity": "sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA==", + "version": "4.16.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.8.tgz", + "integrity": "sha512-sc2m9ohR/49sWEbPj14ZSSZqp+kbi16aLao42Hmn3Z8FpjuMaq2xCA2l4zl9ITfyzvnvyE0hcg62YkIGKxgaNQ==", "dev": true, "dependencies": { - "caniuse-lite": "^1.0.30001248", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.793", + "caniuse-lite": "^1.0.30001251", + "colorette": "^1.3.0", + "electron-to-chromium": "^1.3.811", "escalade": "^3.1.1", - "node-releases": "^1.1.73" + "node-releases": "^1.1.75" }, "bin": { "browserslist": "cli.js" @@ -6120,9 +6128,9 @@ "dev": true }, "node_modules/colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz", + "integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==", "dev": true }, "node_modules/colors": { @@ -6189,12 +6197,12 @@ } }, "node_modules/comment-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.3.tgz", - "integrity": "sha512-vnqDwBSXSsdAkGS5NjwMIPelE47q+UkEgWKHvCDNhVIIaQSUFY6sNnEYGzdoPGMdpV+7KR3ZkRd7oyWIjtuvJg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", + "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", "dev": true, "engines": { - "node": "^12.20 || ^14.14.0 || ^16" + "node": ">= 12.0.0" } }, "node_modules/common-tags": { @@ -6462,9 +6470,9 @@ } }, "node_modules/core-js": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.16.2.tgz", - "integrity": "sha512-P0KPukO6OjMpjBtHSceAZEWlDD1M2Cpzpg6dBbrjFqFhBHe/BwhxaP820xKOjRn/lZRQirrCusIpLS/n2sgXLQ==", + "version": "3.16.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.16.3.tgz", + "integrity": "sha512-lM3GftxzHNtPNUJg0v4pC2RC6puwMd6VZA7vXUczi+SKmCWSf4JwO89VJGMqbzmB7jlK7B5hr3S64PqwFL49cA==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -6472,9 +6480,9 @@ } }, "node_modules/core-js-bundle": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/core-js-bundle/-/core-js-bundle-3.16.2.tgz", - "integrity": "sha512-U+PO0JTnTj4ZG3GaX541aQiaxA4gg34IZNpQt9ll1cO0KCJAh5QRfl27QrZuk2SCfxLRDvFVuW3KG6KNt8XZFQ==", + "version": "3.16.3", + "resolved": "https://registry.npmjs.org/core-js-bundle/-/core-js-bundle-3.16.3.tgz", + "integrity": "sha512-h2AiKHbsoj0RwI4mQqteOhdYxeKClV8QK0LoB92QDaggKgkQ+PSQyLGu0uV8bhXdyuPKB9VvdcCJa6k7OSlo5w==", "dev": true, "hasInstallScript": true, "funding": { @@ -6854,13 +6862,13 @@ "dev": true }, "node_modules/cypress": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-8.3.0.tgz", - "integrity": "sha512-zA5Rcq8AZIfRfPXU0CCcauofF+YpaU9HYbfqkunFTmFV0Kdlo14tNjH2E3++MkjXKFnv3/pXq+HgxWtw8CSe8Q==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-8.3.1.tgz", + "integrity": "sha512-1v6pfx+/5cXhaT5T6QKOvnkawmEHWHLiVzm3MYMoQN1fkX2Ma1C32STd3jBStE9qT5qPSTILjGzypVRxCBi40g==", "dev": true, "hasInstallScript": true, "dependencies": { - "@cypress/request": "^2.88.5", + "@cypress/request": "^2.88.6", "@cypress/xvfb": "^1.2.4", "@types/node": "^14.14.31", "@types/sinonjs__fake-timers": "^6.0.2", @@ -7684,9 +7692,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.3.808", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.808.tgz", - "integrity": "sha512-espnsbWTuUw0a2jMwfabCc09py2ujB+FZZE1hZWn5yYijEmxzEhdhTLKUfZGjynHvdIMQ4X/Pr/t8s4eiyH/QQ==", + "version": "1.3.822", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.822.tgz", + "integrity": "sha512-k7jG5oYYHxF4jx6PcqwHX3JVME/OjzolqOZiIogi9xtsfsmTjTdie4x88OakYFPEa8euciTgCCzvVNwvmjHb1Q==", "dev": true }, "node_modules/elix": { @@ -7902,9 +7910,9 @@ } }, "node_modules/es-abstract": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", - "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "version": "1.18.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", + "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", @@ -7913,16 +7921,17 @@ "get-intrinsic": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", "is-callable": "^1.2.3", "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.2", - "is-string": "^1.0.5", - "object-inspect": "^1.9.0", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.11.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", "string.prototype.trimend": "^1.0.4", "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.0" + "unbox-primitive": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -7932,9 +7941,9 @@ } }, "node_modules/es-module-lexer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", - "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz", + "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==", "dev": true }, "node_modules/es-to-primitive": { @@ -8259,16 +8268,16 @@ } }, "node_modules/eslint-plugin-compat": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.12.0.tgz", - "integrity": "sha512-PVTwl/3aaY2miq6vVfout1uqAYFYFGlMB9oMW7uGBG+a4XKbgxRwv7llC6IrUAWBzwL2XRGng89fW3YEk5rJhA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.13.0.tgz", + "integrity": "sha512-cv8IYMuTXm7PIjMVDN2y4k/KVnKZmoNGHNq27/9dLstOLydKblieIv+oe2BN2WthuXnFNhaNvv3N1Bvl4dbIGA==", "dev": true, "dependencies": { "@mdn/browser-compat-data": "^3.3.14", - "ast-metadata-inferer": "^0.6.0", - "browserslist": "^4.16.7", - "caniuse-lite": "^1.0.30001249", - "core-js": "^3.16.1", + "ast-metadata-inferer": "^0.7.0", + "browserslist": "^4.16.8", + "caniuse-lite": "^1.0.30001251", + "core-js": "^3.16.2", "find-up": "^5.0.0", "lodash.memoize": "4.1.2", "semver": "7.3.5" @@ -8406,26 +8415,26 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.0.tgz", - "integrity": "sha512-Kc6xqT9hiYi2cgybOc0I2vC9OgAYga5o/rAFinam/yF/t5uBqxQbauNPMC6fgb640T/89P0gFoO27FOilJ/Cqg==", + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", + "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", "dev": true, "dependencies": { "array-includes": "^3.1.3", "array.prototype.flat": "^1.2.4", "debug": "^2.6.9", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.5", + "eslint-import-resolver-node": "^0.3.6", "eslint-module-utils": "^2.6.2", "find-up": "^2.0.0", "has": "^1.0.3", - "is-core-module": "^2.4.0", + "is-core-module": "^2.6.0", "minimatch": "^3.0.4", - "object.values": "^1.1.3", + "object.values": "^1.1.4", "pkg-up": "^2.0.0", "read-pkg-up": "^3.0.0", "resolve": "^1.20.0", - "tsconfig-paths": "^3.9.0" + "tsconfig-paths": "^3.11.0" }, "engines": { "node": ">=4" @@ -8505,13 +8514,13 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "36.0.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-36.0.7.tgz", - "integrity": "sha512-x73l/WCRQ1qCjLq46Ca7csuGd5o3y3vbJIa3cktg11tdf3UZleBdIXKN9Cf0xjs3tXYPEy2SoNXowT8ydnjNDQ==", + "version": "36.0.8", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-36.0.8.tgz", + "integrity": "sha512-brNjHvRuBy5CaV01mSp6WljrO/T8fHNj0DXG38odOGDnhI7HdcbLKX7DpSvg2Rfcifwh8GlnNFzx13sI05t3bg==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "0.10.7", - "comment-parser": "1.2.3", + "@es-joy/jsdoccomment": "0.10.8", + "comment-parser": "1.2.4", "debug": "^4.3.2", "esquery": "^1.4.0", "jsdoc-type-pratt-parser": "^1.1.1", @@ -8521,7 +8530,7 @@ "spdx-expression-parse": "^3.0.1" }, "engines": { - "node": "^12.20 || ^14.14.0 || ^16" + "node": "^12 || ^14 || ^16" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0" @@ -10861,6 +10870,20 @@ "insert-module-globals": "bin/cmd.js" } }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -10995,9 +11018,9 @@ } }, "node_modules/is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", + "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -11309,13 +11332,13 @@ } }, "node_modules/is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -11334,12 +11357,18 @@ } }, "node_modules/is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-symbol": { @@ -14786,9 +14815,9 @@ } }, "node_modules/node-releases": { - "version": "1.1.74", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.74.tgz", - "integrity": "sha512-caJBVempXZPepZoZAPCWRTNxYQ+xtG/KAi4ozTA5A+nJ7IU+kLQCbqaUjb5Rwy14M9upBWiQ4NutcmW04LJSRw==", + "version": "1.1.75", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", + "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==", "dev": true }, "node_modules/node-static": { @@ -15361,9 +15390,9 @@ } }, "node_modules/object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15421,15 +15450,14 @@ } }, "node_modules/object.values": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", - "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" + "es-abstract": "^1.18.2" }, "engines": { "node": ">= 0.4" @@ -17858,9 +17886,9 @@ } }, "node_modules/rollup": { - "version": "2.56.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.56.2.tgz", - "integrity": "sha512-s8H00ZsRi29M2/lGdm1u8DJpJ9ML8SUOpVVBd33XNeEeL3NVaTiUcSBHzBdF3eAyR0l7VSpsuoVUGrRHq7aPwQ==", + "version": "2.56.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.56.3.tgz", + "integrity": "sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -18412,6 +18440,20 @@ "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", "dev": true }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", @@ -20056,9 +20098,9 @@ } }, "node_modules/tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", + "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", @@ -23845,9 +23887,9 @@ } }, "@cypress/request": { - "version": "2.88.5", - "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.5.tgz", - "integrity": "sha512-TzEC1XMi1hJkywWpRfD2clreTa/Z+lOrXDCxxBTBPEcY5azdPi56A6Xw+O4tWJnaJH3iIE7G5aDXZC6JgRZLcA==", + "version": "2.88.6", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.6.tgz", + "integrity": "sha512-z0UxBE/+qaESAHY9p9sM2h8Y4XqtsbDCt0/DPOrqA/RZgKi4PkxdpXyK4wCCnSk1xHqWHZZAE+gV6aDAR6+caQ==", "dev": true, "requires": { "aws-sign2": "~0.7.0", @@ -23863,13 +23905,12 @@ "isstream": "~0.1.2", "json-stringify-safe": "~5.0.1", "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" + "uuid": "^8.3.2" }, "dependencies": { "punycode": { @@ -23887,6 +23928,12 @@ "psl": "^1.1.28", "punycode": "^2.1.1" } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true } } }, @@ -23918,12 +23965,12 @@ } }, "@es-joy/jsdoccomment": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.10.7.tgz", - "integrity": "sha512-aNKZEoMESDzOBjKxCWrFuG50mcpMeKVBnBNko4+IZZ5t9zXYs8GT1KB0ZaOq1YUsKumDRc6YII/TQm309MJ0KQ==", + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.10.8.tgz", + "integrity": "sha512-3P1JiGL4xaR9PoTKUHa2N/LKwa2/eUdRqGwijMWWgBqbFEqJUVpmaOi2TcjcemrsRMgFLBzQCK4ToPhrSVDiFQ==", "dev": true, "requires": { - "comment-parser": "1.2.3", + "comment-parser": "1.2.4", "esquery": "^1.4.0", "jsdoc-type-pratt-parser": "1.1.1" } @@ -25207,16 +25254,16 @@ } }, "@web/dev-server": { - "version": "0.1.21", - "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.1.21.tgz", - "integrity": "sha512-au4ALDpojQj16seFYufSlFJCARkHZvC/L2sHsphqsY1lMEB/zLLg4XDpCcyF5t49SfB9glI1c8jgOnyHuofhnw==", + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.1.22.tgz", + "integrity": "sha512-8PZxz2PGK9Ndr0C2LtWHrTzPKkDYTP/IvEMs9nrIebQWxvVjxI/HpvNfli3ivvCtvvcJFI26FvfWaAWDq14GgQ==", "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@rollup/plugin-node-resolve": "^11.0.1", "@types/command-line-args": "^5.0.0", "@web/config-loader": "^0.1.3", - "@web/dev-server-core": "^0.3.12", + "@web/dev-server-core": "^0.3.14", "@web/dev-server-rollup": "^0.3.9", "camelcase": "^6.2.0", "chalk": "^4.1.0", @@ -25340,9 +25387,9 @@ } }, "@web/dev-server-core": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.3.13.tgz", - "integrity": "sha512-bGJHPeFRWATNfuL9Pp2LfqhnmqhBCc5eOO5AWQa0X+WQAwHiFo6xZNfsvsnJ1gvxXgsE4jKBAGu9lQRisvFRFA==", + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.3.14.tgz", + "integrity": "sha512-QHWGbkLI7qZVkELd6a7R4llRF9zydwbZagAeiJRvOIIiDhG5Uu9DfAWAQL+RSCb2hqBlEnaVAK4keNffKol4rQ==", "dev": true, "requires": { "@types/koa": "^2.11.6", @@ -25350,7 +25397,7 @@ "@web/parse5-utils": "^1.2.0", "chokidar": "^3.4.3", "clone": "^2.1.2", - "es-module-lexer": "^0.4.0", + "es-module-lexer": "^0.7.1", "get-stream": "^6.0.0", "is-stream": "^2.0.0", "isbinaryfile": "^4.0.6", @@ -26033,9 +26080,9 @@ "dev": true }, "ast-metadata-inferer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.6.0.tgz", - "integrity": "sha512-vI/F+NP0g40QMfufPiWfuKCvFAZPC0o8VxqkizkLxl63SlBHOyUqRPsvcSm+rFyDDi9Uj+9CxWqGb72rdrgghw==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.7.0.tgz", + "integrity": "sha512-OkMLzd8xelb3gmnp6ToFvvsHLtS6CbagTkFQvQ+ZYFe3/AIl9iKikNR9G7pY3GfOR/2Xc222hwBjzI7HLkE76Q==", "dev": true, "requires": { "@mdn/browser-compat-data": "^3.3.14" @@ -26098,9 +26145,9 @@ "dev": true }, "axe-core": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.2.tgz", - "integrity": "sha512-5LMaDRWm8ZFPAEdzTYmgjjEdj1YnQcpfrVajO/sn/LhbpGp0Y0H64c2hLZI1gRMxfA+w1S71Uc/nHaOXgcCvGg==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.3.tgz", + "integrity": "sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA==", "dev": true }, "axios": { @@ -26601,16 +26648,16 @@ } }, "browserslist": { - "version": "4.16.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.7.tgz", - "integrity": "sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA==", + "version": "4.16.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.8.tgz", + "integrity": "sha512-sc2m9ohR/49sWEbPj14ZSSZqp+kbi16aLao42Hmn3Z8FpjuMaq2xCA2l4zl9ITfyzvnvyE0hcg62YkIGKxgaNQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001248", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.793", + "caniuse-lite": "^1.0.30001251", + "colorette": "^1.3.0", + "electron-to-chromium": "^1.3.811", "escalade": "^3.1.1", - "node-releases": "^1.1.73" + "node-releases": "^1.1.75" } }, "btoa": { @@ -27075,9 +27122,9 @@ "dev": true }, "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz", + "integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==", "dev": true }, "colors": { @@ -27134,9 +27181,9 @@ "dev": true }, "comment-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.3.tgz", - "integrity": "sha512-vnqDwBSXSsdAkGS5NjwMIPelE47q+UkEgWKHvCDNhVIIaQSUFY6sNnEYGzdoPGMdpV+7KR3ZkRd7oyWIjtuvJg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", + "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", "dev": true }, "common-tags": { @@ -27356,14 +27403,14 @@ } }, "core-js": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.16.2.tgz", - "integrity": "sha512-P0KPukO6OjMpjBtHSceAZEWlDD1M2Cpzpg6dBbrjFqFhBHe/BwhxaP820xKOjRn/lZRQirrCusIpLS/n2sgXLQ==" + "version": "3.16.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.16.3.tgz", + "integrity": "sha512-lM3GftxzHNtPNUJg0v4pC2RC6puwMd6VZA7vXUczi+SKmCWSf4JwO89VJGMqbzmB7jlK7B5hr3S64PqwFL49cA==" }, "core-js-bundle": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/core-js-bundle/-/core-js-bundle-3.16.2.tgz", - "integrity": "sha512-U+PO0JTnTj4ZG3GaX541aQiaxA4gg34IZNpQt9ll1cO0KCJAh5QRfl27QrZuk2SCfxLRDvFVuW3KG6KNt8XZFQ==", + "version": "3.16.3", + "resolved": "https://registry.npmjs.org/core-js-bundle/-/core-js-bundle-3.16.3.tgz", + "integrity": "sha512-h2AiKHbsoj0RwI4mQqteOhdYxeKClV8QK0LoB92QDaggKgkQ+PSQyLGu0uV8bhXdyuPKB9VvdcCJa6k7OSlo5w==", "dev": true }, "core-js-compat": { @@ -27682,12 +27729,12 @@ } }, "cypress": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-8.3.0.tgz", - "integrity": "sha512-zA5Rcq8AZIfRfPXU0CCcauofF+YpaU9HYbfqkunFTmFV0Kdlo14tNjH2E3++MkjXKFnv3/pXq+HgxWtw8CSe8Q==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-8.3.1.tgz", + "integrity": "sha512-1v6pfx+/5cXhaT5T6QKOvnkawmEHWHLiVzm3MYMoQN1fkX2Ma1C32STd3jBStE9qT5qPSTILjGzypVRxCBi40g==", "dev": true, "requires": { - "@cypress/request": "^2.88.5", + "@cypress/request": "^2.88.6", "@cypress/xvfb": "^1.2.4", "@types/node": "^14.14.31", "@types/sinonjs__fake-timers": "^6.0.2", @@ -28356,9 +28403,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.808", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.808.tgz", - "integrity": "sha512-espnsbWTuUw0a2jMwfabCc09py2ujB+FZZE1hZWn5yYijEmxzEhdhTLKUfZGjynHvdIMQ4X/Pr/t8s4eiyH/QQ==", + "version": "1.3.822", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.822.tgz", + "integrity": "sha512-k7jG5oYYHxF4jx6PcqwHX3JVME/OjzolqOZiIogi9xtsfsmTjTdie4x88OakYFPEa8euciTgCCzvVNwvmjHb1Q==", "dev": true }, "elix": { @@ -28566,9 +28613,9 @@ } }, "es-abstract": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", - "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "version": "1.18.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", + "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -28577,22 +28624,23 @@ "get-intrinsic": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", "is-callable": "^1.2.3", "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.2", - "is-string": "^1.0.5", - "object-inspect": "^1.9.0", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.11.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", "string.prototype.trimend": "^1.0.4", "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.0" + "unbox-primitive": "^1.0.1" } }, "es-module-lexer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", - "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz", + "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==", "dev": true }, "es-to-primitive": { @@ -29095,16 +29143,16 @@ "requires": {} }, "eslint-plugin-compat": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.12.0.tgz", - "integrity": "sha512-PVTwl/3aaY2miq6vVfout1uqAYFYFGlMB9oMW7uGBG+a4XKbgxRwv7llC6IrUAWBzwL2XRGng89fW3YEk5rJhA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.13.0.tgz", + "integrity": "sha512-cv8IYMuTXm7PIjMVDN2y4k/KVnKZmoNGHNq27/9dLstOLydKblieIv+oe2BN2WthuXnFNhaNvv3N1Bvl4dbIGA==", "dev": true, "requires": { "@mdn/browser-compat-data": "^3.3.14", - "ast-metadata-inferer": "^0.6.0", - "browserslist": "^4.16.7", - "caniuse-lite": "^1.0.30001249", - "core-js": "^3.16.1", + "ast-metadata-inferer": "^0.7.0", + "browserslist": "^4.16.8", + "caniuse-lite": "^1.0.30001251", + "core-js": "^3.16.2", "find-up": "^5.0.0", "lodash.memoize": "4.1.2", "semver": "7.3.5" @@ -29199,26 +29247,26 @@ } }, "eslint-plugin-import": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.0.tgz", - "integrity": "sha512-Kc6xqT9hiYi2cgybOc0I2vC9OgAYga5o/rAFinam/yF/t5uBqxQbauNPMC6fgb640T/89P0gFoO27FOilJ/Cqg==", + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", + "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", "dev": true, "requires": { "array-includes": "^3.1.3", "array.prototype.flat": "^1.2.4", "debug": "^2.6.9", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.5", + "eslint-import-resolver-node": "^0.3.6", "eslint-module-utils": "^2.6.2", "find-up": "^2.0.0", "has": "^1.0.3", - "is-core-module": "^2.4.0", + "is-core-module": "^2.6.0", "minimatch": "^3.0.4", - "object.values": "^1.1.3", + "object.values": "^1.1.4", "pkg-up": "^2.0.0", "read-pkg-up": "^3.0.0", "resolve": "^1.20.0", - "tsconfig-paths": "^3.9.0" + "tsconfig-paths": "^3.11.0" }, "dependencies": { "doctrine": { @@ -29276,13 +29324,13 @@ } }, "eslint-plugin-jsdoc": { - "version": "36.0.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-36.0.7.tgz", - "integrity": "sha512-x73l/WCRQ1qCjLq46Ca7csuGd5o3y3vbJIa3cktg11tdf3UZleBdIXKN9Cf0xjs3tXYPEy2SoNXowT8ydnjNDQ==", + "version": "36.0.8", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-36.0.8.tgz", + "integrity": "sha512-brNjHvRuBy5CaV01mSp6WljrO/T8fHNj0DXG38odOGDnhI7HdcbLKX7DpSvg2Rfcifwh8GlnNFzx13sI05t3bg==", "dev": true, "requires": { - "@es-joy/jsdoccomment": "0.10.7", - "comment-parser": "1.2.3", + "@es-joy/jsdoccomment": "0.10.8", + "comment-parser": "1.2.4", "debug": "^4.3.2", "esquery": "^1.4.0", "jsdoc-type-pratt-parser": "^1.1.1", @@ -30891,6 +30939,17 @@ "xtend": "^4.0.0" } }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -30997,9 +31056,9 @@ "dev": true }, "is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", + "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", "dev": true, "requires": { "has": "^1.0.3" @@ -31242,13 +31301,13 @@ } }, "is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" + "has-tostringtag": "^1.0.0" } }, "is-stream": { @@ -31258,10 +31317,13 @@ "dev": true }, "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-symbol": { "version": "1.0.3", @@ -33852,9 +33914,9 @@ } }, "node-releases": { - "version": "1.1.74", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.74.tgz", - "integrity": "sha512-caJBVempXZPepZoZAPCWRTNxYQ+xtG/KAi4ozTA5A+nJ7IU+kLQCbqaUjb5Rwy14M9upBWiQ4NutcmW04LJSRw==", + "version": "1.1.75", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", + "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==", "dev": true }, "node-static": { @@ -34312,9 +34374,9 @@ } }, "object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", "dev": true }, "object-keys": { @@ -34354,15 +34416,14 @@ } }, "object.values": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", - "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" + "es-abstract": "^1.18.2" } }, "omggif": { @@ -36212,9 +36273,9 @@ } }, "rollup": { - "version": "2.56.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.56.2.tgz", - "integrity": "sha512-s8H00ZsRi29M2/lGdm1u8DJpJ9ML8SUOpVVBd33XNeEeL3NVaTiUcSBHzBdF3eAyR0l7VSpsuoVUGrRHq7aPwQ==", + "version": "2.56.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.56.3.tgz", + "integrity": "sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -36688,6 +36749,17 @@ "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", "dev": true }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", @@ -38033,9 +38105,9 @@ } }, "tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", + "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", "dev": true, "requires": { "@types/json5": "^0.0.29", diff --git a/package.json b/package.json index 6064f631..59c7659b 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "@babel/polyfill": "7.12.1", "browser-fs-access": "^0.20.4", "canvg": "3.0.7", - "core-js": "3.16.2", + "core-js": "3.16.3", "elix": "15.0.0", "html2canvas": "1.3.2", "i18next": "20.4.0", @@ -103,14 +103,14 @@ "@rollup/plugin-node-resolve": "13.0.4", "@rollup/plugin-replace": "3.0.0", "@rollup/plugin-url": "6.1.0", - "@web/dev-server": "0.1.21", + "@web/dev-server": "0.1.22", "@web/dev-server-rollup": "0.3.9", - "axe-core": "4.3.2", + "axe-core": "4.3.3", "babel-plugin-transform-object-rest-spread": "7.0.0-beta.3", "copyfiles": "2.4.1", - "core-js-bundle": "3.16.2", + "core-js-bundle": "3.16.3", "cp-cli": "2.0.0", - "cypress": "8.3.0", + "cypress": "8.3.1", "cypress-axe": "0.13.0", "cypress-multi-reporters": "1.5.0", "cypress-plugin-snapshots": "1.4.4", @@ -120,12 +120,12 @@ "eslint-plugin-chai-expect": "2.2.0", "eslint-plugin-chai-expect-keywords": "2.1.0", "eslint-plugin-chai-friendly": "0.7.2", - "eslint-plugin-compat": "3.12.0", + "eslint-plugin-compat": "3.13.0", "eslint-plugin-cypress": "2.11.3", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-html": "6.1.2", - "eslint-plugin-import": "2.24.0", - "eslint-plugin-jsdoc": "36.0.7", + "eslint-plugin-import": "2.24.2", + "eslint-plugin-jsdoc": "36.0.8", "eslint-plugin-markdown": "2.2.0", "eslint-plugin-no-unsanitized": "3.1.5", "eslint-plugin-no-use-extend-native": "0.5.0", @@ -144,7 +144,7 @@ "remark-cli": "10.0.0", "remark-lint-ordered-list-marker-value": "3.0.1", "rimraf": "3.0.2", - "rollup": "2.56.2", + "rollup": "2.56.3", "rollup-plugin-copy": "3.4.0", "rollup-plugin-filesize": "9.1.1", "rollup-plugin-node-polyfills": "0.2.1", From 5846eca53fab82389f76e89427f15a7f8be86919 Mon Sep 17 00:00:00 2001 From: JFH <20402845+jfhenon@users.noreply.github.com> Date: Sun, 29 Aug 2021 16:05:56 +0200 Subject: [PATCH 7/8] fix issues with svgtransform --- src/svgcanvas/event.js | 4 ++-- src/svgcanvas/history.js | 1 - src/svgcanvas/recalculate.js | 6 +++--- src/svgcanvas/selected-elem.js | 2 +- src/svgcanvas/selection.js | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/svgcanvas/event.js b/src/svgcanvas/event.js index 78acf72e..2fbd63a6 100644 --- a/src/svgcanvas/event.js +++ b/src/svgcanvas/event.js @@ -141,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 = selected.transform.baseVal; + 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 @@ -1043,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 = selectedElement.transform.baseVal; + const slist = selectedElement.transform?.baseVal; if (slist.numberOfItems) { slist.insertItemBefore(svgRoot.createSVGTransform(), 0); } else { diff --git a/src/svgcanvas/history.js b/src/svgcanvas/history.js index fde9e89e..6e0b5310 100644 --- a/src/svgcanvas/history.js +++ b/src/svgcanvas/history.js @@ -242,7 +242,6 @@ export class RemoveElementCommand extends Command { */ apply (handler) { super.apply(handler, () => { - this.removeElementFromListMap(); this.parent = this.elem.parentNode; this.elem.remove(); }); diff --git a/src/svgcanvas/recalculate.js b/src/svgcanvas/recalculate.js index 74562d3a..81e1d6df 100644 --- a/src/svgcanvas/recalculate.js +++ b/src/svgcanvas/recalculate.js @@ -76,7 +76,7 @@ export const recalculateDimensions = function (selected) { if (!selected) return null; const svgroot = context_.getSVGRoot(); const dataStorage = context_.getDataStorage(); - const tlist = selected.transform.baseVal; + const tlist = selected.transform?.baseVal; // remove any unnecessary transforms if (tlist && tlist.numberOfItems > 0) { let k = tlist.numberOfItems; @@ -477,7 +477,7 @@ export const recalculateDimensions = function (selected) { if (child.nodeType === 1) { oldStartTransform = context_.getStartTransform(); context_.setStartTransform(child.getAttribute('transform')); - const childTlist = child.transform.baseVal; + const childTlist = child.transform?.baseVal; if (!childTlist) { continue; } @@ -558,7 +558,7 @@ export const recalculateDimensions = function (selected) { if (child.nodeType === 1) { oldStartTransform = context_.getStartTransform(); context_.setStartTransform(child.getAttribute('transform')); - const childTlist = child.transform.baseVal; + const childTlist = child.transform?.baseVal; const newxlate = svgroot.createSVGTransform(); newxlate.setTranslate(tx, ty); if (childTlist.numberOfItems) { diff --git a/src/svgcanvas/selected-elem.js b/src/svgcanvas/selected-elem.js index a8511864..db0763f3 100644 --- a/src/svgcanvas/selected-elem.js +++ b/src/svgcanvas/selected-elem.js @@ -168,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 = selected.transform.baseVal; + const tlist = selected.transform?.baseVal; // dx and dy could be arrays if (Array.isArray(dx)) { diff --git a/src/svgcanvas/selection.js b/src/svgcanvas/selection.js index 8aef35ec..40e71bf6 100644 --- a/src/svgcanvas/selection.js +++ b/src/svgcanvas/selection.js @@ -161,7 +161,7 @@ export const getMouseTargetMethod = function (evt) { return svgCanvas.selectorManager.selectorParentGroup; } - while (!mouseTarget.parentNode?.isSameNode(selectionContext_.getCurrentGroup() || currentLayer)) { + while (!mouseTarget?.parentNode?.isSameNode(selectionContext_.getCurrentGroup() || currentLayer)) { mouseTarget = mouseTarget.parentNode; } From 33189a22c13a058bd277b5833eb88c84bf763924 Mon Sep 17 00:00:00 2001 From: JFH <20402845+jfhenon@users.noreply.github.com> Date: Sun, 29 Aug 2021 16:17:06 +0200 Subject: [PATCH 8/8] fix snapshots --- .../ui/__snapshots__/scenario2.js.snap | 140 ++++++++-------- .../ui/__snapshots__/scenario4.js.snap | 158 +++++++++--------- .../ui/__snapshots__/scenario5.js.snap | 88 +++++----- 3 files changed, 193 insertions(+), 193 deletions(-) diff --git a/cypress/integration/ui/__snapshots__/scenario2.js.snap b/cypress/integration/ui/__snapshots__/scenario2.js.snap index ce009cdd..241be924 100644 --- a/cypress/integration/ui/__snapshots__/scenario2.js.snap +++ b/cypress/integration/ui/__snapshots__/scenario2.js.snap @@ -331,6 +331,68 @@ exports[`use all parts of svg-edit > check tool_ellipse_change_rotation #0`] = ` `; +exports[`use all parts of svg-edit > check tool_ellipse_change_blur #0`] = ` + + + Layer 1 + + + + + + + + + + +`; + exports[`use all parts of svg-edit > check tool_ellipse_change_cx_cy_coordinate #0`] = ` check tool_ellipse_change_cx_cy_coordinate > - - + + @@ -448,8 +510,8 @@ exports[`use all parts of svg-edit > check tool_ellipse_change_rx_ry_radius #0`] > - - + + @@ -510,8 +572,8 @@ exports[`use all parts of svg-edit > check tool_ellipse_bring_to_back #0`] = ` > - - + + @@ -572,8 +634,8 @@ exports[`use all parts of svg-edit > check tool_ellipse_bring_to_front #0`] = ` > - - + + @@ -646,68 +708,6 @@ exports[`use all parts of svg-edit > check tool_ellipse_clone #0`] = ` id="svg_4" > - - - - - - -`; - -exports[`use all parts of svg-edit > check tool_ellipse_change_blur #0`] = ` - - - Layer 1 - - - - diff --git a/cypress/integration/ui/__snapshots__/scenario4.js.snap b/cypress/integration/ui/__snapshots__/scenario4.js.snap index 3bad2580..57e732f8 100644 --- a/cypress/integration/ui/__snapshots__/scenario4.js.snap +++ b/cypress/integration/ui/__snapshots__/scenario4.js.snap @@ -280,6 +280,69 @@ exports[`use all parts of svg-edit > check tool_rect_change_rotation #0`] = ` `; +exports[`use all parts of svg-edit > check tool_rect_change_blur #0`] = ` + + + Layer 1 + + + + + + + + + + +`; + exports[`use all parts of svg-edit > check tool_rect_change_opacity #0`] = ` check tool_rect_change_opacity #0`] = ` > - - + + @@ -400,8 +463,8 @@ exports[`use all parts of svg-edit > check tool_fhrect_change_x_y_coordinate #0` > - - + + @@ -463,8 +526,8 @@ exports[`use all parts of svg-edit > check tool_fhrect_change_width_height #0`] > - - + + @@ -537,8 +600,8 @@ exports[`use all parts of svg-edit > check tool_square_clone #0`] = ` > - - + + @@ -611,8 +674,8 @@ exports[`use all parts of svg-edit > check tool_square_bring_to_back #0`] = ` > - - + + @@ -685,8 +748,8 @@ exports[`use all parts of svg-edit > check tool_square_bring_to_front #0`] = ` > - - + + @@ -761,8 +824,8 @@ exports[`use all parts of svg-edit > check tool_square_change_corner_radius #0`] > - - + + @@ -835,8 +898,8 @@ exports[`use all parts of svg-edit > check tool_rect_change_to_path #0`] = ` > - - + + @@ -881,69 +944,6 @@ exports[`use all parts of svg-edit > check tool_rect_delete #0`] = ` ry="25" > - - - - - - -`; - -exports[`use all parts of svg-edit > check tool_rect_change_blur #0`] = ` - - - Layer 1 - - - - diff --git a/cypress/integration/ui/__snapshots__/scenario5.js.snap b/cypress/integration/ui/__snapshots__/scenario5.js.snap index ab0a001c..947b63a5 100644 --- a/cypress/integration/ui/__snapshots__/scenario5.js.snap +++ b/cypress/integration/ui/__snapshots__/scenario5.js.snap @@ -84,6 +84,44 @@ exports[`use all parts of svg-edit > check tool_line_change_rotation #0`] = ` `; +exports[`use all parts of svg-edit > check tool_line_change_blur #0`] = ` + + + Layer 1 + + + + + + + + +`; + exports[`use all parts of svg-edit > check tool_line_change_opacity #0`] = ` check tool_line_change_opacity #0`] = ` > - - + + @@ -139,8 +177,8 @@ exports[`use all parts of svg-edit > check tool_line_delete #0`] = ` Layer 1 - - + + @@ -207,8 +245,8 @@ exports[`use all parts of svg-edit > check tool_line_clone #0`] = ` - - + + @@ -265,44 +303,6 @@ exports[`use all parts of svg-edit > check tool_fhrect_change_x_y_coordinate #0` > - - - - - - -`; - -exports[`use all parts of svg-edit > check tool_line_change_blur #0`] = ` - - - Layer 1 - -