- Security fix: 'extPath', 'imgPath', 'extIconsPath', 'canvgPath', 'langPath', 'jGraduatePath', and 'jspdfPath' were not being prevented
- Breaking change: Rename "svgutils.js" to "utilities.js" (make in conformity with JSDoc module naming convention) - Breaking change: Rename "svgedit.js" to "namespaces.js" (to make clear purpose and avoid confusing with editor) - Breaking change: Rename "jquery-svg.js" to "jQuery.attr.js" - Breaking change: Rename "jquery.contextMenu.js" to "jQuery.contextMenu.js" - Breaking change: Rename "jquery.jpicker.js" to "jQuery.jPicker.js" - Breaking change: Rename "JQuerySpinBtn.css" to "jQuery.SpinButton.css" - Breaking change: Rename "JQuerySpinBtn.js" to "jQuery.SpinButton.js" (to have file name more closely reflect name) - Breaking change: Rename "jquery.svgicons.js" to "jQuery.svgIcons.js" - Breaking change: Rename "jquery.jgraduate.js" to "jQuery.jGraduate.js" - Breaking change: Rename "pathseg.js" to "svgpathseg.js" (as it is a poyfill of SVGPathSeg) - Breaking change: Rename `addSvgElementFromJson()` to `addSVGElementFromJson` for consistency - Breaking change: Rename `changeSvgContent()` to `changeSVGContent()` for consistency - Breaking change: Have `exportPDF` resolve with `output` and `outputType` rather than `dataurlstring` (as type may vary) - Breaking change: Rename `extensions/mathjax/MathJax.js` to `extensions/mathjax/MathJax.min.js` - Breaking change: Avoid recent change to have editor ready callbacks return Promises (we're not using and advantageous to keep sequential) - Breaking change: Avoid recent addition of locale-side function in ext-imagelib for l10n - Breaking change: Change name of ext-arrows.js from `Arrows` to `arrows` for sake of file path (not localized anyways). - Breaking change: Change `addlangData` extension event to `addLangData` for consistency with method name - Breaking change: Have `readLang` return lang and data but do not call `setLang` - Fix: Have general locales load first so extensions may use - Fix: Provide `importLocale` to extensions `init` so it may delay adding of the extension until locale data loaded - Fix: Ensure call to `rasterExport` without `imgType` properly sets MIME type to PNG - Fix: Wrong name for moinsave - Update: Update WebAppFind per new API changes - Enhancement: Make `setStrings` public on editor for late setting (used by `ext-shapes.js`) - Enhancement: Add `extensions_added` event - Enhancement: Add `message` event (Relay messages including those which have been been received prior to extension load) - Enhancement: Allow SVGEdit to work out of the box--avoid need for copying sample config file. Should also help with Github-based file servers - Enhancement: Allow avoiding "name" in extension export (just extract out of file name) - Enhancement: Add stack blur to canvg by default (and refactoring it) - Enhancement: Return `Promise` for `embedImage` (as with some other loading methods) - Enhancement: Supply `importLocale` to `langReady` to facilitate extension locale loading - Enhancement: Recover if an extension fails to load (just log and otherwise ignore) - Enhancement: More i18n of extensions (also fixed issue with some console warnings about missing locale strings); i18nize Hello World too - Enhancement: Allowing importing of locales within `addLangData` - npm: Update devDeps - Docs: Migrate copies of all old wiki pages to docs/from-old-wiki folder; intended for a possible move to Markdown, so raw HTML (with formatting) was not preserved, though named links had their absolute URL links preserved - Docs: Begin deleting `SvgCanvas.md` as ensuring jsdoc has replacements - Docs: Add Edtior doc file for help to general users - Docs: Clarify/simplify install instructions - npm/Docs (JSDoc): Add script to check for overly generic types - Docs (JSDoc): For config/prefs and extension creating, link to tutorials (moved tutorials to own directory to avoid recursion problems by jsdoc) - Docs (JSDoc): Add modules (upper case for usual main entrance files or regular names) - Docs (JSDoc): Fill out missing areas; indicate return of `undefined`; consistency with `@returns` - Docs (JSDoc): Add our own layout template to support overflow - Docs (JSDoc): Use cleverLinks and disallow unknown tags - Docs (JSDoc): Insist on "pedantic" flag; put output directory in config - Docs (JSDoc): Use more precise Integer/Float over number, the specific type of array/function/object - Docs (JSDoc): Use `@throws`, `@enum`, `@event`/`@fires`/`@listens` - Docs: Generally update/improve docs (fixes #92) - Docs: Update links to `latest` path (Avoid needing to update such references upon each release) - Docs: 80 chars max - Refactoring: Drop code for extension as function (already requiring export to be an object) - Refactoring: Object destructuring, `Object.entries`, Object shorthand, array extras, more camelCase variable names - Refactoring: Add a `Command` base class - Refactoring: Simplify svgicons `callback` ready detection - Refactoring: Put `let` or `const` closer to scope - Refactoring: Remove unneeded `delimiter` from regex escaping utility - Refactoring: Clearer variable names - Refactoring: Use (non-deprecated) Event constructors - Testing: Use new Sinon
This commit is contained in:
@@ -1,29 +1,22 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-arrows.js
|
||||
*
|
||||
* Licensed under the MIT License
|
||||
* @license MIT
|
||||
*
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
* @copyright 2010 Alexis Deveria
|
||||
*
|
||||
*/
|
||||
export default {
|
||||
name: 'Arrows',
|
||||
init (S) {
|
||||
name: 'arrows',
|
||||
async init (S) {
|
||||
const strings = await S.importLocale();
|
||||
const svgEditor = this;
|
||||
const svgCanvas = svgEditor.canvas;
|
||||
const $ = jQuery;
|
||||
const // {svgcontent} = S,
|
||||
addElem = S.addSvgElementFromJson,
|
||||
addElem = S.addSVGElementFromJson,
|
||||
{nonce} = S,
|
||||
langList = {
|
||||
en: [
|
||||
{id: 'arrow_none', textContent: 'No arrow'}
|
||||
],
|
||||
fr: [
|
||||
{id: 'arrow_none', textContent: 'Sans flèche'}
|
||||
]
|
||||
},
|
||||
prefix = 'se_arrow_';
|
||||
|
||||
let selElems, arrowprefix, randomizeIds = S.randomize_ids;
|
||||
@@ -226,34 +219,32 @@ export default {
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'Arrows',
|
||||
context_tools: [{
|
||||
const contextTools = [
|
||||
{
|
||||
type: 'select',
|
||||
panel: 'arrow_panel',
|
||||
title: 'Select arrow type',
|
||||
id: 'arrow_list',
|
||||
options: {
|
||||
none: 'No arrow',
|
||||
end: '---->',
|
||||
start: '<----',
|
||||
both: '<--->',
|
||||
mid: '-->--',
|
||||
mid_bk: '--<--'
|
||||
},
|
||||
defval: 'none',
|
||||
events: {
|
||||
change: setArrow
|
||||
}
|
||||
}],
|
||||
}
|
||||
];
|
||||
|
||||
return {
|
||||
name: strings.name,
|
||||
context_tools: strings.contextTools.map((contextTool, i) => {
|
||||
return Object.assign(contextTools[i], contextTool);
|
||||
}),
|
||||
callback () {
|
||||
$('#arrow_panel').hide();
|
||||
// Set ID so it can be translated in locale file
|
||||
$('#arrow_list option')[0].id = 'connector_no_arrow';
|
||||
},
|
||||
addLangData (lang) {
|
||||
async addLangData ({lang, importLocale}) {
|
||||
const strings = await importLocale();
|
||||
return {
|
||||
data: langList[lang]
|
||||
data: strings.langList
|
||||
};
|
||||
},
|
||||
selectedChanged (opts) {
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-closepath.js
|
||||
*
|
||||
* Licensed under the MIT License
|
||||
* @license MIT
|
||||
*
|
||||
* Copyright(c) 2010 Jeff Schiller
|
||||
* @copyright 2010 Jeff Schiller
|
||||
*
|
||||
*/
|
||||
import '../pathseg.js';
|
||||
import '../svgpathseg.js';
|
||||
|
||||
// This extension adds a simple button to the contextual panel for paths
|
||||
// The button toggles whether the path is open or closed
|
||||
export default {
|
||||
name: 'ClosePath',
|
||||
init () {
|
||||
name: 'closepath',
|
||||
async init ({importLocale}) {
|
||||
const strings = await importLocale();
|
||||
const $ = jQuery;
|
||||
const svgEditor = this;
|
||||
let selElems;
|
||||
@@ -47,14 +48,11 @@ export default {
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
name: 'ClosePath',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'closepath_icons.svg',
|
||||
buttons: [{
|
||||
const buttons = [
|
||||
{
|
||||
id: 'tool_openpath',
|
||||
type: 'context',
|
||||
panel: 'closepath_panel',
|
||||
title: 'Open path',
|
||||
events: {
|
||||
click () {
|
||||
toggleClosed();
|
||||
@@ -65,13 +63,20 @@ export default {
|
||||
id: 'tool_closepath',
|
||||
type: 'context',
|
||||
panel: 'closepath_panel',
|
||||
title: 'Close path',
|
||||
events: {
|
||||
click () {
|
||||
toggleClosed();
|
||||
}
|
||||
}
|
||||
}],
|
||||
}
|
||||
];
|
||||
|
||||
return {
|
||||
name: strings.name,
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'closepath_icons.svg',
|
||||
buttons: strings.buttons.map((button, i) => {
|
||||
return Object.assign(buttons[i], button);
|
||||
}),
|
||||
callback () {
|
||||
$('#closepath_panel').hide();
|
||||
},
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-connector.js
|
||||
*
|
||||
* Licensed under the MIT License
|
||||
* @license MIT
|
||||
*
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
* @copyright 2010 Alexis Deveria
|
||||
*
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'Connector',
|
||||
init (S) {
|
||||
name: 'connector',
|
||||
async init (S) {
|
||||
const $ = jQuery;
|
||||
const svgEditor = this;
|
||||
const svgCanvas = svgEditor.canvas;
|
||||
const {svgroot, getNextId, getElem} = S,
|
||||
addElem = S.addSvgElementFromJson,
|
||||
const {svgroot, getNextId, getElem, importLocale} = S,
|
||||
addElem = S.addSVGElementFromJson,
|
||||
selManager = S.selectorManager,
|
||||
connSel = '.se_connector',
|
||||
// connect_str = '-SE_CONNECT-',
|
||||
elData = $.data;
|
||||
const strings = await importLocale();
|
||||
|
||||
let startX,
|
||||
startY,
|
||||
@@ -32,15 +33,6 @@ export default {
|
||||
connections = [],
|
||||
selElems = [];
|
||||
|
||||
const langList = {
|
||||
en: [
|
||||
{id: 'mode_connect', title: 'Connect two objects'}
|
||||
],
|
||||
fr: [
|
||||
{id: 'mode_connect', title: 'Connecter deux objets'}
|
||||
]
|
||||
};
|
||||
|
||||
function getBBintersect (x, y, bb, offset) {
|
||||
if (offset) {
|
||||
offset -= 0;
|
||||
@@ -155,7 +147,7 @@ export default {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {array} [elem=selElems] Array of elements
|
||||
* @param {Element[]} [elem=selElems] Array of elements
|
||||
*/
|
||||
function findConnectors (elems = selElems) {
|
||||
const connectors = $(svgcontent).find(connSel);
|
||||
@@ -315,28 +307,31 @@ export default {
|
||||
// // }
|
||||
// });
|
||||
|
||||
return {
|
||||
name: 'Connector',
|
||||
svgicons: svgEditor.curConfig.imgPath + 'conn.svg',
|
||||
buttons: [{
|
||||
id: 'mode_connect',
|
||||
type: 'mode',
|
||||
icon: svgEditor.curConfig.imgPath + 'cut.png',
|
||||
title: 'Connect two objects',
|
||||
includeWith: {
|
||||
button: '#tool_line',
|
||||
isDefault: false,
|
||||
position: 1
|
||||
},
|
||||
events: {
|
||||
click () {
|
||||
svgCanvas.setMode('connector');
|
||||
}
|
||||
const buttons = [{
|
||||
id: 'mode_connect',
|
||||
type: 'mode',
|
||||
icon: svgEditor.curConfig.imgPath + 'cut.png',
|
||||
includeWith: {
|
||||
button: '#tool_line',
|
||||
isDefault: false,
|
||||
position: 1
|
||||
},
|
||||
events: {
|
||||
click () {
|
||||
svgCanvas.setMode('connector');
|
||||
}
|
||||
}],
|
||||
addLangData (lang) {
|
||||
}
|
||||
}];
|
||||
|
||||
return {
|
||||
name: strings.name,
|
||||
svgicons: svgEditor.curConfig.imgPath + 'conn.svg',
|
||||
buttons: strings.buttons.map((button, i) => {
|
||||
return Object.assign(buttons[i], button);
|
||||
}),
|
||||
async addLangData ({lang, importLocale}) {
|
||||
return {
|
||||
data: langList[lang]
|
||||
data: strings.langList
|
||||
};
|
||||
},
|
||||
mouseDown (opts) {
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-eyedropper.js
|
||||
*
|
||||
* Licensed under the MIT License
|
||||
* @license MIT
|
||||
*
|
||||
* Copyright(c) 2010 Jeff Schiller
|
||||
* @copyright 2010 Jeff Schiller
|
||||
*
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'eyedropper',
|
||||
init (S) {
|
||||
async init (S) {
|
||||
const strings = await S.importLocale();
|
||||
const svgEditor = this;
|
||||
const $ = jQuery;
|
||||
const {ChangeElementCommand} = S, // , svgcontent,
|
||||
@@ -55,20 +56,24 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'eyedropper',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'eyedropper-icon.xml',
|
||||
buttons: [{
|
||||
const buttons = [
|
||||
{
|
||||
id: 'tool_eyedropper',
|
||||
type: 'mode',
|
||||
title: 'Eye Dropper Tool',
|
||||
key: 'I',
|
||||
events: {
|
||||
click () {
|
||||
svgCanvas.setMode('eyedropper');
|
||||
}
|
||||
}
|
||||
}],
|
||||
}
|
||||
];
|
||||
|
||||
return {
|
||||
name: strings.name,
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'eyedropper-icon.xml',
|
||||
buttons: strings.buttons.map((button, i) => {
|
||||
return Object.assign(buttons[i], button);
|
||||
}),
|
||||
|
||||
// if we have selected an element, grab its paint and enable the eye dropper button
|
||||
selectedChanged: getStyle,
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-foreignobject.js
|
||||
*
|
||||
* Licensed under the Apache License, Version 2
|
||||
* @license Apache-2.0
|
||||
*
|
||||
* Copyright(c) 2010 Jacques Distler
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
* @copyright 2010 Jacques Distler, 2010 Alexis Deveria
|
||||
*
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'foreignObject',
|
||||
init (S) {
|
||||
name: 'foreignobject',
|
||||
async init (S) {
|
||||
const svgEditor = this;
|
||||
const {text2xml, NS} = S;
|
||||
const {text2xml, NS, importLocale} = S;
|
||||
const $ = jQuery;
|
||||
const svgCanvas = svgEditor.canvas;
|
||||
const
|
||||
// {svgcontent} = S,
|
||||
// addElem = S.addSvgElementFromJson,
|
||||
// addElem = S.addSVGElementFromJson,
|
||||
svgdoc = S.svgroot.parentNode.ownerDocument;
|
||||
const strings = await importLocale();
|
||||
|
||||
const properlySourceSizeTextArea = function () {
|
||||
// TODO: remove magic numbers here and get values from CSS
|
||||
@@ -48,9 +48,9 @@ export default {
|
||||
|
||||
/**
|
||||
* This function sets the content of element elt to the input XML.
|
||||
* @param {String} xmlString - The XML text.
|
||||
* @param elt - the parent element to append to
|
||||
* @returns {Boolean} This function returns false if the set was unsuccessful, true otherwise.
|
||||
* @param {string} xmlString - The XML text
|
||||
* @param {Element} elt - the parent element to append to
|
||||
* @returns {boolean} This function returns false if the set was unsuccessful, true otherwise.
|
||||
*/
|
||||
function setForeignString (xmlString) {
|
||||
const elt = selElems[0];
|
||||
@@ -89,36 +89,30 @@ export default {
|
||||
S.call('changed', selElems);
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'foreignObject',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'foreignobject-icons.xml',
|
||||
buttons: [{
|
||||
id: 'tool_foreign',
|
||||
type: 'mode',
|
||||
title: 'Foreign Object Tool',
|
||||
events: {
|
||||
click () {
|
||||
svgCanvas.setMode('foreign');
|
||||
}
|
||||
const buttons = [{
|
||||
id: 'tool_foreign',
|
||||
type: 'mode',
|
||||
events: {
|
||||
click () {
|
||||
svgCanvas.setMode('foreign');
|
||||
}
|
||||
}, {
|
||||
id: 'edit_foreign',
|
||||
type: 'context',
|
||||
panel: 'foreignObject_panel',
|
||||
title: 'Edit ForeignObject Content',
|
||||
events: {
|
||||
click () {
|
||||
showForeignEditor();
|
||||
}
|
||||
}
|
||||
}, {
|
||||
id: 'edit_foreign',
|
||||
type: 'context',
|
||||
panel: 'foreignObject_panel',
|
||||
events: {
|
||||
click () {
|
||||
showForeignEditor();
|
||||
}
|
||||
}],
|
||||
}
|
||||
}];
|
||||
|
||||
context_tools: [{
|
||||
const contextTools = [
|
||||
{
|
||||
type: 'input',
|
||||
panel: 'foreignObject_panel',
|
||||
title: "Change foreignObject's width",
|
||||
id: 'foreign_width',
|
||||
label: 'w',
|
||||
size: 3,
|
||||
events: {
|
||||
change () {
|
||||
@@ -128,9 +122,7 @@ export default {
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'foreignObject_panel',
|
||||
title: "Change foreignObject's height",
|
||||
id: 'foreign_height',
|
||||
label: 'h',
|
||||
events: {
|
||||
change () {
|
||||
setAttr('height', this.value);
|
||||
@@ -139,9 +131,7 @@ export default {
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'foreignObject_panel',
|
||||
title: "Change foreignObject's font size",
|
||||
id: 'foreign_font_size',
|
||||
label: 'font-size',
|
||||
size: 2,
|
||||
defval: 16,
|
||||
events: {
|
||||
@@ -150,8 +140,17 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
],
|
||||
return {
|
||||
name: strings.name,
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'foreignobject-icons.xml',
|
||||
buttons: strings.buttons.map((button, i) => {
|
||||
return Object.assign(buttons[i], button);
|
||||
}),
|
||||
context_tools: strings.contextTools.map((contextTool, i) => {
|
||||
return Object.assign(contextTools[i], contextTool);
|
||||
}),
|
||||
callback () {
|
||||
$('#foreignObject_panel').hide();
|
||||
|
||||
@@ -193,7 +192,7 @@ export default {
|
||||
|
||||
if (svgCanvas.getMode() === 'foreign') {
|
||||
started = true;
|
||||
newFO = S.addSvgElementFromJson({
|
||||
newFO = S.addSVGElementFromJson({
|
||||
element: 'foreignObject',
|
||||
attr: {
|
||||
x: opts.start_x,
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-grid.js
|
||||
*
|
||||
* Licensed under the Apache License, Version 2
|
||||
* @license Apache-2.0
|
||||
*
|
||||
* Copyright(c) 2010 Redou Mine
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
* @copyright 2010 Redou Mine, 2010 Alexis Deveria
|
||||
*
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'view_grid',
|
||||
init ({NS, getTypeMap}) {
|
||||
name: 'grid',
|
||||
async init ({NS, getTypeMap, importLocale}) {
|
||||
const strings = await importLocale();
|
||||
const svgEditor = this;
|
||||
const $ = jQuery;
|
||||
const svgCanvas = svgEditor.canvas;
|
||||
@@ -131,8 +131,19 @@ export default {
|
||||
$('#canvasGrid').toggle(showGrid);
|
||||
$('#view_grid').toggleClass('push_button_pressed tool_button');
|
||||
}
|
||||
const buttons = [{
|
||||
id: 'view_grid',
|
||||
type: 'context',
|
||||
panel: 'editor_panel',
|
||||
events: {
|
||||
click () {
|
||||
svgEditor.curConfig.showGrid = showGrid = !showGrid;
|
||||
gridUpdate();
|
||||
}
|
||||
}
|
||||
}];
|
||||
return {
|
||||
name: 'view_grid',
|
||||
name: strings.name,
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'grid-icon.xml',
|
||||
|
||||
zoomChanged (zoom) {
|
||||
@@ -143,18 +154,9 @@ export default {
|
||||
gridUpdate();
|
||||
}
|
||||
},
|
||||
buttons: [{
|
||||
id: 'view_grid',
|
||||
type: 'context',
|
||||
panel: 'editor_panel',
|
||||
title: 'Show/Hide Grid',
|
||||
events: {
|
||||
click () {
|
||||
svgEditor.curConfig.showGrid = showGrid = !showGrid;
|
||||
gridUpdate();
|
||||
}
|
||||
}
|
||||
}]
|
||||
buttons: strings.buttons.map((button, i) => {
|
||||
return Object.assign(buttons[i], button);
|
||||
})
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,27 +1,28 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-helloworld.js
|
||||
*
|
||||
* Licensed under the MIT License
|
||||
* @license MIT
|
||||
*
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
* @copyright 2010 Alexis Deveria
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
This is a very basic SVG-Edit extension. It adds a "Hello World" button in
|
||||
the left panel. Clicking on the button, and then the canvas will show the
|
||||
user the point on the canvas that was clicked on.
|
||||
/**
|
||||
* This is a very basic SVG-Edit extension. It adds a "Hello World" button in
|
||||
* the left ("mode") panel. Clicking on the button, and then the canvas
|
||||
* will show the user the point on the canvas that was clicked on.
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'Hello World',
|
||||
init () {
|
||||
name: 'helloworld',
|
||||
async init ({importLocale}) {
|
||||
// See `/editor/extensions/ext-locale/helloworld/`
|
||||
const strings = await importLocale();
|
||||
const svgEditor = this;
|
||||
const $ = jQuery;
|
||||
const svgCanvas = svgEditor.canvas;
|
||||
return {
|
||||
name: 'Hello World',
|
||||
name: strings.name,
|
||||
// For more notes on how to make an icon file, see the source of
|
||||
// the helloworld-icon.xml
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'helloworld-icon.xml',
|
||||
@@ -36,7 +37,7 @@ export default {
|
||||
type: 'mode',
|
||||
|
||||
// Tooltip text
|
||||
title: "Say 'Hello World'",
|
||||
title: strings.buttons[0].title,
|
||||
|
||||
// Events
|
||||
events: {
|
||||
@@ -70,8 +71,14 @@ export default {
|
||||
const x = opts.mouse_x / zoom;
|
||||
const y = opts.mouse_y / zoom;
|
||||
|
||||
const text = 'Hello World!\n\nYou clicked here: ' +
|
||||
x + ', ' + y;
|
||||
// We do our own formatting
|
||||
let {text} = strings;
|
||||
[
|
||||
['x', x],
|
||||
['y', y]
|
||||
].forEach(([prop, val]) => {
|
||||
text = text.replace('{' + prop + '}', val);
|
||||
});
|
||||
|
||||
// Show the text using the custom alert function
|
||||
$.alert(text);
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-imagelib.js
|
||||
*
|
||||
* Licensed under the MIT License
|
||||
* @license MIT
|
||||
*
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
* @copyright 2010 Alexis Deveria
|
||||
*
|
||||
*/
|
||||
import {importSetGlobalDefault} from '../external/dynamic-import-polyfill/importModule.js';
|
||||
|
||||
export default {
|
||||
name: 'imagelib',
|
||||
init ({decode64}) {
|
||||
async init ({decode64, importLocale}) {
|
||||
const imagelibStrings = await importLocale();
|
||||
const svgEditor = this;
|
||||
let imagelibStrings;
|
||||
|
||||
const $ = jQuery;
|
||||
const {uiStrings, canvas: svgCanvas} = svgEditor;
|
||||
@@ -23,7 +21,7 @@ export default {
|
||||
}
|
||||
|
||||
function importImage (url) {
|
||||
const newImage = svgCanvas.addSvgElementFromJson({
|
||||
const newImage = svgCanvas.addSVGElementFromJson({
|
||||
element: 'image',
|
||||
attr: {
|
||||
x: 0,
|
||||
@@ -340,10 +338,19 @@ export default {
|
||||
.appendTo(libOpts)
|
||||
.text(name)
|
||||
.on('click touchend', function () {
|
||||
frame.attr('src', url({
|
||||
path: svgEditor.curConfig.extIconsPath,
|
||||
modularVersion
|
||||
})).show();
|
||||
frame.attr(
|
||||
'src',
|
||||
// Todo: Adopt some standard formatting library like `fluent.js` instead
|
||||
url.replace(
|
||||
'{path}',
|
||||
svgEditor.curConfig.extIconsPath
|
||||
).replace(
|
||||
'{modularVersion}',
|
||||
modularVersion
|
||||
? (imagelibStrings.moduleEnding || '-es')
|
||||
: ''
|
||||
)
|
||||
).show();
|
||||
header.text(name);
|
||||
libOpts.hide();
|
||||
back.show();
|
||||
@@ -354,30 +361,20 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
const buttons = [{
|
||||
id: 'tool_imagelib',
|
||||
type: 'app_menu', // _flyout
|
||||
position: 4,
|
||||
events: {
|
||||
mouseup: showBrowser
|
||||
}
|
||||
}];
|
||||
|
||||
return {
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'ext-imagelib.xml',
|
||||
buttons: [{
|
||||
id: 'tool_imagelib',
|
||||
type: 'app_menu', // _flyout
|
||||
position: 4,
|
||||
title: 'Image library',
|
||||
events: {
|
||||
mouseup: showBrowser
|
||||
}
|
||||
}],
|
||||
async langReady ({lang}) {
|
||||
async function tryImport (lang) {
|
||||
const url = `${svgEditor.curConfig.extPath}ext-locale/imagelib/${lang}.js`;
|
||||
imagelibStrings = await importSetGlobalDefault(url, {
|
||||
global: 'svgEditorExtensionLocale_imagelib_' + lang
|
||||
});
|
||||
}
|
||||
try {
|
||||
await tryImport(lang);
|
||||
} catch (err) {
|
||||
await tryImport('en');
|
||||
}
|
||||
},
|
||||
buttons: imagelibStrings.buttons.map((button, i) => {
|
||||
return Object.assign(buttons[i], button);
|
||||
}),
|
||||
callback () {
|
||||
$('<style>').text(
|
||||
'#imgbrowse_holder {' +
|
||||
|
||||
19
editor/extensions/ext-locale/arrows/en.js
Normal file
19
editor/extensions/ext-locale/arrows/en.js
Normal file
@@ -0,0 +1,19 @@
|
||||
export default {
|
||||
name: 'Arrows',
|
||||
langList: [
|
||||
{id: 'arrow_none', textContent: 'No arrow'}
|
||||
],
|
||||
contextTools: [
|
||||
{
|
||||
title: 'Select arrow type',
|
||||
options: {
|
||||
none: 'No arrow',
|
||||
end: '---->',
|
||||
start: '<----',
|
||||
both: '<--->',
|
||||
mid: '-->--',
|
||||
mid_bk: '--<--'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
19
editor/extensions/ext-locale/arrows/fr.js
Normal file
19
editor/extensions/ext-locale/arrows/fr.js
Normal file
@@ -0,0 +1,19 @@
|
||||
export default {
|
||||
name: 'Arrows',
|
||||
langList: [
|
||||
{id: 'arrow_none', textContent: 'Sans flèche'}
|
||||
],
|
||||
contextTools: [
|
||||
{
|
||||
title: 'Select arrow type',
|
||||
options: {
|
||||
none: 'No arrow',
|
||||
end: '---->',
|
||||
start: '<----',
|
||||
both: '<--->',
|
||||
mid: '-->--',
|
||||
mid_bk: '--<--'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
11
editor/extensions/ext-locale/closepath/en.js
Normal file
11
editor/extensions/ext-locale/closepath/en.js
Normal file
@@ -0,0 +1,11 @@
|
||||
export default {
|
||||
name: 'ClosePath',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Open path'
|
||||
},
|
||||
{
|
||||
title: 'Close path'
|
||||
}
|
||||
]
|
||||
};
|
||||
11
editor/extensions/ext-locale/connector/en.js
Normal file
11
editor/extensions/ext-locale/connector/en.js
Normal file
@@ -0,0 +1,11 @@
|
||||
export default {
|
||||
name: 'Connector',
|
||||
langList: [
|
||||
{id: 'mode_connect', title: 'Connect two objects'}
|
||||
],
|
||||
buttons: [
|
||||
{
|
||||
title: 'Connect two objects'
|
||||
}
|
||||
]
|
||||
};
|
||||
11
editor/extensions/ext-locale/connector/fr.js
Normal file
11
editor/extensions/ext-locale/connector/fr.js
Normal file
@@ -0,0 +1,11 @@
|
||||
export default {
|
||||
name: 'Connector',
|
||||
langList: [
|
||||
{id: 'mode_connect', title: 'Connecter deux objets'}
|
||||
],
|
||||
buttons: [
|
||||
{
|
||||
title: 'Connect two objects'
|
||||
}
|
||||
]
|
||||
};
|
||||
9
editor/extensions/ext-locale/eyedropper/en.js
Normal file
9
editor/extensions/ext-locale/eyedropper/en.js
Normal file
@@ -0,0 +1,9 @@
|
||||
export default {
|
||||
name: 'eyedropper',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Eye Dropper Tool',
|
||||
key: 'I'
|
||||
}
|
||||
]
|
||||
};
|
||||
25
editor/extensions/ext-locale/foreignobject/en.js
Normal file
25
editor/extensions/ext-locale/foreignobject/en.js
Normal file
@@ -0,0 +1,25 @@
|
||||
export default {
|
||||
name: 'foreignObject',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Foreign Object Tool'
|
||||
},
|
||||
{
|
||||
title: 'Edit ForeignObject Content'
|
||||
}
|
||||
],
|
||||
contextTools: [
|
||||
{
|
||||
title: "Change foreignObject's width",
|
||||
label: 'w'
|
||||
},
|
||||
{
|
||||
title: "Change foreignObject's height",
|
||||
label: 'h'
|
||||
},
|
||||
{
|
||||
title: "Change foreignObject's font size",
|
||||
label: 'font-size'
|
||||
}
|
||||
]
|
||||
};
|
||||
8
editor/extensions/ext-locale/grid/en.js
Normal file
8
editor/extensions/ext-locale/grid/en.js
Normal file
@@ -0,0 +1,8 @@
|
||||
export default {
|
||||
name: 'View Grid',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Show/Hide Grid'
|
||||
}
|
||||
]
|
||||
};
|
||||
9
editor/extensions/ext-locale/helloworld/en.js
Normal file
9
editor/extensions/ext-locale/helloworld/en.js
Normal file
@@ -0,0 +1,9 @@
|
||||
export default {
|
||||
name: 'Hello World',
|
||||
text: 'Hello World!\n\nYou clicked here: {x}, {y}',
|
||||
buttons: [
|
||||
{
|
||||
title: "Say 'Hello World'"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -4,12 +4,15 @@ export default {
|
||||
import_single: 'Import single',
|
||||
import_multi: 'Import multiple',
|
||||
open: 'Open as new document',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Image library'
|
||||
}
|
||||
],
|
||||
imgLibs: [
|
||||
{
|
||||
name: 'Demo library (local)',
|
||||
url ({path, modularVersion}) {
|
||||
return path + 'imagelib/index' + (modularVersion ? '-es' : '') + '.html';
|
||||
},
|
||||
url: '{path}imagelib/index{modularVersion}.html',
|
||||
description: 'Demonstration library for SVG-edit on this server'
|
||||
},
|
||||
{
|
||||
|
||||
@@ -4,12 +4,15 @@ export default {
|
||||
import_single: 'import_single',
|
||||
import_multi: 'import_multi',
|
||||
open: 'open',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Image library'
|
||||
}
|
||||
],
|
||||
imgLibs: [
|
||||
{
|
||||
name: 'Demo library (local)',
|
||||
url ({path, modularVersion}) {
|
||||
return path + 'imagelib/index' + (modularVersion ? '-es' : '') + '.html';
|
||||
},
|
||||
url: '{path}imagelib/index{modularVersion}.html',
|
||||
description: 'Demonstration library for SVG-edit on this server'
|
||||
},
|
||||
{
|
||||
|
||||
46
editor/extensions/ext-locale/markers/en.js
Normal file
46
editor/extensions/ext-locale/markers/en.js
Normal file
@@ -0,0 +1,46 @@
|
||||
export default {
|
||||
name: 'Markers',
|
||||
langList: [
|
||||
{id: 'nomarker', title: 'No Marker'},
|
||||
{id: 'leftarrow', title: 'Left Arrow'},
|
||||
{id: 'rightarrow', title: 'Right Arrow'},
|
||||
{id: 'textmarker', title: 'Text Marker'},
|
||||
{id: 'forwardslash', title: 'Forward Slash'},
|
||||
{id: 'reverseslash', title: 'Reverse Slash'},
|
||||
{id: 'verticalslash', title: 'Vertical Slash'},
|
||||
{id: 'box', title: 'Box'},
|
||||
{id: 'star', title: 'Star'},
|
||||
{id: 'xmark', title: 'X'},
|
||||
{id: 'triangle', title: 'Triangle'},
|
||||
{id: 'mcircle', title: 'Circle'},
|
||||
{id: 'leftarrow_o', title: 'Open Left Arrow'},
|
||||
{id: 'rightarrow_o', title: 'Open Right Arrow'},
|
||||
{id: 'box_o', title: 'Open Box'},
|
||||
{id: 'star_o', title: 'Open Star'},
|
||||
{id: 'triangle_o', title: 'Open Triangle'},
|
||||
{id: 'mcircle_o', title: 'Open Circle'}
|
||||
],
|
||||
contextTools: [
|
||||
{
|
||||
title: 'Start marker',
|
||||
label: 's'
|
||||
},
|
||||
{
|
||||
title: 'Select start marker type'
|
||||
},
|
||||
{
|
||||
title: 'Middle marker',
|
||||
label: 'm'
|
||||
},
|
||||
{
|
||||
title: 'Select mid marker type'
|
||||
},
|
||||
{
|
||||
title: 'End marker',
|
||||
label: 'e'
|
||||
},
|
||||
{
|
||||
title: 'Select end marker type'
|
||||
}
|
||||
]
|
||||
};
|
||||
8
editor/extensions/ext-locale/mathjax/en.js
Normal file
8
editor/extensions/ext-locale/mathjax/en.js
Normal file
@@ -0,0 +1,8 @@
|
||||
export default {
|
||||
name: 'MathJax',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Add Mathematics'
|
||||
}
|
||||
]
|
||||
};
|
||||
8
editor/extensions/ext-locale/panning/en.js
Normal file
8
editor/extensions/ext-locale/panning/en.js
Normal file
@@ -0,0 +1,8 @@
|
||||
export default {
|
||||
name: 'Extension Panning',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Panning'
|
||||
}
|
||||
]
|
||||
};
|
||||
14
editor/extensions/ext-locale/polygon/en.js
Normal file
14
editor/extensions/ext-locale/polygon/en.js
Normal file
@@ -0,0 +1,14 @@
|
||||
export default {
|
||||
name: 'polygon',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Polygon Tool'
|
||||
}
|
||||
],
|
||||
contextTools: [
|
||||
{
|
||||
title: 'Number of Sides',
|
||||
label: 'sides'
|
||||
}
|
||||
]
|
||||
};
|
||||
3
editor/extensions/ext-locale/server_moinsave/en.js
Normal file
3
editor/extensions/ext-locale/server_moinsave/en.js
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
saved: 'Saved! Return to Item View!'
|
||||
};
|
||||
3
editor/extensions/ext-locale/server_opensave/en.js
Normal file
3
editor/extensions/ext-locale/server_opensave/en.js
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
uploading: 'Uploading...'
|
||||
};
|
||||
24
editor/extensions/ext-locale/shapes/en.js
Normal file
24
editor/extensions/ext-locale/shapes/en.js
Normal file
@@ -0,0 +1,24 @@
|
||||
export default {
|
||||
loading: 'Loading...',
|
||||
categories: {
|
||||
basic: 'Basic',
|
||||
object: 'Objects',
|
||||
symbol: 'Symbols',
|
||||
arrow: 'Arrows',
|
||||
flowchart: 'Flowchart',
|
||||
animal: 'Animals',
|
||||
game: 'Cards & Chess',
|
||||
dialog_balloon: 'Dialog balloons',
|
||||
electronics: 'Electronics',
|
||||
math: 'Mathematical',
|
||||
music: 'Music',
|
||||
misc: 'Miscellaneous',
|
||||
raphael_1: 'raphaeljs.com set 1',
|
||||
raphael_2: 'raphaeljs.com set 2'
|
||||
},
|
||||
buttons: [
|
||||
{
|
||||
title: 'Shape library'
|
||||
}
|
||||
]
|
||||
};
|
||||
24
editor/extensions/ext-locale/shapes/fr.js
Normal file
24
editor/extensions/ext-locale/shapes/fr.js
Normal file
@@ -0,0 +1,24 @@
|
||||
export default {
|
||||
loading: 'Loading...',
|
||||
categories: {
|
||||
basic: 'Basic',
|
||||
object: 'Objects',
|
||||
symbol: 'Symbols',
|
||||
arrow: 'Arrows',
|
||||
flowchart: 'Flowchart',
|
||||
animal: 'Animals',
|
||||
game: 'Cards & Chess',
|
||||
dialog_balloon: 'Dialog balloons',
|
||||
electronics: 'Electronics',
|
||||
math: 'Mathematical',
|
||||
music: 'Music',
|
||||
misc: 'Miscellaneous',
|
||||
raphael_1: 'raphaeljs.com set 1',
|
||||
raphael_2: 'raphaeljs.com set 2'
|
||||
},
|
||||
buttons: [
|
||||
{
|
||||
title: "Bibliothèque d'images"
|
||||
}
|
||||
]
|
||||
};
|
||||
22
editor/extensions/ext-locale/star/en.js
Normal file
22
editor/extensions/ext-locale/star/en.js
Normal file
@@ -0,0 +1,22 @@
|
||||
export default {
|
||||
name: 'star',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Star Tool'
|
||||
}
|
||||
],
|
||||
contextTools: [
|
||||
{
|
||||
title: 'Number of Sides',
|
||||
label: 'points'
|
||||
},
|
||||
{
|
||||
title: 'Pointiness',
|
||||
label: 'Pointiness'
|
||||
},
|
||||
{
|
||||
title: 'Twists the star',
|
||||
label: 'Radial Shift'
|
||||
}
|
||||
]
|
||||
};
|
||||
8
editor/extensions/ext-locale/webappfind/en.js
Normal file
8
editor/extensions/ext-locale/webappfind/en.js
Normal file
@@ -0,0 +1,8 @@
|
||||
export default {
|
||||
name: 'WebAppFind',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Save Image back to Disk'
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -1,11 +1,10 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-markers.js
|
||||
*
|
||||
* Licensed under the Apache License, Version 2
|
||||
* @license Apache-2.0
|
||||
*
|
||||
* Copyright(c) 2010 Will Schleter
|
||||
* based on ext-arrows.js by Copyright(c) 2010 Alexis Deveria
|
||||
* @copyright 2010 Will Schleter based on ext-arrows.js by Copyright(c) 2010 Alexis Deveria
|
||||
*
|
||||
* This extension provides for the addition of markers to the either end
|
||||
* or the middle of a line, polyline, path, polygon.
|
||||
@@ -24,21 +23,21 @@
|
||||
* an application specific attribute - se_type - is added to each marker element
|
||||
* to store the type of marker
|
||||
*
|
||||
* TODO:
|
||||
* @todo
|
||||
* remove some of the restrictions above
|
||||
* add option for keeping text aligned to horizontal
|
||||
* add support for dimension extension lines
|
||||
*
|
||||
*/
|
||||
|
||||
*/
|
||||
export default {
|
||||
name: 'Markers',
|
||||
init (S) {
|
||||
name: 'markers',
|
||||
async init (S) {
|
||||
const strings = await S.importLocale();
|
||||
const svgEditor = this;
|
||||
const $ = jQuery;
|
||||
const svgCanvas = svgEditor.canvas;
|
||||
const // {svgcontent} = S,
|
||||
addElem = S.addSvgElementFromJson;
|
||||
addElem = S.addSVGElementFromJson;
|
||||
const mtypes = ['start', 'mid', 'end'];
|
||||
const markerPrefix = 'se_marker_';
|
||||
const idPrefix = 'mkr_';
|
||||
@@ -75,41 +74,15 @@ export default {
|
||||
{element: 'circle', attr: {r: 30, cx: 50, cy: 50}}
|
||||
};
|
||||
|
||||
const langList = {
|
||||
en: [
|
||||
{id: 'start_marker_list', title: 'Select start marker type'},
|
||||
{id: 'mid_marker_list', title: 'Select mid marker type'},
|
||||
{id: 'end_marker_list', title: 'Select end marker type'},
|
||||
{id: 'nomarker', title: 'No Marker'},
|
||||
{id: 'leftarrow', title: 'Left Arrow'},
|
||||
{id: 'rightarrow', title: 'Right Arrow'},
|
||||
{id: 'textmarker', title: 'Text Marker'},
|
||||
{id: 'forwardslash', title: 'Forward Slash'},
|
||||
{id: 'reverseslash', title: 'Reverse Slash'},
|
||||
{id: 'verticalslash', title: 'Vertical Slash'},
|
||||
{id: 'box', title: 'Box'},
|
||||
{id: 'star', title: 'Star'},
|
||||
{id: 'xmark', title: 'X'},
|
||||
{id: 'triangle', title: 'Triangle'},
|
||||
{id: 'mcircle', title: 'Circle'},
|
||||
{id: 'leftarrow_o', title: 'Open Left Arrow'},
|
||||
{id: 'rightarrow_o', title: 'Open Right Arrow'},
|
||||
{id: 'box_o', title: 'Open Box'},
|
||||
{id: 'star_o', title: 'Open Star'},
|
||||
{id: 'triangle_o', title: 'Open Triangle'},
|
||||
{id: 'mcircle_o', title: 'Open Circle'}
|
||||
]
|
||||
};
|
||||
|
||||
// duplicate shapes to support unfilled (open) marker types with an _o suffix
|
||||
$.each(['leftarrow', 'rightarrow', 'box', 'star', 'mcircle', 'triangle'], function (i, v) {
|
||||
markerTypes[v + '_o'] = markerTypes[v];
|
||||
});
|
||||
|
||||
/**
|
||||
* @param elem - A graphic element will have an attribute like marker-start
|
||||
* @param attr - marker-start, marker-mid, or marker-end
|
||||
* @returns The marker element that is linked to the graphic element
|
||||
* @param {Element} elem - A graphic element will have an attribute like marker-start
|
||||
* @param {"marker-start"|"marker-mid"|"marker-end"} attr
|
||||
* @returns {Element} The marker element that is linked to the graphic element
|
||||
*/
|
||||
function getLinked (elem, attr) {
|
||||
const str = elem.getAttribute(attr);
|
||||
@@ -421,14 +394,12 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
function getTitle (lang = 'en', id) {
|
||||
const list = langList[lang];
|
||||
for (const i in list) {
|
||||
if (list.hasOwnProperty(i) && list[i].id === id) {
|
||||
return list[i].title;
|
||||
}
|
||||
}
|
||||
return id;
|
||||
function getTitle (id) {
|
||||
const {langList} = strings;
|
||||
const item = langList.find((item) => {
|
||||
return item.id === id;
|
||||
});
|
||||
return item ? item.title : id;
|
||||
}
|
||||
|
||||
// build the toolbar button array from the marker definitions
|
||||
@@ -462,7 +433,7 @@ export default {
|
||||
const listname = pos + '_marker_list';
|
||||
let def = true;
|
||||
$.each(markerTypes, function (id, v) {
|
||||
const title = getTitle(lang, String(id));
|
||||
const title = getTitle(String(id));
|
||||
buttons.push({
|
||||
id: idPrefix + pos + '_' + id,
|
||||
svgicon: id,
|
||||
@@ -479,16 +450,55 @@ export default {
|
||||
return buttons;
|
||||
}
|
||||
|
||||
let currentLang;
|
||||
const ret = {
|
||||
name: 'Markers',
|
||||
const contextTools = [
|
||||
{
|
||||
type: 'input',
|
||||
panel: 'marker_panel',
|
||||
id: 'start_marker',
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
id: 'start_marker_list',
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'marker_panel',
|
||||
id: 'mid_marker',
|
||||
defval: '',
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
id: 'mid_marker_list',
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'marker_panel',
|
||||
id: 'end_marker',
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
id: 'end_marker_list',
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
}
|
||||
];
|
||||
|
||||
return {
|
||||
name: strings.name,
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'markers-icons.xml',
|
||||
callback () {
|
||||
$('#marker_panel').addClass('toolset').hide();
|
||||
},
|
||||
addLangData (lang) {
|
||||
currentLang = lang;
|
||||
return { data: langList[lang] };
|
||||
async addLangData ({importLocale, lang}) {
|
||||
return { data: strings.langList };
|
||||
},
|
||||
selectedChanged (opts) {
|
||||
// Use this to update the current selected elements
|
||||
@@ -524,69 +534,9 @@ export default {
|
||||
updateReferences(elem);
|
||||
}
|
||||
// changing_flag = false; // Not apparently in use
|
||||
}
|
||||
};
|
||||
// Todo: Check if the lang will be available in time
|
||||
Object.defineProperties(ret, {
|
||||
buttons: {
|
||||
get () {
|
||||
return buildButtonList(currentLang);
|
||||
}
|
||||
},
|
||||
context_tools: {
|
||||
get () {
|
||||
return [
|
||||
{
|
||||
type: 'input',
|
||||
panel: 'marker_panel',
|
||||
title: 'Start marker',
|
||||
id: 'start_marker',
|
||||
label: 's',
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
title: getTitle(currentLang, 'start_marker_list'),
|
||||
id: 'start_marker_list',
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'marker_panel',
|
||||
title: 'Middle marker',
|
||||
id: 'mid_marker',
|
||||
label: 'm',
|
||||
defval: '',
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
title: getTitle(currentLang, 'mid_marker_list'),
|
||||
id: 'mid_marker_list',
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'marker_panel',
|
||||
title: 'End marker',
|
||||
id: 'end_marker',
|
||||
label: 'e',
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
title: getTitle(currentLang, 'end_marker_list'),
|
||||
id: 'end_marker_list',
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
buttons: buildButtonList(),
|
||||
context_tools: contextTools
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* globals jQuery, MathJax */
|
||||
/*
|
||||
/**
|
||||
* ext-mathjax.js
|
||||
*
|
||||
* Licensed under the Apache License
|
||||
* @license Apache
|
||||
*
|
||||
* Copyright(c) 2013 Jo Segaert
|
||||
* @copyright 2013 Jo Segaert
|
||||
*
|
||||
*/
|
||||
// Todo: Wait for Mathjax 3.0 to get ES Module/avoid global
|
||||
@@ -12,7 +12,8 @@ import {importScript} from '../external/dynamic-import-polyfill/importModule.js'
|
||||
|
||||
export default {
|
||||
name: 'mathjax',
|
||||
init () {
|
||||
async init ({importLocale}) {
|
||||
const strings = await importLocale();
|
||||
const svgEditor = this;
|
||||
const $ = jQuery;
|
||||
const svgCanvas = svgEditor.canvas;
|
||||
@@ -45,7 +46,7 @@ export default {
|
||||
// mathjaxSrc = 'http://cdn.mathjax.org/mathjax/latest/MathJax.js',
|
||||
// Had been on https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG.js
|
||||
// Obtained Text-AMS-MML_SVG.js from https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.3/config/TeX-AMS-MML_SVG.js
|
||||
mathjaxSrcSecure = 'mathjax/MathJax.js?config=TeX-AMS-MML_SVG.js',
|
||||
mathjaxSrcSecure = 'mathjax/MathJax.min.js?config=TeX-AMS-MML_SVG.js',
|
||||
{uiStrings} = svgEditor;
|
||||
let
|
||||
math,
|
||||
@@ -72,15 +73,15 @@ export default {
|
||||
|
||||
/*
|
||||
* The MathJax library doesn't want to bloat your webpage so it creates
|
||||
* every symbol (glymph) you need only once. These are saved in a <svg> on
|
||||
* every symbol (glymph) you need only once. These are saved in a `<svg>` on
|
||||
* the top of your html document, just under the body tag. Each glymph has
|
||||
* its unique id and is saved as a <path> in the <defs> tag of the <svg>
|
||||
* its unique id and is saved as a `<path>` in the `<defs>` tag of the `<svg>`
|
||||
*
|
||||
* Then when the symbols are needed in the rest of your html document they
|
||||
* are refferd to by a <use> tag.
|
||||
* are refferd to by a `<use>` tag.
|
||||
* Because of bug 1076 we can't just grab the defs tag on the top and add it
|
||||
* to your formula's <svg> and copy the lot. So we have to replace each
|
||||
* <use> tag by it's <path>.
|
||||
* to your formula's `<svg>` and copy the lot. So we have to replace each
|
||||
* `<use>` tag by its `<path>`.
|
||||
*/
|
||||
MathJax.Hub.queue.Push(
|
||||
function () {
|
||||
@@ -116,99 +117,102 @@ export default {
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'MathJax',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'mathjax-icons.xml',
|
||||
buttons: [{
|
||||
id: 'tool_mathjax',
|
||||
type: 'mode',
|
||||
title: 'Add Mathematics',
|
||||
events: {
|
||||
click () {
|
||||
// Only load Mathjax when needed, we don't want to strain Svg-Edit any more.
|
||||
// From this point on it is very probable that it will be needed, so load it.
|
||||
if (mathjaxLoaded === false) {
|
||||
$('<div id="mathjax">' +
|
||||
'<!-- Here is where MathJax creates the math -->' +
|
||||
'<div id="mathjax_creator" class="tex2jax_process" style="display:none">' +
|
||||
'$${}$$' +
|
||||
const buttons = [{
|
||||
id: 'tool_mathjax',
|
||||
type: 'mode',
|
||||
events: {
|
||||
click () {
|
||||
// Only load Mathjax when needed, we don't want to strain Svg-Edit any more.
|
||||
// From this point on it is very probable that it will be needed, so load it.
|
||||
if (mathjaxLoaded === false) {
|
||||
$('<div id="mathjax">' +
|
||||
'<!-- Here is where MathJax creates the math -->' +
|
||||
'<div id="mathjax_creator" class="tex2jax_process" style="display:none">' +
|
||||
'$${}$$' +
|
||||
'</div>' +
|
||||
'<div id="mathjax_overlay"></div>' +
|
||||
'<div id="mathjax_container">' +
|
||||
'<div id="tool_mathjax_back" class="toolbar_button">' +
|
||||
'<button id="tool_mathjax_save">OK</button>' +
|
||||
'<button id="tool_mathjax_cancel">Cancel</button>' +
|
||||
'</div>' +
|
||||
'<div id="mathjax_overlay"></div>' +
|
||||
'<div id="mathjax_container">' +
|
||||
'<div id="tool_mathjax_back" class="toolbar_button">' +
|
||||
'<button id="tool_mathjax_save">OK</button>' +
|
||||
'<button id="tool_mathjax_cancel">Cancel</button>' +
|
||||
'</div>' +
|
||||
'<fieldset>' +
|
||||
'<legend id="mathjax_legend">Mathematics Editor</legend>' +
|
||||
'<label>' +
|
||||
'<span id="mathjax_explication">Please type your mathematics in ' +
|
||||
'<a href="https://en.wikipedia.org/wiki/Help:Displaying_a_formula" target="_blank">TeX</a> code.</span></label>' +
|
||||
'<textarea id="mathjax_code_textarea" spellcheck="false"></textarea>' +
|
||||
'</fieldset>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
).insertAfter('#svg_prefs').hide();
|
||||
'<fieldset>' +
|
||||
'<legend id="mathjax_legend">Mathematics Editor</legend>' +
|
||||
'<label>' +
|
||||
'<span id="mathjax_explication">Please type your mathematics in ' +
|
||||
'<a href="https://en.wikipedia.org/wiki/Help:Displaying_a_formula" target="_blank">TeX</a> code.</span></label>' +
|
||||
'<textarea id="mathjax_code_textarea" spellcheck="false"></textarea>' +
|
||||
'</fieldset>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
).insertAfter('#svg_prefs').hide();
|
||||
|
||||
// Make the MathEditor draggable.
|
||||
$('#mathjax_container').draggable({
|
||||
cancel: 'button,fieldset',
|
||||
containment: 'window'
|
||||
// Make the MathEditor draggable.
|
||||
$('#mathjax_container').draggable({
|
||||
cancel: 'button,fieldset',
|
||||
containment: 'window'
|
||||
});
|
||||
|
||||
// Add functionality and picture to cancel button.
|
||||
$('#tool_mathjax_cancel').prepend($.getSvgIcon('cancel', true))
|
||||
.on('click touched', function () {
|
||||
$('#mathjax').hide();
|
||||
});
|
||||
|
||||
// Add functionality and picture to cancel button.
|
||||
$('#tool_mathjax_cancel').prepend($.getSvgIcon('cancel', true))
|
||||
.on('click touched', function () {
|
||||
$('#mathjax').hide();
|
||||
});
|
||||
|
||||
// Add functionality and picture to the save button.
|
||||
$('#tool_mathjax_save').prepend($.getSvgIcon('ok', true))
|
||||
.on('click touched', function () {
|
||||
saveMath();
|
||||
$('#mathjax').hide();
|
||||
});
|
||||
|
||||
// MathJax preprocessing has to ignore most of the page.
|
||||
$('body').addClass('tex2jax_ignore');
|
||||
|
||||
// Now get (and run) the MathJax Library.
|
||||
// Todo: insert script with modules once widely supported
|
||||
// and if MathJax (and its `TeX-AMS-MML_SVG.js` dependency) ends up
|
||||
// providing an ES6 module export: https://github.com/mathjax/MathJax/issues/1998
|
||||
/*
|
||||
const modularVersion = !('svgEditor' in window) ||
|
||||
!window.svgEditor ||
|
||||
window.svgEditor.modules !== false;
|
||||
// Add as second argument to `importScript`
|
||||
{
|
||||
type: modularVersion
|
||||
? 'module' // Make this the default when widely supported
|
||||
: 'text/javascript'
|
||||
}
|
||||
// If only using modules, just use this:
|
||||
const {default: MathJax} = await importModule( // or `import()` when widely supported
|
||||
svgEditor.curConfig.extIconsPath + mathjaxSrcSecure
|
||||
);
|
||||
*/
|
||||
importScript(svgEditor.curConfig.extIconsPath + mathjaxSrcSecure).then(() => {
|
||||
// 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];
|
||||
console.log(math);
|
||||
mathjaxLoaded = true;
|
||||
console.log('MathJax Loaded');
|
||||
});
|
||||
}).catch(() => {
|
||||
console.log('Failed loadeing MathJax.');
|
||||
$.alert('Failed loading MathJax. You will not be able to change the mathematics.');
|
||||
// Add functionality and picture to the save button.
|
||||
$('#tool_mathjax_save').prepend($.getSvgIcon('ok', true))
|
||||
.on('click touched', function () {
|
||||
saveMath();
|
||||
$('#mathjax').hide();
|
||||
});
|
||||
|
||||
// MathJax preprocessing has to ignore most of the page.
|
||||
$('body').addClass('tex2jax_ignore');
|
||||
|
||||
// Now get (and run) the MathJax Library.
|
||||
// Todo: insert script with modules once widely supported
|
||||
// and if MathJax (and its `TeX-AMS-MML_SVG.js` dependency) ends up
|
||||
// providing an ES6 module export: https://github.com/mathjax/MathJax/issues/1998
|
||||
/*
|
||||
const modularVersion = !('svgEditor' in window) ||
|
||||
!window.svgEditor ||
|
||||
window.svgEditor.modules !== false;
|
||||
// Add as second argument to `importScript`
|
||||
{
|
||||
type: modularVersion
|
||||
? 'module' // Make this the default when widely supported
|
||||
: 'text/javascript'
|
||||
}
|
||||
// Set the mode.
|
||||
svgCanvas.setMode('mathjax');
|
||||
// If only using modules, just use this:
|
||||
const {default: MathJax} = await importModule( // or `import()` when widely supported
|
||||
svgEditor.curConfig.extIconsPath + mathjaxSrcSecure
|
||||
);
|
||||
*/
|
||||
importScript(svgEditor.curConfig.extIconsPath + mathjaxSrcSecure).then(() => {
|
||||
// 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];
|
||||
console.log(math);
|
||||
mathjaxLoaded = true;
|
||||
console.log('MathJax Loaded');
|
||||
});
|
||||
}).catch(() => {
|
||||
console.log('Failed loadeing MathJax.');
|
||||
$.alert('Failed loading MathJax. You will not be able to change the mathematics.');
|
||||
});
|
||||
}
|
||||
// Set the mode.
|
||||
svgCanvas.setMode('mathjax');
|
||||
}
|
||||
}],
|
||||
}
|
||||
}];
|
||||
|
||||
return {
|
||||
name: strings.name,
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'mathjax-icons.xml',
|
||||
buttons: strings.buttons.map((button, i) => {
|
||||
return Object.assign(buttons[i], button);
|
||||
}),
|
||||
|
||||
mouseDown () {
|
||||
if (svgCanvas.getMode() === 'mathjax') {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-overview_window.js
|
||||
*
|
||||
* Licensed under the MIT License
|
||||
* @license MIT
|
||||
*
|
||||
* Copyright(c) 2013 James Sacksteder
|
||||
* @copyright 2013 James Sacksteder
|
||||
*
|
||||
*/
|
||||
export default {
|
||||
|
||||
@@ -1,34 +1,35 @@
|
||||
/*
|
||||
/**
|
||||
* ext-panning.js
|
||||
*
|
||||
* Licensed under the MIT License
|
||||
* @license MIT
|
||||
*
|
||||
* Copyright(c) 2013 Luis Aguirre
|
||||
* @copyright 2013 Luis Aguirre
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
This is a very basic SVG-Edit extension to let tablet/mobile devices pan without problem
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'ext-panning',
|
||||
init () {
|
||||
name: 'panning',
|
||||
async init ({importLocale}) {
|
||||
const strings = await importLocale();
|
||||
const svgEditor = this;
|
||||
const svgCanvas = svgEditor.canvas;
|
||||
return {
|
||||
name: 'Extension Panning',
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'ext-panning.xml',
|
||||
buttons: [{
|
||||
id: 'ext-panning',
|
||||
type: 'mode',
|
||||
title: 'Panning',
|
||||
events: {
|
||||
click () {
|
||||
svgCanvas.setMode('ext-panning');
|
||||
}
|
||||
const buttons = [{
|
||||
id: 'ext-panning',
|
||||
type: 'mode',
|
||||
events: {
|
||||
click () {
|
||||
svgCanvas.setMode('ext-panning');
|
||||
}
|
||||
}],
|
||||
}
|
||||
}];
|
||||
return {
|
||||
name: strings.name,
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'ext-panning.xml',
|
||||
buttons: strings.buttons.map((button, i) => {
|
||||
return Object.assign(buttons[i], button);
|
||||
}),
|
||||
mouseDown () {
|
||||
if (svgCanvas.getMode() === 'ext-panning') {
|
||||
svgEditor.setPanning(true);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
export default {
|
||||
name: 'php_savefile',
|
||||
callback () {
|
||||
init () {
|
||||
const svgEditor = this;
|
||||
const $ = jQuery;
|
||||
const svgCanvas = svgEditor.canvas;
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-polygon.js
|
||||
*
|
||||
*
|
||||
* Copyright(c) 2010 CloudCanvas, Inc.
|
||||
* All rights reserved
|
||||
* @copyright 2010 CloudCanvas, Inc. All rights reserved
|
||||
*
|
||||
*/
|
||||
export default {
|
||||
name: 'polygon',
|
||||
init (S) {
|
||||
async init (S) {
|
||||
const svgEditor = this;
|
||||
const $ = jQuery;
|
||||
const svgCanvas = svgEditor.canvas;
|
||||
const // {svgcontent} = S,
|
||||
// addElem = S.addSvgElementFromJson,
|
||||
const {importLocale} = S, // {svgcontent}
|
||||
// addElem = S.addSVGElementFromJson,
|
||||
editingitex = false;
|
||||
const strings = await importLocale();
|
||||
let selElems,
|
||||
// svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||
// newFOG, newFOGParent, newDef, newImageName, newMaskID, modeChangeG,
|
||||
@@ -71,7 +71,7 @@ export default {
|
||||
* This function sets the content of of the currently-selected foreignObject element,
|
||||
* based on the itex contained in string.
|
||||
* @param {string} tex The itex text.
|
||||
* @returns This function returns false if the set was unsuccessful, true otherwise.
|
||||
* @returns {boolean} This function returns false if the set was unsuccessful, true otherwise.
|
||||
*/
|
||||
/*
|
||||
function setItexString(tex) {
|
||||
@@ -110,36 +110,38 @@ export default {
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
const buttons = [{
|
||||
id: 'tool_polygon',
|
||||
type: 'mode',
|
||||
position: 11,
|
||||
events: {
|
||||
click () {
|
||||
svgCanvas.setMode('polygon');
|
||||
showPanel(true);
|
||||
}
|
||||
}
|
||||
}];
|
||||
const contextTools = [{
|
||||
type: 'input',
|
||||
panel: 'polygon_panel',
|
||||
id: 'polySides',
|
||||
size: 3,
|
||||
defval: 5,
|
||||
events: {
|
||||
change () {
|
||||
setAttr('sides', this.value);
|
||||
}
|
||||
}
|
||||
}];
|
||||
return {
|
||||
name: 'polygon',
|
||||
name: strings.name,
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'polygon-icons.svg',
|
||||
buttons: [{
|
||||
id: 'tool_polygon',
|
||||
type: 'mode',
|
||||
title: 'Polygon Tool',
|
||||
position: 11,
|
||||
events: {
|
||||
click () {
|
||||
svgCanvas.setMode('polygon');
|
||||
showPanel(true);
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
context_tools: [{
|
||||
type: 'input',
|
||||
panel: 'polygon_panel',
|
||||
title: 'Number of Sides',
|
||||
id: 'polySides',
|
||||
label: 'sides',
|
||||
size: 3,
|
||||
defval: 5,
|
||||
events: {
|
||||
change () {
|
||||
setAttr('sides', this.value);
|
||||
}
|
||||
}
|
||||
}],
|
||||
buttons: strings.buttons.map((button, i) => {
|
||||
return Object.assign(buttons[i], button);
|
||||
}),
|
||||
context_tools: strings.contextTools.map((contextTool, i) => {
|
||||
return Object.assign(contextTools[i], contextTool);
|
||||
}),
|
||||
|
||||
callback () {
|
||||
$('#polygon_panel').hide();
|
||||
@@ -185,7 +187,7 @@ export default {
|
||||
if (svgCanvas.getMode() === 'polygon') {
|
||||
started = true;
|
||||
|
||||
newFO = S.addSvgElementFromJson({
|
||||
newFO = S.addSVGElementFromJson({
|
||||
element: 'polygon',
|
||||
attr: {
|
||||
cx: opts.start_x,
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-server_moinsave.js
|
||||
*
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
* 2011 MoinMoin:ReimarBauer
|
||||
* adopted for moinmoins item storage. it sends in one post png and svg data
|
||||
* (I agree to dual license my work to additional GPLv2 or later)
|
||||
* @license MIT
|
||||
*
|
||||
* @copyright 2010 Alexis Deveria, 2011 MoinMoin:ReimarBauer
|
||||
* adopted for moinmoins item storage. It sends in one post png and svg data
|
||||
* (I agree to dual license my work to additional GPLv2 or later)
|
||||
*/
|
||||
import {canvg} from '../canvg/canvg.js';
|
||||
|
||||
export default {
|
||||
name: 'server_opensave',
|
||||
callback ({encode64}) {
|
||||
name: 'server_moinsave',
|
||||
async init ({encode64, importLocale}) {
|
||||
const strings = await importLocale();
|
||||
const svgEditor = this;
|
||||
const $ = jQuery;
|
||||
const svgCanvas = svgEditor.canvas;
|
||||
@@ -49,7 +48,7 @@ export default {
|
||||
.append('<input type="hidden" name="contenttype" value="application/x-svgdraw">')
|
||||
.appendTo('body')
|
||||
.submit().remove();
|
||||
alert('Saved! Return to Item View!');
|
||||
alert(strings.saved);
|
||||
top.window.location = '/' + name;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-server_opensave.js
|
||||
*
|
||||
* Licensed under the MIT License
|
||||
* @license MIT
|
||||
*
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
* @copyright 2010 Alexis Deveria
|
||||
*
|
||||
*/
|
||||
import {canvg} from '../canvg/canvg.js';
|
||||
|
||||
export default {
|
||||
name: 'server_opensave',
|
||||
callback ({decode64, encode64}) {
|
||||
async init ({decode64, encode64, importLocale}) {
|
||||
const strings = await importLocale();
|
||||
const svgEditor = this;
|
||||
const $ = jQuery;
|
||||
const svgCanvas = svgEditor.canvas;
|
||||
@@ -63,7 +64,7 @@ export default {
|
||||
},
|
||||
exportPDF (win, data) {
|
||||
const filename = getFileNameFromTitle(),
|
||||
datauri = data.dataurlstring;
|
||||
datauri = data.output;
|
||||
if (clientDownloadSupport(filename, '.pdf', datauri)) {
|
||||
return;
|
||||
}
|
||||
@@ -186,7 +187,7 @@ export default {
|
||||
form.submit();
|
||||
|
||||
rebuildInput(form);
|
||||
$.process_cancel('Uploading...', function () {
|
||||
$.process_cancel(strings.uploading, function () {
|
||||
cancelled = true;
|
||||
$('#dialog_box').hide();
|
||||
});
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-shapes.js
|
||||
*
|
||||
* Licensed under the MIT License
|
||||
* @license MIT
|
||||
*
|
||||
* Copyright(c) 2010 Christian Tzurcanu
|
||||
* Copyright(c) 2010 Alexis Deveria
|
||||
* @copyright 2010 Christian Tzurcanu, 2010 Alexis Deveria
|
||||
*
|
||||
*/
|
||||
export default {
|
||||
name: 'shapes',
|
||||
init () {
|
||||
async init ({importLocale}) {
|
||||
const strings = await importLocale();
|
||||
const svgEditor = this;
|
||||
const $ = jQuery;
|
||||
const canv = svgEditor.canvas;
|
||||
@@ -18,22 +18,7 @@ export default {
|
||||
let lastBBox = {};
|
||||
|
||||
// This populates the category list
|
||||
const categories = {
|
||||
basic: 'Basic',
|
||||
object: 'Objects',
|
||||
symbol: 'Symbols',
|
||||
arrow: 'Arrows',
|
||||
flowchart: 'Flowchart',
|
||||
animal: 'Animals',
|
||||
game: 'Cards & Chess',
|
||||
dialog_balloon: 'Dialog balloons',
|
||||
electronics: 'Electronics',
|
||||
math: 'Mathematical',
|
||||
music: 'Music',
|
||||
misc: 'Miscellaneous',
|
||||
raphael_1: 'raphaeljs.com set 1',
|
||||
raphael_2: 'raphaeljs.com set 2'
|
||||
};
|
||||
const {categories} = strings;
|
||||
|
||||
const library = {
|
||||
basic: {
|
||||
@@ -89,7 +74,10 @@ export default {
|
||||
const vb = [-off, -off, size + off * 2, size + off * 2].join(' ');
|
||||
const stroke = fill ? 0 : (size / 30);
|
||||
const shapeIcon = new DOMParser().parseFromString(
|
||||
'<svg xmlns="http://www.w3.org/2000/svg"><svg viewBox="' + vb + '"><path fill="' + (fill ? '#333' : 'none') + '" stroke="#000" stroke-width="' + stroke + '" /></svg></svg>',
|
||||
'<svg xmlns="http://www.w3.org/2000/svg">' +
|
||||
'<svg viewBox="' + vb + '">' +
|
||||
'<path fill="' + (fill ? '#333' : 'none') +
|
||||
'" stroke="#000" stroke-width="' + stroke + '" /></svg></svg>',
|
||||
'text/xml');
|
||||
|
||||
const width = 24;
|
||||
@@ -119,7 +107,7 @@ export default {
|
||||
const lib = library[catId];
|
||||
|
||||
if (!lib) {
|
||||
$('#shape_buttons').html('Loading...');
|
||||
$('#shape_buttons').html(strings.loading);
|
||||
$.getJSON(svgEditor.curConfig.extIconsPath + 'shapelib/' + catId + '.json', function (result) {
|
||||
curLib = library[catId] = {
|
||||
data: result.data,
|
||||
@@ -135,20 +123,22 @@ export default {
|
||||
if (!lib.buttons.length) { makeButtons(catId, lib); }
|
||||
loadIcons();
|
||||
}
|
||||
const buttons = [{
|
||||
id: 'tool_shapelib',
|
||||
type: 'mode_flyout', // _flyout
|
||||
position: 6,
|
||||
events: {
|
||||
click () {
|
||||
canv.setMode(modeId);
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
return {
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'ext-shapes.xml',
|
||||
buttons: [{
|
||||
id: 'tool_shapelib',
|
||||
type: 'mode_flyout', // _flyout
|
||||
position: 6,
|
||||
title: 'Shape library',
|
||||
events: {
|
||||
click () {
|
||||
canv.setMode(modeId);
|
||||
}
|
||||
}
|
||||
}],
|
||||
buttons: strings.buttons.map((button, i) => {
|
||||
return Object.assign(buttons[i], button);
|
||||
}),
|
||||
callback () {
|
||||
$('<style>').text(
|
||||
'#shape_buttons {' +
|
||||
@@ -236,6 +226,12 @@ export default {
|
||||
'margin-top': -(h / 2 - 15),
|
||||
'margin-left': 3
|
||||
});
|
||||
// Now add shape categories from locale
|
||||
const cats = {};
|
||||
for (const o in categories) {
|
||||
cats['#shape_cats [data-cat="' + o + '"]'] = categories[o];
|
||||
}
|
||||
this.setStrings('content', cats);
|
||||
},
|
||||
mouseDown (opts) {
|
||||
const mode = canv.getMode();
|
||||
@@ -250,7 +246,7 @@ export default {
|
||||
startClientPos.x = opts.event.clientX;
|
||||
startClientPos.y = opts.event.clientY;
|
||||
|
||||
curShape = canv.addSvgElementFromJson({
|
||||
curShape = canv.addSVGElementFromJson({
|
||||
element: 'path',
|
||||
curStyles: true,
|
||||
attr: {
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-star.js
|
||||
*
|
||||
*
|
||||
* Copyright(c) 2010 CloudCanvas, Inc.
|
||||
* All rights reserved
|
||||
* @copyright 2010 CloudCanvas, Inc. All rights reserved
|
||||
*
|
||||
*/
|
||||
export default {
|
||||
name: 'star',
|
||||
init (S) {
|
||||
async init (S) {
|
||||
const svgEditor = this;
|
||||
const $ = jQuery;
|
||||
const svgCanvas = svgEditor.canvas;
|
||||
|
||||
let // {svgcontent} = S,
|
||||
const {importLocale} = S; // {svgcontent},
|
||||
let
|
||||
selElems,
|
||||
// editingitex = false,
|
||||
// svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||
@@ -24,7 +24,7 @@ export default {
|
||||
// newFOG, newFOGParent, newDef, newImageName, newMaskID,
|
||||
// undoCommand = 'Not image',
|
||||
// modeChangeG, ccZoom, wEl, hEl, wOffset, hOffset, ccRgbEl, brushW, brushH;
|
||||
|
||||
const strings = await importLocale();
|
||||
function showPanel (on) {
|
||||
let fcRules = $('#fc_rules');
|
||||
if (!fcRules.length) {
|
||||
@@ -54,58 +54,56 @@ export default {
|
||||
return 1 / Math.cos(n);
|
||||
}
|
||||
*/
|
||||
const buttons = [{
|
||||
id: 'tool_star',
|
||||
type: 'mode',
|
||||
position: 12,
|
||||
events: {
|
||||
click () {
|
||||
showPanel(true);
|
||||
svgCanvas.setMode('star');
|
||||
}
|
||||
}
|
||||
}];
|
||||
const contextTools = [{
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
id: 'starNumPoints',
|
||||
size: 3,
|
||||
defval: 5,
|
||||
events: {
|
||||
change () {
|
||||
setAttr('point', this.value);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
id: 'starRadiusMulitplier',
|
||||
size: 3,
|
||||
defval: 2.5
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
id: 'radialShift',
|
||||
size: 3,
|
||||
defval: 0,
|
||||
events: {
|
||||
change () {
|
||||
setAttr('radialshift', this.value);
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
return {
|
||||
name: 'star',
|
||||
name: strings.name,
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'star-icons.svg',
|
||||
buttons: [{
|
||||
id: 'tool_star',
|
||||
type: 'mode',
|
||||
title: 'Star Tool',
|
||||
position: 12,
|
||||
events: {
|
||||
click () {
|
||||
showPanel(true);
|
||||
svgCanvas.setMode('star');
|
||||
}
|
||||
}
|
||||
}],
|
||||
|
||||
context_tools: [{
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
title: 'Number of Sides',
|
||||
id: 'starNumPoints',
|
||||
label: 'points',
|
||||
size: 3,
|
||||
defval: 5,
|
||||
events: {
|
||||
change () {
|
||||
setAttr('point', this.value);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
title: 'Pointiness',
|
||||
id: 'starRadiusMulitplier',
|
||||
label: 'Pointiness',
|
||||
size: 3,
|
||||
defval: 2.5
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'star_panel',
|
||||
title: 'Twists the star',
|
||||
id: 'radialShift',
|
||||
label: 'Radial Shift',
|
||||
size: 3,
|
||||
defval: 0,
|
||||
events: {
|
||||
change () {
|
||||
setAttr('radialshift', this.value);
|
||||
}
|
||||
}
|
||||
}],
|
||||
buttons: strings.buttons.map((button, i) => {
|
||||
return Object.assign(buttons[i], button);
|
||||
}),
|
||||
context_tools: strings.contextTools.map((contextTool, i) => {
|
||||
return Object.assign(contextTools[i], contextTool);
|
||||
}),
|
||||
callback () {
|
||||
$('#star_panel').hide();
|
||||
// const endChanges = function(){};
|
||||
@@ -120,7 +118,7 @@ export default {
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
started = true;
|
||||
|
||||
newFO = S.addSvgElementFromJson({
|
||||
newFO = S.addSVGElementFromJson({
|
||||
element: 'polygon',
|
||||
attr: {
|
||||
cx: opts.start_x,
|
||||
|
||||
@@ -1,36 +1,26 @@
|
||||
/* globals jQuery */
|
||||
/*
|
||||
/**
|
||||
* ext-storage.js
|
||||
*
|
||||
* Licensed under the MIT License
|
||||
* This extension allows automatic saving of the SVG canvas contents upon
|
||||
* page unload (which can later be automatically retrieved upon future
|
||||
* editor loads).
|
||||
*
|
||||
* Copyright(c) 2010 Brett Zamir
|
||||
* The functionality was originally part of the SVG Editor, but moved to a
|
||||
* separate extension to make the setting behavior optional, and adapted
|
||||
* to inform the user of its setting of local data.
|
||||
* Dependencies:
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* This extension allows automatic saving of the SVG canvas contents upon
|
||||
* page unload (which can later be automatically retrieved upon future
|
||||
* editor loads).
|
||||
*
|
||||
* The functionality was originally part of the SVG Editor, but moved to a
|
||||
* separate extension to make the setting behavior optional, and adapted
|
||||
* to inform the user of its setting of local data.
|
||||
* 1. jQuery BBQ (for deparam)
|
||||
* @license MIT
|
||||
*
|
||||
* @copyright 2010 Brett Zamir
|
||||
* @todo Revisit on whether to use $.pref over directly setting curConfig in all
|
||||
* extensions for a more public API (not only for extPath and imagePath,
|
||||
* but other currently used config in the extensions)
|
||||
* @todo We might provide control of storage settings through the UI besides the
|
||||
* initial (or URL-forced) dialog. *
|
||||
*/
|
||||
/*
|
||||
Dependencies:
|
||||
|
||||
1. jQuery BBQ (for deparam)
|
||||
*/
|
||||
/*
|
||||
TODOS
|
||||
1. Revisit on whether to use $.pref over directly setting curConfig in all
|
||||
extensions for a more public API (not only for extPath and imagePath,
|
||||
but other currently used config in the extensions)
|
||||
2. We might provide control of storage settings through the UI besides the
|
||||
initial (or URL-forced) dialog.
|
||||
*/
|
||||
import {importSetGlobalDefault} from '../external/dynamic-import-polyfill/importModule.js';
|
||||
|
||||
export default {
|
||||
name: 'storage',
|
||||
init () {
|
||||
@@ -151,23 +141,10 @@ export default {
|
||||
let loaded = false;
|
||||
return {
|
||||
name: 'storage',
|
||||
async langReady ({lang}) {
|
||||
async langReady ({importLocale}) {
|
||||
const {storagePrompt} = $.deparam.querystring(true);
|
||||
|
||||
let confirmSetStorage;
|
||||
async function tryImport (lang) {
|
||||
const url = `${svgEditor.curConfig.extPath}ext-locale/storage/${lang}.js`;
|
||||
confirmSetStorage = await importSetGlobalDefault(url, {
|
||||
global: 'svgEditorExtensionLocale_storage_' + lang
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await tryImport(lang);
|
||||
} catch (err) {
|
||||
await tryImport('en');
|
||||
}
|
||||
|
||||
const confirmSetStorage = await importLocale();
|
||||
const {
|
||||
message, storagePrefsAndContent, storagePrefsOnly,
|
||||
storagePrefs, storageNoPrefsOrContent, storageNoPrefs,
|
||||
|
||||
@@ -1,71 +1,104 @@
|
||||
/*
|
||||
Depends on Firefox add-on and executables from https://github.com/brettz9/webappfind
|
||||
|
||||
Todos:
|
||||
1. See WebAppFind Readme for SVG-related todos
|
||||
/**
|
||||
* Depends on Firefox add-on and executables from {@link https://github.com/brettz9/webappfind}
|
||||
* @author Brett Zamir
|
||||
* @license MIT
|
||||
* @todo See WebAppFind Readme for SVG-related todos
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'WebAppFind',
|
||||
init () {
|
||||
name: 'webappfind',
|
||||
async init ({importLocale}) {
|
||||
const strings = await importLocale();
|
||||
const svgEditor = this;
|
||||
// Todo: Update to new API once released
|
||||
window.addEventListener('message', function (e) {
|
||||
if (e.origin !== window.location.origin || // PRIVACY AND SECURITY! (for viewing and saving, respectively)
|
||||
(!Array.isArray(e.data) || excludedMessages.includes(e.data[0])) // Validate format and avoid our post below
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const messageType = e.data[0];
|
||||
let svgString;
|
||||
switch (messageType) {
|
||||
case 'webapp-view':
|
||||
// Populate the contents
|
||||
pathID = e.data[1];
|
||||
|
||||
svgString = e.data[2];
|
||||
svgEditor.loadFromString(svgString);
|
||||
|
||||
/* if ($('#tool_save_file')) {
|
||||
$('#tool_save_file').disabled = false;
|
||||
} */
|
||||
break;
|
||||
case 'webapp-save-end':
|
||||
alert('save complete for pathID ' + e.data[1] + '!');
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unexpected mode');
|
||||
}
|
||||
}, false);
|
||||
const saveMessage = 'webapp-save',
|
||||
readMessage = 'webapp-read',
|
||||
const saveMessage = 'save',
|
||||
readMessage = 'read',
|
||||
excludedMessages = [readMessage, saveMessage];
|
||||
let pathID;
|
||||
|
||||
window.postMessage(
|
||||
[readMessage],
|
||||
window.location.origin !== 'null'
|
||||
? window.location.origin
|
||||
: '*'
|
||||
); // Avoid "null" string error for file: protocol (even though file protocol not currently supported by add-on)
|
||||
let pathID;
|
||||
this.canvas.bind(
|
||||
'message',
|
||||
/**
|
||||
* @param {external:Window} win
|
||||
* @param {module:svgcanvas.SvgCanvas#event:message} data
|
||||
* @listens module:svgcanvas.SvgCanvas#event:message
|
||||
* @throws {Error} Unexpected event type
|
||||
* @returns {undefined}
|
||||
*/
|
||||
(win, {data, origin}) => {
|
||||
// console.log('data, origin', data, origin);
|
||||
let type, content;
|
||||
try {
|
||||
({type, pathID, content} = data.webappfind); // May throw if data is not an object
|
||||
if (origin !== location.origin || // We are only interested in a message sent as though within this URL by our browser add-on
|
||||
excludedMessages.includes(type) // Avoid our post below (other messages might be possible in the future which may also need to be excluded if your subsequent code makes assumptions on the type of message this is)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'view':
|
||||
// Populate the contents
|
||||
svgEditor.loadFromString(content);
|
||||
|
||||
/* if ($('#tool_save_file')) {
|
||||
$('#tool_save_file').disabled = false;
|
||||
} */
|
||||
break;
|
||||
case 'save-end':
|
||||
alert(`save complete for pathID ${pathID}!`);
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unexpected WebAppFind event type');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/*
|
||||
window.postMessage({
|
||||
webappfind: {
|
||||
type: readMessage
|
||||
}
|
||||
}, window.location.origin === 'null'
|
||||
// Avoid "null" string error for `file:` protocol (even though
|
||||
// file protocol not currently supported by Firefox)
|
||||
? '*'
|
||||
: window.location.origin
|
||||
);
|
||||
*/
|
||||
const buttons = [{
|
||||
id: 'webappfind_save', //
|
||||
type: 'app_menu',
|
||||
position: 4, // Before 0-based index position 4 (after the regular "Save Image (S)")
|
||||
events: {
|
||||
click () {
|
||||
if (!pathID) { // Not ready yet as haven't received first payload
|
||||
return;
|
||||
}
|
||||
window.postMessage({
|
||||
webappfind: {
|
||||
type: saveMessage,
|
||||
pathID,
|
||||
content: svgEditor.canvas.getSvgString()
|
||||
}
|
||||
}, window.location.origin === 'null'
|
||||
// Avoid "null" string error for `file:` protocol (even
|
||||
// though file protocol not currently supported by add-on)
|
||||
? '*'
|
||||
: window.location.origin
|
||||
);
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
return {
|
||||
name: 'WebAppFind',
|
||||
name: strings.name,
|
||||
svgicons: svgEditor.curConfig.extIconsPath + 'webappfind-icon.svg',
|
||||
buttons: [{
|
||||
id: 'webappfind_save', //
|
||||
type: 'app_menu',
|
||||
title: 'Save Image back to Disk',
|
||||
position: 4, // Before 0-based index position 4 (after the regular "Save Image (S)")
|
||||
events: {
|
||||
click () {
|
||||
if (!pathID) { // Not ready yet as haven't received first payload
|
||||
return;
|
||||
}
|
||||
window.postMessage([saveMessage, pathID, svgEditor.canvas.getSvgString()], window.location.origin);
|
||||
}
|
||||
}
|
||||
}]
|
||||
buttons: strings.buttons.map((button, i) => {
|
||||
return Object.assign(buttons[i], button);
|
||||
})
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
// The default is not to allow any origins, including even the same domain or if run on a file:// URL
|
||||
// See config-sample.js for an example of how to configure
|
||||
// See svgedit-config-es.js for an example of how to configure
|
||||
const {allowedOrigins} = svgEditor.curConfig;
|
||||
if (!allowedOrigins.includes('*') && !allowedOrigins.includes(e.origin)) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user