diff --git a/archive/extensions/ext-opensave/ext-opensave.js b/archive/extensions/ext-opensave/ext-opensave.js new file mode 100644 index 00000000..b856d2fe --- /dev/null +++ b/archive/extensions/ext-opensave/ext-opensave.js @@ -0,0 +1,78 @@ +/* globals seAlert */ +/** + * @file ext-opensave.js + * + * @license MIT + * + * @copyright 2020 OptimistikSAS + * + */ + +/** + * @type {module:svgcanvas.EventHandler} + * @param {external:Window} wind + * @param {module:svgcanvas.SvgCanvas#event:saved} svg The SVG source + * @listens module:svgcanvas.SvgCanvas#event:saved + * @returns {void} + */ + +export default { + name: 'opensave', + init ({ encode64 }) { + const svgEditor = this; + + svgEditor.setCustomHandlers({ + save (win, svg) { + this.showSaveWarning = false; + + // by default, we add the XML prolog back, systems integrating SVG-edit (wikis, CMSs) + // can just provide their own custom save handler and might not want the XML prolog + svg = '\n' + svg; + + // Since saving SVGs by opening a new window was removed in Chrome use artificial link-click + // https://stackoverflow.com/questions/45603201/window-is-not-allowed-to-navigate-top-frame-navigations-to-data-urls + const a = document.createElement('a'); + a.href = 'data:image/svg+xml;base64,' + encode64(svg); + a.download = 'icon.svg'; + a.style.display = 'none'; + document.body.append(a); // Need to append for Firefox + + a.click(); + + // Alert will only appear the first time saved OR the + // first time the bug is encountered + const done = this.configObj.pref('save_notice_done'); + + if (done !== 'all') { + const note = svgEditor.i18next.t('notification.saveFromBrowser', { type: 'SVG' }); + + this.configObj.pref('save_notice_done', 'all'); + if (done !== 'part') { + seAlert(note); + } + } + }, + async open () { + const ok = await this.openPrep(); + if (ok === 'Cancel') { return; } + this.svgCanvas.clear(); + const input = document.createElement('input'); + input.type = 'file'; + input.addEventListener('change', (e) => { + // getting a hold of the file reference + const file = e.target.files[0]; + // setting up the reader + const reader = new FileReader(); + reader.readAsText(file, 'UTF-8'); + // here we tell the reader what to do when it's done reading... + reader.addEventListener('load', async (readerEvent) => { + const content = readerEvent.target.result; + await this.loadSvgString(content); + this.updateCanvas(); + }); + }); + input.click(); + } + }); + } +}; diff --git a/cypress/integration/ui/__snapshots__/scenario1.js.snap b/cypress/integration/ui/__snapshots__/scenario1.js.snap index 6c29fcec..ee4d81cd 100644 --- a/cypress/integration/ui/__snapshots__/scenario1.js.snap +++ b/cypress/integration/ui/__snapshots__/scenario1.js.snap @@ -101,7 +101,109 @@ exports[`use all parts of svg-edit > check tool_shape #0`] = ` `; -exports[`use all parts of svg-edit > check mode_connect #0`] = ` +exports[`use all parts of svg-edit > check tool_rect_square #0`] = ` + + + Layer 1 + + + + + + + + + + + + + +`; + +exports[`use all parts of svg-edit > check tool_image #0`] = ` check mode_connect #0`] = ` fill="#FF0000" stroke="#000000" stroke-width="5" - opacity="0.5" style="pointer-events:inherit" x="446" y="76" width="180" height="180" id="svg_4" + fill-opacity="1" + stroke-opacity="1" + > + + check mode_connect #0`] = ` fill="freeze" to="1" > - + `; diff --git a/cypress/integration/ui/scenario1.js b/cypress/integration/ui/scenario1.js index becc5409..9813aed0 100644 --- a/cypress/integration/ui/scenario1.js +++ b/cypress/integration/ui/scenario1.js @@ -49,7 +49,7 @@ describe('use all parts of svg-edit', function () { .trigger('mouseup', { force: true }); cy.get('#svgcontent').toMatchSnapshot(); }); - it('check mode_connect', function () { + it('check tool_rect_square', function () { cy.get('#tool_rect').click({ force: true }); cy.get('#svgcontent') .trigger('mousedown', 100, -60, { force: true }) @@ -60,24 +60,32 @@ describe('use all parts of svg-edit', function () { .trigger('mousedown', 250, -60, { force: true }) .trigger('mousemove', 430, 120, { force: true }) .trigger('mouseup', { force: true }); - cy.get('#tool_select').click({ force: true }); - cy.get('#mode_connect').click({ force: true }); - + cy.get('#tool_fhrect') + .click({ force: true }); cy.get('#svgcontent') - .trigger('mousedown', -10, -10, { force: true }) - .trigger('mousemove', -180, -180, { force: true }) - .trigger('mouseup', { force: true }); + .trigger('mousedown', 20, 80, { force: true }) + .trigger('mousemove', 120, 80, { force: true }) + .trigger('mousemove', 120, 180, { force: true }) + .trigger('mousemove', 20, 180, { force: true }) + .trigger('mousemove', 20, 80, { force: true }) + .trigger('mouseup', 20, 80, { force: true }); cy.get('#svgcontent').toMatchSnapshot(); }); - /* it('check tool_image', function () { + it('check tool_image', function () { cy.get('#tool_image').click({ force: true }); cy.get('#svgcontent') - .trigger('mousemove', 100, 100, { force: true }) .trigger('mousedown', 100, 100, { force: true }) + .trigger('mousemove', 120, 120, { force: true }) .trigger('mouseup', { force: true }); - cy.on('window:confirm', () => true); + // eslint-disable-next-line promise/catch-or-return + cy.window() + // eslint-disable-next-line promise/always-return + .then(($win) => { + cy.stub($win, 'prompt').returns('./images/logo.svg'); + cy.contains('OK'); + }); cy.get('#svgcontent').toMatchSnapshot(); - }); */ + }); }); diff --git a/package-lock.json b/package-lock.json index 2180c530..6fc909af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "license": "(MIT AND Apache-2.0 AND ISC AND LGPL-3.0-or-later AND X11)", "dependencies": { "@babel/polyfill": "7.12.1", + "browser-fs-access": "^0.20.4", "canvg": "3.0.7", "core-js": "3.16.2", "elix": "15.0.0", @@ -5299,6 +5300,11 @@ "node": ">= 10.16.0" } }, + "node_modules/browser-fs-access": { + "version": "0.20.4", + "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.20.4.tgz", + "integrity": "sha512-rSbY1AIoDe+fvYZ1LiRDdKBnytfsd1nN/GKS/DRZAhaJkz3cfbp14IHw5lk4FFWBelD6Sw6EtdnAI990ZuBZjg==" + }, "node_modules/browser-pack": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", @@ -26396,6 +26402,11 @@ "duplexer": "0.1.1" } }, + "browser-fs-access": { + "version": "0.20.4", + "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.20.4.tgz", + "integrity": "sha512-rSbY1AIoDe+fvYZ1LiRDdKBnytfsd1nN/GKS/DRZAhaJkz3cfbp14IHw5lk4FFWBelD6Sw6EtdnAI990ZuBZjg==" + }, "browser-pack": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", diff --git a/package.json b/package.json index 89e91820..66ab46c1 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ ], "dependencies": { "@babel/polyfill": "7.12.1", + "browser-fs-access": "^0.20.4", "canvg": "3.0.7", "core-js": "3.16.2", "elix": "15.0.0", diff --git a/src/editor/Editor.js b/src/editor/Editor.js index 2b3887e4..c5e58ff8 100644 --- a/src/editor/Editor.js +++ b/src/editor/Editor.js @@ -180,38 +180,6 @@ class Editor extends EditorStartup { * @returns {void} */ - /** - * Allows one to override default SVGEdit `open`, `save`, and - * `export` editor behaviors. - * @function module:SVGthis.setCustomHandlers - * @param {module:SVGthis.CustomHandler} opts Extension mechanisms may call `setCustomHandlers` with three functions: `opts.open`, `opts.save`, and `opts.exportImage` - * @returns {Promise} - */ - - /** - * @param {PlainObject} opts - * @returns {Promise} - */ - setCustomHandlers(opts) { - return this.ready(() => { - if (opts.open) { - this.svgCanvas.open = opts.open.bind(this); - } - if (opts.save) { - this.showSaveWarning = false; - this.svgCanvas.bind('saved', opts.save.bind(this)); - } - if (opts.exportImage) { - this.customExportImage = opts.exportImage.bind(this); - this.svgCanvas.bind('exported', this.customExportImage); // canvg and our RGBColor will be available to the method - } - if (opts.exportPDF) { - this.customExportPDF = opts.exportPDF.bind(this); - this.svgCanvas.bind('exportedPDF', this.customExportPDF); // jsPDF and our RGBColor will be available to the method - } - }); - } - /** * @function module:SVGthis.randomizeIds * @param {boolean} arg diff --git a/src/editor/MainMenu.js b/src/editor/MainMenu.js index 27dd08ac..bac71306 100644 --- a/src/editor/MainMenu.js +++ b/src/editor/MainMenu.js @@ -129,20 +129,6 @@ class MainMenu { this.editor.updateCanvas(); this.hidePreferences(); } - - /** - * - * @returns {void} - */ - clickSave() { - // In the future, more options can be provided here - const saveOpts = { - images: this.editor.configObj.pref("img_save"), - round_digits: 6 - }; - this.editor.svgCanvas.save(saveOpts); - } - /** * * @param e @@ -210,16 +196,6 @@ class MainMenu { } } - /** - * By default, this.editor.svgCanvas.open() is a no-op. It is up to an extension - * mechanism (opera widget, etc.) to call `setCustomHandlers()` which - * will make it do something. - * @returns {void} - */ - clickOpen() { - this.editor.svgCanvas.open(); - } - /** * * @returns {void} @@ -307,9 +283,6 @@ class MainMenu { // eslint-disable-next-line no-unsanitized/property template.innerHTML = ` - - - @@ -324,29 +297,10 @@ class MainMenu { * Associate all button actions as well as non-button keyboard shortcuts. */ - $id("tool_clear").addEventListener("click", this.clickClear.bind(this)); - $id("tool_open").addEventListener("click", (e) => { - e.preventDefault(); - this.clickOpen(); - window.dispatchEvent(new CustomEvent("openImage")); - }); $id("tool_import").addEventListener("click", () => { this.clickImport(); window.dispatchEvent(new CustomEvent("importImages")); }); - $id("tool_save").addEventListener( - "click", - function() { - const $editorDialog = $id("se-svg-editor-dialog"); - const editingsource = $editorDialog.getAttribute("dialog") === "open"; - if (editingsource) { - this.saveSourceEditor(); - } else { - this.clickSave(); - } - }.bind(this) - ); - // this.clickExport.bind(this) $id("tool_export").addEventListener("click", function() { document .getElementById("se-export-dialog") diff --git a/src/editor/extensions/ext-opensave/ext-opensave.js b/src/editor/extensions/ext-opensave/ext-opensave.js index b856d2fe..fd9a463f 100644 --- a/src/editor/extensions/ext-opensave/ext-opensave.js +++ b/src/editor/extensions/ext-opensave/ext-opensave.js @@ -1,4 +1,4 @@ -/* globals seAlert */ +/* globals seConfirm */ /** * @file ext-opensave.js * @@ -15,64 +15,167 @@ * @listens module:svgcanvas.SvgCanvas#event:saved * @returns {void} */ +import { fileOpen, fileSave } from 'browser-fs-access'; + +const name = "opensave"; +let handle = null; + +const loadExtensionTranslation = async function (svgEditor) { + let translationModule; + const lang = svgEditor.configObj.pref('lang'); + try { + // eslint-disable-next-line no-unsanitized/method + translationModule = await import(`./locale/${lang}.js`); + } catch (_error) { + // eslint-disable-next-line no-console + console.warn(`Missing translation (${lang}) for ${name} - using 'en'`); + // eslint-disable-next-line no-unsanitized/method + translationModule = await import(`./locale/en.js`); + } + svgEditor.i18next.addResourceBundle(lang, 'translation', translationModule.default, true, true); +}; export default { - name: 'opensave', - init ({ encode64 }) { + name, + async init(_S) { const svgEditor = this; + const { imgPath } = svgEditor.configObj.curConfig; + const { svgCanvas } = svgEditor; + const { $id } = svgCanvas; + await loadExtensionTranslation(svgEditor); - svgEditor.setCustomHandlers({ - save (win, svg) { - this.showSaveWarning = false; + /** + * @fires module:svgcanvas.SvgCanvas#event:ext_onNewDocument + * @returns {void} + */ + const clickClear = async function () { + const [ x, y ] = svgEditor.configObj.curConfig.dimensions; + const ok = await seConfirm(svgEditor.i18next.t('notification.QwantToClear')); + if (ok === "Cancel") { + return; + } + svgEditor.leftPanel.clickSelect(); + svgEditor.svgCanvas.clear(); + svgEditor.svgCanvas.setResolution(x, y); + svgEditor.updateCanvas(true); + svgEditor.zoomImage(); + svgEditor.layersPanel.populateLayers(); + svgEditor.topPanel.updateContextPanel(); + svgEditor.svgCanvas.runExtensions("onNewDocument"); + }; - // by default, we add the XML prolog back, systems integrating SVG-edit (wikis, CMSs) - // can just provide their own custom save handler and might not want the XML prolog - svg = '\n' + svg; + /** + * By default, this.editor.svgCanvas.open() is a no-op. It is up to an extension + * mechanism (opera widget, etc.) to call `setCustomHandlers()` which + * will make it do something. + * @returns {void} + */ + const clickOpen = async function () { + // ask user before clearing an unsaved SVG + const response = await svgEditor.openPrep(); + if (response === 'Cancel') { return; } + svgCanvas.clear(); + try { + const blob = await fileOpen({ + mimeTypes: [ 'image/*' ] + }); + const svgContent = await blob.text(); + await svgEditor.loadSvgString(svgContent); + svgEditor.updateCanvas(); + } catch (err) { + if (err.name !== 'AbortError') { + return console.error(err); + } + } + }; - // Since saving SVGs by opening a new window was removed in Chrome use artificial link-click - // https://stackoverflow.com/questions/45603201/window-is-not-allowed-to-navigate-top-frame-navigations-to-data-urls - const a = document.createElement('a'); - a.href = 'data:image/svg+xml;base64,' + encode64(svg); - a.download = 'icon.svg'; - a.style.display = 'none'; - document.body.append(a); // Need to append for Firefox + const b64toBlob = (b64Data, contentType='', sliceSize=512) => { + const byteCharacters = atob(b64Data); + const byteArrays = []; + for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) { + const slice = byteCharacters.slice(offset, offset + sliceSize); + const byteNumbers = new Array(slice.length); + for (let i = 0; i < slice.length; i++) { + byteNumbers[i] = slice.charCodeAt(i); + } + const byteArray = new Uint8Array(byteNumbers); + byteArrays.push(byteArray); + } + const blob = new Blob(byteArrays, { type: contentType }); + return blob; + }; - a.click(); - - // Alert will only appear the first time saved OR the - // first time the bug is encountered - const done = this.configObj.pref('save_notice_done'); - - if (done !== 'all') { - const note = svgEditor.i18next.t('notification.saveFromBrowser', { type: 'SVG' }); - - this.configObj.pref('save_notice_done', 'all'); - if (done !== 'part') { - seAlert(note); + /** + * + * @returns {void} + */ + const clickSave = async function (type, _) { + const $editorDialog = $id("se-svg-editor-dialog"); + const editingsource = $editorDialog.getAttribute("dialog") === "open"; + if (editingsource) { + svgEditor.saveSourceEditor(); + } else { + // In the future, more options can be provided here + const saveOpts = { + images: svgEditor.configObj.pref("img_save"), + round_digits: 6 + }; + // remove the selected outline before serializing + svgCanvas.clearSelection(); + // Update save options if provided + if (saveOpts) { + const saveOptions = svgCanvas.mergeDeep(svgCanvas.getSvgOption(), saveOpts); + for (const [ key, value ] of Object.entries(saveOptions)) { + svgCanvas.setSvgOption(key, value); + } + } + svgCanvas.setSvgOption('apply', true); + + // no need for doctype, see https://jwatt.org/svg/authoring/#doctype-declaration + const svg = '\n' + svgCanvas.svgCanvasToString(); + const b64Data = svgCanvas.encode64(svg); + const blob = b64toBlob(b64Data, 'image/svg+xml'); + try { + if(type === "save" && handle !== null) { + const throwIfExistingHandleNotGood = false; + handle = await fileSave(blob, { + fileName: 'icon.svg', + extensions: [ '.svg' ] + }, handle, throwIfExistingHandleNotGood); + } else { + handle = await fileSave(blob, { + fileName: 'icon.svg', + extensions: [ '.svg' ] + }); + } + } catch (err) { + if (err.name !== 'AbortError') { + return console.error(err); } } - }, - async open () { - const ok = await this.openPrep(); - if (ok === 'Cancel') { return; } - this.svgCanvas.clear(); - const input = document.createElement('input'); - input.type = 'file'; - input.addEventListener('change', (e) => { - // getting a hold of the file reference - const file = e.target.files[0]; - // setting up the reader - const reader = new FileReader(); - reader.readAsText(file, 'UTF-8'); - // here we tell the reader what to do when it's done reading... - reader.addEventListener('load', async (readerEvent) => { - const content = readerEvent.target.result; - await this.loadSvgString(content); - this.updateCanvas(); - }); - }); - input.click(); } - }); + }; + + return { + name: svgEditor.i18next.t(`${name}:name`), + // The callback should be used to load the DOM with the appropriate UI items + callback() { + // eslint-disable-next-line no-unsanitized/property + const buttonTemplate = ` + `; + svgCanvas.insertChildAtIndex($id('main_button'), buttonTemplate, 0); + const openButtonTemplate = ``; + svgCanvas.insertChildAtIndex($id('main_button'), openButtonTemplate, 1); + const saveButtonTemplate = ``; + svgCanvas.insertChildAtIndex($id('main_button'), saveButtonTemplate, 2); + const saveAsButtonTemplate = ``; + svgCanvas.insertChildAtIndex($id('main_button'), saveAsButtonTemplate, 3); + // handler + $id("tool_clear").addEventListener("click", clickClear.bind(this)); + $id("tool_open").addEventListener("click", clickOpen.bind(this)); + $id("tool_save").addEventListener("click", clickSave.bind(this, "save")); + $id("tool_save_as").addEventListener("click", clickSave.bind(this, "saveas")); + } + }; } }; diff --git a/src/editor/extensions/ext-opensave/locale/en.js b/src/editor/extensions/ext-opensave/locale/en.js new file mode 100644 index 00000000..bedd8cf0 --- /dev/null +++ b/src/editor/extensions/ext-opensave/locale/en.js @@ -0,0 +1,8 @@ +export default { + opensave: { + new_doc: 'New Image', + open_image_doc: 'Open SVG', + save_doc: 'Save SVG', + save_as_doc: 'Save as SVG' + } +}; diff --git a/src/editor/extensions/ext-opensave/locale/fr.js b/src/editor/extensions/ext-opensave/locale/fr.js new file mode 100644 index 00000000..7704f6d6 --- /dev/null +++ b/src/editor/extensions/ext-opensave/locale/fr.js @@ -0,0 +1,8 @@ +export default { + opensave: { + new_doc: 'Nouvelle image', + open_image_doc: 'Ouvrir le SVG', + save_doc: 'Enregistrer l\'image', + save_as_doc: 'Enregistrer en tant qu\'image' + } +}; diff --git a/src/editor/extensions/ext-opensave/locale/zh-CN.js b/src/editor/extensions/ext-opensave/locale/zh-CN.js new file mode 100755 index 00000000..c1f47c07 --- /dev/null +++ b/src/editor/extensions/ext-opensave/locale/zh-CN.js @@ -0,0 +1,8 @@ +export default { + opensave: { + new_doc: '新图片', + open_image_doc: '打开 SVG', + save_doc: '保存图像', + save_as_doc: '另存为图像' + } +}; diff --git a/src/editor/locale/lang.af.js b/src/editor/locale/lang.af.js index 1027a18f..5c3b7432 100644 --- a/src/editor/locale/lang.af.js +++ b/src/editor/locale/lang.af.js @@ -107,11 +107,8 @@ export default { largest_object: 'grootste voorwerp', selected_objects: 'verkose voorwerpe', smallest_object: 'kleinste voorwerp', - new_doc: 'Nuwe Beeld', - open_doc: 'Open Beeld', export_img: 'Export', - save_doc: 'Slaan Beeld', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align Bottom', align_center: 'Rig Middel', diff --git a/src/editor/locale/lang.ar.js b/src/editor/locale/lang.ar.js index 3e2673cc..ee393452 100644 --- a/src/editor/locale/lang.ar.js +++ b/src/editor/locale/lang.ar.js @@ -107,11 +107,8 @@ export default { largest_object: 'أكبر كائن', selected_objects: 'انتخب الأجسام', smallest_object: 'أصغر كائن', - new_doc: 'صورة جديدة', - open_doc: 'فتح الصورة', export_img: 'Export', - save_doc: 'حفظ صورة', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'محاذاة القاع', align_center: 'مركز محاذاة', diff --git a/src/editor/locale/lang.az.js b/src/editor/locale/lang.az.js index bc7bae51..2d50b659 100644 --- a/src/editor/locale/lang.az.js +++ b/src/editor/locale/lang.az.js @@ -107,11 +107,8 @@ export default { largest_object: 'largest object', selected_objects: 'selected objects', smallest_object: 'smallest object', - new_doc: 'New Image', - open_doc: 'Open SVG', export_img: 'Export', - save_doc: 'Save Image', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align Bottom', align_center: 'Align Center', diff --git a/src/editor/locale/lang.be.js b/src/editor/locale/lang.be.js index 071cf304..64182cb7 100644 --- a/src/editor/locale/lang.be.js +++ b/src/editor/locale/lang.be.js @@ -107,11 +107,8 @@ export default { largest_object: 'найбуйнейшы аб'ект', selected_objects: 'выбранымі аб'ектамі', smallest_object: 'маленькі аб'ект', - new_doc: 'Новае выява', - open_doc: 'Адкрыць выява', export_img: 'Export', - save_doc: 'Захаваць малюнак', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Лінаваць па ніжнім краю', align_center: 'Лінаваць па цэнтру', diff --git a/src/editor/locale/lang.bg.js b/src/editor/locale/lang.bg.js index 783a2ee6..cae8dd2e 100644 --- a/src/editor/locale/lang.bg.js +++ b/src/editor/locale/lang.bg.js @@ -107,11 +107,8 @@ export default { largest_object: 'най-големият обект', selected_objects: 'избраните обекти', smallest_object: 'най-малката обект', - new_doc: 'Ню Имидж', - open_doc: 'Отворете изображението', export_img: 'Export', - save_doc: 'Save Image', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Привеждане Отдолу', align_center: 'Подравняване в средата', diff --git a/src/editor/locale/lang.ca.js b/src/editor/locale/lang.ca.js index ca3157c7..6f56c947 100644 --- a/src/editor/locale/lang.ca.js +++ b/src/editor/locale/lang.ca.js @@ -111,7 +111,7 @@ export default { open_doc: 'Obrir imatge', export_img: 'Export', save_doc: 'Guardar imatge', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Alinear baix', align_center: 'Alinear al centre', diff --git a/src/editor/locale/lang.cy.js b/src/editor/locale/lang.cy.js index 031a97ed..72c466e6 100644 --- a/src/editor/locale/lang.cy.js +++ b/src/editor/locale/lang.cy.js @@ -111,7 +111,7 @@ export default { open_doc: 'Delwedd Agored', export_img: 'Export', save_doc: 'Cadw Delwedd', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Alinio Gwaelod', align_center: 'Alinio Center', diff --git a/src/editor/locale/lang.da.js b/src/editor/locale/lang.da.js index 3bd6c198..85ce8179 100644 --- a/src/editor/locale/lang.da.js +++ b/src/editor/locale/lang.da.js @@ -107,11 +107,8 @@ export default { largest_object: 'største objekt', selected_objects: 'valgte objekter', smallest_object: 'mindste objekt', - new_doc: 'Nyt billede', - open_doc: 'Open SVG', export_img: 'Export', - save_doc: 'Gem billede', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Juster Bottom', align_center: 'Centrer', diff --git a/src/editor/locale/lang.el.js b/src/editor/locale/lang.el.js index fa939618..fa64435c 100644 --- a/src/editor/locale/lang.el.js +++ b/src/editor/locale/lang.el.js @@ -111,7 +111,7 @@ export default { open_doc: 'Άνοιγμα εικόνας', export_img: 'Export', save_doc: 'Αποθήκευση εικόνας', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Στοίχισηκάτω', align_center: 'Στοίχισηστοκέντρο', diff --git a/src/editor/locale/lang.en.js b/src/editor/locale/lang.en.js index 7d9ba8f3..93230482 100644 --- a/src/editor/locale/lang.en.js +++ b/src/editor/locale/lang.en.js @@ -108,11 +108,8 @@ export default { largest_object: 'largest object', selected_objects: 'selected objects', smallest_object: 'smallest object', - new_doc: 'New Image', - open_doc: 'Open SVG', export_img: 'Export', - save_doc: 'Save Image', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align Bottom', align_center: 'Align Center', diff --git a/src/editor/locale/lang.et.js b/src/editor/locale/lang.et.js index 5d10396b..e4620d74 100644 --- a/src/editor/locale/lang.et.js +++ b/src/editor/locale/lang.et.js @@ -111,7 +111,7 @@ export default { open_doc: 'Pildi avamine', export_img: 'Export', save_doc: 'Salvesta pilt', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Viia Bottom', align_center: 'Keskele joondamine', diff --git a/src/editor/locale/lang.fa.js b/src/editor/locale/lang.fa.js index bb3cadb8..ce340d49 100644 --- a/src/editor/locale/lang.fa.js +++ b/src/editor/locale/lang.fa.js @@ -111,7 +111,7 @@ export default { open_doc: '‫باز کردن تصویر ‬', export_img: 'Export', save_doc: '‫ذخیره تصویر ‬', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: '‫تراز پایین‬', align_center: '‫وسط چین‬', diff --git a/src/editor/locale/lang.fi.js b/src/editor/locale/lang.fi.js index 168958f6..b59302ce 100644 --- a/src/editor/locale/lang.fi.js +++ b/src/editor/locale/lang.fi.js @@ -107,11 +107,8 @@ export default { largest_object: 'Suurin kohde', selected_objects: 'valittujen objektien', smallest_object: 'pienin kohde', - new_doc: 'Uusi kuva', - open_doc: 'Avaa kuva', export_img: 'Export', - save_doc: 'Save Image', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align Bottom', align_center: 'Keskitä', diff --git a/src/editor/locale/lang.fy.js b/src/editor/locale/lang.fy.js index ae0a903f..fe0a367b 100644 --- a/src/editor/locale/lang.fy.js +++ b/src/editor/locale/lang.fy.js @@ -111,7 +111,7 @@ export default { open_doc: 'Ôfbielding iepenje', export_img: 'Export', save_doc: 'Ôfbielding bewarje', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Ûnder útlijne', align_center: 'Midden útlijne', diff --git a/src/editor/locale/lang.ga.js b/src/editor/locale/lang.ga.js index f15eb4fe..b0ca32b3 100644 --- a/src/editor/locale/lang.ga.js +++ b/src/editor/locale/lang.ga.js @@ -111,7 +111,7 @@ export default { open_doc: 'Íomhá Oscailte', export_img: 'Export', save_doc: 'Sábháil Íomhá', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Cineál Bun', align_center: 'Ailínigh sa Lár', diff --git a/src/editor/locale/lang.gl.js b/src/editor/locale/lang.gl.js index ee9134be..aa7c2e7d 100644 --- a/src/editor/locale/lang.gl.js +++ b/src/editor/locale/lang.gl.js @@ -111,7 +111,7 @@ export default { open_doc: 'Abrir Imaxe', export_img: 'Export', save_doc: 'Gardar Imaxe', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align bottom', align_center: 'Centrar', diff --git a/src/editor/locale/lang.he.js b/src/editor/locale/lang.he.js index bcfe4f62..d50591bf 100755 --- a/src/editor/locale/lang.he.js +++ b/src/editor/locale/lang.he.js @@ -111,7 +111,7 @@ export default { open_doc: 'פתח תמונה', export_img: 'Export', save_doc: 'שמור תמונה', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'יישור תחתון', align_center: 'ישור לאמצע', diff --git a/src/editor/locale/lang.hi.js b/src/editor/locale/lang.hi.js index 056ecb18..8446c0f7 100644 --- a/src/editor/locale/lang.hi.js +++ b/src/editor/locale/lang.hi.js @@ -111,7 +111,7 @@ export default { open_doc: 'छवि खोलें', export_img: 'Export', save_doc: 'सहेजें छवि', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'तलमेंपंक्तिबद्धकरें', align_center: 'मध्य में समंजित करें', diff --git a/src/editor/locale/lang.hr.js b/src/editor/locale/lang.hr.js index f3c2850c..ff8f322b 100644 --- a/src/editor/locale/lang.hr.js +++ b/src/editor/locale/lang.hr.js @@ -111,7 +111,7 @@ export default { open_doc: 'Otvori sliku', export_img: 'Export', save_doc: 'Spremanje slike', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Poravnaj dolje', align_center: 'Centriraj', diff --git a/src/editor/locale/lang.hu.js b/src/editor/locale/lang.hu.js index a540bcb3..48aed81e 100644 --- a/src/editor/locale/lang.hu.js +++ b/src/editor/locale/lang.hu.js @@ -111,7 +111,7 @@ export default { open_doc: 'Kép megnyitása', export_img: 'Export', save_doc: 'Kép mentése más', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Alulra igazítás', align_center: 'Középre igazítás', diff --git a/src/editor/locale/lang.hy.js b/src/editor/locale/lang.hy.js index bdebebb4..85e2e763 100644 --- a/src/editor/locale/lang.hy.js +++ b/src/editor/locale/lang.hy.js @@ -107,11 +107,8 @@ export default { largest_object: 'largest object', selected_objects: 'elected objects', smallest_object: 'smallest object', - new_doc: 'New Image', - open_doc: 'Open SVG', export_img: 'Export', - save_doc: 'Save Image', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align Bottom', align_center: 'Align Center', diff --git a/src/editor/locale/lang.id.js b/src/editor/locale/lang.id.js index 0d23baba..606e3c6d 100644 --- a/src/editor/locale/lang.id.js +++ b/src/editor/locale/lang.id.js @@ -107,11 +107,8 @@ export default { largest_object: 'objek terbesar', selected_objects: 'objek terpilih', smallest_object: 'objek terkecil', - new_doc: 'Gambar Baru', - open_doc: 'Membuka Image', export_img: 'Export', - save_doc: 'Save Image', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Rata Bottom', align_center: 'Rata Tengah', diff --git a/src/editor/locale/lang.is.js b/src/editor/locale/lang.is.js index ebe482a3..018a3200 100644 --- a/src/editor/locale/lang.is.js +++ b/src/editor/locale/lang.is.js @@ -107,11 +107,8 @@ export default { largest_object: 'stærsti hlutinn', selected_objects: 'kjörinn hlutir', smallest_object: 'lítill hluti', - new_doc: 'New Image', - open_doc: 'Opna mynd', export_img: 'Export', - save_doc: 'Spara Image', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Jafna Bottom', align_center: 'Jafna Center', diff --git a/src/editor/locale/lang.ja.js b/src/editor/locale/lang.ja.js index 1d4ccf4b..d381f025 100644 --- a/src/editor/locale/lang.ja.js +++ b/src/editor/locale/lang.ja.js @@ -111,7 +111,7 @@ export default { open_doc: 'イメージを開く', export_img: 'Export', save_doc: '画像を保存', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: '下揃え', align_center: '中央揃え', diff --git a/src/editor/locale/lang.ko.js b/src/editor/locale/lang.ko.js index 5200387c..27abf111 100644 --- a/src/editor/locale/lang.ko.js +++ b/src/editor/locale/lang.ko.js @@ -111,7 +111,7 @@ export default { open_doc: '오픈 이미지', export_img: 'Export', save_doc: '이미지 저장', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: '히프 정렬', align_center: '정렬 센터', diff --git a/src/editor/locale/lang.lt.js b/src/editor/locale/lang.lt.js index 11e4d980..c0aa8b12 100644 --- a/src/editor/locale/lang.lt.js +++ b/src/editor/locale/lang.lt.js @@ -107,11 +107,8 @@ export default { largest_object: 'didžiausias objektas', selected_objects: 'išrinktas objektai', smallest_object: 'mažiausias objektą', - new_doc: 'New Image', - open_doc: 'Atidaryti atvaizdą', export_img: 'Export', - save_doc: 'Išsaugoti nuotrauką', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Lygiuoti apačioje', align_center: 'Lygiuoti', diff --git a/src/editor/locale/lang.lv.js b/src/editor/locale/lang.lv.js index 79c6b845..671f2299 100644 --- a/src/editor/locale/lang.lv.js +++ b/src/editor/locale/lang.lv.js @@ -107,11 +107,8 @@ export default { largest_object: 'lielākais objekts', selected_objects: 'ievēlēts objekti', smallest_object: 'mazākais objekts', - new_doc: 'New Image', - open_doc: 'Open SVG', export_img: 'Export', - save_doc: 'Save Image', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Līdzināt Bottom', align_center: 'Līdzināt uz centru', diff --git a/src/editor/locale/lang.mk.js b/src/editor/locale/lang.mk.js index 7de7cee2..4e28ade6 100644 --- a/src/editor/locale/lang.mk.js +++ b/src/editor/locale/lang.mk.js @@ -111,7 +111,7 @@ export default { open_doc: 'Отвори слика', export_img: 'Export', save_doc: 'Зачувај слика', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align Bottom', align_center: 'Центрирано', diff --git a/src/editor/locale/lang.ms.js b/src/editor/locale/lang.ms.js index d4d6c64d..9fc3c53e 100644 --- a/src/editor/locale/lang.ms.js +++ b/src/editor/locale/lang.ms.js @@ -107,11 +107,8 @@ export default { largest_object: 'objek terbesar', selected_objects: 'objek terpilih', smallest_object: 'objek terkecil', - new_doc: 'Imej Baru', - open_doc: 'Membuka Image', export_img: 'Export', - save_doc: 'Save Image', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Rata Bottom', align_center: 'Rata Tengah', diff --git a/src/editor/locale/lang.mt.js b/src/editor/locale/lang.mt.js index 4f50c796..7ef159af 100644 --- a/src/editor/locale/lang.mt.js +++ b/src/editor/locale/lang.mt.js @@ -107,11 +107,8 @@ export default { largest_object: 'akbar oġġett', selected_objects: 'oġġetti elett', smallest_object: 'iżgħar oġġett', - new_doc: 'Image New', - open_doc: 'Open SVG', export_img: 'Export', - save_doc: 'Image Save', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Tallinja Bottom', align_center: 'Tallinja Center', diff --git a/src/editor/locale/lang.no.js b/src/editor/locale/lang.no.js index 4315dafb..e6e3057f 100644 --- a/src/editor/locale/lang.no.js +++ b/src/editor/locale/lang.no.js @@ -107,11 +107,8 @@ export default { largest_object: 'største objekt', selected_objects: 'velges objekter', smallest_object: 'minste objekt', - new_doc: 'New Image', - open_doc: 'Åpne Image', export_img: 'Export', - save_doc: 'Lagre bilde', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align Bottom', align_center: 'Midtstill', diff --git a/src/editor/locale/lang.pt-PT.js b/src/editor/locale/lang.pt-PT.js index 1f8e3a3a..049ed220 100644 --- a/src/editor/locale/lang.pt-PT.js +++ b/src/editor/locale/lang.pt-PT.js @@ -111,7 +111,7 @@ export default { open_doc: 'Abrir Imagem', export_img: 'Export', save_doc: 'Salvar Imagem', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align Bottom', align_center: 'Alinhar ao centro', diff --git a/src/editor/locale/lang.sk.js b/src/editor/locale/lang.sk.js index 903a2f8e..c9ba63d5 100644 --- a/src/editor/locale/lang.sk.js +++ b/src/editor/locale/lang.sk.js @@ -111,7 +111,7 @@ export default { open_doc: 'Otvoriť obrázok', export_img: 'Export', save_doc: 'Uložiť obrázok', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Zarovnať element na stránku', align_bottom: 'Zarovnať dole', align_center: 'Zarovnať na stred', diff --git a/src/editor/locale/lang.sq.js b/src/editor/locale/lang.sq.js index 663b458b..f559de7a 100644 --- a/src/editor/locale/lang.sq.js +++ b/src/editor/locale/lang.sq.js @@ -107,11 +107,8 @@ export default { largest_object: 'madh objekt', selected_objects: 'objektet e zgjedhur', smallest_object: 'objektit më të vogël', - new_doc: 'New Image', - open_doc: 'Image Hapur', export_img: 'Export', - save_doc: 'Image Ruaj', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align Bottom', align_center: 'Align Center', diff --git a/src/editor/locale/lang.sr.js b/src/editor/locale/lang.sr.js index 1685384b..63b9fe7e 100644 --- a/src/editor/locale/lang.sr.js +++ b/src/editor/locale/lang.sr.js @@ -111,7 +111,7 @@ export default { open_doc: 'Отвори слике', export_img: 'Export', save_doc: 'Сачувај слика', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Поравнај доле', align_center: 'Поравнај по центру', diff --git a/src/editor/locale/lang.sv.js b/src/editor/locale/lang.sv.js index a370367e..4c8ab860 100644 --- a/src/editor/locale/lang.sv.js +++ b/src/editor/locale/lang.sv.js @@ -107,11 +107,8 @@ export default { largest_object: 'största objekt', selected_objects: 'valda objekt', smallest_object: 'minsta objektet', - new_doc: 'New Image', - open_doc: 'Öppna bild', export_img: 'Export', - save_doc: 'Save Image', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align Bottom', align_center: 'Centrera', diff --git a/src/editor/locale/lang.sw.js b/src/editor/locale/lang.sw.js index 12dc3c5d..8987ea86 100644 --- a/src/editor/locale/lang.sw.js +++ b/src/editor/locale/lang.sw.js @@ -107,11 +107,8 @@ export default { largest_object: 'ukubwa object', selected_objects: 'waliochaguliwa vitu', smallest_object: 'minsta object', - new_doc: 'New Image', - open_doc: 'Open SVG', export_img: 'Export', - save_doc: 'Save Image', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align Bottom', align_center: 'Align Center', diff --git a/src/editor/locale/lang.test.js b/src/editor/locale/lang.test.js index fa606987..45447307 100644 --- a/src/editor/locale/lang.test.js +++ b/src/editor/locale/lang.test.js @@ -107,11 +107,8 @@ export default { largest_object: 'largest object', selected_objects: 'selected objects', smallest_object: 'smallest object', - new_doc: 'New Image', - open_doc: 'Open SVG', export_img: 'Export', - save_doc: 'Save Image', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align Bottom', align_center: 'Align Center', diff --git a/src/editor/locale/lang.th.js b/src/editor/locale/lang.th.js index 48f5c859..c127a5f9 100644 --- a/src/editor/locale/lang.th.js +++ b/src/editor/locale/lang.th.js @@ -111,7 +111,7 @@ export default { open_doc: 'ภาพเปิด', export_img: 'Export', save_doc: 'บันทึกรูปภาพ', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'ด้านล่างชิด', align_center: 'จัดแนวกึ่งกลาง', diff --git a/src/editor/locale/lang.tl.js b/src/editor/locale/lang.tl.js index 7a026afc..6140c032 100644 --- a/src/editor/locale/lang.tl.js +++ b/src/editor/locale/lang.tl.js @@ -111,7 +111,7 @@ export default { open_doc: 'Buksan ang Image', export_img: 'Export', save_doc: 'I-save ang Image', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Pantayin sa Ibaba', align_center: 'Pantayin sa Gitna', diff --git a/src/editor/locale/lang.tr.js b/src/editor/locale/lang.tr.js index a1643c3e..ac1a4105 100644 --- a/src/editor/locale/lang.tr.js +++ b/src/editor/locale/lang.tr.js @@ -111,7 +111,7 @@ export default { open_doc: 'Aç Resim', export_img: 'Export', save_doc: 'Görüntüyü Kaydet', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align Bottom', align_center: 'Ortala', diff --git a/src/editor/locale/lang.uk.js b/src/editor/locale/lang.uk.js index 378a4105..de83ddb8 100644 --- a/src/editor/locale/lang.uk.js +++ b/src/editor/locale/lang.uk.js @@ -111,7 +111,7 @@ export default { open_doc: 'Відкрити зображення', export_img: 'Export', save_doc: 'Зберегти малюнок', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Вирівняти по нижньому краю', align_center: 'Вирівняти по центру', diff --git a/src/editor/locale/lang.vi.js b/src/editor/locale/lang.vi.js index 16aca1a6..cc23fa2a 100644 --- a/src/editor/locale/lang.vi.js +++ b/src/editor/locale/lang.vi.js @@ -107,11 +107,8 @@ export default { largest_object: 'lớn nhất đối tượng', selected_objects: 'bầu các đối tượng', smallest_object: 'nhỏ đối tượng', - new_doc: 'Hình mới', - open_doc: 'Mở Image', export_img: 'Export', - save_doc: 'Save Image', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'Align Bottom', align_center: 'Căn giữa', diff --git a/src/editor/locale/lang.yi.js b/src/editor/locale/lang.yi.js index 5c207466..1ae027b4 100644 --- a/src/editor/locale/lang.yi.js +++ b/src/editor/locale/lang.yi.js @@ -111,7 +111,7 @@ export default { open_doc: 'Open בילד', export_img: 'Export', save_doc: 'היט בילד', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: 'יינרייען באָטטאָם', align_center: 'יינרייען צענטער', diff --git a/src/editor/locale/lang.zh-HK.js b/src/editor/locale/lang.zh-HK.js index 93a7a189..5d235d52 100644 --- a/src/editor/locale/lang.zh-HK.js +++ b/src/editor/locale/lang.zh-HK.js @@ -111,7 +111,7 @@ export default { open_doc: '打开图像', export_img: 'Export', save_doc: '保存图像', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: '底部对齐', align_center: '居中对齐', diff --git a/src/editor/locale/lang.zh-TW.js b/src/editor/locale/lang.zh-TW.js index 5c67e718..7b3311f3 100644 --- a/src/editor/locale/lang.zh-TW.js +++ b/src/editor/locale/lang.zh-TW.js @@ -111,7 +111,7 @@ export default { open_doc: '打開圖像', export_img: 'Export', save_doc: '保存圖像', - import_doc: 'Import Image', + import_doc: 'Import SVG', align_to_page: 'Align Element to Page', align_bottom: '底部對齊', align_center: '居中對齊', diff --git a/src/editor/panels/TopPanel.js b/src/editor/panels/TopPanel.js index d0163493..34928a31 100644 --- a/src/editor/panels/TopPanel.js +++ b/src/editor/panels/TopPanel.js @@ -191,6 +191,7 @@ class TopPanel { this.hideTool("container_panel"); this.hideTool("use_panel"); this.hideTool("a_panel"); + this.hideTool("xy_panel"); if (elem) { const elname = elem.nodeName; diff --git a/src/svgcanvas/sanitize.js b/src/svgcanvas/sanitize.js index d3e65014..90f68bcd 100644 --- a/src/svgcanvas/sanitize.js +++ b/src/svgcanvas/sanitize.js @@ -55,7 +55,7 @@ const svgWhiteList_ = { stop: [ 'class', 'id', 'offset', 'requiredFeatures', 'stop-opacity', 'style', 'systemLanguage', 'stop-color', 'gradientUnits', 'gradientTransform' ], svg: [ 'class', 'clip-path', 'clip-rule', 'filter', 'id', 'height', 'mask', 'preserveAspectRatio', 'requiredFeatures', 'style', 'systemLanguage', 'version', 'viewBox', 'width', 'x', 'xmlns', 'xmlns:se', 'xmlns:xlink', 'xmlns:oi', 'oi:animations', 'y', 'stroke-linejoin', 'fill-rule', 'aria-label', 'stroke-width', 'fill-rule' ], switch: [ 'class', 'id', 'requiredFeatures', 'systemLanguage' ], - symbol: [ 'class', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'opacity', 'overflow', 'preserveAspectRatio', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'viewBox' ], + symbol: [ 'class', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'opacity', 'overflow', 'preserveAspectRatio', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'viewBox', 'width', 'height' ], text: [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'transform', 'x', 'xml:space', 'y' ], textPath: [ 'class', 'id', 'method', 'requiredFeatures', 'spacing', 'startOffset', 'style', 'systemLanguage', 'transform', 'xlink:href' ], title: [], diff --git a/src/svgcanvas/selected-elem.js b/src/svgcanvas/selected-elem.js index 00758f8e..28bf680e 100644 --- a/src/svgcanvas/selected-elem.js +++ b/src/svgcanvas/selected-elem.js @@ -743,15 +743,17 @@ export const convertToGroup = function (elem) { // Not ideal, but works ts += ' translate(' + (pos.x || 0) + ',' + (pos.y || 0) + ')'; - const prev = $elem.prev(); + const prev = $elem.previousElementSibling; // Remove element - batchCmd.addSubCommand(new RemoveElementCommand($elem[0], $elem[0].nextSibling, $elem[0].parentNode)); + batchCmd.addSubCommand(new RemoveElementCommand($elem, $elem.nextElementSibling, $elem.parentNode)); $elem.remove(); // See if other elements reference this symbol const svgcontent = elementContext_.getSVGContent(); - const hasMore = svgcontent.querySelectorAll('use:data(symbol)').length; + // const hasMore = svgcontent.querySelectorAll('use:data(symbol)').length; + // @todo review this logic + const hasMore = svgcontent.querySelectorAll('use').length; const g = elementContext_.getDOMDocument().createElementNS(NS.SVG, 'g'); const childs = elem.childNodes; diff --git a/src/svgcanvas/svg-exec.js b/src/svgcanvas/svg-exec.js index a18daa43..53de4c22 100644 --- a/src/svgcanvas/svg-exec.js +++ b/src/svgcanvas/svg-exec.js @@ -678,31 +678,6 @@ export const embedImage = function (src) { }); }; -/** -* Serializes the current drawing into SVG XML text and passes it to the 'saved' handler. -* This function also includes the XML prolog. Clients of the `SvgCanvas` bind their save -* function to the 'saved' event. -* @function module:svgcanvas.SvgCanvas#save -* @param {module:svgcanvas.SaveOptions} opts -* @fires module:svgcanvas.SvgCanvas#event:saved -* @returns {void} -*/ -export const save = function (opts) { - // remove the selected outline before serializing - svgCanvas.clearSelection(); - // Update save options if provided - if (opts) { - const saveOptions = svgCanvas.mergeDeep(svgContext_.getSvgOption(), opts); - for (const [ key, value ] of Object.entries(saveOptions)) { - svgContext_.setSvgOption(key, value); - } - } - svgContext_.setSvgOption('apply', true); - - // no need for doctype, see https://jwatt.org/svg/authoring/#doctype-declaration - const str = svgCanvas.svgCanvasToString(); - svgContext_.call('saved', str); -}; /** * @typedef {PlainObject} module:svgcanvas.IssuesAndCodes * @property {string[]} issueCodes The locale-independent code names diff --git a/src/svgcanvas/svgcanvas.js b/src/svgcanvas/svgcanvas.js index f4ac97ff..255df02a 100644 --- a/src/svgcanvas/svgcanvas.js +++ b/src/svgcanvas/svgcanvas.js @@ -80,7 +80,7 @@ import { convertToNum, getTypeMap, init as unitsInit } from '../common/units.js'; import { - svgCanvasToString, svgToString, setSvgString, save, exportPDF, setUseDataMethod, + svgCanvasToString, svgToString, setSvgString, exportPDF, setUseDataMethod, init as svgInit, importSvgString, embedImage, rasterExport, uniquifyElemsMethod, removeUnusedDefElemsMethod, convertGradientsMethod } from './svg-exec.js'; @@ -188,6 +188,8 @@ class SvgCanvas { this.$id = $id; this.$qq = $qq; this.$qa = $qa; + this.encode64 = encode64; + this.decode64 = decode64; this.stringToHTML = stringToHTML; this.insertChildAtIndex = insertChildAtIndex; this.getClosest = getClosest; @@ -1365,6 +1367,8 @@ class SvgCanvas { /** * Group: Serialization. */ + this.getSvgOption = () => { return saveOptions; }; + this.setSvgOption = (key, value) => { saveOptions[key] = value; }; svgInit( /** @@ -1379,8 +1383,8 @@ class SvgCanvas { getCurrentGroup() { return currentGroup; }, getCurConfig() { return curConfig; }, getNsMap() { return nsMap; }, - getSvgOption() { return saveOptions; }, - setSvgOption(key, value) { saveOptions[key] = value; }, + getSvgOption: this.getSvgOption, + setSvgOption: this.setSvgOption, getSvgOptionApply() { return saveOptions.apply; }, getSvgOptionImages() { return saveOptions.images; }, getEncodableImages(key) { return encodableImages[key]; }, @@ -1448,26 +1452,6 @@ class SvgCanvas { lastGoodImgUrl = val; }; - /** -* Does nothing by default, handled by optional widget/extension. -* @function module:svgcanvas.SvgCanvas#open -* @returns {void} -*/ - this.open = function () { - /* empty fn */ - }; - - /** -* Serializes the current drawing into SVG XML text and passes it to the 'saved' handler. -* This function also includes the XML prolog. Clients of the `SvgCanvas` bind their save -* function to the 'saved' event. -* @function module:svgcanvas.SvgCanvas#save -* @param {module:svgcanvas.SaveOptions} opts -* @fires module:svgcanvas.SvgCanvas#event:saved -* @returns {void} -*/ - this.save = save; - /** * @typedef {PlainObject} module:svgcanvas.IssuesAndCodes * @property {string[]} issueCodes The locale-independent code names