- Breaking change: Extension now formatted as export (and this is set to editor, including for callback)

- Breaking change: Locale now formatted as export
- Breaking change: Moved out remaining modular i18n (imagelib) to own folder
- Breaking change: Drop `executeAfterLoads` (and getJSPDF/getCanvg)
- Breaking change: `RGBColor` must accept `new`
- Breaking change: canvg - `stackBlurCanvasRGBA` must be set now by function (`setStackBlurCanvasRGBA`) rather than global; `canvg` now a named export
- Breaking change: Avoid passing `canvg`/`buildCanvgCallback` to extensions (have them import)
- Fix: i18nize imaglib more deeply
- Fix: Positioning of Document Properties dialog (Fixes #246)
- Fix (regression): PDF Export (Fixes #249)
- Fix (regression): Add polyfill for `ChildNode`/`ParentNode` (and use further)
- Fix (regression): Apply Babel universally to dependencies
- Fix (regression): Ordering of `uaPrefix` function in `svgEditor.js`
- Fix (regression): Embedded API
- Fix (embedded editor): Fix backspace key in Firefox so it doesn't navigate out of frame
- Fix: Alert if no exportWindow for PDF (e.g., if blocked)
- Refactoring( RGBColor) `RGBColor` as class, without rebuilding constants, optimize string replacement, move methods to prototype, use templates and object literals, use `Object.keys`
- Refactoring (canvg) Use classes more internally, use shorthand objects; array extras, return to lazy-loading
- Refactoring: Use Promises in place of `$.getScript`; always return Promises in case deciding to await resolving
- Refactoring: Avoid importing `RGBColor` into `svgutils.js` (jsPDF imports it itself)
- Refactoring: Arrow functions, destructuring, shorter property references
- Refactoring: Fix `lang` and `dir` for locales (though not in use currently anyways)
- Refactoring: Provide path config for canvg, jspdf
This commit is contained in:
Brett Zamir
2018-06-02 09:14:38 +08:00
parent a2df54881f
commit 9f65b1adb9
226 changed files with 26026 additions and 19715 deletions

View File

@@ -20,6 +20,7 @@ import {getTypeMap, convertUnit, isValidUnit} from './units.js';
import {
hasCustomHandler, getCustomHandler, injectExtendedContextMenuItemsIntoDom
} from './contextmenu.js';
import {importSetGlobalDefault} from './external/dynamic-import-polyfill/importModule.js';
import SvgCanvas from './svgcanvas.js';
import Layer from './layer.js';
@@ -133,6 +134,8 @@ const callbacks = [],
imgPath: 'images/',
langPath: 'locale/', // Default will be changed if this is a modular load
extPath: 'extensions/', // Default will be changed if this is a modular load
canvgPath: 'canvg/', // Default will be changed if this is a modular load
jspdfPath: 'jspdf/', // Default will be changed if this is a modular load
extIconsPath: 'extensions/',
jGraduatePath: 'jgraduate/images/',
// DOCUMENT PROPERTIES
@@ -428,7 +431,9 @@ editor.init = function () {
if (!modularVersion) {
Object.assign(defaultConfig, {
langPath: '../dist/locale/',
extPath: '../dist/extensions/'
extPath: '../dist/extensions/',
canvgPath: '../dist/',
jspdfPath: '../dist/'
});
}
@@ -492,8 +497,8 @@ editor.init = function () {
// ways with other script resources
$.each(
[
'extPath', 'imgPath', 'extIconsPath',
'langPath', 'jGraduatePath'
'extPath', 'imgPath', 'extIconsPath', 'canvgPath',
'langPath', 'jGraduatePath', 'jspdfPath'
],
function (pathConfig) {
if (urldata[pathConfig]) {
@@ -547,36 +552,30 @@ editor.init = function () {
$(elem).empty().append(icon);
};
const extFunc = function () {
$.each(curConfig.extensions, function () {
const extname = this;
if (!extname.match(/^ext-.*\.js/)) { // Ensure URL cannot specify some other unintended file in the extPath
return;
}
const s = document.createElement('script');
if (modularVersion) {
s.type = 'module'; // Make this the default when widely supported
}
const url = curConfig.extPath + extname;
s.src = url;
document.querySelector('head').appendChild(s);
/*
// Todo: Insert script with type=module instead when modules widely supported
$.getScript(curConfig.extPath + extname, function (d) {
// Fails locally in Chrome 5
if (!d) {
const s = document.createElement('script');
s.src = curConfig.extPath + extname;
document.querySelector('head').appendChild(s);
}
}).fail((jqxhr, settings, exception) => {
console.log(exception);
});
*/
});
const extFunc = async function () {
try {
await Promise.all(
curConfig.extensions.map(async (extname) => {
const extName = extname.match(/^ext-(.+)\.js/);
if (!extName) { // Ensure URL cannot specify some other unintended file in the extPath
return;
}
const url = curConfig.extPath + extname;
// Todo: Replace this with `return import(url);` when
// `import()` widely supported
const imported = await importSetGlobalDefault(url, {
global: 'svgEditorExtension_' + extName[1].replace(/-/g, '_')
});
const {name, init} = imported;
return editor.addExtension(name, (init && init.bind(editor)) || imported);
})
);
} catch (err) {
console.log(err);
}
// const lang = ('lang' in curPrefs) ? curPrefs.lang : null;
editor.putLocale(null, goodLangs, curConfig);
return editor.putLocale(null, goodLangs, curConfig);
};
const stateObj = {tool_scale: editor.tool_scale};
@@ -590,6 +589,23 @@ editor.init = function () {
});
};
const uaPrefix = (function () {
const regex = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/;
const someScript = document.getElementsByTagName('script')[0];
for (const prop in someScript.style) {
if (regex.test(prop)) {
// test is faster than match, so it's better to perform
// that on the lot and match only when necessary
return prop.match(regex)[0];
}
}
// Nothing found so far?
if ('WebkitOpacity' in someScript.style) { return 'Webkit'; }
if ('KhtmlOpacity' in someScript.style) { return 'Khtml'; }
return '';
}());
const scaleElements = function (elems, scale) {
// const prefix = '-' + uaPrefix.toLowerCase() + '-'; // Currently unused
const sides = ['top', 'left', 'bottom', 'right'];
@@ -1567,7 +1583,7 @@ editor.init = function () {
for (i = 1; i < ctxArrNum; i++) {
hcanv[lentype] = limit;
copy = hcanv.cloneNode(true);
hcanv.parentNode.appendChild(copy);
hcanv.parentNode.append(copy);
ctxArr[i] = copy.getContext('2d');
}
@@ -2459,24 +2475,6 @@ editor.init = function () {
return div;
};
const uaPrefix = (function () {
let prop;
const regex = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/;
const someScript = document.getElementsByTagName('script')[0];
for (prop in someScript.style) {
if (regex.test(prop)) {
// test is faster than match, so it's better to perform
// that on the lot and match only when necessary
return prop.match(regex)[0];
}
}
// Nothing found so far?
if ('WebkitOpacity' in someScript.style) { return 'Webkit'; }
if ('KhtmlOpacity' in someScript.style) { return 'Khtml'; }
return '';
}());
// TODO: Combine this with addDropDown or find other way to optimize
const addAltDropDown = function (elem, list, callback, opts) {
const button = $(elem);
@@ -2570,7 +2568,7 @@ editor.init = function () {
const runCallback = function () {
if (ext.callback && !cbCalled && cbReady) {
cbCalled = true;
ext.callback();
ext.callback.call(editor);
}
};
@@ -2937,6 +2935,10 @@ editor.init = function () {
if (exportWindowName) {
exportWindow = window.open('', exportWindowName); // A hack to get the window via JSON-able name without opening a new one
}
if (!exportWindow || exportWindow.closed) {
$.alert(uiStrings.notification.popupWindowBlocked);
return;
}
exportWindow.location.href = data.dataurlstring;
});
svgCanvas.bind('zoomed', zoomChanged);
@@ -3810,7 +3812,10 @@ editor.init = function () {
updateWireFrame();
};
$('#svg_docprops_container, #svg_prefs_container').draggable({cancel: 'button,fieldset', containment: 'window'});
$('#svg_docprops_container, #svg_prefs_container').draggable({
cancel: 'button,fieldset',
containment: 'window'
}).css('position', 'absolute');
let docprops = false;
let preferences = false;
@@ -4115,7 +4120,10 @@ editor.init = function () {
const pos = elem.offset();
let {paint} = paintBox[picker];
$('#color_picker')
.draggable({cancel: '.jGraduate_tabs, .jGraduate_colPick, .jGraduate_gradPick, .jPicker', containment: 'window'})
.draggable({
cancel: '.jGraduate_tabs, .jGraduate_colPick, .jGraduate_gradPick, .jPicker',
containment: 'window'
})
.css(curConfig.colorPickerCSS || {left: pos.left - 140, bottom: 40})
.jGraduate(
{
@@ -4168,7 +4176,7 @@ editor.init = function () {
break;
case 'linearGradient':
case 'radialGradient':
this.defs.removeChild(this.grad);
this.grad.remove();
this.grad = this.defs.appendChild(paint[ptype]);
const id = this.grad.id = 'gradbox_' + this.type;
fillAttr = 'url(#' + id + ')';
@@ -5228,6 +5236,7 @@ editor.init = function () {
if (document.location.protocol === 'file:') {
setTimeout(extFunc, 100);
} else {
// Returns a promise (if we wanted to fire 'extensions-loaded' event)
extFunc();
}
};
@@ -5252,7 +5261,7 @@ editor.ready = function (cb) {
editor.runCallbacks = function () {
// Todo: See if there is any benefit to refactoring some
// of the existing `editor.ready()` calls to return Promises
Promise.all(callbacks.map((cb) => {
return Promise.all(callbacks.map((cb) => {
return cb();
})).then(() => {
isReady = true;