- 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
This commit is contained in:
@@ -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) => {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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); },
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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}
|
||||
*/
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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} = {}) {
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user