From f9fb7f47ae9ba1e9acecc99a06efdd90777be269 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Thu, 17 May 2018 11:57:28 -0700 Subject: [PATCH 1/2] Residual linting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit {object} -> {Object} Remove extra semicolons. Use jQuery’s .empty(). Make nodelist loops O(n) rather than O(n^2). Specify radix in parseInt to prevent guessing octal. --- editor/canvg/canvg.js | 11 +++++------ editor/coords.js | 2 +- editor/history.js | 2 +- editor/historyrecording.js | 2 +- editor/layer.js | 2 +- editor/locale/locale.js | 7 +++---- editor/math.js | 12 ++++++------ editor/svg-editor.js | 6 +++--- editor/svgcanvas.js | 14 +++++++------- editor/svgutils.js | 2 +- 10 files changed, 29 insertions(+), 31 deletions(-) diff --git a/editor/canvg/canvg.js b/editor/canvg/canvg.js index a125543f..359ab28b 100644 --- a/editor/canvg/canvg.js +++ b/editor/canvg/canvg.js @@ -745,8 +745,7 @@ function build (opts) { if (node != null && node.nodeType === 1) { // ELEMENT_NODE // add children - for (var i = 0; i < node.childNodes.length; i++) { - var childNode = node.childNodes[i]; + for (var i = 0, childNode; (childNode = node.childNodes[i]); i++) { if (childNode.nodeType === 1) this.addChild(childNode, true); // ELEMENT_NODE if (this.captureTextNodes && (childNode.nodeType === 3 || childNode.nodeType === 4)) { var text = childNode.nodeValue || childNode.text || ''; @@ -2227,8 +2226,8 @@ function build (opts) { this.base(node); this.hasText = true; - for (var i = 0; i < node.childNodes.length; i++) { - if (node.childNodes[i].nodeType !== 3) this.hasText = false; + for (var i = 0, childNode; (childNode = node.childNodes[i]); i++) { + if (childNode.nodeType !== 3) this.hasText = false; } // this might contain text @@ -2359,8 +2358,8 @@ function build (opts) { // text, or spaces then CDATA var css = ''; - for (var i = 0; i < node.childNodes.length; i++) { - css += node.childNodes[i].nodeValue; + for (var i = 0, childNode; (childNode = node.childNodes[i]); i++) { + css += childNode.nodeValue; } css = css.replace(/(\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/)|(^[\s]*\/\/.*)/gm, ''); // remove comments css = svg.compressSpaces(css); // replace whitespace diff --git a/editor/coords.js b/editor/coords.js index 6e839f80..760e1e4c 100644 --- a/editor/coords.js +++ b/editor/coords.js @@ -47,7 +47,7 @@ svgedit.coords.init = function (editorContext) { /** * Applies coordinate changes to an element based on the given matrix * @param {Element} selected - DOM element to be changed - * @param {object} changes - Object with changes to be remapped + * @param {Object} changes - Object with changes to be remapped * @param {SVGMatrix} m - Matrix object to use for remapping coordinates */ svgedit.coords.remapElement = function (selected, changes, m) { diff --git a/editor/history.js b/editor/history.js index fcff7061..d546779b 100644 --- a/editor/history.js +++ b/editor/history.js @@ -33,7 +33,7 @@ svgedit.history.HistoryEventTypes = { /** * An interface that all command objects must implement. * @typedef svgedit.history.HistoryCommand - * @type {object} + * @type {Object} * void apply(svgedit.history.HistoryEventHandler); * void unapply(svgedit.history.HistoryEventHandler); * Element[] elements(); diff --git a/editor/historyrecording.js b/editor/historyrecording.js index 6a44a4ea..9fdd0280 100644 --- a/editor/historyrecording.js +++ b/editor/historyrecording.js @@ -142,7 +142,7 @@ HistoryRecordingService.prototype.removeElement = function (elem, oldNextSibling /** * Add a ChangeElementCommand to the history or current batch command * @param {Element} elem - The DOM element that was changed - * @param {object} attrs - An object with the attributes to be changed and the values they had *before* the change + * @param {Object} attrs - An object with the attributes to be changed and the values they had *before* the change * @param {string} [text] - An optional string visible to user related to this change * @returns {svgedit.history.HistoryRecordingService} */ diff --git a/editor/layer.js b/editor/layer.js index 4c901171..b9f56239 100644 --- a/editor/layer.js +++ b/editor/layer.js @@ -180,7 +180,7 @@ Layer.prototype.setName = function (name, hrService) { // now change the underlying title element contents var title = this.getTitleElement(); if (title) { - while (title.firstChild) { title.removeChild(title.firstChild); } + $(title).empty(); title.textContent = name; this.name_ = name; if (hrService) { diff --git a/editor/locale/locale.js b/editor/locale/locale.js index 039d35fa..f4561ea6 100644 --- a/editor/locale/locale.js +++ b/editor/locale/locale.js @@ -22,7 +22,7 @@ var langParam; function setStrings (type, obj, ids) { // Root element to look for element from - var i, sel, val, $elem, elem, node, parent = $('#svg_editor').parent(); + var sel, val, $elem, elem, parent = $('#svg_editor').parent(); for (sel in obj) { val = obj[sel]; if (!val) { console.log(sel); } @@ -34,9 +34,8 @@ function setStrings (type, obj, ids) { switch (type) { case 'content': - for (i = 0; i < elem.childNodes.length; i++) { - node = elem.childNodes[i]; - if (node.nodeType === 3 && node.textContent.replace(/\s/g, '')) { + for (var i = 0, node; (node = elem.childNodes[i]); i++) { + if (node.nodeType === 3 && node.textContent.trim() === '') { node.textContent = val; break; } diff --git a/editor/math.js b/editor/math.js index b84e6dfd..466f76c0 100644 --- a/editor/math.js +++ b/editor/math.js @@ -14,7 +14,7 @@ /** * @typedef AngleCoord45 -* @type {object} +* @type {Object} * @property {number} x - The angle-snapped x value * @property {number} y - The angle-snapped y value * @property {number} a - The angle at which to snap @@ -39,7 +39,7 @@ var svg = document.createElementNS(svgedit.NS.SVG, 'svg'); * @param {number} x - Float representing the x coordinate * @param {number} y - Float representing the y coordinate * @param {SVGMatrix} m - Matrix object to transform the point with - * @returns {object} An x, y object representing the transformed point + * @returns {Object} An x, y object representing the transformed point */ svgedit.math.transformPoint = function (x, y, m) { return {x: m.a * x + m.c * y + m.e, y: m.b * x + m.d * y + m.f}; @@ -80,7 +80,7 @@ svgedit.math.matrixMultiply = function (matr) { /** * See if the given transformlist includes a non-indentity matrix transform - * @param {object} [tlist] - The transformlist to check + * @param {Object} [tlist] - The transformlist to check * @returns {boolean} Whether or not a matrix transform was found */ svgedit.math.hasMatrixTransform = function (tlist) { @@ -100,7 +100,7 @@ svgedit.math.hasMatrixTransform = function (tlist) { * @param {number} w - Float with the box width * @param {number} h - Float with the box height * @param {SVGMatrix} m - Matrix object to transform the box by - * @returns {object} An object with the following values: + * @returns {Object} An object with the following values: * tl - The top left coordinate (x,y object) * tr - The top right coordinate (x,y object) * bl - The bottom left coordinate (x,y object) @@ -143,11 +143,11 @@ svgedit.math.transformBox = function (l, t, w, h, m) { * (this is the equivalent of SVGTransformList.consolidate() but unlike * that method, this one does not modify the actual SVGTransformList) * This function is very liberal with its min, max arguments - * @param {object} tlist - The transformlist object + * @param {Object} tlist - The transformlist object * @param {integer} [min=0] - Optional integer indicating start transform position * @param {integer} [max] - Optional integer indicating end transform position; * defaults to one less than the tlist's numberOfItems - * @returns {object} A single matrix transform object + * @returns {Object} A single matrix transform object */ svgedit.math.transformListToTransform = function (tlist, min, max) { if (tlist == null) { diff --git a/editor/svg-editor.js b/editor/svg-editor.js index b9dfe93b..2cb022f3 100644 --- a/editor/svg-editor.js +++ b/editor/svg-editor.js @@ -291,8 +291,8 @@ window.svgEditor = (function ($) { /** * Allows setting of preferences or configuration (including extensions). - * @param {object} opts The preferences or configuration (including extensions) - * @param {object} [cfgCfg] Describes configuration which applies to the particular batch of supplied options + * @param {Object} opts The preferences or configuration (including extensions) + * @param {Object} [cfgCfg] Describes configuration which applies to the particular batch of supplied options * @param {boolean} [cfgCfg.allowInitialUserOverride=false] Set to true if you wish * to allow initial overriding of settings by the user via the URL * (if permitted) or previously stored preferences (if permitted); @@ -375,7 +375,7 @@ window.svgEditor = (function ($) { }; /** - * @param {object} opts Extension mechanisms may call setCustomHandlers with three functions: opts.open, opts.save, and opts.exportImage + * @param {Object} opts Extension mechanisms may call setCustomHandlers with three functions: opts.open, opts.save, and opts.exportImage * opts.open's responsibilities are: * - invoke a file chooser dialog in 'open' mode * - let user pick a SVG file diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index 8a7db3b1..d52b50fc 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -99,7 +99,7 @@ var svgcontent = svgdoc.createElementNS(NS.SVG, 'svg'); // This function resets the svgcontent element while keeping it in the DOM. var clearSvgContentElement = canvas.clearSvgContentElement = function () { - while (svgcontent.firstChild) { svgcontent.removeChild(svgcontent.firstChild); } + $(svgcontent).empty(); // TODO: Clear out all other attributes first? $(svgcontent).attr({ @@ -193,13 +193,13 @@ var getJsonFromSvgElement = this.getJsonFromSvgElement = function (data) { }; // Iterate attributes - for (var i = 0; i < data.attributes.length; i++) { - retval.attr[data.attributes[i].name] = data.attributes[i].value; - }; + for (var i = 0, attr; (attr = data.attributes[i]); i++) { + retval.attr[attr.name] = attr.value; + } // Iterate children - for (var i = 0; i < data.childNodes.length; i++) { - retval.children.push(getJsonFromSvgElement(data.childNodes[i])); + for (var i = 0, node; (node = data.childNodes[i]); i++) { + retval.children[i] = getJsonFromSvgElement(node); } return retval; @@ -3056,7 +3056,7 @@ return { var curPt; if (id.substr(0, 14) === 'pathpointgrip_') { // Select this point - curPt = svgedit.path.path.cur_pt = parseInt(id.substr(14)); + curPt = svgedit.path.path.cur_pt = parseInt(id.substr(14), 10); svgedit.path.path.dragging = [startX, startY]; var seg = svgedit.path.path.segs[curPt]; diff --git a/editor/svgutils.js b/editor/svgutils.js index 878317aa..48ea412b 100644 --- a/editor/svgutils.js +++ b/editor/svgutils.js @@ -926,7 +926,7 @@ svgedit.utilities.getBBoxWithTransform = function (elem, addSvgElementFromJson, function getStrokeOffsetForBBox (elem) { var sw = elem.getAttribute('stroke-width'); return (!isNaN(sw) && elem.getAttribute('stroke') !== 'none') ? sw / 2 : 0; -}; +} // Function: getStrokedBBox // Get the bounding box for one or more stroked and/or transformed elements From 7bb89f53a5f0447f6136b10f306be2485e1ceb78 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Thu, 17 May 2018 12:04:58 -0700 Subject: [PATCH 2/2] =?UTF-8?q?Don=E2=80=99t=20throw=20error=20for=20unlin?= =?UTF-8?q?ked=20nodes=20in=20Chrome?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit evt.target in Chrome is the abandoned shape, not connected to the DOM. evt.target in Firefox is the svgroot. Add checks to ensure that no matter what node is presented by the event, there are no property calls to null or undefined. Fixes issue #232. --- editor/svgcanvas.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index d52b50fc..2ed645d8 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -2205,13 +2205,14 @@ var mouseUp = function (evt) { // if this element is in a group, go up until we reach the top-level group // just below the layer groups // TODO: once we implement links, we also would have to check for elements - while (t.parentNode.parentNode.tagName === 'g') { + while (t && t.parentNode && t.parentNode.parentNode && t.parentNode.parentNode.tagName === 'g') { t = t.parentNode; } // if we are not in the middle of creating a path, and we've clicked on some shape, // then go to Select mode. // WebKit returns
when the canvas is clicked, Firefox/Opera return if ((currentMode !== 'path' || !drawnPath) && + t && t.parentNode && t.parentNode.id !== 'selectorParentGroup' && t.id !== 'svgcanvas' && t.id !== 'svgroot' ) {