- Fix: Avoid race condition in jQuery.svgIcons.js (evident

when attempting to load from `file:` URL in Chrome)
- npm: Update devDeps
This commit is contained in:
Brett Zamir
2019-07-04 15:15:58 +08:00
parent b5e61a238e
commit f734625587
23 changed files with 2816 additions and 851 deletions

View File

@@ -88,6 +88,66 @@ $(function() {
});
*/
const isOpera = Boolean(window.opera);
const fixIDs = function (svgEl, svgNum, force) {
const defs = svgEl.find('defs');
if (!defs.length) return svgEl;
let idElems;
if (isOpera) {
idElems = defs.find('*').filter(function () {
return Boolean(this.id);
});
} else {
idElems = defs.find('[id]');
}
const allElems = svgEl[0].getElementsByTagName('*'),
len = allElems.length;
idElems.each(function (i) {
const {id} = this;
/*
const noDupes = ($(svgdoc).find('#' + id).length <= 1);
if (isOpera) noDupes = false; // Opera didn't clone svgEl, so not reliable
if(!force && noDupes) return;
*/
const newId = 'x' + id + svgNum + i;
this.id = newId;
const oldVal = 'url(#' + id + ')';
const newVal = 'url(#' + newId + ')';
// Selector method, possibly faster but fails in Opera / jQuery 1.4.3
// svgEl.find('[fill="url(#' + id + ')"]').each(function() {
// this.setAttribute('fill', 'url(#' + newId + ')');
// }).end().find('[stroke="url(#' + id + ')"]').each(function() {
// this.setAttribute('stroke', 'url(#' + newId + ')');
// }).end().find('use').each(function() {
// if(this.getAttribute('xlink:href') == '#' + id) {
// this.setAttributeNS(xlinkns,'href','#' + newId);
// }
// }).end().find('[filter="url(#' + id + ')"]').each(function() {
// this.setAttribute('filter', 'url(#' + newId + ')');
// });
for (i = 0; i < len; i++) {
const elem = allElems[i];
if (elem.getAttribute('fill') === oldVal) {
elem.setAttribute('fill', newVal);
}
if (elem.getAttribute('stroke') === oldVal) {
elem.setAttribute('stroke', newVal);
}
if (elem.getAttribute('filter') === oldVal) {
elem.setAttribute('filter', newVal);
}
}
});
return svgEl;
};
/**
* @callback module:jQuerySVGIcons.SVGIconsLoadedCallback
* @param {PlainObject<string, external:jQuery>} svgIcons IDs keyed to jQuery objects of images
@@ -101,7 +161,6 @@ $(function() {
export default function jQueryPluginSVGIcons ($) {
const svgIcons = {};
let fixIDs;
/**
* Map of raster images with each key being the SVG icon ID
* to replace, and the value the image file name
@@ -154,8 +213,7 @@ export default function jQueryPluginSVGIcons ($) {
iconsMade = false,
dataLoaded = false,
loadAttempts = 0;
const isOpera = Boolean(window.opera),
// ua = navigator.userAgent,
const // ua = navigator.userAgent,
// isSafari = (ua.includes('Safari/') && !ua.includes('Chrome/')),
dataPre = 'data:image/svg+xml;charset=utf-8;base64,';
@@ -414,64 +472,6 @@ export default function jQueryPluginSVGIcons ($) {
if (opts.callback) opts.callback(svgIcons);
}
fixIDs = function (svgEl, svgNum, force) {
const defs = svgEl.find('defs');
if (!defs.length) return svgEl;
let idElems;
if (isOpera) {
idElems = defs.find('*').filter(function () {
return Boolean(this.id);
});
} else {
idElems = defs.find('[id]');
}
const allElems = svgEl[0].getElementsByTagName('*'),
len = allElems.length;
idElems.each(function (i) {
const {id} = this;
/*
const noDupes = ($(svgdoc).find('#' + id).length <= 1);
if (isOpera) noDupes = false; // Opera didn't clone svgEl, so not reliable
if(!force && noDupes) return;
*/
const newId = 'x' + id + svgNum + i;
this.id = newId;
const oldVal = 'url(#' + id + ')';
const newVal = 'url(#' + newId + ')';
// Selector method, possibly faster but fails in Opera / jQuery 1.4.3
// svgEl.find('[fill="url(#' + id + ')"]').each(function() {
// this.setAttribute('fill', 'url(#' + newId + ')');
// }).end().find('[stroke="url(#' + id + ')"]').each(function() {
// this.setAttribute('stroke', 'url(#' + newId + ')');
// }).end().find('use').each(function() {
// if(this.getAttribute('xlink:href') == '#' + id) {
// this.setAttributeNS(xlinkns,'href','#' + newId);
// }
// }).end().find('[filter="url(#' + id + ')"]').each(function() {
// this.setAttribute('filter', 'url(#' + newId + ')');
// });
for (i = 0; i < len; i++) {
const elem = allElems[i];
if (elem.getAttribute('fill') === oldVal) {
elem.setAttribute('fill', newVal);
}
if (elem.getAttribute('stroke') === oldVal) {
elem.setAttribute('stroke', newVal);
}
if (elem.getAttribute('filter') === oldVal) {
elem.setAttribute('filter', newVal);
}
}
});
return svgEl;
};
/**
* @returns {void}
*/

