Fix layer initialisation for orphans (#1005)
* beautify with standard * update dependencies * name is created below so no need here * initialize name before using it.
This commit is contained in:
1752
package-lock.json
generated
1752
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
36
package.json
36
package.json
@@ -89,24 +89,24 @@
|
||||
"browser-fs-access": "0.35.0",
|
||||
"core-js": "3.38.1",
|
||||
"elix": "15.0.1",
|
||||
"i18next": "23.15.1",
|
||||
"jspdf": "2.5.1",
|
||||
"i18next": "23.16.4",
|
||||
"jspdf": "2.5.2",
|
||||
"pathseg": "1.2.1",
|
||||
"regenerator-runtime": "0.14.1",
|
||||
"replace-in-file": "^8.1.0",
|
||||
"replace-in-file": "^8.2.0",
|
||||
"svg2pdf.js": "2.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.25.2",
|
||||
"@babel/preset-env": "7.25.4",
|
||||
"@babel/register": "7.24.6",
|
||||
"@babel/runtime-corejs3": "7.25.6",
|
||||
"@cypress/code-coverage": "3.12.48",
|
||||
"@babel/core": "7.26.0",
|
||||
"@babel/preset-env": "7.26.0",
|
||||
"@babel/register": "7.25.9",
|
||||
"@babel/runtime-corejs3": "7.26.0",
|
||||
"@cypress/code-coverage": "3.13.4",
|
||||
"@rollup/plugin-babel": "6.0.4",
|
||||
"@rollup/plugin-commonjs": "^26",
|
||||
"@rollup/plugin-dynamic-import-vars": "2.1.2",
|
||||
"@rollup/plugin-node-resolve": "15.2.3",
|
||||
"@rollup/plugin-replace": "5.0.7",
|
||||
"@rollup/plugin-commonjs": "^28",
|
||||
"@rollup/plugin-dynamic-import-vars": "2.1.5",
|
||||
"@rollup/plugin-node-resolve": "15.3.0",
|
||||
"@rollup/plugin-replace": "6.0.1",
|
||||
"@rollup/plugin-terser": "0.4.4",
|
||||
"@rollup/plugin-url": "8.0.2",
|
||||
"@web/dev-server": "0.4.6",
|
||||
@@ -115,13 +115,13 @@
|
||||
"babel-plugin-transform-object-rest-spread": "7.0.0-beta.3",
|
||||
"core-js-bundle": "3.38.1",
|
||||
"cp-cli": "2.0.0",
|
||||
"cypress": "13.14.2",
|
||||
"cypress-multi-reporters": "1.6.4",
|
||||
"cypress": "13.15.1",
|
||||
"cypress-multi-reporters": "2.0.4",
|
||||
"jamilih": "0.60.0",
|
||||
"jsdoc": "4.0.3",
|
||||
"jsdoc": "4.0.4",
|
||||
"node-static": "0.7.11",
|
||||
"npm-run-all": "4.1.5",
|
||||
"nyc": "17.0.0",
|
||||
"nyc": "17.1.0",
|
||||
"open-cli": "8.0.0",
|
||||
"promise-fs": "2.1.1",
|
||||
"qr-manipulation": "0.7.0",
|
||||
@@ -129,7 +129,7 @@
|
||||
"remark-cli": "12.0.1",
|
||||
"remark-lint-ordered-list-marker-value": "4.0.0",
|
||||
"rimraf": "6.0.1",
|
||||
"rollup": "4.21.3",
|
||||
"rollup": "4.24.0",
|
||||
"rollup-plugin-copy": "3.5.0",
|
||||
"rollup-plugin-filesize": "10.0.0",
|
||||
"rollup-plugin-html": "0.2.1",
|
||||
@@ -139,6 +139,6 @@
|
||||
"start-server-and-test": "2.0.8"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-linux-x64-gnu": "4.21.3"
|
||||
"@rollup/rollup-linux-x64-gnu": "4.24.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,15 +9,14 @@ import Layer from './layer.js'
|
||||
import HistoryRecordingService from './historyrecording.js'
|
||||
|
||||
import { NS } from './namespaces.js'
|
||||
import {
|
||||
toXml, getElement
|
||||
} from './utilities.js'
|
||||
import {
|
||||
copyElem as utilCopyElem
|
||||
} from './copy-elem.js'
|
||||
import { toXml, getElement } from './utilities.js'
|
||||
import { copyElem as utilCopyElem } from './copy-elem.js'
|
||||
import { getParentsUntil } from '../common/util.js'
|
||||
|
||||
const visElems = 'a,circle,ellipse,foreignObject,g,image,line,path,polygon,polyline,rect,svg,text,tspan,use'.split(',')
|
||||
const visElems =
|
||||
'a,circle,ellipse,foreignObject,g,image,line,path,polygon,polyline,rect,svg,text,tspan,use'.split(
|
||||
','
|
||||
)
|
||||
|
||||
const RandomizeModes = {
|
||||
LET_DOCUMENT_DECIDE: 0,
|
||||
@@ -64,9 +63,10 @@ function isLayerElement (element) {
|
||||
*/
|
||||
function getNewLayerName (existingLayerNames) {
|
||||
let i = 1
|
||||
// TODO(codedread): What about internationalization of "Layer"?
|
||||
while (existingLayerNames.includes(('Layer ' + i))) { i++ }
|
||||
return 'Layer ' + i
|
||||
while (existingLayerNames.includes(`Layer ${i}`)) {
|
||||
i++
|
||||
}
|
||||
return `Layer ${i}`
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,9 +81,16 @@ export class Drawing {
|
||||
* @throws {Error} If not initialized with an SVG element
|
||||
*/
|
||||
constructor (svgElem, optIdPrefix) {
|
||||
if (!svgElem || !svgElem.tagName || !svgElem.namespaceURI ||
|
||||
svgElem.tagName !== 'svg' || svgElem.namespaceURI !== NS.SVG) {
|
||||
throw new Error('Error: svgedit.draw.Drawing instance initialized without a <svg> element')
|
||||
if (
|
||||
!svgElem ||
|
||||
!svgElem.tagName ||
|
||||
!svgElem.namespaceURI ||
|
||||
svgElem.tagName !== 'svg' ||
|
||||
svgElem.namespaceURI !== NS.SVG
|
||||
) {
|
||||
throw new Error(
|
||||
'Error: svgedit.draw.Drawing instance initialized without a <svg> element'
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,7 +267,11 @@ export class Drawing {
|
||||
|
||||
// if we didn't get a positive number or we already released this number
|
||||
// then return false.
|
||||
if (typeof num !== 'number' || num <= 0 || this.releasedNums.includes(num)) {
|
||||
if (
|
||||
typeof num !== 'number' ||
|
||||
num <= 0 ||
|
||||
this.releasedNums.includes(num)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -353,7 +364,9 @@ export class Drawing {
|
||||
}
|
||||
|
||||
const oldpos = this.indexCurrentLayer()
|
||||
if ((oldpos === -1) || (oldpos === newpos)) { return null }
|
||||
if (oldpos === -1 || oldpos === newpos) {
|
||||
return null
|
||||
}
|
||||
|
||||
// if our new position is below us, we need to insert before the node after newpos
|
||||
const currentGroup = this.current_layer.getGroup()
|
||||
@@ -386,7 +399,9 @@ export class Drawing {
|
||||
mergeLayer (hrService) {
|
||||
const currentGroup = this.current_layer.getGroup()
|
||||
const prevGroup = currentGroup.previousElementSibling
|
||||
if (!prevGroup) { return }
|
||||
if (!prevGroup) {
|
||||
return
|
||||
}
|
||||
|
||||
hrService.startBatchCommand('Merge Layer')
|
||||
|
||||
@@ -490,7 +505,8 @@ export class Drawing {
|
||||
this.layer_map = {}
|
||||
const numchildren = this.svgElem_.childNodes.length
|
||||
// loop through all children of SVG element
|
||||
const orphans = []; const layernames = []
|
||||
const orphans = []
|
||||
const layernames = []
|
||||
let layer = null
|
||||
let childgroups = false
|
||||
for (let i = 0; i < numchildren; ++i) {
|
||||
@@ -518,7 +534,8 @@ export class Drawing {
|
||||
|
||||
// If orphans or no layers found, create a new layer and add all the orphans to it
|
||||
if (orphans.length > 0 || !childgroups) {
|
||||
layer = new Layer(getNewLayerName(layernames), null, this.svgElem_)
|
||||
const name = getNewLayerName(layernames)
|
||||
layer = new Layer(name, null, this.svgElem_)
|
||||
layer.appendChildren(orphans)
|
||||
this.all_layers.push(layer)
|
||||
this.layer_map[name] = layer
|
||||
@@ -541,7 +558,12 @@ export class Drawing {
|
||||
this.current_layer.deactivate()
|
||||
}
|
||||
// Check for duplicate name.
|
||||
if (name === undefined || name === null || name === '' || this.layer_map[name]) {
|
||||
if (
|
||||
name === undefined ||
|
||||
name === null ||
|
||||
name === '' ||
|
||||
this.layer_map[name]
|
||||
) {
|
||||
name = getNewLayerName(Object.keys(this.layer_map))
|
||||
}
|
||||
|
||||
@@ -568,10 +590,17 @@ export class Drawing {
|
||||
* also the current layer of this drawing.
|
||||
*/
|
||||
cloneLayer (name, hrService) {
|
||||
if (!this.current_layer) { return null }
|
||||
if (!this.current_layer) {
|
||||
return null
|
||||
}
|
||||
this.current_layer.deactivate()
|
||||
// Check for duplicate name.
|
||||
if (name === undefined || name === null || name === '' || this.layer_map[name]) {
|
||||
if (
|
||||
name === undefined ||
|
||||
name === null ||
|
||||
name === '' ||
|
||||
this.layer_map[name]
|
||||
) {
|
||||
name = getNewLayerName(Object.keys(this.layer_map))
|
||||
}
|
||||
|
||||
@@ -582,8 +611,10 @@ export class Drawing {
|
||||
|
||||
// Clone children
|
||||
const children = [...currentGroup.childNodes]
|
||||
children.forEach((child) => {
|
||||
if (child.localName === 'title') { return }
|
||||
children.forEach(child => {
|
||||
if (child.localName === 'title') {
|
||||
return
|
||||
}
|
||||
group.append(this.copyElem(child))
|
||||
})
|
||||
|
||||
@@ -630,7 +661,9 @@ export class Drawing {
|
||||
return null
|
||||
}
|
||||
const layer = this.layer_map[layerName]
|
||||
if (!layer) { return null }
|
||||
if (!layer) {
|
||||
return null
|
||||
}
|
||||
layer.setVisible(bVisible)
|
||||
return layer.getGroup()
|
||||
}
|
||||
@@ -643,7 +676,9 @@ export class Drawing {
|
||||
*/
|
||||
getLayerOpacity (layerName) {
|
||||
const layer = this.layer_map[layerName]
|
||||
if (!layer) { return null }
|
||||
if (!layer) {
|
||||
return null
|
||||
}
|
||||
return layer.getOpacity()
|
||||
}
|
||||
|
||||
@@ -676,7 +711,9 @@ export class Drawing {
|
||||
*/
|
||||
copyElem (el) {
|
||||
const that = this
|
||||
const getNextIdClosure = function () { return that.getNextId() }
|
||||
const getNextIdClosure = function () {
|
||||
return that.getNextId()
|
||||
}
|
||||
return utilCopyElem(el, getNextIdClosure)
|
||||
}
|
||||
}
|
||||
@@ -690,13 +727,20 @@ export class Drawing {
|
||||
* @returns {void}
|
||||
*/
|
||||
export const randomizeIds = function (enableRandomization, currentDrawing) {
|
||||
randIds = enableRandomization === false
|
||||
? RandomizeModes.NEVER_RANDOMIZE
|
||||
: RandomizeModes.ALWAYS_RANDOMIZE
|
||||
randIds =
|
||||
enableRandomization === false
|
||||
? RandomizeModes.NEVER_RANDOMIZE
|
||||
: RandomizeModes.ALWAYS_RANDOMIZE
|
||||
|
||||
if (randIds === RandomizeModes.ALWAYS_RANDOMIZE && !currentDrawing.getNonce()) {
|
||||
if (
|
||||
randIds === RandomizeModes.ALWAYS_RANDOMIZE &&
|
||||
!currentDrawing.getNonce()
|
||||
) {
|
||||
currentDrawing.setNonce(Math.floor(Math.random() * 100001))
|
||||
} else if (randIds === RandomizeModes.NEVER_RANDOMIZE && currentDrawing.getNonce()) {
|
||||
} else if (
|
||||
randIds === RandomizeModes.NEVER_RANDOMIZE &&
|
||||
currentDrawing.getNonce()
|
||||
) {
|
||||
currentDrawing.clearNonce()
|
||||
}
|
||||
}
|
||||
@@ -768,7 +812,7 @@ let svgCanvas
|
||||
* @param {module:draw.DrawCanvasInit} canvas
|
||||
* @returns {void}
|
||||
*/
|
||||
export const init = (canvas) => {
|
||||
export const init = canvas => {
|
||||
svgCanvas = canvas
|
||||
}
|
||||
|
||||
@@ -802,10 +846,9 @@ export const indexCurrentLayer = () => {
|
||||
* @returns {void}
|
||||
*/
|
||||
export const createLayer = (name, hrService) => {
|
||||
const newLayer = svgCanvas.getCurrentDrawing().createLayer(
|
||||
name,
|
||||
historyRecordingService(hrService)
|
||||
)
|
||||
const newLayer = svgCanvas
|
||||
.getCurrentDrawing()
|
||||
.createLayer(name, historyRecordingService(hrService))
|
||||
svgCanvas.clearSelection()
|
||||
svgCanvas.call('changed', [newLayer])
|
||||
}
|
||||
@@ -822,7 +865,9 @@ export const createLayer = (name, hrService) => {
|
||||
*/
|
||||
export const cloneLayer = (name, hrService) => {
|
||||
// Clone the current layer and make the cloned layer the new current layer
|
||||
const newLayer = svgCanvas.getCurrentDrawing().cloneLayer(name, historyRecordingService(hrService))
|
||||
const newLayer = svgCanvas
|
||||
.getCurrentDrawing()
|
||||
.cloneLayer(name, historyRecordingService(hrService))
|
||||
|
||||
svgCanvas.clearSelection()
|
||||
leaveContext()
|
||||
@@ -845,7 +890,9 @@ export const deleteCurrentLayer = () => {
|
||||
if (currentLayer) {
|
||||
const batchCmd = new BatchCommand('Delete Layer')
|
||||
// store in our Undo History
|
||||
batchCmd.addSubCommand(new RemoveElementCommand(currentLayer, nextSibling, parent))
|
||||
batchCmd.addSubCommand(
|
||||
new RemoveElementCommand(currentLayer, nextSibling, parent)
|
||||
)
|
||||
svgCanvas.addCommandToHistory(batchCmd)
|
||||
svgCanvas.clearSelection()
|
||||
svgCanvas.call('changed', [parent])
|
||||
@@ -861,7 +908,7 @@ export const deleteCurrentLayer = () => {
|
||||
* @param {string} name - The name of the layer you want to switch to.
|
||||
* @returns {boolean} true if the current layer was switched, otherwise false
|
||||
*/
|
||||
export const setCurrentLayer = (name) => {
|
||||
export const setCurrentLayer = name => {
|
||||
const result = svgCanvas.getCurrentDrawing().setCurrentLayer(toXml(name))
|
||||
if (result) {
|
||||
svgCanvas.clearSelection()
|
||||
@@ -878,11 +925,14 @@ export const setCurrentLayer = (name) => {
|
||||
* @fires module:svgcanvas.SvgCanvas#event:changed
|
||||
* @returns {boolean} Whether the rename succeeded
|
||||
*/
|
||||
export const renameCurrentLayer = (newName) => {
|
||||
export const renameCurrentLayer = newName => {
|
||||
const drawing = svgCanvas.getCurrentDrawing()
|
||||
const layer = drawing.getCurrentLayer()
|
||||
if (layer) {
|
||||
const result = drawing.setCurrentLayerName(newName, historyRecordingService())
|
||||
const result = drawing.setCurrentLayerName(
|
||||
newName,
|
||||
historyRecordingService()
|
||||
)
|
||||
if (result) {
|
||||
svgCanvas.call('changed', [layer])
|
||||
return true
|
||||
@@ -900,12 +950,18 @@ export const renameCurrentLayer = (newName) => {
|
||||
* 0 and (number of layers - 1)
|
||||
* @returns {boolean} `true` if the current layer position was changed, `false` otherwise.
|
||||
*/
|
||||
export const setCurrentLayerPosition = (newPos) => {
|
||||
export const setCurrentLayerPosition = newPos => {
|
||||
const { MoveElementCommand } = svgCanvas.history
|
||||
const drawing = svgCanvas.getCurrentDrawing()
|
||||
const result = drawing.setCurrentLayerPosition(newPos)
|
||||
if (result) {
|
||||
svgCanvas.addCommandToHistory(new MoveElementCommand(result.currentGroup, result.oldNextSibling, svgCanvas.getSvgContent()))
|
||||
svgCanvas.addCommandToHistory(
|
||||
new MoveElementCommand(
|
||||
result.currentGroup,
|
||||
result.oldNextSibling,
|
||||
svgCanvas.getSvgContent()
|
||||
)
|
||||
)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -926,7 +982,13 @@ export const setLayerVisibility = (layerName, bVisible) => {
|
||||
const layer = drawing.setLayerVisibility(layerName, bVisible)
|
||||
if (layer) {
|
||||
const oldDisplay = prevVisibility ? 'inline' : 'none'
|
||||
svgCanvas.addCommandToHistory(new ChangeElementCommand(layer, { display: oldDisplay }, 'Layer Visibility'))
|
||||
svgCanvas.addCommandToHistory(
|
||||
new ChangeElementCommand(
|
||||
layer,
|
||||
{ display: oldDisplay },
|
||||
'Layer Visibility'
|
||||
)
|
||||
)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
@@ -946,12 +1008,14 @@ export const setLayerVisibility = (layerName, bVisible) => {
|
||||
* @param {string} layerName - The name of the layer you want to which you want to move the selected elements
|
||||
* @returns {boolean} Whether the selected elements were moved to the layer.
|
||||
*/
|
||||
export const moveSelectedToLayer = (layerName) => {
|
||||
export const moveSelectedToLayer = layerName => {
|
||||
const { BatchCommand, MoveElementCommand } = svgCanvas.history
|
||||
// find the layer
|
||||
const drawing = svgCanvas.getCurrentDrawing()
|
||||
const layer = drawing.getLayerByName(layerName)
|
||||
if (!layer) { return false }
|
||||
if (!layer) {
|
||||
return false
|
||||
}
|
||||
|
||||
const batchCmd = new BatchCommand('Move Elements to Layer')
|
||||
|
||||
@@ -960,12 +1024,16 @@ export const moveSelectedToLayer = (layerName) => {
|
||||
let i = selElems.length
|
||||
while (i--) {
|
||||
const elem = selElems[i]
|
||||
if (!elem) { continue }
|
||||
if (!elem) {
|
||||
continue
|
||||
}
|
||||
const oldNextSibling = elem.nextSibling
|
||||
// TODO: this is pretty brittle!
|
||||
const oldLayer = elem.parentNode
|
||||
layer.append(elem)
|
||||
batchCmd.addSubCommand(new MoveElementCommand(elem, oldNextSibling, oldLayer))
|
||||
batchCmd.addSubCommand(
|
||||
new MoveElementCommand(elem, oldNextSibling, oldLayer)
|
||||
)
|
||||
}
|
||||
|
||||
svgCanvas.addCommandToHistory(batchCmd)
|
||||
@@ -978,7 +1046,7 @@ export const moveSelectedToLayer = (layerName) => {
|
||||
* @param {module:history.HistoryRecordingService} hrService
|
||||
* @returns {void}
|
||||
*/
|
||||
export const mergeLayer = (hrService) => {
|
||||
export const mergeLayer = hrService => {
|
||||
svgCanvas.getCurrentDrawing().mergeLayer(historyRecordingService(hrService))
|
||||
svgCanvas.clearSelection()
|
||||
leaveContext()
|
||||
@@ -990,8 +1058,10 @@ export const mergeLayer = (hrService) => {
|
||||
* @param {module:history.HistoryRecordingService} hrService
|
||||
* @returns {void}
|
||||
*/
|
||||
export const mergeAllLayers = (hrService) => {
|
||||
svgCanvas.getCurrentDrawing().mergeAllLayers(historyRecordingService(hrService))
|
||||
export const mergeAllLayers = hrService => {
|
||||
svgCanvas
|
||||
.getCurrentDrawing()
|
||||
.mergeAllLayers(historyRecordingService(hrService))
|
||||
svgCanvas.clearSelection()
|
||||
leaveContext()
|
||||
svgCanvas.changeSvgContent()
|
||||
@@ -1032,7 +1102,7 @@ export const leaveContext = () => {
|
||||
* @fires module:svgcanvas.SvgCanvas#event:contextset
|
||||
* @returns {void}
|
||||
*/
|
||||
export const setContext = (elem) => {
|
||||
export const setContext = elem => {
|
||||
const dataStorage = svgCanvas.getDataStorage()
|
||||
leaveContext()
|
||||
if (typeof elem === 'string') {
|
||||
@@ -1046,9 +1116,12 @@ export const setContext = (elem) => {
|
||||
const parentsUntil = getParentsUntil(elem, '#svgcontent')
|
||||
const siblings = []
|
||||
parentsUntil.forEach(function (parent) {
|
||||
const elements = Array.prototype.filter.call(parent.parentNode.children, function (child) {
|
||||
return child !== parent
|
||||
})
|
||||
const elements = Array.prototype.filter.call(
|
||||
parent.parentNode.children,
|
||||
function (child) {
|
||||
return child !== parent
|
||||
}
|
||||
)
|
||||
elements.forEach(function (element) {
|
||||
siblings.push(element)
|
||||
})
|
||||
|
||||
@@ -852,7 +852,7 @@ class SvgCanvas {
|
||||
// create new document
|
||||
this.current_drawing_ = new draw.Drawing(this.svgContent)
|
||||
// create empty first layer
|
||||
this.createLayer('Layer 1')
|
||||
this.createLayer()
|
||||
// clear the undo stack
|
||||
this.undoMgr.resetUndoStack()
|
||||
// reset the selector manager
|
||||
|
||||
Reference in New Issue
Block a user