- Linting (ESLint): Lint per latest ash-nazg (e.g., named capture)

- Linting (ESLint): Add HTML files to linting and add devDeps for new ash-nazg
- npm: Update devDeps
master
Brett Zamir 2019-07-02 12:21:21 +08:00
parent af290bd743
commit e4231aeb10
30 changed files with 313 additions and 267 deletions

View File

@ -99,6 +99,18 @@ module.exports = {
"import/unambiguous": ["off"]
}
},
{
files: ['test/browser-bugs/**'],
rules: {
'no-var': 'off'
}
},
{
files: ['**/*.html'],
rules: {
'import/unambiguous': 'off'
}
},
// Our Markdown rules (and used for JSDoc examples as well, by way of
// our use of `matchingFileName` in conjunction with
// `jsdoc/check-examples` within `ash-nazg`)
@ -114,6 +126,7 @@ module.exports = {
"import/no-unresolved": ["off"],
"node/no-missing-import": ["off"],
"no-multi-spaces": "off",
"sonarjs/no-all-duplicated-branches": "off",
// Disable until may fix https://github.com/gajus/eslint-plugin-jsdoc/issues/211
"indent": "off"
}
@ -126,6 +139,7 @@ module.exports = {
root: "off"
},
rules: {
"node/no-unsupported-features/es-syntax": "off",
"node/no-unsupported-features/node-builtins": "off"
}
},

View File

@ -8,6 +8,7 @@
`ext-server_opensave.js`
- Optimization: Re-rerun image optimization per update
- Linting (ESLint): Adjust per now applied rules
- Linting (ESLint): Add HTML files to linting
- Refactoring: Use `static` keyword for classes
- Testing: Accessibility test API update
- Docs: Clarify need for Node.js/npm being installed

View File

@ -25,6 +25,7 @@
</div>
<script type="module">
/* globals canvas */
import SvgCanvas from '../editor/svgcanvas.js';
const container = document.querySelector('#editorContainer');
@ -39,7 +40,7 @@ const config = {
initOpacity: 1,
imgPath: 'editor/images/',
dimensions: [width, height],
baseUnit: 'px',
baseUnit: 'px'
};
window.canvas = new SvgCanvas(container, config);

View File

@ -1,4 +1,4 @@
/* eslint-disable new-cap, class-methods-use-this */
/* eslint-disable new-cap, class-methods-use-this, prefer-named-capture-group */
// Todo: Compare with latest canvg (add any improvements of ours) and add full JSDocs (denoting links to standard APIs and which are custom): https://github.com/canvg/canvg
/**
* canvg.js - Javascript SVG parser and renderer on Canvas
@ -13,7 +13,7 @@ import {canvasRGBA} from '../external/stackblur-canvas/dist/stackblur-es.js';
/**
* Whether a value is `null` or `undefined`.
* @param {Any} val
* @param {any} val
* @returns {boolean}
*/
const isNullish = (val) => {

View File

@ -154,21 +154,21 @@ const simpleColors = {
// array of color definition objects
const colorDefs = [
{
re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
re: /^rgb\((?<r>\d{1,3}),\s*(?<g>\d{1,3}),\s*(?<b>\d{1,3})\)$/,
example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'],
process (_, ...bits) {
return bits.map((b) => parseInt(b));
}
},
{
re: /^(\w{2})(\w{2})(\w{2})$/,
re: /^(?<r>\w{2})(?<g>\w{2})(?<b>\w{2})$/,
example: ['#00ff00', '336699'],
process (_, ...bits) {
return bits.map((b) => parseInt(b, 16));
}
},
{
re: /^(\w{1})(\w{1})(\w{1})$/,
re: /^(?<r>\w{1})(?<g>\w{1})(?<b>\w{1})$/,
example: ['#fb0', 'f0f'],
process (_, ...bits) {
return bits.map((b) => parseInt(b + b, 16));
@ -210,7 +210,7 @@ export default class RGBColor {
Object.assign(this, {r, g, b});
this.ok = true;
}
}, this);
});
// validate/cleanup values
this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);

View File