View File

@@ -122,6 +122,74 @@
return _setPrototypeOf(o, p);
}
function isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _construct(Parent, args, Class) {
if (isNativeReflectConstruct()) {
_construct = Reflect.construct;
} else {
_construct = function _construct(Parent, args, Class) {
var a = [null];
a.push.apply(a, args);
var Constructor = Function.bind.apply(Parent, a);
var instance = new Constructor();
if (Class) _setPrototypeOf(instance, Class.prototype);
return instance;
};
}
return _construct.apply(null, arguments);
}
function _isNativeFunction(fn) {
return Function.toString.call(fn).indexOf("[native code]") !== -1;
}
function _wrapNativeSuper(Class) {
var _cache = typeof Map === "function" ? new Map() : undefined;
_wrapNativeSuper = function _wrapNativeSuper(Class) {
if (Class === null || !_isNativeFunction(Class)) return Class;
if (typeof Class !== "function") {
throw new TypeError("Super expression must either be null or a function");
}
if (typeof _cache !== "undefined") {
if (_cache.has(Class)) return _cache.get(Class);
_cache.set(Class, Wrapper);
}
function Wrapper() {
return _construct(Class, arguments, _getPrototypeOf(this).constructor);
}
Wrapper.prototype = Object.create(Class.prototype, {
constructor: {
value: Wrapper,
enumerable: false,
writable: true,
configurable: true
}
});
return _setPrototypeOf(Wrapper, Class);
};
return _wrapNativeSuper(Class);
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
@@ -196,6 +264,71 @@
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
function _wrapRegExp(re, groups) {
_wrapRegExp = function (re, groups) {
return new BabelRegExp(re, groups);
};
var _RegExp = _wrapNativeSuper(RegExp);
var _super = RegExp.prototype;
var _groups = new WeakMap();
function BabelRegExp(re, groups) {
var _this = _RegExp.call(this, re);
_groups.set(_this, groups);
return _this;
}
_inherits(BabelRegExp, _RegExp);
BabelRegExp.prototype.exec = function (str) {
var result = _super.exec.call(this, str);
if (result) result.groups = buildGroups(result, this);
return result;
};
BabelRegExp.prototype[Symbol.replace] = function (str, substitution) {
if (typeof substitution === "string") {
var groups = _groups.get(this);
return _super[Symbol.replace].call(this, str, substitution.replace(/\$<([^>]+)>/g, function (_, name) {
return "$" + groups[name];
}));
} else if (typeof substitution === "function") {
var _this = this;
return _super[Symbol.replace].call(this, str, function () {
var args = [];
args.push.apply(args, arguments);
if (typeof args[args.length - 1] !== "object") {
args.push(buildGroups(args, _this));
}
return substitution.apply(this, args);
});
} else {
return _super[Symbol.replace].call(this, str, substitution);
}
};
function buildGroups(result, re) {
var g = _groups.get(re);
return Object.keys(g).reduce(function (groups, name) {
groups[name] = result[g[name]];
return groups;
}, Object.create(null));
}
return _wrapRegExp.apply(this, arguments);
}
// http://ross.posterous.com/2008/08/19/iphone-touch-events-in-javascript/
/**
@@ -3170,22 +3303,35 @@
} // TODO: Add skew support in future
var re = /\s*((scale|matrix|rotate|translate)\s*\(.*?\))\s*,?\s*/;
var re = _wrapRegExp(/\s*((?:scale|matrix|rotate|translate)\s*\(.*?\))\s*,?\s*/, {
xform: 1
});
var m = true;
while (m) {
m = str.match(re);
str = str.replace(re, '');
if (m && m[1]) {
if (m && m.groups.xform) {
(function () {
var x = m[1];
var bits = x.split(/\s*\(/);
var name = bits[0];
var valBits = bits[1].match(/\s*(.*?)\s*\)/);
valBits[1] = valBits[1].replace(/(\d)-/g, '$1 -');
var valArr = valBits[1].split(/[, ]+/);
var letters = 'abcdef'.split('');
var x = m.groups.xform;
var _x$split = x.split(/\s*\(/),
_x$split2 = _slicedToArray(_x$split, 2),
name = _x$split2[0],
bits = _x$split2[1];
var valBits = bits.match(_wrapRegExp(/\s*(.*?)\s*\)/, {
nonWhitespace: 1
}));
valBits.groups.nonWhitespace = valBits.groups.nonWhitespace.replace(_wrapRegExp(/(\d)-/g, {
digit: 1
}), '$<digit> -');
var valArr = valBits.groups.nonWhitespace.split(/[, ]+/);
var letters = _toConsumableArray('abcdef');
var mtx = svgroot.createSVGMatrix();
Object.values(valArr).forEach(function (item, i) {
valArr[i] = parseFloat(item);
@@ -6518,11 +6664,12 @@
var pt1 = transformPoint(x1, y1, m);
var pt2 = transformPoint(x2, y2, m); // Convert back to BB points
var 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;
var 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
};
var newgrad = grad.cloneNode(true);
$$1(newgrad).attr(gCoords);
newgrad.id = editorContext_.getNextId();
@@ -6706,6 +6853,7 @@
d += pathDSegment(letter, [[x1, y1], [x, y]]);
break;
// eslint-disable-next-line sonarjs/no-duplicated-branches
case 10:
// absolute elliptical arc (A)
@@ -7953,7 +8101,10 @@
*/
var dropXMLInteralSubset = function dropXMLInteralSubset(str) {
return str.replace(/(<!DOCTYPE\s+\w*\s*\[).*(\?\]>)/, '$1$2');
return str.replace(_wrapRegExp(/(<!DOCTYPE\s+\w*\s*\[).*(\?\]>)/, {
doctypeOpen: 1,
doctypeClose: 2
}), '$<doctypeOpen>$<doctypeClose>');
};
/**
* Converts characters in a string to XML-friendly entities.
@@ -8093,9 +8244,16 @@
return '';
}
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]);
var _dataurl$split = dataurl.split(','),
_dataurl$split2 = _slicedToArray(_dataurl$split, 2),
prefix = _dataurl$split2[0],
suffix = _dataurl$split2[1],
_prefix$match = prefix.match(_wrapRegExp(/:(.*?);/, {
mime: 1
})),
mime = _prefix$match.groups.mime,
bstr = atob(suffix);
var n = bstr.length;
var u8arr = new Uint8Array(n);
@@ -8147,6 +8305,7 @@
var text2xml = function text2xml(sXML) {
if (sXML.includes('<svg:svg')) {
// eslint-disable-next-line prefer-named-capture-group
sXML = sXML.replace(/<(\/?)svg:/g, '<$1').replace('xmlns:svg', 'xmlns');
}
@@ -8528,11 +8687,17 @@
if (!isWebkit()) {
var 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);
var _ret = ret,
x = _ret.x,
y = _ret.y,
width = _ret.width,
height = _ret.height;
var bb = {
width: width,
height: height,
x: x + parseFloat(selected.getAttribute('x') || 0),
y: y + parseFloat(selected.getAttribute('y') || 0)
};
ret = bb;
}
} else if (visElemsArr.includes(elname)) {
@@ -8544,12 +8709,13 @@
// Re: Chrome returning bbox for containing text element, see: https://bugs.chromium.org/p/chromium/issues/detail?id=349835
var extent = selected.getExtentOfChar(0); // pos+dimensions of the first glyph
var width = selected.getComputedTextLength(); // width of the tspan
var _width = selected.getComputedTextLength(); // width of the tspan
ret = {
x: extent.x,
y: extent.y,
width: width,
width: _width,
height: extent.height
};
}
@@ -9275,7 +9441,7 @@
};
/**
* Whether a value is `null` or `undefined`.
* @param {Any} val
* @param {any} val
* @returns {boolean}
*/
@@ -9382,9 +9548,9 @@
/**
* @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.
*/
@@ -9505,7 +9671,7 @@
* @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.
*/
@@ -11578,7 +11744,9 @@
case 'gradientTransform':
case 'patternTransform':
{
var val = attr.value.replace(/(\d)-/g, '$1 -');
var val = attr.value.replace(_wrapRegExp(/(\d)-/g, {
digit: 1
}), '$<digit> -');
node.setAttribute(attrName, val);
break;
}
@@ -11711,9 +11879,8 @@
};
/**
* 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}
*/
var remapElement = function remapElement(selected, changes, m) {
@@ -13684,9 +13851,8 @@
canvas.current_drawing_ = new 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}
*/
var getCurrentDrawing = canvas.getCurrentDrawing = function () {
@@ -13765,9 +13931,8 @@
};
/**
* 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}
*/
@@ -13823,8 +13988,7 @@
canvas.hasMatrixTransform = hasMatrixTransform;
canvas.transformListToTransform = transformListToTransform;
/**
* @implements {module:utilities.EditorContext#getBaseUnit}
* @returns {string}
* @type {module:utilities.EditorContext#getBaseUnit}
*/
var getBaseUnit = function getBaseUnit() {
@@ -13856,8 +14020,7 @@
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}
*/
var getSVGContent = function getSVGContent() {
@@ -13865,9 +14028,8 @@
};
/**
* 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}
*/
@@ -13878,8 +14040,7 @@
var pathActions$1 = pathActions;
/**
* 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}
*/
var getSVGRoot = function getSVGRoot() {
@@ -13923,8 +14084,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}
*/
var getGridSnapping = function getGridSnapping() {
@@ -14038,8 +14198,8 @@
});
/**
* 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}
*/
var addCommandToHistory = function addCommandToHistory(cmd) {
@@ -14047,9 +14207,8 @@
};
/**
* 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}
*/
@@ -14058,9 +14217,8 @@
};
/**
* 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}
*/
@@ -14093,18 +14251,16 @@
var 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}
*/
var 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}
*/
@@ -14113,11 +14269,8 @@
};
/**
* 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}
*/
@@ -14131,8 +14284,8 @@
/**
* 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
*/
@@ -14153,10 +14306,9 @@
};
/**
* 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}
*/
@@ -14238,8 +14390,7 @@
}
};
/**
* @implements {module:path.EditorContext#getOpacity}
* @returns {Float}
* @type {module:path.EditorContext#getOpacity}
*/
@@ -14247,9 +14398,8 @@
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}
*/
@@ -14317,7 +14467,7 @@
canvas.pathActions = pathActions$1;
/**
* @implements {module:path.EditorContext#resetD}
* @type {module:path.EditorContext#resetD}
*/
function resetD(p) {
@@ -14982,7 +15132,7 @@
/**
* @typedef {PlainObject} module:svgcanvas.Message
* @property {Any} data The data
* @property {any} data The data
* @property {string} origin The origin
*/
@@ -18587,10 +18737,12 @@
if (val) {
if (val.startsWith('data:')) {
// Check if an SVG-edit data URI
var m = val.match(/svgedit_url=(.*?);/);
var m = val.match(_wrapRegExp(/svgedit_url=(.*?);/, {
url: 1
}));
if (m) {
var url = decodeURIComponent(m[1]);
var url = decodeURIComponent(m.groups.url);
$$9(new Image()).load(function () {
image.setAttributeNS(NS.XLINK, 'xlink:href', url);
}).attr('src', url);
@@ -22383,6 +22535,65 @@
});
*/
var isOpera$1 = Boolean(window.opera);
var fixIDs = function fixIDs(svgEl, svgNum, force) {
var defs = svgEl.find('defs');
if (!defs.length) return svgEl;
var idElems;
if (isOpera$1) {
idElems = defs.find('*').filter(function () {
return Boolean(this.id);
});
} else {
idElems = defs.find('[id]');
}
var allElems = svgEl[0].getElementsByTagName('*'),
len = allElems.length;
idElems.each(function (i) {
var id = this.id;
/*
const noDupes = ($(svgdoc).find('#' + id).length <= 1);
if (isOpera) noDupes = false; // Opera didn't clone svgEl, so not reliable
if(!force && noDupes) return;
*/
var newId = 'x' + id + svgNum + i;
this.id = newId;
var oldVal = 'url(#' + id + ')';
var newVal = 'url(#' + newId + ')'; // Selector method, possibly faster but fails in Opera / jQuery 1.4.3
// svgEl.find('[fill="url(#' + id + ')"]').each(function() {
// this.setAttribute('fill', 'url(#' + newId + ')');
// }).end().find('[stroke="url(#' + id + ')"]').each(function() {
// this.setAttribute('stroke', 'url(#' + newId + ')');
// }).end().find('use').each(function() {
// if(this.getAttribute('xlink:href') == '#' + id) {
// this.setAttributeNS(xlinkns,'href','#' + newId);
// }
// }).end().find('[filter="url(#' + id + ')"]').each(function() {
// this.setAttribute('filter', 'url(#' + newId + ')');
// });
for (i = 0; i < len; i++) {
var elem = allElems[i];
if (elem.getAttribute('fill') === oldVal) {
elem.setAttribute('fill', newVal);
}
if (elem.getAttribute('stroke') === oldVal) {
elem.setAttribute('stroke', newVal);
}
if (elem.getAttribute('filter') === oldVal) {
elem.setAttribute('filter', newVal);
}
}
});
return svgEl;
};
/**
* @callback module:jQuerySVGIcons.SVGIconsLoadedCallback
* @param {PlainObject<string, external:jQuery>} svgIcons IDs keyed to jQuery objects of images
@@ -22394,9 +22605,9 @@
* @returns {external:jQuery} The enhanced jQuery object
*/
function jQueryPluginSVGIcons($) {
var svgIcons = {};
var fixIDs;
/**
* Map of raster images with each key being the SVG icon ID
* to replace, and the value the image file name
@@ -22455,8 +22666,7 @@
iconsMade = false,
dataLoaded = false,
loadAttempts = 0;
var isOpera = Boolean(window.opera),
// ua = navigator.userAgent,
var // ua = navigator.userAgent,
// isSafari = (ua.includes('Safari/') && !ua.includes('Chrome/')),
dataPre = 'data:image/svg+xml;charset=utf-8;base64,';
var dataEl;
@@ -22575,7 +22785,7 @@
function setIcon(target, icon, id, setID) {
if (isOpera) icon.css('visibility', 'hidden');
if (isOpera$1) icon.css('visibility', 'hidden');
if (opts.replace) {
if (setID) icon.attr('id', id);
@@ -22597,7 +22807,7 @@
target.append(icon);
}
if (isOpera) {
if (isOpera$1) {
setTimeout(function () {
icon.removeAttr('style');
}, 1);
@@ -22689,7 +22899,7 @@
svgroot.setAttribute('class', 'svg_icon'); // Without cloning, Firefox will make another GET request.
// With cloning, causes issue in Opera/Win/Non-EN
if (!isOpera) svg = svg.cloneNode(true);
if (!isOpera$1) svg = svg.cloneNode(true);
svgroot.append(svg);
var icon = void 0;
@@ -22720,7 +22930,7 @@
if (!svgIcons[id]) return;
$(sel).each(function (i) {
var copy = svgIcons[id].clone();
if (i > 0 && !toImage) copy = fixIDs(copy, i, true);
if (i > 0 && !toImage) copy = fixIDs(copy, i);
setIcon($(this), copy, id);
});
});
@@ -22736,64 +22946,6 @@
iconsMade = true;
if (opts.callback) opts.callback(svgIcons);
}
fixIDs = function fixIDs(svgEl, svgNum, force) {
var defs = svgEl.find('defs');
if (!defs.length) return svgEl;
var idElems;
if (isOpera) {
idElems = defs.find('*').filter(function () {
return Boolean(this.id);
});
} else {
idElems = defs.find('[id]');
}
var allElems = svgEl[0].getElementsByTagName('*'),
len = allElems.length;
idElems.each(function (i) {
var id = this.id;
/*
const noDupes = ($(svgdoc).find('#' + id).length <= 1);
if (isOpera) noDupes = false; // Opera didn't clone svgEl, so not reliable
if(!force && noDupes) return;
*/
var newId = 'x' + id + svgNum + i;
this.id = newId;
var oldVal = 'url(#' + id + ')';
var newVal = 'url(#' + newId + ')'; // Selector method, possibly faster but fails in Opera / jQuery 1.4.3
// svgEl.find('[fill="url(#' + id + ')"]').each(function() {
// this.setAttribute('fill', 'url(#' + newId + ')');
// }).end().find('[stroke="url(#' + id + ')"]').each(function() {
// this.setAttribute('stroke', 'url(#' + newId + ')');
// }).end().find('use').each(function() {
// if(this.getAttribute('xlink:href') == '#' + id) {
// this.setAttributeNS(xlinkns,'href','#' + newId);
// }
// }).end().find('[filter="url(#' + id + ')"]').each(function() {
// this.setAttribute('filter', 'url(#' + newId + ')');
// });
for (i = 0; i < len; i++) {
var elem = allElems[i];
if (elem.getAttribute('fill') === oldVal) {
elem.setAttribute('fill', newVal);
}
if (elem.getAttribute('stroke') === oldVal) {
elem.setAttribute('stroke', newVal);
}
if (elem.getAttribute('filter') === oldVal) {
elem.setAttribute('filter', newVal);
}
}
});
return svgEl;
};
/**
* @returns {void}
*/
@@ -22825,7 +22977,7 @@
var icon = svgIcons[id];
if (uniqueClone && icon) {
icon = fixIDs(icon, 0, true).clone(true);
icon = fixIDs(icon, 0).clone(true);
}
return icon;
@@ -24898,7 +25050,7 @@
}
/**
* Whether a value is `null` or `undefined`.
* @param {Any} val
* @param {any} val
* @returns {boolean}
*/
@@ -29347,7 +29499,7 @@
*
* @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}
*/
@@ -29624,7 +29776,9 @@
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(_wrapRegExp(/source=(data:[^&]*)/, {
src: 1
})).groups.src;
}
}
@@ -29728,7 +29882,9 @@
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
extName = extname.match(/^ext-(.+)\.js/);
extName = extname.match(_wrapRegExp(/^ext-(.+)\.js/, {
extName: 1
})).groups.extName;
if (extName) {
_context2.next = 3;
@@ -29751,12 +29907,12 @@
_context2.prev = 4;
_context2.next = 7;
return importSetGlobalDefault(url, {
global: 'svgEditorExtension_' + extName[1].replace(/-/g, '_')
global: 'svgEditorExtension_' + extName.replace(/-/g, '_')
});
case 7:
imported = _context2.sent;
_imported$name = imported.name, _name2 = _imported$name === void 0 ? extName[1] : _imported$name, init = imported.init;
_imported$name = imported.name, _name2 = _imported$name === void 0 ? extName : _imported$name, init = imported.init;
importLocale = getImportLocale({
defaultLang: langParam,
defaultName: _name2
@@ -29870,7 +30026,7 @@
var uaPrefix = function () {
var regex = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/;
var regex = /^(?:Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/;
var someScript = document.getElementsByTagName('script')[0];
for (var prop in someScript.style) {
@@ -31798,7 +31954,7 @@
zoomDone();
};
/**
* @implements {module:jQuerySpinButton.ValueCallback}
* @type {module:jQuerySpinButton.ValueCallback}
*/
@@ -32764,14 +32920,14 @@
setBackground($$b.pref('bkgd_color'), $$b.pref('bkgd_url'));
$$b('#image_save_opts input').val([$$b.pref('img_save')]);
/**
* @implements {module:jQuerySpinButton.ValueCallback}
* @type {module:jQuerySpinButton.ValueCallback}
*/
var changeRectRadius = function changeRectRadius(ctl) {
svgCanvas.setRectRadius(ctl.value);
};
/**
* @implements {module:jQuerySpinButton.ValueCallback}
* @type {module:jQuerySpinButton.ValueCallback}
*/
@@ -32779,7 +32935,7 @@
svgCanvas.setFontSize(ctl.value);
};
/**
* @implements {module:jQuerySpinButton.ValueCallback}
* @type {module:jQuerySpinButton.ValueCallback}
*/
@@ -32793,7 +32949,7 @@
svgCanvas.setStrokeWidth(val);
};
/**
* @implements {module:jQuerySpinButton.ValueCallback}
* @type {module:jQuerySpinButton.ValueCallback}
*/
@@ -35120,8 +35276,7 @@
$$b(window).bind('load resize', centerCanvas);
/**
* @implements {module:jQuerySpinButton.StepCallback}
* @returns {Float}
* @type {module:jQuerySpinButton.StepCallback}
*/
function stepFontSize(elem, step) {
@@ -35152,8 +35307,7 @@
return sugVal;
}
/**
* @implements {module:jQuerySpinButton.StepCallback}
* @returns {Float}
* @type {module:jQuerySpinButton.StepCallback}
*/
@@ -36732,7 +36886,7 @@
var messageQueue = [];
/**
* @param {PlainObject} info
* @param {Any} info.data
* @param {any} info.data
* @param {string} info.origin
* @fires module:svgcanvas.SvgCanvas#event:message
* @returns {void}