From ff347649558047395d01dd7ea18c1cab8117781d Mon Sep 17 00:00:00 2001
From: JFH <20402845+jfhenon@users.noreply.github.com>
Date: Thu, 30 Dec 2021 23:18:43 -0300
Subject: [PATCH] fix lgtm warnings and other minor fixes
---
cypress/integration/unit/utilities-bbox.js | 2 +-
.../integration/unit/utilities-performance.js | 2 +-
src/editor/Editor.js | 16 ++++----
.../components/jgraduate/ColorValuePicker.js | 38 ++++++++-----------
.../components/jgraduate/jQuery.jPicker.js | 24 ++++++------
.../extensions/ext-imagelib/ext-imagelib.js | 4 +-
src/editor/panels/BottomPanel.js | 6 +--
src/editor/panels/TopPanel.js | 2 +-
src/svgcanvas/coords.js | 6 +--
src/svgcanvas/dataStorage.js | 2 +-
src/svgcanvas/history.js | 8 ++--
src/svgcanvas/layer.js | 6 +--
src/svgcanvas/path-actions.js | 8 ++--
src/svgcanvas/path-method.js | 6 +--
src/svgcanvas/path.js | 8 +---
src/svgcanvas/recalculate.js | 4 +-
src/svgcanvas/select.js | 4 +-
17 files changed, 62 insertions(+), 84 deletions(-)
diff --git a/cypress/integration/unit/utilities-bbox.js b/cypress/integration/unit/utilities-bbox.js
index d21936f9..9e475390 100644
--- a/cypress/integration/unit/utilities-bbox.js
+++ b/cypress/integration/unit/utilities-bbox.js
@@ -37,7 +37,7 @@ describe('utilities bbox', function () {
}
const mockPathActions = {
resetOrientation (pth) {
- if (utilities.isNullish(pth) || pth.nodeName !== 'path') { return false }
+ if (pth?.nodeName !== 'path') { return false }
const tlist = pth.transform.baseVal
const m = math.transformListToTransform(tlist).matrix
tlist.clear()
diff --git a/cypress/integration/unit/utilities-performance.js b/cypress/integration/unit/utilities-performance.js
index 88b08eac..49536cc7 100644
--- a/cypress/integration/unit/utilities-performance.js
+++ b/cypress/integration/unit/utilities-performance.js
@@ -116,7 +116,7 @@ describe('utilities performance', function () {
const mockPathActions = {
resetOrientation (path) {
- if (utilities.isNullish(path) || path.nodeName !== 'path') { return false }
+ if (path?.nodeName !== 'path') { return false }
const tlist = path.transform.baseVal
const m = math.transformListToTransform(tlist).matrix
tlist.clear()
diff --git a/src/editor/Editor.js b/src/editor/Editor.js
index 47daccd1..6cbf16c5 100644
--- a/src/editor/Editor.js
+++ b/src/editor/Editor.js
@@ -102,7 +102,7 @@ class Editor extends EditorStartup {
{
key: ['delete/backspace', true],
fn: () => {
- if (!isNullish(this.selectedElement) || this.multiselected) { this.svgCanvas.deleteSelectedElements() }
+ if (this.selectedElement || this.multiselected) { this.svgCanvas.deleteSelectedElements() }
}
},
{ key: 'a', fn: () => { this.svgCanvas.selectAllInCurrentLayer() } },
@@ -489,9 +489,9 @@ class Editor extends EditorStartup {
// if this.elems[1] is present, then we have more than one element
this.selectedElement = (elems.length === 1 || isNullish(elems[1]) ? elems[0] : null)
this.multiselected = (elems.length >= 2 && !isNullish(elems[1]))
- if (!isNullish(this.selectedElement) && !isNode) {
+ if (this.selectedElement && !isNode) {
this.topPanel.update()
- } // if (!isNullish(elem))
+ } // if (elem)
// Deal with pathedit mode
this.topPanel.togglePathEditMode(isNode, elems)
@@ -742,7 +742,7 @@ class Editor extends EditorStartup {
* @returns {void}
*/
cutSelected () {
- if (!isNullish(this.selectedElement) || this.multiselected) {
+ if (this.selectedElement || this.multiselected) {
this.svgCanvas.cutSelectedElements()
}
}
@@ -752,7 +752,7 @@ class Editor extends EditorStartup {
* @returns {void}
*/
copySelected () {
- if (!isNullish(this.selectedElement) || this.multiselected) {
+ if (this.selectedElement || this.multiselected) {
this.svgCanvas.copySelectedElements()
}
}
@@ -774,7 +774,7 @@ class Editor extends EditorStartup {
* @returns {void}
*/
moveUpDownSelected (dir) {
- if (!isNullish(this.selectedElement)) {
+ if (this.selectedElement) {
this.svgCanvas.moveUpDownSelected(dir)
}
}
@@ -785,7 +785,7 @@ class Editor extends EditorStartup {
* @returns {void}
*/
moveSelected (dx, dy) {
- if (!isNullish(this.selectedElement) || this.multiselected) {
+ if (this.selectedElement || this.multiselected) {
if (this.configObj.curConfig.gridSnapping) {
// Use grid snap value regardless of zoom level
const multi = this.svgCanvas.getZoom() * this.configObj.curConfig.snappingStep
@@ -818,7 +818,7 @@ class Editor extends EditorStartup {
* @returns {void}
*/
rotateSelected (cw, step) {
- if (isNullish(this.selectedElement) || this.multiselected) { return }
+ if (!this.selectedElement || this.multiselected) { return }
if (!cw) { step *= -1 }
const angle = Number.parseFloat($id('angle').value) + step
this.svgCanvas.setRotationAngle(angle)
diff --git a/src/editor/components/jgraduate/ColorValuePicker.js b/src/editor/components/jgraduate/ColorValuePicker.js
index bea65008..73c426a1 100644
--- a/src/editor/components/jgraduate/ColorValuePicker.js
+++ b/src/editor/components/jgraduate/ColorValuePicker.js
@@ -11,14 +11,6 @@ function toFixedNumeric (value, precision) {
if (precision === undefined) precision = 0
return Math.round(value * (10 ** precision)) / (10 ** precision)
}
-/**
- * Whether a value is `null` or `undefined`.
- * @param {any} val
- * @returns {boolean}
- */
-const isNullish = (val) => {
- return val === null || val === undefined
-}
/**
* Controls for all the input elements for the typing in color values.
*/
@@ -39,7 +31,7 @@ export default class ColorValuePicker {
* @returns {Event|false|void}
*/
function keyDown (e) {
- if (e.target.value === '' && e.target !== hex && ((!isNullish(bindedHex) && e.target !== bindedHex) || isNullish(bindedHex))) return undefined
+ if (e.target.value === '' && e.target !== hex && ((bindedHex && e.target !== bindedHex) || !bindedHex)) return undefined
if (!validateKey(e)) return e
switch (e.target) {
case red:
@@ -137,8 +129,8 @@ export default class ColorValuePicker {
*/
function keyUp (e) {
if (e.target.value === '' && e.target !== hex &&
- ((!isNullish(bindedHex) && e.target !== bindedHex) ||
- isNullish(bindedHex))) return undefined
+ ((bindedHex && e.target !== bindedHex) ||
+ !bindedHex)) return undefined
if (!validateKey(e)) return e
switch (e.target) {
case red:
@@ -181,7 +173,7 @@ export default class ColorValuePicker {
break
case ahex:
ahex.value = ahex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 2)
- color.val('a', !isNullish(ahex.value) ? Number.parseInt(ahex.value, 16) : null, e.target)
+ color.val('a', ahex.value ? Number.parseInt(ahex.value, 16) : null, e.target)
break
}
return undefined
@@ -192,7 +184,7 @@ export default class ColorValuePicker {
* @returns {void}
*/
function blur (e) {
- if (!isNullish(color.value)) {
+ if (color.value) {
switch (e.target) {
case red:
color.value = 'r'
@@ -274,16 +266,16 @@ export default class ColorValuePicker {
*/
function colorChanged (ui, context) {
const all = ui.val('all')
- if (context !== red) red.value = (!isNullish(all) ? all.r : '')
- if (context !== green) green.value = (!isNullish(all) ? all.g : '')
- if (context !== blue) blue.value = (!isNullish(all) ? all.b : '')
- if (alpha && context !== alpha) alpha.value = (!isNullish(all) ? toFixedNumeric((all.a * 100) / 255, alphaPrecision) : '')
- if (context !== hue) hue.value = (!isNullish(all) ? all.h : '')
- if (context !== saturation) saturation.value = (!isNullish(all) ? all.s : '')
- if (context !== value) value.value = (!isNullish(all) ? all.v : '')
- if (context !== hex && ((bindedHex && context !== bindedHex) || !bindedHex)) hex.value = (!isNullish(all) ? all.hex : '')
- if (bindedHex && context !== bindedHex && context !== hex) bindedHex.value = (!isNullish(all) ? all.hex : '')
- if (ahex && context !== ahex) ahex.value = (!isNullish(all) ? all.ahex.substring(6) : '')
+ if (context !== red) red.value = (all ? all.r : '')
+ if (context !== green) green.value = (all ? all.g : '')
+ if (context !== blue) blue.value = (all ? all.b : '')
+ if (alpha && context !== alpha) alpha.value = (all ? toFixedNumeric((all.a * 100) / 255, alphaPrecision) : '')
+ if (context !== hue) hue.value = (all ? all.h : '')
+ if (context !== saturation) saturation.value = (all ? all.s : '')
+ if (context !== value) value.value = (all ? all.v : '')
+ if (context !== hex && ((bindedHex && context !== bindedHex) || !bindedHex)) hex.value = (all ? all.hex : '')
+ if (bindedHex && context !== bindedHex && context !== hex) bindedHex.value = (all ? all.hex : '')
+ if (ahex && context !== ahex) ahex.value = (all ? all.ahex.substring(6) : '')
}
/**
* Unbind all events and null objects.
diff --git a/src/editor/components/jgraduate/jQuery.jPicker.js b/src/editor/components/jgraduate/jQuery.jPicker.js
index f672f9f5..59294aad 100755
--- a/src/editor/components/jgraduate/jQuery.jPicker.js
+++ b/src/editor/components/jgraduate/jQuery.jPicker.js
@@ -1337,34 +1337,34 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
- ° |
+ ° |
|
- % |
+ % |
|
- %
|
+ %
|
|
- |
+ |
|
- |
+ |
|
- |
+ |
${win.alphaSupport ? `` : ' '} |
- ${win.alphaSupport ? ` %` : ' '} |
+ ${win.alphaSupport ? ` %` : ' '} |
- ${win.alphaSupport ? ` | ` : ' '}
+ ${win.alphaSupport ? ` | ` : ' '}
`
if (win.expandable) {
@@ -1455,7 +1455,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
win.expandable && win.bindToInput ? win.input : null,
win.alphaPrecision
)
- const hex = !isNullish(all) ? all.hex : null
+ const hex = all ? all.hex : null
const preview = tbody.querySelector('#Preview')
const button = tbody.querySelector('#Button')
activePreview = preview.querySelector('#Active')
@@ -1523,7 +1523,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
iconColor.style.backgroundColor = (hex && '#' + hex) || 'transparent'
iconAlpha = that.icon.querySelector('.Alpha')
setImg.call(that, iconAlpha, images.clientPath + 'bar-opacity.png')
- setAlpha.call(that, iconAlpha, toFixedNumeric(((255 - (!isNullish(all) ? all.a : 0)) * 100) / 255, 4))
+ setAlpha.call(that, iconAlpha, toFixedNumeric(((255 - (all ? all.a : 0)) * 100) / 255, 4))
iconImage = that.icon.querySelector('.Image')
iconImage.style.backgroundImage = 'url(\'' + images.clientPath + images.picker.file + '\')'
iconImage.addEventListener('click', iconImageClicked)
@@ -1531,7 +1531,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
win.input.style.backgroundColor = (hex && '#' + hex) || 'transparent'
win.input.style.color = isNullish(all) || all.v > 75 ? '#000000' : '#ffffff'
}
- const moveBar = tbody.querySelector('.Move')
+ moveBar = tbody.querySelector('.Move')
moveBar.addEventListener('mousedown', moveBarMouseDown)
color.active.bind(expandableColorChanged)
} else {
@@ -1658,7 +1658,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
let iconColor = null // iconColor for popup icon
let iconAlpha = null // iconAlpha for popup icon
let iconImage = null // iconImage popup icon
- const moveBar = null // drag bar
+ let moveBar = null // drag bar
Object.assign(that, {
// public properties, methods, and callbacks
commitCallback, // commitCallback function can be overridden to return the selected color to a method you specify when the user clicks "OK"
diff --git a/src/editor/extensions/ext-imagelib/ext-imagelib.js b/src/editor/extensions/ext-imagelib/ext-imagelib.js
index 3bc6c5e1..6be807d9 100644
--- a/src/editor/extensions/ext-imagelib/ext-imagelib.js
+++ b/src/editor/extensions/ext-imagelib/ext-imagelib.js
@@ -233,9 +233,7 @@ export default {
}
// Else fall through
default:
- // TODO: See if there's a way to base64 encode the binary data stream
- // const str = 'data:;base64,' + svgedit.utilities.encode64(response, true);
-
+ // TODO: See if there's a way to base64 encode the binary data stream
// Assume it's raw image data
// importImage(str);
diff --git a/src/editor/panels/BottomPanel.js b/src/editor/panels/BottomPanel.js
index e9bf5886..cecba2ea 100644
--- a/src/editor/panels/BottomPanel.js
+++ b/src/editor/panels/BottomPanel.js
@@ -56,11 +56,7 @@ class BottomPanel {
break
default:
{
- const zoomlevel = Number(value) / 100
- if (zoomlevel < 0.001) {
- value = 0.1
- return
- }
+ const zoomlevel = Number(value) > 0.1 ? Number(value) > 0.1 : 0.1
const zoom = this.editor.svgCanvas.getZoom()
const { workarea } = this.editor
this.editor.zoomChanged(window, {
diff --git a/src/editor/panels/TopPanel.js b/src/editor/panels/TopPanel.js
index 571e74dc..1cb48d9d 100644
--- a/src/editor/panels/TopPanel.js
+++ b/src/editor/panels/TopPanel.js
@@ -409,7 +409,7 @@ class TopPanel {
'#group'
)
- // if (!isNullish(elem))
+ // if (elem)
} else if (this.multiselected) {
this.displayTool('multiselected_panel')
menuItems.setAttribute('enablemenuitems', '#group')
diff --git a/src/svgcanvas/coords.js b/src/svgcanvas/coords.js
index c55619e8..fca06b54 100644
--- a/src/svgcanvas/coords.js
+++ b/src/svgcanvas/coords.js
@@ -24,10 +24,6 @@ const pathMap = [
* @function module:coords.EditorContext#getGridSnapping
* @returns {boolean}
*/
-/**
- * @function module:coords.EditorContext#getDrawing
- * @returns {module:draw.Drawing}
-*/
/**
* @function module:coords.EditorContext#getSvgRoot
* @returns {SVGSVGElement}
@@ -84,7 +80,7 @@ export const remapElement = function (selected, changes, m) {
newgrad.setAttribute('y1', -(y1 - 1))
newgrad.setAttribute('y2', -(y2 - 1))
}
- newgrad.id = svgCanvas.getDrawing().getNextId()
+ newgrad.id = svgCanvas.getCurrentDrawing().getNextId()
findDefs().append(newgrad)
selected.setAttribute(type, 'url(#' + newgrad.id + ')')
}
diff --git a/src/svgcanvas/dataStorage.js b/src/svgcanvas/dataStorage.js
index 26a4ade7..8079ec02 100644
--- a/src/svgcanvas/dataStorage.js
+++ b/src/svgcanvas/dataStorage.js
@@ -18,7 +18,7 @@ const dataStorage = {
},
remove: function (element, key) {
const ret = this._storage.get(element).delete(key)
- if (!this._storage.get(element).size === 0) {
+ if (this._storage.get(element).size === 0) {
this._storage.delete(element)
}
return ret
diff --git a/src/svgcanvas/history.js b/src/svgcanvas/history.js
index 3d04a70b..9d9aa1ba 100644
--- a/src/svgcanvas/history.js
+++ b/src/svgcanvas/history.js
@@ -6,7 +6,7 @@
* @copyright 2010 Jeff Schiller
*/
-import { getHref, setHref, getRotationAngle, isNullish, getBBox } from './utilities.js'
+import { getHref, setHref, getRotationAngle, getBBox } from './utilities.js'
/**
* Group: Undo/Redo history management.
@@ -255,7 +255,7 @@ export class RemoveElementCommand extends Command {
*/
unapply (handler) {
super.unapply(handler, () => {
- if (isNullish(this.nextSibling) && window.console) {
+ if (!this.nextSibling && window.console) {
console.error('Reference element was lost')
}
this.parent.insertBefore(this.elem, this.nextSibling) // Don't use `before` or `prepend` as `this.nextSibling` may be `null`
@@ -581,7 +581,7 @@ export class UndoManager {
const oldValues = new Array(i); const elements = new Array(i)
while (i--) {
const elem = elems[i]
- if (isNullish(elem)) { continue }
+ if (!elem) { continue }
elements[i] = elem
oldValues[i] = elem.getAttribute(attrName)
}
@@ -606,7 +606,7 @@ export class UndoManager {
let i = changeset.elements.length
while (i--) {
const elem = changeset.elements[i]
- if (isNullish(elem)) { continue }
+ if (!elem) { continue }
const changes = {}
changes[attrName] = changeset.oldValues[i]
if (changes[attrName] !== elem.getAttribute(attrName)) {
diff --git a/src/svgcanvas/layer.js b/src/svgcanvas/layer.js
index f49d1446..b9bca7df 100644
--- a/src/svgcanvas/layer.js
+++ b/src/svgcanvas/layer.js
@@ -7,7 +7,7 @@
*/
import { NS } from './namespaces.js'
-import { toXml, walkTree, isNullish } from './utilities.js'
+import { toXml, walkTree } from './utilities.js'
/**
* This class encapsulates the concept of a layer in the drawing. It can be constructed with
@@ -114,7 +114,7 @@ class Layer {
*/
getOpacity () {
const opacity = this.group_.getAttribute('opacity')
- if (isNullish(opacity)) {
+ if (!opacity) {
return 1
}
return Number.parseFloat(opacity)
@@ -218,7 +218,7 @@ Layer.CLASS_REGEX = new RegExp('(\\s|^)' + Layer.CLASS_NAME + '(\\s|$)')
*/
function addLayerClass (elem) {
const classes = elem.getAttribute('class')
- if (isNullish(classes) || !classes.length) {
+ if (!classes || !classes.length) {
elem.setAttribute('class', Layer.CLASS_NAME)
} else if (!Layer.CLASS_REGEX.test(classes)) {
elem.setAttribute('class', classes + ' ' + Layer.CLASS_NAME)
diff --git a/src/svgcanvas/path-actions.js b/src/svgcanvas/path-actions.js
index 3bc21394..b6349392 100644
--- a/src/svgcanvas/path-actions.js
+++ b/src/svgcanvas/path-actions.js
@@ -14,7 +14,7 @@ import {
transformListToTransform
} from './math.js'
import {
- assignAttributes, getElement, getRotationAngle, snapToGrid, isNullish,
+ assignAttributes, getElement, getRotationAngle, snapToGrid,
getBBox
} from './utilities.js'
@@ -541,7 +541,7 @@ export const pathActionsMethod = (function () {
// Start selection box
if (!path.dragging) {
let rubberBox = svgCanvas.getRubberBox()
- if (isNullish(rubberBox)) {
+ if (!rubberBox) {
rubberBox = svgCanvas.setRubberBox(
svgCanvas.selectorManager.getRubberBandBox()
)
@@ -875,7 +875,7 @@ export const pathActionsMethod = (function () {
* @returns {false|void}
*/
resetOrientation (pth) {
- if (isNullish(pth) || pth.nodeName !== 'path') { return false }
+ if (pth?.nodeName !== 'path') { return false }
const tlist = pth.transform.baseVal
const m = transformListToTransform(tlist).matrix
tlist.clear()
@@ -1007,7 +1007,7 @@ export const pathActionsMethod = (function () {
return true
})
- if (isNullish(openPt)) {
+ if (!openPt) {
// Single path, so close last seg
openPt = path.segs.length - 1
}
diff --git a/src/svgcanvas/path-method.js b/src/svgcanvas/path-method.js
index 6672441a..fa5b1ad8 100644
--- a/src/svgcanvas/path-method.js
+++ b/src/svgcanvas/path-method.js
@@ -12,7 +12,7 @@ import {
transformPoint, getMatrix
} from './math.js'
import {
- assignAttributes, getRotationAngle, isNullish,
+ assignAttributes, getRotationAngle,
getElement
} from './utilities.js'
@@ -635,7 +635,7 @@ export class Path {
seg.next.prev = seg
seg.mate = segs[startI]
seg.addGrip()
- if (isNullish(this.first_seg)) {
+ if (!this.first_seg) {
this.first_seg = seg
}
} else if (!nextSeg) {
@@ -907,7 +907,7 @@ export class Path {
*/
selectPt (pt, ctrlNum) {
this.clearSelection()
- if (isNullish(pt)) {
+ if (!pt) {
this.eachSeg(function (i) {
// 'this' is the segment here.
if (this.prev) {
diff --git a/src/svgcanvas/path.js b/src/svgcanvas/path.js
index 3f7763d9..5ce3b075 100644
--- a/src/svgcanvas/path.js
+++ b/src/svgcanvas/path.js
@@ -10,7 +10,7 @@ import { shortFloat } from '../common/units.js'
import { transformPoint } from './math.js'
import {
getRotationAngle, getBBox,
- getRefElem, findDefs, isNullish,
+ getRefElem, findDefs,
getBBox as utilsGetBBox
} from './utilities.js'
import {
@@ -209,10 +209,6 @@ export let path = null
* @param {string} cm The mode
* @returns {string} The same mode as passed in
*/
-/**
- * @function module:path.EditorContext#getDrawnPath
- * @returns {SVGPathElement|null}
- */
/**
* @function module:path.EditorContext#setDrawnPath
* @param {SVGPathElement|null} dp
@@ -501,7 +497,7 @@ export const recalcRotatedPath = () => {
const rvals = getRotVals(seg.x, seg.y)
const points = [rvals.x, rvals.y]
- if (!isNullish(seg.x1) && !isNullish(seg.x2)) {
+ if (seg.x1 && seg.x2) {
const cVals1 = getRotVals(seg.x1, seg.y1)
const cVals2 = getRotVals(seg.x2, seg.y2)
points.splice(points.length, 0, cVals1.x, cVals1.y, cVals2.x, cVals2.y)
diff --git a/src/svgcanvas/recalculate.js b/src/svgcanvas/recalculate.js
index cc5ab1e6..f2a1a045 100644
--- a/src/svgcanvas/recalculate.js
+++ b/src/svgcanvas/recalculate.js
@@ -6,7 +6,7 @@
import { NS } from './namespaces.js'
import { convertToNum } from '../common/units.js'
-import { getRotationAngle, getHref, getBBox, getRefElem, isNullish } from './utilities.js'
+import { getRotationAngle, getHref, getBBox, getRefElem } from './utilities.js'
import { BatchCommand, ChangeElementCommand } from './history.js'
import { remapElement } from './coords.js'
import {
@@ -231,7 +231,7 @@ export const recalculateDimensions = function (selected) {
// if we haven't created an initial array in polygon/polyline/path, then
// make a copy of initial values and include the transform
- if (isNullish(initial)) {
+ if (!initial) {
initial = mergeDeep({}, changes)
for (const [attr, val] of Object.entries(initial)) {
initial[attr] = convertToNum(attr, val)
diff --git a/src/svgcanvas/select.js b/src/svgcanvas/select.js
index fc2200eb..ec455f3f 100644
--- a/src/svgcanvas/select.js
+++ b/src/svgcanvas/select.js
@@ -7,7 +7,7 @@
*/
import { isTouch, isWebkit } from '../common/browser.js' // , isOpera
-import { getRotationAngle, getBBox, getStrokedBBox, isNullish } from './utilities.js'
+import { getRotationAngle, getBBox, getStrokedBBox } from './utilities.js'
import { transformListToTransform, transformBox, transformPoint } from './math.js'
let svgCanvas
@@ -439,7 +439,7 @@ export class SelectorManager {
* @returns {void}
*/
releaseSelector (elem) {
- if (isNullish(elem)) { return }
+ if (!elem) { return }
const N = this.selectors.length
const sel = this.selectorMap[elem.id]
if (sel && !sel.locked) {