now use dynamic import() and rely on Babel to polyfill

This commit is contained in:
JFH
2020-08-07 22:12:40 +02:00
parent 06c48ec088
commit 72df064ea3
7 changed files with 34 additions and 235 deletions

View File

@@ -7,8 +7,6 @@
* @copyright 2013 Jo Segaert
*
*/
// Todo: Wait for Mathjax 3.0 to get ES Module/avoid global
import {importScript} from '../../external/dynamic-import-polyfill/importModule.js';
export default {
name: 'mathjax',
@@ -204,7 +202,8 @@ export default {
// We use `extIconsPath` here for now as it does not vary with
// the modular type as does `extPath`
try {
await importScript(svgEditor.curConfig.extIconsPath + mathjaxSrcSecure);
// eslint-disable-next-line node/no-unsupported-features/es-syntax
await import(svgEditor.curConfig.extIconsPath + mathjaxSrcSecure);
// When MathJax is loaded get the div where the math will be rendered.
MathJax.Hub.queue.Push(function () {
math = MathJax.Hub.getAllJax('#mathjax_creator')[0];

View File

@@ -76,7 +76,7 @@ svgEditor.setConfig({
// no_save_warning: false,
// PATH CONFIGURATION
// imgPath: 'images/',
// langPath: 'locale/',
// langPath: '/src/editor/locale/',
// extPath: 'extensions/',
// jGraduatePath: 'jgraduate/images/',
/*

View File

@@ -24,8 +24,6 @@
* @typedef {PlainObject<string, string>} module:locale.LocaleSelectorValue
*/
import {importSetGlobalDefault} from '../../external/dynamic-import-polyfill/importModule.js';
const $ = jQuery;
let langParam;
@@ -388,11 +386,7 @@ export const putLocale = async function (givenParam, goodLangs, conf) {
}
const url = conf.langPath + 'lang.' + langParam + '.js';
return readLang(
// Todo: Replace this with `return import(url);` when
// `import()` widely supported
await importSetGlobalDefault(url, {
global: 'svgEditorLang_' + langParam.replace(/-/g, '_')
})
);
// eslint-disable-next-line node/no-unsupported-features/es-syntax
const module = await import(url);
return readLang(module.default);
};

View File

@@ -26,7 +26,6 @@ import {getTypeMap, convertUnit, isValidUnit} from '../common/units.js';
import {
hasCustomHandler, getCustomHandler, injectExtendedContextMenuItemsIntoDom
} from './contextmenu.js';
import {importSetGlobalDefault} from '../external/dynamic-import-polyfill/importModule.js';
import deparam from '../external/deparam/deparam.esm.js';
import SvgCanvas from '../svgcanvas/svgcanvas.js';
@@ -237,13 +236,13 @@ const callbacks = [],
no_save_warning: false,
// PATH CONFIGURATION
// The following path configuration items are disallowed in the URL (as should any future path configurations)
langPath: 'locale/', // Default will be changed if this is a non-modular load
extPath: 'extensions/', // Default will be changed if this is a non-modular load
canvgPath: 'canvg/', // Default will be changed if this is a non-modular load
jspdfPath: 'jspdf/', // Default will be changed if this is a non-modular load
imgPath: 'images/',
jGraduatePath: 'jgraduate/images/',
extIconsPath: 'extensions/',
langPath: '/src/editor/locale/', // Default will be changed if this is a non-modular load
extPath: '/src/editor/extensions/', // Default will be changed if this is a non-modular load
canvgPath: '/src/editor/canvg/', // Default will be changed if this is a non-modular load
jspdfPath: '/src/editor/jspdf/', // Default will be changed if this is a non-modular load
imgPath: '/src/editor/images/',
jGraduatePath: '/src/editor/jgraduate/images/',
extIconsPath: '/src/editor/extensions/',
// DOCUMENT PROPERTIES
// Change the following to a preference (already in the Document Properties dialog)?
dimensions: [640, 480],
@@ -351,11 +350,11 @@ function getImportLocale ({defaultLang, defaultName}) {
* @param {string} language
* @returns {Promise<module:locale.LocaleStrings>} Resolves to {@link module:locale.LocaleStrings}
*/
function importLocale (language) {
async function importLocale (language) {
const url = `${curConfig.extPath}ext-locale/${name}/${language}.js`;
return importSetGlobalDefault(url, {
global: `svgEditorExtensionLocale_${name}_${language.replace(/-/g, '_')}`
});
// eslint-disable-next-line node/no-unsupported-features/es-syntax
const locale = await import(url);
return locale.default;
}
try {
return await importLocale(lang);
@@ -836,14 +835,13 @@ editor.init = function () {
try {
await Promise.all(
curConfig.extensions.map(async (extname) => {
const extName = extname.match(/^ext-(.+)\.js/);
const extensionName = extname.match(/^ext-(.+)\.js/);
// const {extName} = extname.match(/^ext-(?<extName>.+)\.js/).groups;
if (!extName) { // Ensure URL cannot specify some other unintended file in the extPath
if (!extensionName) { // Ensure URL cannot specify some other unintended file in the extPath
return undefined;
}
const url = curConfig.extPath + extname;
// Todo: Replace this with `return import(url);` when
// `import()` widely supported
/**
* @tutorial ExtensionDocs
* @typedef {PlainObject} module:SVGEditor.ExtensionObject
@@ -854,11 +852,9 @@ editor.init = function () {
/**
* @type {module:SVGEditor.ExtensionObject}
*/
const imported = await importSetGlobalDefault(url, {
global: 'svgEditorExtension_' + extName[1].replace(/-/g, '_')
// global: 'svgEditorExtension_' + extName.replace(/-/g, '_')
});
const {name = extName[1], init} = imported;
// eslint-disable-next-line node/no-unsupported-features/es-syntax
const imported = await import(url);
const {name = extensionName[1], init} = imported.default;
// const {name = extName, init} = imported;
const importLocale = getImportLocale({defaultLang: langParam, defaultName: name});
return editor.addExtension(name, (init && init.bind(editor)), {$, importLocale});

View File

@@ -1,176 +0,0 @@
/* eslint-disable jsdoc/require-file-overview */
/**
* Adapted from {@link https://github.com/uupaa/dynamic-import-polyfill/blob/master/importModule.js}.
* @module importModule
* @license MIT
*/
/**
* Converts a possible relative URL into an absolute one.
* @param {string} url
* @returns {string}
*/
function toAbsoluteURL (url) {
const a = document.createElement('a');
a.setAttribute('href', url); // <a href="hoge.html">
return a.cloneNode(false).href; // -> "http://example.com/hoge.html"
}
/**
* Add any of the whitelisted attributes to the script tag.
* @param {HTMLScriptElement} script
* @param {PlainObject<string, string>} atts
* @returns {void}
*/
function addScriptAtts (script, atts) {
['id', 'class', 'type'].forEach((prop) => {
if (prop in atts) {
script[prop] = atts[prop];
}
});
}
// Additions by Brett
/**
* @typedef {PlainObject} module:importModule.ImportConfig
* @property {string} global The variable name to set on `window` (when not using the modular version)
* @property {boolean} [returnDefault=false]
*/
/**
* @function module:importModule.importSetGlobalDefault
* @param {string|GenericArray<any>} url
* @param {module:importModule.ImportConfig} config
* @returns {Promise<any>} The value to which it resolves depends on the export of the targeted module.
*/
export function importSetGlobalDefault (url, config) {
return importSetGlobal(url, {...config, returnDefault: true});
}
/**
* @function module:importModule.importSetGlobal
* @param {string|string[]} url
* @param {module:importModule.ImportConfig} config
* @returns {Promise<ArbitraryModule>} The promise resolves to either an `ArbitraryModule` or
* any other value depends on the export of the targeted module.
*/
export async function importSetGlobal (url, {global: glob, returnDefault}) {
// Todo: Replace calls to this function with `import()` when supported
const modularVersion = !('svgEditor' in window) ||
!window.svgEditor ||
window.svgEditor.modules !== false;
if (modularVersion) {
return importModule(url, undefined, {returnDefault});
}
await importScript(url);
return window[glob];
}
/**
*
* @author Brett Zamir (other items are from `dynamic-import-polyfill`)
* @param {string|string[]} url
* @param {PlainObject} [atts={}]
* @returns {Promise<void|Error>} Resolves to `undefined` or rejects with an `Error` upon a
* script loading error
*/
export function importScript (url, atts = {}) {
if (Array.isArray(url)) {
return Promise.all(url.map((u) => {
return importScript(u, atts);
}));
}
return new Promise((resolve, reject) => { // eslint-disable-line promise/avoid-new
const script = document.createElement('script');
/**
*
* @returns {void}
*/
function scriptOnError () {
reject(new Error(`Failed to import: ${url}`));
destructor();
}
/**
*
* @returns {void}
*/
function scriptOnLoad () {
resolve();
destructor();
}
const destructor = () => {
script.removeEventListener('error', scriptOnError);
script.removeEventListener('load', scriptOnLoad);
script.remove();
script.src = '';
};
script.defer = 'defer';
addScriptAtts(script, atts);
script.addEventListener('error', scriptOnError);
script.addEventListener('load', scriptOnLoad);
script.src = url;
document.head.append(script);
});
}
/**
*
* @param {string|string[]} url
* @param {PlainObject} [atts={}]
* @param {PlainObject} opts
* @param {boolean} [opts.returnDefault=false} = {}]
* @returns {Promise<any>} Resolves to value of loading module or rejects with
* `Error` upon a script loading error.
*/
export function importModule (url, atts = {}, {returnDefault = false} = {}) {
if (Array.isArray(url)) {
return Promise.all(url.map((u) => {
return importModule(u, atts);
}));
}
return new Promise((resolve, reject) => { // eslint-disable-line promise/avoid-new
const vector = '$importModule$' + Math.random().toString(32).slice(2);
const script = document.createElement('script');
/**
*
* @returns {void}
*/
function scriptOnError () {
reject(new Error(`Failed to import: ${url}`));
destructor();
}
/**
*
* @returns {void}
*/
function scriptOnLoad () {
resolve(window[vector]);
destructor();
}
const destructor = () => {
delete window[vector];
script.removeEventListener('error', scriptOnError);
script.removeEventListener('load', scriptOnLoad);
script.remove();
URL.revokeObjectURL(script.src);
script.src = '';
};
addScriptAtts(script, atts);
script.defer = 'defer';
script.type = 'module';
script.addEventListener('error', scriptOnError);
script.addEventListener('load', scriptOnLoad);
const absURL = toAbsoluteURL(url);
const loader = `import * as m from '${
absURL.replace(/'/g, "\\'")
}'; window.${vector} = ${
returnDefault ? 'm.default || ' : ''
}m;`; // export Module
const blob = new Blob([loader], {type: 'text/javascript'});
script.src = URL.createObjectURL(blob);
document.head.append(script);
});
}
export default importModule;

View File

@@ -33,7 +33,6 @@ import {
} from './draw.js';
import {sanitizeSvg} from './sanitize.js';
import {getReverseNS, NS} from '../common/namespaces.js';
import {importSetGlobal, importScript} from '../external/dynamic-import-polyfill/importModule.js';
import {
text2xml, assignAttributes, cleanupElement, getElem, getUrlFromAttr,
findDefs, getHref, setHref, getRefElem, getRotationAngle, getPathBBox,
@@ -3990,9 +3989,8 @@ this.rasterExport = async function (imgType, quality, exportWindowName, opts = {
const svg = this.svgCanvasToString();
if (!canvg) {
({canvg} = await importSetGlobal(curConfig.canvgPath + 'canvg.js', {
global: 'canvg'
}));
// eslint-disable-next-line node/no-unsupported-features/es-syntax
({canvg} = await import(curConfig.canvgPath + 'canvg.js').default);
}
if (!$('#export_canvas').length) {
$('<canvas>', {id: 'export_canvas'}).hide().appendTo('body');
@@ -4076,24 +4074,12 @@ this.exportPDF = async function (
) {
if (!window.jsPDF) {
// Todo: Switch to `import()` when widely supported and available (also allow customization of path)
await importScript([
// We do not currently have these paths configurable as they are
// currently global-only, so not Rolled-up
'jspdf/underscore-min.js',
// 'jspdf/jspdf.min.js',
'../../svgedit-myfix/editor/jspdf/jspdf-1.0.150.debug.js'
]);
const modularVersion = !('svgEditor' in window) ||
!window.svgEditor ||
window.svgEditor.modules !== false;
// Todo: Switch to `import()` when widely supported and available (also allow customization of path)
await importScript(curConfig.jspdfPath + 'jspdf.plugin.svgToPdf.js', {
type: modularVersion
? 'module'
: 'text/javascript'
});
// await importModule('jspdf/jspdf.plugin.svgToPdf.js');
// eslint-disable-next-line node/no-unsupported-features/es-syntax
await import('../editor/jspdf/underscore-min.js');
// eslint-disable-next-line node/no-unsupported-features/es-syntax
await import('../editor/jspdf/jspdf.min.js');
// eslint-disable-next-line node/no-unsupported-features/es-syntax
await import('../editor/jspdf/jspdf.plugin.svgToPdf.js');
}
const res = getResolution();