diff --git a/src/editor/extensions/ext-connector/ext-connector.js b/src/editor/extensions/ext-connector/ext-connector.js index 2c0db502..40c2205a 100644 --- a/src/editor/extensions/ext-connector/ext-connector.js +++ b/src/editor/extensions/ext-connector/ext-connector.js @@ -360,13 +360,11 @@ export default { name: svgEditor.i18next.t(`${name}:name`), callback() { const btitle = svgEditor.i18next.t(`${name}:langListTitle`); - // Add the button and its handler(s) - const buttonTemplate = document.createElement("template"); // eslint-disable-next-line no-unsanitized/property - buttonTemplate.innerHTML = ` + const buttonTemplate = ` `; - $id('tools_left').append(buttonTemplate.content.cloneNode(true)); + svgCanvas.insertChildAtIndex($id('tools_left'), buttonTemplate, 13); $id('mode_connect').addEventListener("click", () => { svgCanvas.setMode('connector'); }); diff --git a/src/editor/extensions/ext-eyedropper/ext-eyedropper.js b/src/editor/extensions/ext-eyedropper/ext-eyedropper.js index 18d8fcb7..88b9d166 100644 --- a/src/editor/extensions/ext-eyedropper/ext-eyedropper.js +++ b/src/editor/extensions/ext-eyedropper/ext-eyedropper.js @@ -82,14 +82,13 @@ export default { name: svgEditor.i18next.t(`${name}:name`), callback() { // Add the button and its handler(s) - const buttonTemplate = document.createElement("template"); const title = svgEditor.i18next.t(`${name}:buttons.0.title`); const key = svgEditor.i18next.t(`${name}:buttons.0.key`); // eslint-disable-next-line no-unsanitized/property - buttonTemplate.innerHTML = ` + const buttonTemplate = ` `; - $id('tools_left').append(buttonTemplate.content.cloneNode(true)); + svgCanvas.insertChildAtIndex($id('tools_left'), buttonTemplate, 12); $id('tool_eyedropper').addEventListener("click", () => { svgCanvas.setMode('eyedropper'); }); diff --git a/src/editor/extensions/ext-polystar/ext-polystar.js b/src/editor/extensions/ext-polystar/ext-polystar.js index 27884a4b..d7ff7df9 100644 --- a/src/editor/extensions/ext-polystar/ext-polystar.js +++ b/src/editor/extensions/ext-polystar/ext-polystar.js @@ -79,9 +79,8 @@ export default { const fbtitle = svgEditor.i18next.t(`${name}:title`); const title_star = svgEditor.i18next.t(`${name}:buttons.0.title`); const title_polygon = svgEditor.i18next.t(`${name}:buttons.1.title`); - const buttonTemplate = document.createElement("template"); // eslint-disable-next-line no-unsanitized/property - buttonTemplate.innerHTML = ` + const buttonTemplate = ` @@ -89,7 +88,7 @@ export default { `; - $id("tools_left").append(buttonTemplate.content.cloneNode(true)); + svgCanvas.insertChildAtIndex($id('tools_left'), buttonTemplate, 10); // handler $id("tool_star").addEventListener("click", () => { if (this.leftPanel.updateLeftPanel("tool_star")) { diff --git a/src/editor/extensions/ext-shapes/ext-shapes.js b/src/editor/extensions/ext-shapes/ext-shapes.js index 98997ef3..d7dfcad3 100644 --- a/src/editor/extensions/ext-shapes/ext-shapes.js +++ b/src/editor/extensions/ext-shapes/ext-shapes.js @@ -43,13 +43,12 @@ export default { return { callback () { if ($id('tool_shapelib') === null) { - const buttonTemplate = document.createElement("template"); // eslint-disable-next-line no-unsanitized/property - buttonTemplate.innerHTML = ` + const buttonTemplate = ` `; - $id('tools_left').append(buttonTemplate.content.cloneNode(true)); + canv.insertChildAtIndex($id('tools_left'), buttonTemplate, 9); $id('tool_shapelib').addEventListener("click", () => { canv.setMode(modeId); }); diff --git a/src/editor/panels/LeftPanel.js b/src/editor/panels/LeftPanel.js index 9edd7929..f1e8cc90 100644 --- a/src/editor/panels/LeftPanel.js +++ b/src/editor/panels/LeftPanel.js @@ -1,4 +1,5 @@ import SvgCanvas from "../../svgcanvas/svgcanvas.js"; +import { insertChildAtIndex } from '../../svgcanvas/utilities.js'; const { $id, $qa } = SvgCanvas; @@ -196,30 +197,60 @@ class LeftPanel { init() { const { i18next } = this.editor; // add Left panel + const leftMenu = [ + { + menu: ``, + position: 1 + }, + { + menu: ``, + position: 2 + }, + { + menu: ``, + position: 3 + }, + { + menu: ``, + position: 4 + }, + { + menu: ``, + position: 5 + }, + { + menu: ` + + + + `, + position: 6 + }, + { + menu: ` + + + + `, + position: 7 + }, + { + menu: ``, + position: 8 + }, + { + menu: ``, + position: 11 + } + ]; const template = document.createElement("template"); - // eslint-disable-next-line no-unsanitized/property - template.innerHTML = ` -
- - - - - - - - - - - - - - - - - -
- `; + template.innerHTML = `
`; this.editor.$svgEditor.append(template.content.cloneNode(true)); + const leftMenuSort = leftMenu.sort((a, b) => (a.position > b.position) ? 1 : ((b.position > a.position) ? -1 : 0)); + const parent = $id("tools_left"); + leftMenuSort.forEach(function (value) { + insertChildAtIndex(parent, value.menu, value.position); + }); // register actions for left panel $id("tool_select").addEventListener("click", this.clickSelect.bind(this)); $id("tool_fhpath").addEventListener("click", this.clickFHPath.bind(this)); diff --git a/src/svgcanvas/svgcanvas.js b/src/svgcanvas/svgcanvas.js index 3ba97f4c..0703c133 100644 --- a/src/svgcanvas/svgcanvas.js +++ b/src/svgcanvas/svgcanvas.js @@ -70,7 +70,7 @@ import { preventClickDefault, walkTree, getBBoxOfElementAsPath, convertToPath, encode64, decode64, getVisibleElements, dropXMLInternalSubset, init as utilsInit, getBBox as utilsGetBBox, getStrokedBBoxDefaultVisible, isNullish, blankPageObjectURL, - $id, $qa, $qq, getFeGaussianBlur + $id, $qa, $qq, getFeGaussianBlur, stringToHTML, insertChildAtIndex } from './utilities.js'; import { transformPoint, matrixMultiply, hasMatrixTransform, transformListToTransform, @@ -188,6 +188,8 @@ class SvgCanvas { this.$id = $id; this.$qq = $qq; this.$qa = $qa; + this.stringToHTML = stringToHTML; + this.insertChildAtIndex = insertChildAtIndex; this.getClosest = getClosest; this.getParents = getParents; /** A storage solution aimed at replacing jQuerys data function. diff --git a/src/svgcanvas/utilities.js b/src/svgcanvas/utilities.js index 2b41c90b..f05e8850 100644 --- a/src/svgcanvas/utilities.js +++ b/src/svgcanvas/utilities.js @@ -1375,6 +1375,22 @@ export const mock = ({ getRotationAngle = getRotationAngleUser; }; +export const stringToHTML = (str) => { + const parser = new DOMParser(); + const doc = parser.parseFromString(str, 'text/html'); + return doc.body.firstChild; +}; + +export const insertChildAtIndex = function(parent, child, index) { + const doc = stringToHTML(child); + if (!index) index = 0; + if (index >= parent.children.length) { + parent.appendChild(doc); + } else { + parent.insertBefore(doc, parent.children[index]); + } +}; + // shortcuts to common DOM functions export const $id = (id) => document.getElementById(id); export const $qq = (sel) => document.querySelector(sel);