@ -51,9 +51,8 @@ export const init = function (editorContext) {
/**
* Applies coordinate changes to an element based on the given matrix.
* @function module:coords.remapElement
* @implements {module:path.EditorContext#remapElement}
* @returns {void}
* @name module:coords.remapElement
* @type {module:path.EditorContext#remapElement}
*/
export const remapElement = function (selected, changes, m) {
const remap = function (x, y) { return transformPoint(x, y, m); },

View File

@ -96,6 +96,8 @@ const framePath = '/editor/xdomain-svg-editor-es.html?extensions=ext-xdomain-mes
const iframe = $('<iframe width="900px" height="600px" id="svgedit"></iframe>');
iframe[0].src = frameBase + framePath +
(location.href.includes('?')
// ? location.href.replace(/\?(?<search>.*)$/, '&$<search>')
// eslint-disable-next-line prefer-named-capture-group
? location.href.replace(/\?(.*)$/, '&$1')
: ''); // Append arguments to this file onto the iframe

View File

@ -12,7 +12,7 @@ let cbid = 0;
*/
/**
* @callback module:EmbeddedSVGEdit.CallbackSetGetter
* @param {...Any} args Signature dependent on the function
* @param {...any} args Signature dependent on the function
* @returns {module:EmbeddedSVGEdit.CallbackSetter}
*/

View File

@ -65,11 +65,11 @@ export default {
function getLinked (elem, attr) {
const str = elem.getAttribute(attr);
if (!str) { return null; }
const m = str.match(/\(#(.*)\)/);
if (!m || m.length !== 2) {
const m = str.match(/\(#(?<id>.+)\)/);
if (!m || !m.groups.id) {
return null;
}
return svgCanvas.getElem(m[1]);
return svgCanvas.getElem(m.groups.id);
}
/**

View File

@ -86,11 +86,11 @@ export default {
function getLinked (elem, attr) {
const str = elem.getAttribute(attr);
if (!str) { return null; }
const m = str.match(/\(#(.*)\)/);
if (!m || m.length !== 2) {
const m = str.match(/\(#(?<id>.+)\)/);
if (!m || !m.groups.id) {
return null;
}
return svgCanvas.getElem(m[1]);
return svgCanvas.getElem(m.groups.id);
}
/**
@ -254,7 +254,7 @@ export default {
function convertline (elem) {
// this routine came from the connectors extension
// it is needed because midpoint markers don't work with line elements
if (!(elem.tagName === 'line')) { return elem; }
if (elem.tagName !== 'line') { return elem; }
// Convert to polyline to accept mid-arrow

View File

@ -70,11 +70,11 @@ export default {
if (!elem) { return null; }
const str = elem.getAttribute(attr);
if (!str) { return null; }
const m = str.match(/\(#(.*)\)/);
if (!m || m.length !== 2) {
const m = str.match(/\(#(?<id>.+)\)/);
if (!m || !m.groups.id) {
return null;
}
return svgCanvas.getElem(m[1]);
return svgCanvas.getElem(m.groups.id);
}
/**

View File

@ -56,8 +56,8 @@ export default {
val = val ? 'storagePrompt=' + val : '';
const loc = top.location; // Allow this to work with the embedded editor as well
if (loc.href.includes('storagePrompt=')) {
loc.href = loc.href.replace(/([&?])storagePrompt=[^&]*(&?)/, function (n0, n1, amp) {
return (val ? n1 : '') + val + (!val && amp ? n1 : (amp || ''));
loc.href = loc.href.replace(/(?<sep>[&?])storagePrompt=[^&]*(?<amp>&?)/, function (n0, sep, amp) {
return (val ? sep : '') + val + (!val && amp ? sep : (amp || ''));
});
} else {
loc.href += (loc.href.includes('?') ? '&' : '?') + val;

View File

@ -39,9 +39,9 @@ function addScriptAtts (script, atts) {
/**
* @function module:importModule.importSetGlobalDefault
* @param {string|GenericArray<Any>} url
* @param {string|GenericArray<any>} url
* @param {module:importModule.ImportConfig} config
* @returns {Promise<Any>} The value to which it resolves depends on the export of the targeted module.
* @returns {Promise<any>} The value to which it resolves depends on the export of the targeted module.
*/
export function importSetGlobalDefault (url, config) {
return importSetGlobal(url, {...config, returnDefault: true});
@ -118,7 +118,7 @@ export function importScript (url, atts = {}) {
* @param {PlainObject} [atts={}]
* @param {PlainObject} opts
* @param {boolean} [opts.returnDefault=false} = {}]
* @returns {Promise<Any>} Resolves to value of loading module or rejects with
* @returns {Promise<any>} Resolves to value of loading module or rejects with
* `Error` upon a script loading error.
*/
export function importModule (url, atts = {}, {returnDefault = false} = {}) {

View File

@ -32,7 +32,7 @@ function toFixedNumeric (value, precision) {
/**
* Whether a value is `null` or `undefined`.
* @param {Any} val
* @param {any} val
* @returns {boolean}
*/
const isNullish = (val) => {

View File

@ -1484,12 +1484,12 @@ export const reorientGrads = function (elem, m) {
const pt2 = transformPoint(x2, y2, m);
// Convert back to BB points
const gCoords = {};
gCoords.x1 = (pt1.x - bb.x) / bb.width;
gCoords.y1 = (pt1.y - bb.y) / bb.height;
gCoords.x2 = (pt2.x - bb.x) / bb.width;
gCoords.y2 = (pt2.y - bb.y) / bb.height;
const gCoords = {
x1: (pt1.x - bb.x) / bb.width,
y1: (pt1.y - bb.y) / bb.height,
x2: (pt2.x - bb.x) / bb.width,
y2: (pt2.y - bb.y) / bb.height
};
const newgrad = grad.cloneNode(true);
$(newgrad).attr(gCoords);
@ -1632,6 +1632,7 @@ export const convertPath = function (pth, toRel) {
}
d += pathDSegment(letter, [[x1, y1], [x, y]]);
break;
// eslint-disable-next-line sonarjs/no-duplicated-branches
case 10: // absolute elliptical arc (A)
x -= curx;
y -= cury;

View File

@ -3,6 +3,6 @@
// We only need to replace the first instance
location.href = location.href
.replace(/(xdomain-)?svg-editor-es\.html/, 'svg-editor.html')
.replace(/(?:xdomain-)?svg-editor-es\.html/, 'svg-editor.html')
.replace('openclipart-es.html', 'openclipart.html')
.replace('imagelib/index-es.html', 'imagelib/index.html');

View File

@ -166,7 +166,7 @@ export const sanitizeSvg = function (node) {
case 'transform':
case 'gradientTransform':
case 'patternTransform': {
const val = attr.value.replace(/(\d)-/g, '$1 -');
const val = attr.value.replace(/(?<digit>\d)-/g, '$<digit> -');
node.setAttribute(attrName, val);
break;
}

View File

@ -495,7 +495,7 @@ editor.setConfig = function (opts, cfgCfg) {
*
* @param {module:SVGEditor.Config|module:SVGEditor.Prefs} cfgObj
* @param {string} key
* @param {Any} val See {@link module:SVGEditor.Config} or {@link module:SVGEditor.Prefs}
* @param {any} val See {@link module:SVGEditor.Config} or {@link module:SVGEditor.Prefs}
* @returns {void}
*/
function extendOrAdd (cfgObj, key, val) {
@ -757,7 +757,7 @@ editor.init = function () {
qstr = $.param.querystring();
if (!src) { // urldata.source may have been null if it ended with '='
if (qstr.includes('source=data:')) {
src = qstr.match(/source=(data:[^&]*)/)[1];
({src} = qstr.match(/source=(?<src>data:[^&]*)/).groups);
}
}
if (src) {
@ -820,7 +820,7 @@ editor.init = function () {
try {
await Promise.all(
curConfig.extensions.map(async (extname) => {
const extName = extname.match(/^ext-(.+)\.js/);
const {extName} = extname.match(/^ext-(?<extName>.+)\.js/).groups;
if (!extName) { // Ensure URL cannot specify some other unintended file in the extPath
return undefined;
}
@ -838,9 +838,9 @@ editor.init = function () {
* @type {module:SVGEditor.ExtensionObject}
*/
const imported = await importSetGlobalDefault(url, {
global: 'svgEditorExtension_' + extName[1].replace(/-/g, '_')
global: 'svgEditorExtension_' + extName.replace(/-/g, '_')
});
const {name = extName[1], init} = imported;
const {name = extName, init} = imported;
const importLocale = getImportLocale({defaultLang: langParam, defaultName: name});
return editor.addExtension(name, (init && init.bind(editor)), {$, importLocale});
} catch (err) {
@ -909,7 +909,7 @@ editor.init = function () {
* @type {string}
*/
const uaPrefix = (function () {
const regex = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/;
const regex = /^(?:Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/;
const someScript = document.getElementsByTagName('script')[0];
for (const prop in someScript.style) {
if (regex.test(prop)) {
@ -2735,7 +2735,7 @@ editor.init = function () {
};
/**
* @implements {module:jQuerySpinButton.ValueCallback}
* @type {module:jQuerySpinButton.ValueCallback}
*/
const changeZoom = function (ctl) {
const zoomlevel = ctl.value / 100;
@ -3581,21 +3581,21 @@ editor.init = function () {
$('#image_save_opts input').val([$.pref('img_save')]);
/**
* @implements {module:jQuerySpinButton.ValueCallback}
* @type {module:jQuerySpinButton.ValueCallback}
*/
const changeRectRadius = function (ctl) {
svgCanvas.setRectRadius(ctl.value);
};
/**
* @implements {module:jQuerySpinButton.ValueCallback}
* @type {module:jQuerySpinButton.ValueCallback}
*/
const changeFontSize = function (ctl) {
svgCanvas.setFontSize(ctl.value);
};
/**
* @implements {module:jQuerySpinButton.ValueCallback}
* @type {module:jQuerySpinButton.ValueCallback}
*/
const changeStrokeWidth = function (ctl) {
let val = ctl.value;
@ -3606,7 +3606,7 @@ editor.init = function () {
};
/**
* @implements {module:jQuerySpinButton.ValueCallback}
* @type {module:jQuerySpinButton.ValueCallback}
*/
const changeRotationAngle = function (ctl) {
svgCanvas.setRotationAngle(ctl.value);
@ -5456,8 +5456,7 @@ editor.init = function () {
$(window).bind('load resize', centerCanvas);
/**
* @implements {module:jQuerySpinButton.StepCallback}
* @returns {Float}
* @type {module:jQuerySpinButton.StepCallback}
*/
function stepFontSize (elem, step) {
const origVal = Number(elem.value);
@ -5481,8 +5480,7 @@ editor.init = function () {
}
/**
* @implements {module:jQuerySpinButton.StepCallback}
* @returns {Float}
* @type {module:jQuerySpinButton.StepCallback}
*/
function stepZoom (elem, step) {
const origVal = Number(elem.value);
@ -6519,7 +6517,7 @@ let extensionsAdded = false;
const messageQueue = [];
/**
* @param {PlainObject} info
* @param {Any} info.data
* @param {any} info.data
* @param {string} info.origin
* @fires module:svgcanvas.SvgCanvas#event:message
* @returns {void}

View File

@ -228,9 +228,8 @@ canvas.current_drawing_ = new draw.Drawing(svgcontent, idprefix);
/**
* Returns the current Drawing.
* @function module:svgcanvas.SvgCanvas#getCurrentDrawing
* @implements {module:draw.DrawCanvasInit#getCurrentDrawing}
* @returns {module:draw.Drawing}
* @name module:svgcanvas.SvgCanvas#getCurrentDrawing
* @type {module:draw.DrawCanvasInit#getCurrentDrawing}
*/
const getCurrentDrawing = canvas.getCurrentDrawing = function () {
return canvas.current_drawing_;
@ -315,9 +314,8 @@ const getJsonFromSvgElement = this.getJsonFromSvgElement = function (data) {
/**
* This should really be an intersection implementing all rather than a union.
* @function module:svgcanvas.SvgCanvas#addSVGElementFromJson
* @implements {module:utilities.EditorContext#addSVGElementFromJson|module:path.EditorContext#addSVGElementFromJson}
* @returns {Element} The new element
* @name module:svgcanvas.SvgCanvas#addSVGElementFromJson
* @type {module:utilities.EditorContext#addSVGElementFromJson|module:path.EditorContext#addSVGElementFromJson}
*/
const addSVGElementFromJson = this.addSVGElementFromJson = function (data) {
if (typeof data === 'string') return svgdoc.createTextNode(data);
@ -370,8 +368,7 @@ canvas.hasMatrixTransform = hasMatrixTransform;
canvas.transformListToTransform = transformListToTransform;
/**
* @implements {module:utilities.EditorContext#getBaseUnit}
* @returns {string}
* @type {module:utilities.EditorContext#getBaseUnit}
*/
const getBaseUnit = () => { return curConfig.baseUnit; };
@ -396,16 +393,14 @@ canvas.convertToNum = convertToNum;
/**
* This should really be an intersection implementing all rather than a union.
* @implements {module:draw.DrawCanvasInit#getSVGContent|module:utilities.EditorContext#getSVGContent}
* @returns {SVGSVGElement}
* @type {module:draw.DrawCanvasInit#getSVGContent|module:utilities.EditorContext#getSVGContent}
*/
const getSVGContent = () => { return svgcontent; };
/**
* Should really be an intersection with all needing to apply rather than a union.
* @function module:svgcanvas.SvgCanvas#getSelectedElements
* @implements {module:utilities.EditorContext#getSelectedElements|module:draw.DrawCanvasInit#getSelectedElements|module:path.EditorContext#getSelectedElements}
* @returns {Element[]} the array with selected DOM elements
* @name module:svgcanvas.SvgCanvas#getSelectedElements
* @type {module:utilities.EditorContext#getSelectedElements|module:draw.DrawCanvasInit#getSelectedElements|module:path.EditorContext#getSelectedElements}
*/
const getSelectedElements = this.getSelectedElems = function () {
return selectedElements;
@ -415,8 +410,7 @@ const {pathActions} = pathModule;
/**
* This should actually be an intersection as all interfaces should be met.
* @implements {module:utilities.EditorContext#getSVGRoot|module:recalculate.EditorContext#getSVGRoot|module:coords.EditorContext#getSVGRoot|module:path.EditorContext#getSVGRoot}
* @returns {SVGSVGElement}
* @type {module:utilities.EditorContext#getSVGRoot|module:recalculate.EditorContext#getSVGRoot|module:coords.EditorContext#getSVGRoot|module:path.EditorContext#getSVGRoot}
*/
const getSVGRoot = () => svgroot;
@ -452,8 +446,7 @@ this.cleanupElement = cleanupElement;
/**
* This should actually be an intersection not a union as all should apply.
* @implements {module:coords.EditorContext#getGridSnapping|module:path.EditorContext#getGridSnapping}
* @returns {boolean}
* @type {module:coords.EditorContext#getGridSnapping|module:path.EditorContext#getGridSnapping}
*/
const getGridSnapping = () => { return curConfig.gridSnapping; };
@ -559,8 +552,8 @@ const undoMgr = canvas.undoMgr = new UndoManager({
/**
* This should really be an intersection applying to all types rather than a union.
* @function module:svgcanvas~addCommandToHistory
* @implements {module:path.EditorContext#addCommandToHistory|module:draw.DrawCanvasInit#addCommandToHistory}
* @name module:svgcanvas~addCommandToHistory
* @type {module:path.EditorContext#addCommandToHistory|module:draw.DrawCanvasInit#addCommandToHistory}
*/
const addCommandToHistory = function (cmd) {
canvas.undoMgr.addCommandToHistory(cmd);
@ -568,17 +561,15 @@ const addCommandToHistory = function (cmd) {
/**
* This should really be an intersection applying to all types rather than a union.
* @function module:svgcanvas.SvgCanvas#getZoom
* @implements {module:path.EditorContext#getCurrentZoom|module:select.SVGFactory#getCurrentZoom}
* @returns {Float} The current zoom level
* @name module:svgcanvas.SvgCanvas#getZoom
* @type {module:path.EditorContext#getCurrentZoom|module:select.SVGFactory#getCurrentZoom}
*/
const getCurrentZoom = this.getZoom = function () { return currentZoom; };
/**
* This method rounds the incoming value to the nearest value based on the `currentZoom`
* @function module:svgcanvas.SvgCanvas#round
* @implements {module:path.EditorContext#round}
* @returns {Float} Rounded value to nearest value based on `currentZoom`
* @name module:svgcanvas.SvgCanvas#round
* @type {module:path.EditorContext#round}
*/
const round = this.round = function (val) {
return parseInt(val * currentZoom) / currentZoom;
@ -605,18 +596,16 @@ selectInit(
const selectorManager = this.selectorManager = getSelectorManager();
/**
* @function module:svgcanvas.SvgCanvas#getNextId
* @implements {module:path.EditorContext#getNextId}
* @returns {string}
* @name module:svgcanvas.SvgCanvas#getNextId
* @type {module:path.EditorContext#getNextId}
*/
const getNextId = canvas.getNextId = function () {
return getCurrentDrawing().getNextId();
};
/**
* @function module:svgcanvas.SvgCanvas#getId
* @implements {module:path.EditorContext#getId}
* @returns {string}
* @name module:svgcanvas.SvgCanvas#getId
* @type {module:path.EditorContext#getId}
*/
const getId = canvas.getId = function () {
return getCurrentDrawing().getId();
@ -624,11 +613,8 @@ const getId = canvas.getId = function () {
/**
* The "implements" should really be an intersection applying to all types rather than a union.
* @function module:svgcanvas.SvgCanvas#call
* @implements {module:draw.DrawCanvasInit#call|module:path.EditorContext#call}
* @param {"selected"|"changed"|"contextset"|"pointsAdded"|"extension_added"|"extensions_added"|"message"|"transition"|"zoomed"|"updateCanvas"|"zoomDone"|"saved"|"exported"|"exportedPDF"|"setnonce"|"unsetnonce"|"cleared"} ev - String with the event name
* @param {module:svgcanvas.SvgCanvas#event:GenericCanvasEvent} arg - Argument to pass through to the callback function.
* @returns {module:svgcanvas.EventHandlerReturn|void}
* @name module:svgcanvas.SvgCanvas#call
* @type {module:draw.DrawCanvasInit#call|module:path.EditorContext#call}
*/
const call = function (ev, arg) {
if (events[ev]) {
@ -640,8 +626,8 @@ const call = function (ev, arg) {
/**
* Clears the selection. The 'selected' handler is then optionally called.
* This should really be an intersection applying to all types rather than a union.
* @function module:svgcanvas.SvgCanvas#clearSelection
* @implements {module:draw.DrawCanvasInit#clearSelection|module:path.EditorContext#clearSelection}
* @name module:svgcanvas.SvgCanvas#clearSelection
* @type {module:draw.DrawCanvasInit#clearSelection|module:path.EditorContext#clearSelection}
* @fires module:svgcanvas.SvgCanvas#event:selected
*/
const clearSelection = this.clearSelection = function (noCall) {
@ -658,10 +644,9 @@ const clearSelection = this.clearSelection = function (noCall) {
/**
* Adds a list of elements to the selection. The 'selected' handler is then called.
* @function module:svgcanvas.SvgCanvas#addToSelection
* @implements {module:path.EditorContext#addToSelection}
* @name module:svgcanvas.SvgCanvas#addToSelection
* @type {module:path.EditorContext#addToSelection}
* @fires module:svgcanvas.SvgCanvas#event:selected
* @returns {void}
*/
const addToSelection = this.addToSelection = function (elemsToAdd, showGrips) {
if (!elemsToAdd.length) { return; }
@ -730,17 +715,15 @@ const addToSelection = this.addToSelection = function (elemsToAdd, showGrips) {
};
/**
* @implements {module:path.EditorContext#getOpacity}
* @returns {Float}
* @type {module:path.EditorContext#getOpacity}
*/
const getOpacity = function () {
return curShape.opacity;
};
/**
* @function module:svgcanvas.SvgCanvas#getMouseTarget
* @implements {module:path.EditorContext#getMouseTarget}
* @returns {Element} DOM element we want
* @name module:svgcanvas.SvgCanvas#getMouseTarget
* @type {module:path.EditorContext#getMouseTarget}
*/
const getMouseTarget = this.getMouseTarget = function (evt) {
if (isNullish(evt)) {
@ -803,7 +786,7 @@ const getMouseTarget = this.getMouseTarget = function (evt) {
*/
canvas.pathActions = pathActions;
/**
* @implements {module:path.EditorContext#resetD}
* @type {module:path.EditorContext#resetD}
*/
function resetD (p) {
p.setAttribute('d', pathActions.convertPath(p));
@ -1386,7 +1369,7 @@ canvas.call = call;
*/
/**
* @typedef {PlainObject} module:svgcanvas.Message
* @property {Any} data The data
* @property {any} data The data
* @property {string} origin The origin
*/
/**
@ -4549,9 +4532,9 @@ this.setSvgString = function (xmlString, preventUndo) {
if (val) {
if (val.startsWith('data:')) {
// Check if an SVG-edit data URI
const m = val.match(/svgedit_url=(.*?);/);
const m = val.match(/svgedit_url=(?<url>.*?);/);
if (m) {
const url = decodeURIComponent(m[1]);
const url = decodeURIComponent(m.groups.url);
$(new Image()).load(function () {
image.setAttributeNS(NS.XLINK, 'xlink:href', url);
}).attr('src', url);

View File

@ -145,19 +145,20 @@ export class SVGTransformList { // eslint-disable-line no-shadow
if (!str) { return; }
// TODO: Add skew support in future
const re = /\s*((scale|matrix|rotate|translate)\s*\(.*?\))\s*,?\s*/;
const re = /\s*(?<xform>(?:scale|matrix|rotate|translate)\s*\(.*?\))\s*,?\s*/;
let m = true;
while (m) {
m = str.match(re);
str = str.replace(re, '');
if (m && m[1]) {
const x = m[1];
const bits = x.split(/\s*\(/);
const name = bits[0];
const valBits = bits[1].match(/\s*(.*?)\s*\)/);
valBits[1] = valBits[1].replace(/(\d)-/g, '$1 -');
const valArr = valBits[1].split(/[, ]+/);
const letters = 'abcdef'.split('');
if (m && m.groups.xform) {
const x = m.groups.xform;
const [name, bits] = x.split(/\s*\(/);
const valBits = bits.match(/\s*(?<nonWhitespace>.*?)\s*\)/);
valBits.groups.nonWhitespace = valBits.groups.nonWhitespace.replace(
/(?<digit>\d)-/g, '$<digit> -'
);
const valArr = valBits.groups.nonWhitespace.split(/[, ]+/);
const letters = [...'abcdef'];
const mtx = svgroot.createSVGMatrix();
Object.values(valArr).forEach(function (item, i) {
valArr[i] = parseFloat(item);

View File

@ -13,12 +13,12 @@
/**
* This should only be used when the return result from a callback
* is not known as to type.
* @typedef {Any} ArbitraryCallbackResult
* @typedef {any} ArbitraryCallbackResult
*/
/**
* @callback GenericCallback
* @param {...Any} args Signature dependent on the function
* @param {...any} args Signature dependent on the function
* @returns {ArbitraryCallbackResult} Return dependent on the function
*/

View File

@ -110,7 +110,7 @@ export const init = function (editorContext) {
* @todo This might be needed in other places `parseFromString` is used even without LGTM flagging
*/
export const dropXMLInteralSubset = (str) => {
return str.replace(/(<!DOCTYPE\s+\w*\s*\[).*(\?\]>)/, '$1$2');
return str.replace(/(?<doctypeOpen><!DOCTYPE\s+\w*\s*\[).*(?<doctypeClose>\?\]>)/, '$<doctypeOpen>$<doctypeClose>');
};
/**
@ -265,9 +265,9 @@ export const dataURLToObjectURL = function (dataurl) {
if (typeof Uint8Array === 'undefined' || typeof Blob === 'undefined' || typeof URL === 'undefined' || !URL.createObjectURL) {
return '';
}
const arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]);
const [prefix, suffix] = dataurl.split(','),
{groups: {mime}} = prefix.match(/:(?<mime>.*?);/),
bstr = atob(suffix);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
@ -330,6 +330,7 @@ export const convertToXMLReferences = function (input) {
*/
export const text2xml = function (sXML) {
if (sXML.includes('<svg:svg')) {
// eslint-disable-next-line prefer-named-capture-group
sXML = sXML.replace(/<(\/?)svg:/g, '<$1').replace('xmlns:svg', 'xmlns');
}
@ -651,11 +652,13 @@ export const getBBox = function (elem) {
// have a featured detection for correct 'use' behavior?
// ——————————
if (!isWebkit()) {
const bb = {};
bb.width = ret.width;
bb.height = ret.height;
bb.x = ret.x + parseFloat(selected.getAttribute('x') || 0);
bb.y = ret.y + parseFloat(selected.getAttribute('y') || 0);
const {x, y, width, height} = ret;
const bb = {
width,
height,
x: x + parseFloat(selected.getAttribute('x') || 0),
y: y + parseFloat(selected.getAttribute('y') || 0)
};
ret = bb;
}
} else if (visElemsArr.includes(elname)) {
@ -1369,7 +1372,7 @@ export const copyElem = function (el, getNextId) {
/**
* Whether a value is `null` or `undefined`.
* @param {Any} val
* @param {any} val
* @returns {boolean}
*/
export const isNullish = (val) => {

View File

@ -5,11 +5,15 @@
<title>SVG Edit</title>
<link rel="stylesheet" href="style.css">
<script>
// This method adds the script that overrides the default open/save handlers
/* eslint-disable no-unused-vars */
/**
* This method adds the script that overrides the default open/save handlers.
* @returns {void}
*/
function addHandlers () {
var cdoc = document.getElementById('container').contentDocument;
const cdoc = document.getElementById('container').contentDocument;
if (cdoc) {
var scriptelm = cdoc.createElement('script');
const scriptelm = cdoc.createElement('script');
scriptelm.src = '../handlers.js';
cdoc.getElementsByTagName('head')[0].appendChild(scriptelm);
}

292
package-lock.json generated
View File

@ -822,36 +822,20 @@
}
},
"@mysticatea/eslint-plugin": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/@mysticatea/eslint-plugin/-/eslint-plugin-10.0.3.tgz",
"integrity": "sha512-lsZeSINcepg5SSbA+FX/n/A7M/Qz+wwRWKBsg2IPk52Xi+R1X02lqd4sAzZGG2HvsPiGyoKJ/Ejx9rQPzLoh4A==",
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/@mysticatea/eslint-plugin/-/eslint-plugin-11.0.0.tgz",
"integrity": "sha512-MJt/iaAeYeKP7JpTWpGuoLBtyV4o743ipTUC0ZrM2CC7X0HB6PvxGhjQpQEy2IcM1yrwnuZvbIxlg0UComL7uQ==",
"dev": true,
"requires": {
"@typescript-eslint/eslint-plugin": "~1.7.0",
"@typescript-eslint/parser": "~1.7.0",
"eslint-plugin-eslint-comments": "~3.1.1",
"eslint-plugin-eslint-plugin": "~2.0.1",
"eslint-plugin-node": "~8.0.1",
"eslint-plugin-prettier": "~3.0.1",
"eslint-plugin-vue": "~5.2.2",
"prettier": "~1.14.3",
"@typescript-eslint/eslint-plugin": "~1.11.0",
"@typescript-eslint/parser": "~1.11.0",
"eslint-plugin-eslint-comments": "~3.1.2",
"eslint-plugin-eslint-plugin": "~2.1.0",
"eslint-plugin-node": "~9.1.0",
"eslint-plugin-prettier": "~3.1.0",
"eslint-plugin-vue": "~5.2.3",
"prettier": "~1.18.2",
"vue-eslint-parser": "^5.0.0"
},
"dependencies": {
"eslint-plugin-node": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-8.0.1.tgz",
"integrity": "sha512-ZjOjbjEi6jd82rIpFSgagv4CHWzG9xsQAVp1ZPlhRnnYxcTgENUVBvhYmkQ7GvT1QFijUSo69RaiOJKhMu6i8w==",
"dev": true,
"requires": {
"eslint-plugin-es": "^1.3.1",
"eslint-utils": "^1.3.1",
"ignore": "^5.0.2",
"minimatch": "^3.0.4",
"resolve": "^1.8.1",
"semver": "^5.5.0"
}
}
}
},
"@nodelib/fs.stat": {
@ -920,6 +904,12 @@
"integrity": "sha1-4ByfjIXKg7YQMgxiJYsMkCat4Pc=",
"dev": true
},
"@types/eslint-visitor-keys": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
"integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
"dev": true
},
"@types/estree": {
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
@ -989,34 +979,44 @@
}
},
"@typescript-eslint/eslint-plugin": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.7.0.tgz",
"integrity": "sha512-NUSz1aTlIzzTjFFVFyzrbo8oFjHg3K/M9MzYByqbMCxeFdErhLAcGITVfXzSz+Yvp5OOpMu3HkIttB0NyKl54Q==",
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.11.0.tgz",
"integrity": "sha512-mXv9ccCou89C8/4avKHuPB2WkSZyY/XcTQUXd5LFZAcLw1I3mWYVjUu6eS9Ja0QkP/ClolbcW9tb3Ov/pMdcqw==",
"dev": true,
"requires": {
"@typescript-eslint/parser": "1.7.0",
"@typescript-eslint/typescript-estree": "1.7.0",
"@typescript-eslint/experimental-utils": "1.11.0",
"eslint-utils": "^1.3.1",
"functional-red-black-tree": "^1.0.1",
"regexpp": "^2.0.1",
"requireindex": "^1.2.0",
"tsutils": "^3.7.0"
}
},
"@typescript-eslint/parser": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.7.0.tgz",
"integrity": "sha512-1QFKxs2V940372srm12ovSE683afqc1jB6zF/f8iKhgLz1yoSjYeGHipasao33VXKI+0a/ob9okeogGdKGvvlg==",
"@typescript-eslint/experimental-utils": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.11.0.tgz",
"integrity": "sha512-7LbfaqF6B8oa8cp/315zxKk8FFzosRzzhF8Kn/ZRsRsnpm7Qcu25cR/9RnAQo5utZ2KIWVgaALr+ZmcbG47ruw==",
"dev": true,
"requires": {
"@typescript-eslint/typescript-estree": "1.7.0",
"eslint-scope": "^4.0.0",
"@typescript-eslint/typescript-estree": "1.11.0",
"eslint-scope": "^4.0.0"
}
},
"@typescript-eslint/parser": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.11.0.tgz",
"integrity": "sha512-5xBExyXaxVyczrZvbRKEXvaTUFFq7gIM9BynXukXZE0zF3IQP/FxF4mPmmh3gJ9egafZFqByCpPTFm3dk4SY7Q==",
"dev": true,
"requires": {
"@types/eslint-visitor-keys": "^1.0.0",
"@typescript-eslint/experimental-utils": "1.11.0",
"@typescript-eslint/typescript-estree": "1.11.0",
"eslint-visitor-keys": "^1.0.0"
}
},
"@typescript-eslint/typescript-estree": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.7.0.tgz",
"integrity": "sha512-K5uedUxVmlYrVkFbyV3htDipvLqTE3QMOUQEHYJaKtgzxj6r7c5Ca/DG1tGgFxX+fsbi9nDIrf4arq7Ib7H/Yw==",
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.11.0.tgz",
"integrity": "sha512-fquUHF5tAx1sM2OeRCC7wVxFd1iMELWMGCzOSmJ3pLzArj9+kRixdlC4d5MncuzXpjEqc6045p3KwM0o/3FuUA==",
"dev": true,
"requires": {
"lodash.unescape": "4.0.1",
@ -3256,6 +3256,22 @@
"esutils": "^2.0.2"
}
},
"dom-serializer": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
"integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
"dev": true,
"requires": {
"domelementtype": "^1.3.0",
"entities": "^1.1.1"
}
},
"domelementtype": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
"dev": true
},
"domexception": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
@ -3265,6 +3281,25 @@
"webidl-conversions": "^4.0.2"
}
},
"domhandler": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
"dev": true,
"requires": {
"domelementtype": "1"
}
},
"domutils": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
"integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
"dev": true,
"requires": {
"dom-serializer": "0",
"domelementtype": "1"
}
},
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@ -3503,9 +3538,9 @@
}
},
"eslint-config-ash-nazg": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/eslint-config-ash-nazg/-/eslint-config-ash-nazg-7.0.1.tgz",
"integrity": "sha512-ehn/qLall1uvXzyQlaU0qDlIMQNdP4n8HjnGDA10W4srGyvSw8D7FcWLWVhqYVXuLf6XvUqEQJ4kduv2Y2yCjA==",
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-ash-nazg/-/eslint-config-ash-nazg-8.0.0.tgz",
"integrity": "sha512-up9ExREHf2ag2ps/xXg8OTpwqOnYtPALs0kEKJBp0Ljq5okdJMHiv5RI7tuYNbtkNm1TsgYJp45EmvqpRiQqFQ==",
"dev": true
},
"eslint-config-standard": {
@ -3620,6 +3655,12 @@
}
}
},
"eslint-plugin-array-func": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-array-func/-/eslint-plugin-array-func-3.1.3.tgz",
"integrity": "sha512-uRfJ4d9Fyyvxm6/w++++RSQoXZyERFF0+6zqupgg5Mw/+eG4y19yrptTghJlApntKlPZBpA4XCOIBzJbvLrArQ==",
"dev": true
},
"eslint-plugin-compat": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.2.0.tgz",
@ -3663,11 +3704,20 @@
}
},
"eslint-plugin-eslint-plugin": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-eslint-plugin/-/eslint-plugin-eslint-plugin-2.0.1.tgz",
"integrity": "sha512-kJ5TZsRJH/xYstG07v3YeOy/W5SDAEzV+bvvoL0aiG1HtqDmg4mJvNPnn/JngANMmsx8oXlJrIcBTCpJzm+9kg==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-eslint-plugin/-/eslint-plugin-eslint-plugin-2.1.0.tgz",
"integrity": "sha512-kT3A/ZJftt28gbl/Cv04qezb/NQ1dwYIbi8lyf806XMxkus7DvOVCLIfTXMrorp322Pnoez7+zabXH29tADIDg==",
"dev": true
},
"eslint-plugin-html": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.0.0.tgz",
"integrity": "sha512-PQcGippOHS+HTbQCStmH5MY1BF2MaU8qW/+Mvo/8xTa/ioeMXdSP+IiaBw2+nh0KEMfYQKuTz1Zo+vHynjwhbg==",
"dev": true,
"requires": {
"htmlparser2": "^3.10.1"
}
},
"eslint-plugin-import": {
"version": "2.18.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.0.tgz",
@ -3773,9 +3823,9 @@
}
},
"eslint-plugin-prettier": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.0.1.tgz",
"integrity": "sha512-/PMttrarPAY78PLvV3xfWibMOdMDl57hmlQ2XqFeA37wd+CJ7WSxV7txqjVPHi/AAFKd2lX0ZqfsOc/i5yFCSQ==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.0.tgz",
"integrity": "sha512-XWX2yVuwVNLOUhQijAkXz+rMPPoCr7WFiAl8ig6I7Xn+pPVhDhzg4DxHpmbeb0iqjO9UronEA3Tb09ChnFVHHA==",
"dev": true,
"requires": {
"prettier-linter-helpers": "^1.0.0"
@ -3793,6 +3843,12 @@
"integrity": "sha512-+0i2xcYryUoLawi47Lp0iJKzkP931G5GXwIOq1KBKQc2pknV1VPjfE6b4mI2mR2RnL7WRoS30YjwC9SjQgJDXQ==",
"dev": true
},
"eslint-plugin-sonarjs": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.4.0.tgz",
"integrity": "sha512-l8E4ueMKVtEcocINHSNVH/YBSmDDXZlPEbud7bagRGyoCeB0otoyltoro5kdnIvVzS5usUwvjzMocHnPax2FEw==",
"dev": true
},
"eslint-plugin-standard": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz",
@ -5123,6 +5179,33 @@
"whatwg-encoding": "^1.0.1"
}
},
"htmlparser2": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
"dev": true,
"requires": {
"domelementtype": "^1.3.1",
"domhandler": "^2.3.0",
"domutils": "^1.5.1",
"entities": "^1.1.1",
"inherits": "^2.0.1",
"readable-stream": "^3.1.1"
},
"dependencies": {
"readable-stream": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
"integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
@ -5150,9 +5233,9 @@
"dev": true
},
"imageoptim-cli": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/imageoptim-cli/-/imageoptim-cli-2.3.6.tgz",
"integrity": "sha512-Ua5zNEAEDrQU9R9L+2Y5n2dcPTxeqCgrd93HRa2aZ95Negp3/LIZH/mmne80Pl6WGldR3sDgYZ8SJw8RQNojVQ==",
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/imageoptim-cli/-/imageoptim-cli-2.3.7.tgz",
"integrity": "sha512-DKNwuFhK+ovU3vdOxZdKvRB6xx4DFe68hs2ohv1EoRGNyqpjGTyMN34bycSt787QCTLXZPpF6ppD2yKVm0EE+A==",
"dev": true,
"requires": {
"chalk": "2.4.2",
@ -6208,9 +6291,9 @@
"dev": true
},
"match-url-wildcard": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/match-url-wildcard/-/match-url-wildcard-0.0.2.tgz",
"integrity": "sha512-XQWEV4NdsB6HymtjW5sJthh1oHr/IZZPp+lOhu+RPkWDD0iQYXVCe8ozGQmi5ZxWqXYteERjHhN80zxLV/TNWA==",
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/match-url-wildcard/-/match-url-wildcard-0.0.4.tgz",
"integrity": "sha512-R1XhQaamUZPWLOPtp4ig5j+3jctN+skhgRmEQTUamMzmNtRG69QEirQs0NZKLtHMR7tzWpmtnS4Eqv65DcgXUA==",
"dev": true,
"requires": {
"escape-string-regexp": "^1.0.5"
@ -7106,9 +7189,9 @@
"dev": true
},
"prettier": {
"version": "1.14.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.14.3.tgz",
"integrity": "sha512-qZDVnCrnpsRJJq5nSsiHCE3BYMED2OtsI+cmzIzF1QIfqm5ALf8tEJcO27zV1gKNKRPdhjO0dNWnrzssDQ1tFg==",
"version": "1.18.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz",
"integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==",
"dev": true
},
"prettier-linter-helpers": {
@ -7733,12 +7816,6 @@
}
}
},
"requireindex": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz",
"integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==",
"dev": true
},
"requizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.2.tgz",
@ -7818,13 +7895,13 @@
}
},
"rollup": {
"version": "1.16.3",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-1.16.3.tgz",
"integrity": "sha512-iXINUUEk2NTZXE3GcUtLQt2cvfQsAUXBQ8AFsDK8tg7Wp5bwTKdZXPdzB2IJQwHpdUNfsIgYMAfajurh7SVTnA==",
"version": "1.16.4",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-1.16.4.tgz",
"integrity": "sha512-Bht8QXoo2dJc8lUGyEMfnfKCV7hkf1oLzN6L8YdDE2toaaoCe5DxoqYjTyKswWQyiZseViZw9quEdDRz0YXifw==",
"dev": true,
"requires": {
"@types/estree": "0.0.39",
"@types/node": "^12.0.8",
"@types/node": "^12.0.10",
"acorn": "^6.1.1"
}
},
@ -7860,13 +7937,14 @@
}
},
"rollup-plugin-terser": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.0.0.tgz",
"integrity": "sha512-W+jJ4opYnlmNyVW0vtRufs+EGf68BIJ7bnOazgz8mgz8pA9lUyrEifAhPs5y9M16wFeAyBGaRjKip4dnFBtXaw==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.1.0.tgz",
"integrity": "sha512-tvJweguo+f9T1SBcSmEMaArCUM07mIg61ArqPj3Fty9OdwTLCxBUBdxS3e1cU68Z1lXf52JBhbt3yRuQoHLtQg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"jest-worker": "^24.6.0",
"rollup-pluginutils": "^2.8.1",
"serialize-javascript": "^1.7.0",
"terser": "^4.0.0"
}
@ -8485,9 +8563,9 @@
}
},
"terser": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.0.0.tgz",
"integrity": "sha512-dOapGTU0hETFl1tCo4t56FN+2jffoKyER9qBGoUFyZ6y7WLoKT0bF+lAYi6B6YsILcGF3q1C2FBh8QcKSCgkgA==",
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.0.2.tgz",
"integrity": "sha512-IWLuJqTvx97KP3uTYkFVn93cXO+EtlzJu8TdJylq+H0VBDlPMIfQA9MBS5Vc5t3xTEUG1q0hIfHMpAP2R+gWTw==",
"dev": true,
"requires": {
"commander": "^2.19.0",
@ -8504,9 +8582,9 @@
}
},
"testcafe": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/testcafe/-/testcafe-1.2.1.tgz",
"integrity": "sha512-kLlrtujAPabG8mh2JNLFIUmhZSHgfeQlT1TO9PikkjBhduirK2OCL6ye8pvyw9rOQVqwIl214wCv5DgAJcaC0w==",
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/testcafe/-/testcafe-1.3.0.tgz",
"integrity": "sha512-5OJoHKIEjKJB9CkNzdnQ7tzdegurohAlojw61fGyTtD7ZK0zZ4pd34+4pGMnJyqQh66U6RfYSNHdxWhHcDYnKA==",
"dev": true,
"requires": {
"@types/node": "^10.12.19",
@ -8535,7 +8613,7 @@
"emittery": "^0.4.1",
"endpoint-utils": "^1.0.2",
"error-stack-parser": "^1.3.6",
"globby": "^3.0.1",
"globby": "^9.2.0",
"graceful-fs": "^4.1.11",
"graphlib": "^2.1.5",
"import-lazy": "^3.1.0",
@ -8569,7 +8647,7 @@
"source-map-support": "^0.5.5",
"strip-bom": "^2.0.0",
"testcafe-browser-tools": "1.6.8",
"testcafe-hammerhead": "14.6.8",
"testcafe-hammerhead": "14.6.10",
"testcafe-legacy-api": "3.1.11",
"testcafe-reporter-json": "^2.1.0",
"testcafe-reporter-list": "^2.1.0",
@ -8629,33 +8707,6 @@
"integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
"dev": true
},
"glob": {
"version": "5.0.15",
"resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
"integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
"dev": true,
"requires": {
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "2 || 3",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"globby": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/globby/-/globby-3.0.1.tgz",
"integrity": "sha1-IJSvhCHhkVIVDViT62QWsxLZoi8=",
"dev": true,
"requires": {
"array-union": "^1.0.1",
"arrify": "^1.0.0",
"glob": "^5.0.3",
"object-assign": "^4.0.1",
"pify": "^2.0.0",
"pinkie-promise": "^1.0.0"
}
},
"indent-string": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-1.2.2.tgz",
@ -8717,23 +8768,6 @@
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
},
"pinkie-promise": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz",
"integrity": "sha1-0dpn9UglY7t89X8oauKCLs+/NnA=",
"dev": true,
"requires": {
"pinkie": "^1.0.0"
},
"dependencies": {
"pinkie": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz",
"integrity": "sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q=",
"dev": true
}
}
},
"repeating": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz",
@ -8821,9 +8855,9 @@
}
},
"testcafe-hammerhead": {
"version": "14.6.8",
"resolved": "https://registry.npmjs.org/testcafe-hammerhead/-/testcafe-hammerhead-14.6.8.tgz",
"integrity": "sha512-Ep/eBmIBli/utdtzczl1NFRO9Gl/WHzyLTh0kifkbV/xm5EM8FBnSEb72kNrTlPLngvFXAqJccAUaU4DALA+Jg==",
"version": "14.6.10",
"resolved": "https://registry.npmjs.org/testcafe-hammerhead/-/testcafe-hammerhead-14.6.10.tgz",
"integrity": "sha512-fG/YTz7wKs6Fd0Fl9WlzO4j/ovDSAGxDLvLAz4ydzIKAdnZMZ22QbjYpfahCVpe9nzq/UHCQpSFdThQTmlFEmA==",
"dev": true,
"requires": {
"acorn-hammerhead": "^0.2.0",
@ -8835,7 +8869,7 @@
"iconv-lite": "0.4.11",
"lodash": "4.17.11",
"lru-cache": "2.6.3",
"match-url-wildcard": "0.0.2",
"match-url-wildcard": "0.0.4",
"merge-stream": "^1.0.1",
"mime": "~1.4.1",
"mustache": "^2.1.1",

View File

@ -22,7 +22,7 @@
"compress-images": "imageoptim 'chrome-app/*.png' && imageoptim 'editor/extensions/*.png' && imageoptim 'editor/spinbtn/*.png' && imageoptim 'editor/jgraduate/images/*.{png,gif}' && imageoptim 'editor/images/*.png'",
"copy": "cp node_modules/load-stylesheets/dist/index-es.js editor/external/load-stylesheets/index-es.js && cp node_modules/jamilih/dist/jml-es.js editor/external/jamilih/jml-es.js && cp node_modules/query-result/esm/index.js editor/external/query-result/esm/index.js && cp node_modules/qr-manipulation/dist/index-es.js editor/external/qr-manipulation/dist/index-es.js && cp node_modules/stackblur-canvas/dist/stackblur-es.js editor/external/stackblur-canvas/dist/stackblur-es.js && cp node_modules/regenerator-runtime/runtime.js editor/external/regenerator-runtime/runtime.js && cp node_modules/core-js-bundle/minified.js editor/external/core-js-bundle/minified.js",
"remark": "remark -q -f .",
"eslint": "eslint --ext js,md .",
"eslint": "eslint --ext js,md,html .",
"rollup": "rollup -c",
"start-embedded": "echo \"Open file to http://localhost:8000/editor/embedapi.html\" && static -p 8000 | static -p 8001 -H '{\"Access-Control-Allow-Origin\": \"*\"}'",
"start": "echo \"Open file to http://localhost:8000/test/all_tests.html\" && static -p 8000",
@ -80,16 +80,18 @@
"@babel/node": "^7.4.5",
"@babel/plugin-transform-modules-commonjs": "^7.4.4",
"@babel/preset-env": "^7.4.5",
"@mysticatea/eslint-plugin": "^10.0.3",
"@mysticatea/eslint-plugin": "^11.0.0",
"axe-core": "^3.2.2",
"axe-testcafe": "^3.0.0",
"babel-plugin-transform-object-rest-spread": "^7.0.0-beta.3",
"core-js-bundle": "^3.1.4",
"eslint": "6.0.1",
"eslint-config-ash-nazg": "7.0.1",
"eslint-config-ash-nazg": "8.0.0",
"eslint-config-standard": "12.0.0",
"eslint-plugin-array-func": "^3.1.3",
"eslint-plugin-compat": "^3.2.0",
"eslint-plugin-eslint-comments": "^3.1.2",
"eslint-plugin-html": "^6.0.0",
"eslint-plugin-import": "2.18.0",
"eslint-plugin-jsdoc": "^10.0.3",
"eslint-plugin-markdown": "^1.0.0",
@ -97,10 +99,11 @@
"eslint-plugin-node": "9.1.0",
"eslint-plugin-promise": "4.2.1",
"eslint-plugin-qunit": "^4.0.0",
"eslint-plugin-sonarjs": "^0.4.0",
"eslint-plugin-standard": "4.0.0",
"eslint-plugin-testcafe": "^0.2.1",
"eslint-plugin-unicorn": "^9.1.1",
"imageoptim-cli": "^2.3.6",
"imageoptim-cli": "^2.3.7",
"jamilih": "^0.45.0",
"jsdoc": "^3.6.2",
"load-stylesheets": "^0.8.0",
@ -113,13 +116,13 @@
"regenerator-runtime": "^0.13.2",
"remark-cli": "^6.0.1",
"remark-lint-ordered-list-marker-value": "^1.0.3",
"rollup": "1.16.3",
"rollup": "1.16.4",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-re": "^1.0.7",
"rollup-plugin-terser": "^5.0.0",
"rollup-plugin-terser": "^5.1.0",
"sinon": "^7.3.2",
"sinon-test": "^2.4.0",
"stackblur-canvas": "^2.2.0",
"testcafe": "^1.2.1"
"testcafe": "^1.3.0"
}
}

View File

@ -1,4 +1,6 @@
/* eslint-env node */
// Wait until Node 10 to enable
/* eslint-disable prefer-named-capture-group */
// NOTE:
// See rollup-config.config.js instead for building the main (configurable)

View File

@ -244,7 +244,7 @@ SlideShow.prototype = {
}
},
handleKeys (e) {
if ((/^(input|textarea)$/i).test(e.target.nodeName)) return;
if ((/^(?:input|textarea)$/i).test(e.target.nodeName)) return;
switch (e.keyCode) {
case 37: // left arrow

View File

@ -7,9 +7,10 @@
<link rel="stylesheet" href="../node_modules/qunit/qunit/qunit.css"/>
<script src="../editor/jquery.min.js"></script>
<script>
// Mock for browser.js
window.svgEditor = {
ready () {}
ready () {
// Mock for browser.js
}
};
</script>
<script src="../node_modules/qunit/qunit/qunit.js"></script>

View File

@ -2,7 +2,7 @@
* Expects an out of bounds `INDEX_SIZE_ERR` exception.
* @param {GenericObject} obj
* @param {GenericCallback} fn
* @param {Any} arg1
* @param {any} arg1
* @returns {void}
*/
function expectOutOfBoundsException (obj, fn, arg1) {

View File

@ -290,8 +290,7 @@ QUnit.test('Test getPathDFromElement', function (assert) {
QUnit.test('Test getBBoxOfElementAsPath', function (assert) {
/**
* Wrap `utilities.getBBoxOfElementAsPath` to convert bbox to object for testing.
* @implements {module:utilities.getBBoxOfElementAsPath}
* @returns {DOMRect|false} The resulting path's bounding box object.
* @type {module:utilities.getBBoxOfElementAsPath}
*/
function getBBoxOfElementAsPath (elem, addSVGElementFromJson, pathActions) {
const bbox = utilities.getBBoxOfElementAsPath(elem, addSVGElementFromJson, pathActions);