diff --git a/src/editor/extensions/ext-server_opensave/ext-php_savefile.js b/src/editor/extensions/ext-server_opensave/ext-php_savefile.js index a66d747d..05110be1 100644 --- a/src/editor/extensions/ext-server_opensave/ext-php_savefile.js +++ b/src/editor/extensions/ext-server_opensave/ext-php_savefile.js @@ -6,7 +6,6 @@ export default { init ({$}) { const svgEditor = this; const { - curConfig: {extPath}, canvas: svgCanvas } = svgEditor; /** @@ -17,7 +16,7 @@ export default { const title = svgCanvas.getDocumentTitle(); return title.trim(); } - const saveSvgAction = extPath + 'savefile.php'; + const saveSvgAction = './savefile.php'; svgEditor.setCustomHandlers({ save (win, data) { const svg = '\n' + data, diff --git a/src/editor/extensions/ext-server_opensave/ext-server_opensave.js b/src/editor/extensions/ext-server_opensave/ext-server_opensave.js index ff58e4c3..d30eee6e 100644 --- a/src/editor/extensions/ext-server_opensave/ext-server_opensave.js +++ b/src/editor/extensions/ext-server_opensave/ext-server_opensave.js @@ -27,7 +27,6 @@ export default { const strings = await loadExtensionTranslation(svgEditor.curPrefs.lang); const { curConfig: { - extPath, avoidClientSide, // Deprecated avoidClientSideDownload, avoidClientSideOpen }, @@ -76,8 +75,8 @@ export default { return false; } const - saveSvgAction = extPath + 'filesave.php', - saveImgAction = extPath + 'filesave.php'; + saveSvgAction = './filesave.php', + saveImgAction = './filesave.php'; // Create upload target (hidden iframe) let cancelled = false; @@ -174,9 +173,9 @@ export default { if (window.FileReader && !avoidClientSideOpen) { return; } // Change these to appropriate script file - const openSvgAction = extPath + 'fileopen.php?type=load_svg'; - const importSvgAction = extPath + 'fileopen.php?type=import_svg'; - const importImgAction = extPath + 'fileopen.php?type=import_img'; + const openSvgAction = './fileopen.php?type=load_svg'; + const importSvgAction = './fileopen.php?type=import_svg'; + const importImgAction = './fileopen.php?type=import_img'; // Set up function for PHP uploader to use svgEditor.processFile = function (str64, type) { diff --git a/src/editor/index.js b/src/editor/index.js index b46e7b70..44e85ad3 100644 --- a/src/editor/index.js +++ b/src/editor/index.js @@ -35,7 +35,8 @@ svgEditor.setConfig( // EXTENSION CONFIG svgEditor.setConfig({ extensions: [], - noDefaultExtensions: false + noDefaultExtensions: false, + userExtensions: [] }); // OTHER CONFIG @@ -60,7 +61,6 @@ svgEditor.setConfig({ // no_save_warning: false, // PATH CONFIGURATION // imgPath: 'images/', - // extPath: 'extensions/', /* Uncomment the following to allow at least same domain (embedded) access, including `file:///` access. diff --git a/src/editor/svgedit.js b/src/editor/svgedit.js index e19bdf18..c3c0762a 100644 --- a/src/editor/svgedit.js +++ b/src/editor/svgedit.js @@ -157,7 +157,6 @@ const callbacks = [], * @property {string} [canvasName="default"] Used to namespace storage provided via `ext-storage.js`; you can use this if you wish to have multiple independent instances of SVG Edit on the same domain * @property {boolean} [no_save_warning=false] If `true`, prevents the warning dialog box from appearing when closing/reloading the page. Mostly useful for testing. * @property {string} [imgPath="images/"] The path where the SVG icons are located, with trailing slash. Note that as of version 2.7, this is not configurable by URL for security reasons. - * @property {string} [extPath="extensions/"] The path used for extension files, with trailing slash. Note that as of version 2.7, this is not configurable by URL for security reasons. * @property {boolean} [preventAllURLConfig=false] Set to `true` to override the ability for URLs to set non-content configuration (including extension config). Must be set early, i.e., in `svgedit-config-iife.js`; extension loading is too late! * @property {boolean} [preventURLContentLoading=false] Set to `true` to override the ability for URLs to set URL-based SVG content. Must be set early, i.e., in `svgedit-config-iife.js`; extension loading is too late! * @property {boolean} [lockExtensions=false] Set to `true` to override the ability for URLs to set their own extensions; disallowed in URL setting. There is no need for this when `preventAllURLConfig` is used. Must be set early, i.e., in `svgedit-config-iife.js`; extension loading is too late! @@ -231,7 +230,6 @@ const callbacks = [], no_save_warning: false, // PATH CONFIGURATION // The following path configuration items are disallowed in the URL (as should any future path configurations) - extPath: './extensions/', imgPath: './images/', // DOCUMENT PROPERTIES // Change the following to a preference (already in the Document Properties dialog)? @@ -693,7 +691,7 @@ editor.init = function () { // security reasons, even for same-domain // ones given potential to interact in undesirable // ways with other script resources - ['extPath', 'imgPath'] + ['userExtensions', 'imgPath'] .forEach(function (pathConfig) { if (urldata[pathConfig]) { delete urldata[pathConfig]; @@ -771,6 +769,7 @@ editor.init = function () { setIcons(); // Wait for dbox as needed for i18n try { + // load standard extensions await Promise.all( curConfig.extensions.map(async (extname) => { /** @@ -783,8 +782,7 @@ editor.init = function () { /** * @type {module:SVGEditor.ExtensionObject} */ - const url = `${curConfig.extPath}${extname}/${extname}.js`; - const imported = await import(url); + const imported = await import(`./extensions/${extname}/${extname}.js`); const {name = extname, init} = imported.default; return editor.addExtension(name, (init && init.bind(editor)), {$, langParam}); } catch (err) { @@ -794,6 +792,29 @@ editor.init = function () { } }) ); + // load user extensions (given as pathNames) + await Promise.all( + curConfig.userExtensions.map(async (extPathName) => { + /** + * @tutorial ExtensionDocs + * @typedef {PlainObject} module:SVGEditor.ExtensionObject + * @property {string} [name] Name of the extension. Used internally; no need for i18n. Defaults to extension name without beginning "ext-" or ending ".js". + * @property {module:svgcanvas.ExtensionInitCallback} [init] + */ + try { + /** + * @type {module:SVGEditor.ExtensionObject} + */ + const imported = await import(extPathName); + const {name, init} = imported.default; + return editor.addExtension(name, (init && init.bind(editor)), {$, langParam}); + } catch (err) { + // Todo: Add config to alert any errors + console.error('Extension failed to load: ' + extPathName + '; ', err); // eslint-disable-line no-console + return undefined; + } + }) + ); svgCanvas.bind( 'extensions_added', /**