diff --git a/src/editor/ConfigObj.js b/src/editor/ConfigObj.js index 2d292a94..e23102f1 100644 --- a/src/editor/ConfigObj.js +++ b/src/editor/ConfigObj.js @@ -173,7 +173,8 @@ export default class ConfigObj { 'ext-polygon', 'ext-shapes', 'ext-star', - 'ext-storage' + 'ext-storage', + 'ext-opensave' ]; this.curConfig = { // We do not put on defaultConfig to simplify object copying diff --git a/src/editor/EditorStartup.js b/src/editor/EditorStartup.js index 6426e961..fc2c504e 100644 --- a/src/editor/EditorStartup.js +++ b/src/editor/EditorStartup.js @@ -139,7 +139,6 @@ class EditorStartup { this.svgCanvas.bind('selected', this.selectedChanged.bind(this)); this.svgCanvas.bind('transition', this.elementTransition.bind(this)); this.svgCanvas.bind('changed', this.elementChanged.bind(this)); - this.svgCanvas.bind('saved', this.saveHandler.bind(this)); this.svgCanvas.bind('exported', this.exportHandler.bind(this)); this.svgCanvas.bind('exportedPDF', function (win, data) { if (!data.output) { // Ignore Chrome @@ -454,10 +453,11 @@ class EditorStartup { this.layersPanel.init(); $id('tool_clear').addEventListener('click', this.clickClear.bind(this)); - $id('tool_open').addEventListener('click', function (e) { + $id('tool_open').addEventListener('click', (e) => { + e.preventDefault(); this.clickOpen(); window.dispatchEvent(new CustomEvent('openImage')); - }.bind(this)); + }); $id('tool_import').addEventListener('click', (e) => { this.clickImport(); window.dispatchEvent(new CustomEvent('importImage')); @@ -702,27 +702,6 @@ class EditorStartup { this.workarea[0].addEventListener('dragover', this.onDragOver); this.workarea[0].addEventListener('dragleave', this.onDragLeave); this.workarea[0].addEventListener('drop', importImage); - - const open = $('').change(async function (e) { - const ok = await this.openPrep(); - if (!ok) { return; } - this.svgCanvas.clear(); - if (this.files.length === 1) { - $.process_cancel(this.uiStrings.notification.loadingImage); - const reader = new FileReader(); - reader.onloadend = async function ({target}) { - await this.loadSvgString(target.result); - this.updateCanvas(); - }; - reader.readAsText(this.files[0]); - } - }); - $('#tool_open').show(); - $(window).on('openImage', () => open.click()); - - const imgImport = $('').change(importImage); - $('#tool_import').show(); - $(window).on('importImage', () => imgImport.click()); } this.updateCanvas(true); diff --git a/src/editor/extensions/ext-opensave/ext-opensave.js b/src/editor/extensions/ext-opensave/ext-opensave.js new file mode 100644 index 00000000..ad736155 --- /dev/null +++ b/src/editor/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 ({$, decode64, 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 = this.uiStrings.notification.saveFromBrowser.replace('%s', 'SVG'); + + this.configObj.pref('save_notice_done', 'all'); + if (done !== 'part') { + seAlert(note); + } + } + }, + async open () { + const ok = await this.openPrep(); + if (!ok) { 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/src/editor/svgedit.js b/src/editor/svgedit.js index 36009fae..8ac43d4a 100644 --- a/src/editor/svgedit.js +++ b/src/editor/svgedit.js @@ -17,7 +17,7 @@ */ import './touch.js'; -import {isChrome, isGecko, isMac} from '../common/browser.js'; +import {isChrome, isMac} from '../common/browser.js'; import {convertUnit, isValidUnit} from '../common/units.js'; import SvgCanvas from '../svgcanvas/svgcanvas.js'; @@ -205,20 +205,18 @@ class Editor extends EditorStartup { setCustomHandlers (opts) { return this.ready(() => { if (opts.open) { - $('#tool_open > input[type="file"]').remove(); - $('#tool_open').show(); - this.svgCanvas.open = opts.open; + this.svgCanvas.open = opts.open.bind(this); } if (opts.save) { this.showSaveWarning = false; - this.svgCanvas.bind('saved', opts.save); + this.svgCanvas.bind('saved', opts.save.bind(this)); } if (opts.exportImage) { - this.customExportImage = 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; + this.customExportPDF = opts.exportPDF.bind(this); this.svgCanvas.bind('exportedPDF', this.customExportPDF); // jsPDF and our RGBColor will be available to the method } }); @@ -368,55 +366,6 @@ class Editor extends EditorStartup { } } - /** - * @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} - */ - saveHandler (wind, 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 - let done = this.configObj.pref('save_notice_done'); - - if (done !== 'all') { - let note = this.uiStrings.notification.saveFromBrowser.replace('%s', 'SVG'); - // Check if FF and has - if (isGecko()) { - if (svg.includes('