Merge branch 'master' of https://github.com/SVG-Edit/svgedit into V7-preview
@@ -8,7 +8,7 @@
|
||||
|
||||
import 'pathseg';
|
||||
|
||||
import {NS} from './namespaces.js';
|
||||
import { NS } from './namespaces.js';
|
||||
|
||||
const supportsSVG_ = (function () {
|
||||
return Boolean(document.createElementNS && document.createElementNS(NS.SVG, 'svg').createSVGRect);
|
||||
@@ -20,7 +20,7 @@ return Boolean(document.createElementNS && document.createElementNS(NS.SVG, 'svg
|
||||
*/
|
||||
export const supportsSvg = () => supportsSVG_;
|
||||
|
||||
const {userAgent} = navigator;
|
||||
const { userAgent } = navigator;
|
||||
const svg = document.createElementNS(NS.SVG, 'svg');
|
||||
|
||||
// Note: Browser sniffing should only be used if no other detection method is possible
|
||||
|
||||
@@ -27,7 +27,7 @@ export const NS = {
|
||||
*/
|
||||
export const getReverseNS = function () {
|
||||
const reverseNS = {};
|
||||
Object.entries(NS).forEach(([name, URI]) => {
|
||||
Object.entries(NS).forEach(([ name, URI ]) => {
|
||||
reverseNS[URI] = name.toLowerCase();
|
||||
});
|
||||
return reverseNS;
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
* @copyright 2010 Alexis Deveria, 2010 Jeff Schiller
|
||||
*/
|
||||
|
||||
import {NS} from './namespaces.js';
|
||||
import { NS } from './namespaces.js';
|
||||
|
||||
const wAttrs = ['x', 'x1', 'cx', 'rx', 'width'];
|
||||
const hAttrs = ['y', 'y1', 'cy', 'ry', 'height'];
|
||||
const unitAttrs = ['r', 'radius', ...wAttrs, ...hAttrs];
|
||||
const wAttrs = [ 'x', 'x1', 'cx', 'rx', 'width' ];
|
||||
const hAttrs = [ 'y', 'y1', 'cy', 'ry', 'height' ];
|
||||
const unitAttrs = [ 'r', 'radius', ...wAttrs, ...hAttrs ];
|
||||
// unused
|
||||
/*
|
||||
const unitNumMap = {
|
||||
@@ -202,14 +202,14 @@ export const setUnitAttr = function (elem, attr, val) {
|
||||
};
|
||||
|
||||
const attrsToConvert = {
|
||||
line: ['x1', 'x2', 'y1', 'y2'],
|
||||
circle: ['cx', 'cy', 'r'],
|
||||
ellipse: ['cx', 'cy', 'rx', 'ry'],
|
||||
foreignObject: ['x', 'y', 'width', 'height'],
|
||||
rect: ['x', 'y', 'width', 'height'],
|
||||
image: ['x', 'y', 'width', 'height'],
|
||||
use: ['x', 'y', 'width', 'height'],
|
||||
text: ['x', 'y']
|
||||
line: [ 'x1', 'x2', 'y1', 'y2' ],
|
||||
circle: [ 'cx', 'cy', 'r' ],
|
||||
ellipse: [ 'cx', 'cy', 'rx', 'ry' ],
|
||||
foreignObject: [ 'x', 'y', 'width', 'height' ],
|
||||
rect: [ 'x', 'y', 'width', 'height' ],
|
||||
image: [ 'x', 'y', 'width', 'height' ],
|
||||
use: [ 'x', 'y', 'width', 'height' ],
|
||||
text: [ 'x', 'y' ]
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// eslint-disable-next-line node/no-unpublished-import
|
||||
import deparam from 'deparam';
|
||||
import {mergeDeep} from './components/jgraduate/Util.js';
|
||||
import { mergeDeep } from './components/jgraduate/Util.js';
|
||||
|
||||
/**
|
||||
* Escapes special characters in a regular expression.
|
||||
@@ -126,7 +126,7 @@ export default class ConfigObj {
|
||||
imgPath: './images/',
|
||||
// DOCUMENT PROPERTIES
|
||||
// Change the following to a preference (already in the Document Properties dialog)?
|
||||
dimensions: [640, 480],
|
||||
dimensions: [ 640, 480 ],
|
||||
// EDITOR OPTIONS
|
||||
// Change the following to preferences (already in the Editor Options dialog)?
|
||||
gridSnapping: false,
|
||||
@@ -170,11 +170,11 @@ export default class ConfigObj {
|
||||
// 'ext-markers',
|
||||
'ext-overview_window',
|
||||
'ext-panning',
|
||||
'ext-polygon',
|
||||
'ext-shapes',
|
||||
'ext-star',
|
||||
'ext-polystar',
|
||||
'ext-storage',
|
||||
'ext-opensave'
|
||||
'ext-opensave',
|
||||
// 'ext-helloworld',
|
||||
];
|
||||
this.curConfig = {
|
||||
// We do not put on defaultConfig to simplify object copying
|
||||
@@ -204,7 +204,7 @@ export default class ConfigObj {
|
||||
* @returns {void}
|
||||
*/
|
||||
setupCurPrefs () {
|
||||
const curPrefs = {...this.defaultPrefs, ...this.curPrefs}; // Now safe to merge with priority for curPrefs in the event any are already set
|
||||
const curPrefs = { ...this.defaultPrefs, ...this.curPrefs }; // Now safe to merge with priority for curPrefs in the event any are already set
|
||||
// Export updated prefs
|
||||
this.curPrefs = curPrefs;
|
||||
}
|
||||
@@ -213,11 +213,11 @@ export default class ConfigObj {
|
||||
* @returns {void}
|
||||
*/
|
||||
setupCurConfig () {
|
||||
const curConfig = {...this.defaultConfig, ...this.curConfig}; // Now safe to merge with priority for curConfig in the event any are already set
|
||||
const curConfig = { ...this.defaultConfig, ...this.curConfig }; // Now safe to merge with priority for curConfig in the event any are already set
|
||||
|
||||
// Now deal with extensions and other array config
|
||||
if (!curConfig.noDefaultExtensions) {
|
||||
curConfig.extensions = [...this.defaultExtensions];
|
||||
curConfig.extensions = [ ...this.defaultExtensions ];
|
||||
}
|
||||
// Export updated config
|
||||
this.curConfig = curConfig;
|
||||
@@ -227,12 +227,12 @@ export default class ConfigObj {
|
||||
* @returns {void}
|
||||
*/
|
||||
loadFromURL () {
|
||||
const {search, searchParams} = new URL(location);
|
||||
const { search, searchParams } = new URL(location);
|
||||
|
||||
if (search) {
|
||||
this.urldata = deparam(searchParams.toString());
|
||||
|
||||
['initStroke', 'initFill'].forEach((prop) => {
|
||||
[ 'initStroke', 'initFill' ].forEach((prop) => {
|
||||
if (searchParams.has(`${prop}[color]`)) {
|
||||
// Restore back to original non-deparamed value to avoid color
|
||||
// strings being converted to numbers
|
||||
@@ -260,7 +260,7 @@ export default class ConfigObj {
|
||||
// security reasons, even for same-domain
|
||||
// ones given potential to interact in undesirable
|
||||
// ways with other script resources
|
||||
['userExtensions', 'imgPath']
|
||||
[ 'userExtensions', 'imgPath' ]
|
||||
.forEach(function (pathConfig) {
|
||||
if (this.urldata[pathConfig]) {
|
||||
delete this.urldata[pathConfig];
|
||||
@@ -269,11 +269,11 @@ export default class ConfigObj {
|
||||
|
||||
// Note: `source` and `url` (as with `storagePrompt` later) are not
|
||||
// set on config but are used below
|
||||
this.setConfig(this.urldata, {overwrite: false});
|
||||
this.setConfig(this.urldata, { overwrite: false });
|
||||
this.setupCurConfig();
|
||||
|
||||
if (!this.curConfig.preventURLContentLoading) {
|
||||
let {source} = this.urldata;
|
||||
let { source } = this.urldata;
|
||||
if (!source) { // urldata.source may have been null if it ended with '='
|
||||
const src = searchParams.get('source');
|
||||
if (src && src.startsWith('data:')) {
|
||||
@@ -396,7 +396,7 @@ export default class ConfigObj {
|
||||
cfgObj[key] = val;
|
||||
}
|
||||
};
|
||||
Object.entries(opts).forEach(([key, val]) => {
|
||||
Object.entries(opts).forEach(([ key, val ]) => {
|
||||
// Only allow prefs defined in configObj.defaultPrefs or...
|
||||
if (this.defaultPrefs[key]) {
|
||||
if (cfgCfg.overwrite === false && (
|
||||
@@ -410,11 +410,11 @@ export default class ConfigObj {
|
||||
} else {
|
||||
this.pref(key, val);
|
||||
}
|
||||
} else if (['extensions', 'userExtensions', 'allowedOrigins'].includes(key)) {
|
||||
} else if ([ 'extensions', 'userExtensions', 'allowedOrigins' ].includes(key)) {
|
||||
if (cfgCfg.overwrite === false &&
|
||||
(
|
||||
this.curConfig.preventAllURLConfig ||
|
||||
['allowedOrigins'].includes(key) ||
|
||||
[ 'allowedOrigins' ].includes(key) ||
|
||||
(key === 'extensions' && this.curConfig.lockExtensions)
|
||||
)
|
||||
) {
|
||||
|
||||
@@ -40,14 +40,6 @@ class Editor extends EditorStartup {
|
||||
constructor() {
|
||||
super();
|
||||
/**
|
||||
* @type {Float}
|
||||
*/
|
||||
this.tool_scale = 1;
|
||||
/**
|
||||
* @type {Integer}
|
||||
*/
|
||||
this.exportWindowCt = 0;
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.langChanged = false;
|
||||
@@ -60,7 +52,6 @@ class Editor extends EditorStartup {
|
||||
* @type {"ignore"|"waiting"|"closed"}
|
||||
*/
|
||||
this.storagePromptState = 'ignore';
|
||||
|
||||
this.svgCanvas = null;
|
||||
this.isReady = false;
|
||||
this.customExportImage = false;
|
||||
@@ -75,44 +66,43 @@ class Editor extends EditorStartup {
|
||||
this.configObj.preferences = false;
|
||||
this.canvMenu = null;
|
||||
// eslint-disable-next-line max-len
|
||||
this.goodLangs = ['ar', 'cs', 'de', 'en', 'es', 'fa', 'fr', 'fy', 'hi', 'it', 'ja', 'nl', 'pl', 'pt-BR', 'ro', 'ru', 'sk', 'sl', 'zh-CN', 'zh-TW'];
|
||||
this.goodLangs = [ 'ar', 'cs', 'de', 'en', 'es', 'fa', 'fr', 'fy', 'hi', 'it', 'ja', 'nl', 'pl', 'pt-BR', 'ro', 'ru', 'sk', 'sl', 'zh-CN', 'zh-TW' ];
|
||||
const modKey = (isMac() ? 'meta+' : 'ctrl+');
|
||||
const curObj = this;
|
||||
this.toolButtons = [
|
||||
this.shortcuts = [
|
||||
// Shortcuts not associated with buttons
|
||||
{ key: 'ctrl+arrowleft', fn() { curObj.rotateSelected(0, 1); } },
|
||||
{ key: 'ctrl+arrowright', fn() { curObj.rotateSelected(1, 1); } },
|
||||
{ key: 'ctrl+shift+arrowleft', fn() { curObj.rotateSelected(0, 5); } },
|
||||
{ key: 'ctrl+shift+arrowright', fn() { curObj.rotateSelected(1, 5); } },
|
||||
{ key: 'shift+o', fn() { curObj.svgCanvas.cycleElement(0); } },
|
||||
{ key: 'shift+p', fn() { curObj.svgCanvas.cycleElement(1); } },
|
||||
{ key: 'tab', fn() { curObj.svgCanvas.cycleElement(0); } },
|
||||
{ key: 'shift+tab', fn() { curObj.svgCanvas.cycleElement(1); } },
|
||||
{ key: [modKey + 'arrowup', true], fn() { curObj.zoomImage(2); } },
|
||||
{ key: [modKey + 'arrowdown', true], fn() { curObj.zoomImage(0.5); } },
|
||||
{ key: [modKey + ']', true], fn() { curObj.moveUpDownSelected('Up'); } },
|
||||
{ key: [modKey + '[', true], fn() { curObj.moveUpDownSelected('Down'); } },
|
||||
{ key: ['arrowup', true], fn() { curObj.moveSelected(0, -1); } },
|
||||
{ key: ['arrowdown', true], fn() { curObj.moveSelected(0, 1); } },
|
||||
{ key: ['arrowleft', true], fn() { curObj.moveSelected(-1, 0); } },
|
||||
{ key: ['arrowright', true], fn() { curObj.moveSelected(1, 0); } },
|
||||
{ key: 'shift+arrowup', fn() { curObj.moveSelected(0, -10); } },
|
||||
{ key: 'shift+arrowdown', fn() { curObj.moveSelected(0, 10); } },
|
||||
{ key: 'shift+arrowleft', fn() { curObj.moveSelected(-10, 0); } },
|
||||
{ key: 'shift+arrowright', fn() { curObj.moveSelected(10, 0); } },
|
||||
{ key: ['alt+arrowup', true], fn() { curObj.svgCanvas.cloneSelectedElements(0, -1); } },
|
||||
{ key: ['alt+arrowdown', true], fn() { curObj.svgCanvas.cloneSelectedElements(0, 1); } },
|
||||
{ key: ['alt+arrowleft', true], fn() { curObj.svgCanvas.cloneSelectedElements(-1, 0); } },
|
||||
{ key: ['alt+arrowright', true], fn() { curObj.svgCanvas.cloneSelectedElements(1, 0); } },
|
||||
{ key: ['alt+shift+arrowup', true], fn() { curObj.svgCanvas.cloneSelectedElements(0, -10); } },
|
||||
{ key: ['alt+shift+arrowdown', true], fn() { curObj.svgCanvas.cloneSelectedElements(0, 10); } },
|
||||
{ key: ['alt+shift+arrowleft', true], fn() { curObj.svgCanvas.cloneSelectedElements(-10, 0); } },
|
||||
{ key: ['alt+shift+arrowright', true], fn() { curObj.svgCanvas.cloneSelectedElements(10, 0); } },
|
||||
{ key: 'a', fn() { curObj.svgCanvas.selectAllInCurrentLayer(); } },
|
||||
{ key: modKey + 'a', fn() { curObj.svgCanvas.selectAllInCurrentLayer(); } },
|
||||
{ key: modKey + 'x', fn() { curObj.cutSelected(); } },
|
||||
{ key: modKey + 'c', fn() { curObj.copySelected(); } },
|
||||
{ key: modKey + 'v', fn() { curObj.pasteInCenter(); } }
|
||||
{ key: 'ctrl+arrowleft', fn: () => { this.rotateSelected(0, 1); } },
|
||||
{ key: 'ctrl+arrowright', fn: () => { this.rotateSelected(1, 1); } },
|
||||
{ key: 'ctrl+shift+arrowleft', fn: () => { this.rotateSelected(0, 5); } },
|
||||
{ key: 'ctrl+shift+arrowright', fn: () => { this.rotateSelected(1, 5); } },
|
||||
{ key: 'shift+o', fn: () => { this.svgCanvas.cycleElement(0); } },
|
||||
{ key: 'shift+p', fn: () => { this.svgCanvas.cycleElement(1); } },
|
||||
{ key: 'tab', fn: () => { this.svgCanvas.cycleElement(0); } },
|
||||
{ key: 'shift+tab', fn: () => { this.svgCanvas.cycleElement(1); } },
|
||||
{ key: [ modKey + 'arrowup', true ], fn: () => { this.zoomImage(2); } },
|
||||
{ key: [ modKey + 'arrowdown', true ], fn: () => { this.zoomImage(0.5); } },
|
||||
{ key: [ modKey + ']', true ], fn: () => { this.moveUpDownSelected('Up'); } },
|
||||
{ key: [ modKey + '[', true ], fn: () => { this.moveUpDownSelected('Down'); } },
|
||||
{ key: [ 'arrowup', true ], fn: () => { this.moveSelected(0, -1); } },
|
||||
{ key: [ 'arrowdown', true ], fn: () => { this.moveSelected(0, 1); } },
|
||||
{ key: [ 'arrowleft', true ], fn: () => { this.moveSelected(-1, 0); } },
|
||||
{ key: [ 'arrowright', true ], fn: () => { this.moveSelected(1, 0); } },
|
||||
{ key: 'shift+arrowup', fn: () => { this.moveSelected(0, -10); } },
|
||||
{ key: 'shift+arrowdown', fn: () => { this.moveSelected(0, 10); } },
|
||||
{ key: 'shift+arrowleft', fn: () => { this.moveSelected(-10, 0); } },
|
||||
{ key: 'shift+arrowright', fn: () => { this.moveSelected(10, 0); } },
|
||||
{ key: [ 'alt+arrowup', true ], fn: () => { this.svgCanvas.cloneSelectedElements(0, -1); } },
|
||||
{ key: [ 'alt+arrowdown', true ], fn: () => { this.svgCanvas.cloneSelectedElements(0, 1); } },
|
||||
{ key: [ 'alt+arrowleft', true ], fn: () => { this.svgCanvas.cloneSelectedElements(-1, 0); } },
|
||||
{ key: [ 'alt+arrowright', true ], fn: () => { this.svgCanvas.cloneSelectedElements(1, 0); } },
|
||||
{ key: [ 'alt+shift+arrowup', true ], fn: () => { this.svgCanvas.cloneSelectedElements(0, -10); } },
|
||||
{ key: [ 'alt+shift+arrowdown', true ], fn: () => { this.svgCanvas.cloneSelectedElements(0, 10); } },
|
||||
{ key: [ 'alt+shift+arrowleft', true ], fn: () => { this.svgCanvas.cloneSelectedElements(-10, 0); } },
|
||||
{ key: [ 'alt+shift+arrowright', true ], fn: () => { this.svgCanvas.cloneSelectedElements(10, 0); } },
|
||||
{ key: 'a', fn: () => { this.svgCanvas.selectAllInCurrentLayer(); } },
|
||||
{ key: modKey + 'a', fn: () => { this.svgCanvas.selectAllInCurrentLayer(); } },
|
||||
{ key: modKey + 'x', fn: () => { this.cutSelected(); } },
|
||||
{ key: modKey + 'c', fn: () => { this.copySelected(); } },
|
||||
{ key: modKey + 'v', fn: () => { this.pasteInCenter(); } }
|
||||
];
|
||||
this.leftPanel = new LeftPanel(this);
|
||||
this.bottomPanel = new BottomPanel(this);
|
||||
@@ -228,18 +218,18 @@ class Editor extends EditorStartup {
|
||||
setAll() {
|
||||
const keyHandler = {}; // will contain the action for each pressed key
|
||||
|
||||
this.toolButtons.forEach((opts) => {
|
||||
this.shortcuts.forEach((shortcut) => {
|
||||
// Bind function to shortcut key
|
||||
if (opts.key) {
|
||||
if (shortcut.key) {
|
||||
// Set shortcut based on options
|
||||
let keyval = opts.key;
|
||||
let keyval = shortcut.key;
|
||||
let pd = false;
|
||||
if (Array.isArray(opts.key)) {
|
||||
keyval = opts.key[0];
|
||||
if (opts.key.length > 1) { pd = opts.key[1]; }
|
||||
if (Array.isArray(shortcut.key)) {
|
||||
keyval = shortcut.key[0];
|
||||
if (shortcut.key.length > 1) { pd = shortcut.key[1]; }
|
||||
}
|
||||
keyval = String(keyval);
|
||||
const { fn } = opts;
|
||||
const { fn } = shortcut;
|
||||
keyval.split('/').forEach((key) => { keyHandler[key] = { fn, pd }; });
|
||||
}
|
||||
return true;
|
||||
@@ -303,8 +293,8 @@ class Editor extends EditorStartup {
|
||||
'4/Shift+4': 'tools_rect',
|
||||
'5/Shift+5': 'tools_ellipse'
|
||||
};
|
||||
Object.entries(keyAssocs).forEach(([keyval, sel]) => {
|
||||
const parentsElements = this.getParents($id(sel), $id('main_menu'))
|
||||
Object.entries(keyAssocs).forEach(([ keyval, sel ]) => {
|
||||
const parentsElements = this.getParents($id(sel), $id('main_menu'));
|
||||
const menu = (parentsElements.length);
|
||||
|
||||
$qa(sel).forEach((element) => {
|
||||
@@ -318,7 +308,7 @@ class Editor extends EditorStartup {
|
||||
mod = modBits[0] + '+';
|
||||
key = modBits[1];
|
||||
}
|
||||
keyStr += (i ? '/' : '') + mod + (this.uiStrings['key_' + key] || key);
|
||||
keyStr += (i ? '/' : '') + mod + (this.i18next.t('key_' + key) || key);
|
||||
});
|
||||
if (menu) {
|
||||
this.lastChild.textContent = t + ' [' + keyStr + ']';
|
||||
@@ -333,20 +323,11 @@ class Editor extends EditorStartup {
|
||||
* @returns {module:SVGthis.ToolButton}
|
||||
*/
|
||||
getButtonData(sel) {
|
||||
return Object.values(this.toolButtons).find((btn) => {
|
||||
return Object.values(this.shortcuts).find((btn) => {
|
||||
return btn.sel === sel;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose the `uiStrings`.
|
||||
* @function module:SVGthis.canvas.getUIStrings
|
||||
* @returns {module:SVGthis.uiStrings}
|
||||
*/
|
||||
getUIStrings() {
|
||||
return this.uiStrings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} editmode
|
||||
* @param {module:svgcanvas.SvgCanvas#event:selected} elems
|
||||
@@ -359,9 +340,9 @@ class Editor extends EditorStartup {
|
||||
const elements = document.getElementsByClassName("tool_button_current");
|
||||
Array.from(elements).forEach(function (element) {
|
||||
element.classList.add('tool_button_current');
|
||||
element.classList.remove('tool_button')
|
||||
element.classList.remove('tool_button');
|
||||
});
|
||||
$id('tool_select').classList.add('tool_button_current')
|
||||
$id('tool_select').classList.add('tool_button_current');
|
||||
$id('tool_select').classList.remove('tool_button');
|
||||
this.multiselected = false;
|
||||
if (elems.length) {
|
||||
@@ -386,19 +367,19 @@ class Editor extends EditorStartup {
|
||||
this.exportWindow = window.open(blankPageObjectURL || '', exportWindowName); // A hack to get the window via JSON-able name without opening a new one
|
||||
|
||||
if (!this.exportWindow || this.exportWindow.closed) {
|
||||
seAlert(this.uiStrings.notification.popupWindowBlocked);
|
||||
seAlert(this.i18next.t('notification.popupWindowBlocked'));
|
||||
return;
|
||||
}
|
||||
|
||||
this.exportWindow.location.href = data.bloburl || data.datauri;
|
||||
const done = this.configObj.pref('export_notice_done');
|
||||
if (done !== 'all') {
|
||||
let note = this.i18next.t('notification.saveFromBrowser', { type: data.type});
|
||||
let note = this.i18next.t('notification.saveFromBrowser', { type: data.type });
|
||||
|
||||
// Check if there are issues
|
||||
if (issues.length) {
|
||||
const pre = '\n \u2022 ';
|
||||
note += ('\n\n' + this.uiStrings.notification.noteTheseIssues + pre + issues.join(pre));
|
||||
note += ('\n\n' + this.i18next.t('notification..noteTheseIssues') + pre + issues.join(pre));
|
||||
}
|
||||
|
||||
// Note that this will also prevent the notice even though new issues may appear later.
|
||||
@@ -784,7 +765,7 @@ class Editor extends EditorStartup {
|
||||
const icon = (typeof iconId === 'string') ? img : iconId.cloneNode(true);
|
||||
if (!icon) {
|
||||
// Todo: Investigate why this still occurs in some cases
|
||||
console.log('NOTE: Icon image missing: ' + iconId);
|
||||
console.warn('NOTE: Icon image missing: ' + iconId);
|
||||
return;
|
||||
}
|
||||
// empty()
|
||||
@@ -950,7 +931,7 @@ class Editor extends EditorStartup {
|
||||
};
|
||||
|
||||
if (!this.svgCanvas.setSvgString(e.detail.value)) {
|
||||
const ok = await seConfirm(this.uiStrings.notification.QerrorsRevertToSource);
|
||||
const ok = await seConfirm(this.i18next.t('notification.QerrorsRevertToSource'));
|
||||
if (ok === false || ok === 'Cancel') {
|
||||
return;
|
||||
}
|
||||
@@ -979,7 +960,7 @@ class Editor extends EditorStartup {
|
||||
if (editingsource) {
|
||||
const origSource = this.svgCanvas.getSvgString();
|
||||
if (origSource !== e.detail.value) {
|
||||
const ok = seConfirm(this.uiStrings.notification.QignoreSourceChanges);
|
||||
const ok = seConfirm(this.i18next.t('notification.QignoreSourceChanges'));
|
||||
if (ok) {
|
||||
this.hideSourceEditor();
|
||||
}
|
||||
@@ -1009,7 +990,7 @@ class Editor extends EditorStartup {
|
||||
if (this.svgCanvas.undoMgr.getUndoStackSize() === 0) {
|
||||
return true;
|
||||
}
|
||||
return await seConfirm(this.uiStrings.notification.QwantToOpen);
|
||||
return await seConfirm(this.i18next.t('notification.QwantToOpen'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1061,13 +1042,12 @@ class Editor extends EditorStartup {
|
||||
const $editDialog = document.getElementById('se-edit-prefs');
|
||||
$editDialog.setAttribute('lang', lang);
|
||||
const oldLayerName = ($id('#layerlist')) ? $id('#layerlist').querySelector('tr.layersel td.layername').textContent : "";
|
||||
const renameLayer = (oldLayerName === this.uiStrings.common.layer + ' 1');
|
||||
const renameLayer = (oldLayerName === this.i18next.t('notification.common.layer') + ' 1');
|
||||
|
||||
// this.svgCanvas.setUiStrings(allStrings);
|
||||
this.setTitles();
|
||||
|
||||
if (renameLayer) {
|
||||
this.svgCanvas.renameCurrentLayer(this.uiStrings.common.layer + ' 1');
|
||||
this.svgCanvas.renameCurrentLayer(this.i18next.t('notification.common.layer') + ' 1');
|
||||
this.layersPanel.populateLayers();
|
||||
}
|
||||
|
||||
@@ -1092,7 +1072,7 @@ class Editor extends EditorStartup {
|
||||
resolve(cb());
|
||||
return;
|
||||
}
|
||||
this.callbacks.push([cb, resolve, reject]);
|
||||
this.callbacks.push([ cb, resolve, reject ]);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1103,16 +1083,16 @@ class Editor extends EditorStartup {
|
||||
*/
|
||||
async runCallbacks() {
|
||||
try {
|
||||
await Promise.all(this.callbacks.map(([cb]) => {
|
||||
await Promise.all(this.callbacks.map(([ cb ]) => {
|
||||
return cb();
|
||||
}));
|
||||
} catch (err) {
|
||||
this.callbacks.forEach(([, , reject]) => {
|
||||
this.callbacks.forEach(([ , , reject ]) => {
|
||||
reject();
|
||||
});
|
||||
throw err;
|
||||
}
|
||||
this.callbacks.forEach(([, resolve]) => {
|
||||
this.callbacks.forEach(([ , resolve ]) => {
|
||||
resolve();
|
||||
});
|
||||
this.isReady = true;
|
||||
@@ -1160,7 +1140,7 @@ class Editor extends EditorStartup {
|
||||
dataType: 'text',
|
||||
cache: Boolean(cache),
|
||||
beforeSend() {
|
||||
$.process_cancel(this.uiStrings.notification.loadingImage);
|
||||
$.process_cancel(this.i18next.t('notification.loadingImage'));
|
||||
},
|
||||
success(str) {
|
||||
this.loadSvgString(str, { noAlert });
|
||||
@@ -1174,7 +1154,7 @@ class Editor extends EditorStartup {
|
||||
reject(new Error('URLLoadFail'));
|
||||
return;
|
||||
}
|
||||
seAlert(this.uiStrings.notification.URLLoadFail + ': \n' + err);
|
||||
seAlert(this.i18next.t('notification.URLLoadFail') + ': \n' + err);
|
||||
resolve();
|
||||
},
|
||||
complete() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* globals $ seConfirm seAlert */
|
||||
import './touch.js';
|
||||
import {convertUnit} from '../common/units.js';
|
||||
import { convertUnit } from '../common/units.js';
|
||||
import {
|
||||
putLocale
|
||||
} from './locale.js';
|
||||
@@ -41,7 +41,7 @@ const readySignal = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const {$id} = SvgCanvas;
|
||||
const { $id } = SvgCanvas;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -53,7 +53,7 @@ class EditorStartup {
|
||||
constructor () {
|
||||
this.extensionsAdded = false;
|
||||
this.messageQueue = [];
|
||||
this.$svgEditor = $id('svg_editor')
|
||||
this.$svgEditor = $id('svg_editor');
|
||||
}
|
||||
/**
|
||||
* Auto-run after a Promise microtask.
|
||||
@@ -61,6 +61,10 @@ class EditorStartup {
|
||||
* @returns {void}
|
||||
*/
|
||||
async init () {
|
||||
if ('localStorage' in window) { // && onWeb removed so Webkit works locally
|
||||
this.storage = window.localStorage;
|
||||
}
|
||||
this.configObj.load();
|
||||
const self = this;
|
||||
const { i18next } = await putLocale(this.configObj.pref('lang'), this.goodLangs);
|
||||
this.i18next = i18next;
|
||||
@@ -97,12 +101,6 @@ class EditorStartup {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
if ('localStorage' in window) { // && onWeb removed so Webkit works locally
|
||||
this.storage = window.localStorage;
|
||||
}
|
||||
|
||||
this.configObj.load();
|
||||
|
||||
/**
|
||||
* @name module:SVGthis.canvas
|
||||
* @type {module:svgcanvas.SvgCanvas}
|
||||
@@ -118,7 +116,7 @@ class EditorStartup {
|
||||
this.layersPanel.init();
|
||||
this.mainMenu.init();
|
||||
|
||||
const {undoMgr} = this.svgCanvas;
|
||||
const { undoMgr } = this.svgCanvas;
|
||||
this.workarea = document.getElementById('workarea');
|
||||
this.canvMenu = document.getElementById('se-cmenu_canvas');
|
||||
this.exportWindow = null;
|
||||
@@ -136,7 +134,7 @@ class EditorStartup {
|
||||
this.selectedElement = null;
|
||||
this.multiselected = false;
|
||||
|
||||
const aLinks = $id('cur_context_panel').querySelectorAll('a')
|
||||
const aLinks = $id('cur_context_panel').querySelectorAll('a');
|
||||
|
||||
for (const aLink of aLinks) {
|
||||
aLink.addEventListener('click', (evt) => {
|
||||
@@ -160,12 +158,12 @@ class EditorStartup {
|
||||
if (!data.output) { // Ignore Chrome
|
||||
return;
|
||||
}
|
||||
const {exportWindowName} = data;
|
||||
const { exportWindowName } = data;
|
||||
if (exportWindowName) {
|
||||
this.exportWindow = window.open('', this.exportWindowName); // A hack to get the window via JSON-able name without opening a new one
|
||||
}
|
||||
if (!this.exportWindow || this.exportWindow.closed) {
|
||||
seAlert(this.uiStrings.notification.popupWindowBlocked);
|
||||
seAlert(this.i18next.t('notification.popupWindowBlocked'));
|
||||
return;
|
||||
}
|
||||
this.exportWindow.location.href = data.output;
|
||||
@@ -182,7 +180,7 @@ class EditorStartup {
|
||||
* @listens module:svgcanvas.SvgCanvas#event:updateCanvas
|
||||
* @returns {void}
|
||||
*/
|
||||
function (win, {center, newCtr}) {
|
||||
function (win, { center, newCtr }) {
|
||||
this.updateCanvas(center, newCtr);
|
||||
}.bind(this)
|
||||
);
|
||||
@@ -216,7 +214,7 @@ class EditorStartup {
|
||||
let promptMoveLayerOnce = false;
|
||||
$id('selLayerNames').addEventListener('change', function(evt) {
|
||||
const destLayer = evt.currentTarget.options[evt.currentTarget.selectedIndex].value;
|
||||
const confirmStr = self.uiStrings.notification.QmoveElemsToLayer.replace('%s', destLayer);
|
||||
const confirmStr = self.i18next.t('notification.QmoveElemsToLayer').replace('%s', destLayer);
|
||||
/**
|
||||
* @param {boolean} ok
|
||||
* @returns {void}
|
||||
@@ -279,7 +277,7 @@ class EditorStartup {
|
||||
let lastX = null, lastY = null,
|
||||
panning = false, keypan = false;
|
||||
|
||||
$id('svgcanvas').addEventListener('mouseup', function(evt) {
|
||||
$id('svgcanvas').addEventListener('mouseup', function(evt) {
|
||||
if (panning === false) { return true; }
|
||||
|
||||
wArea.scrollLeft -= (evt.clientX - lastX);
|
||||
@@ -290,9 +288,9 @@ class EditorStartup {
|
||||
|
||||
if (evt.type === 'mouseup') { panning = false; }
|
||||
return false;
|
||||
});
|
||||
});
|
||||
// eslint-disable-next-line sonarjs/no-identical-functions
|
||||
$id('svgcanvas').addEventListener('mousemove', function(evt) {
|
||||
$id('svgcanvas').addEventListener('mousemove', function(evt) {
|
||||
if (panning === false) { return true; }
|
||||
|
||||
wArea.scrollLeft -= (evt.clientX - lastX);
|
||||
@@ -322,10 +320,10 @@ class EditorStartup {
|
||||
if (e.target.nodeName !== 'BODY') return;
|
||||
if(e.code.toLowerCase() === 'space'){
|
||||
this.svgCanvas.spaceKey = keypan = true;
|
||||
e.preventDefault();
|
||||
e.preventDefault();
|
||||
} else if((e.key.toLowerCase() === 'shift') && (this.svgCanvas.getMode() === 'zoom')){
|
||||
this.workarea.style.cursor = zoomOutIcon;
|
||||
e.preventDefault();
|
||||
e.preventDefault();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@@ -335,10 +333,10 @@ class EditorStartup {
|
||||
if (e.target.nodeName !== 'BODY') return;
|
||||
if(e.code.toLowerCase() === 'space'){
|
||||
this.svgCanvas.spaceKey = keypan = false;
|
||||
e.preventDefault();
|
||||
e.preventDefault();
|
||||
} else if((e.key.toLowerCase() === 'shift') && (this.svgCanvas.getMode() === 'zoom')){
|
||||
this.workarea.style.cursor = zoomInIcon;
|
||||
e.preventDefault();
|
||||
e.preventDefault();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@@ -367,7 +365,7 @@ class EditorStartup {
|
||||
el.addEventListener("focus", (e) => {
|
||||
inp = e.currentTarget;
|
||||
this.uiContext = 'toolbars';
|
||||
this.workarea.addEventListener('mousedown', unfocus);
|
||||
this.workarea.addEventListener('mousedown', unfocus);
|
||||
});
|
||||
el.addEventListener("blur", () => {
|
||||
this.uiContext = 'canvas';
|
||||
@@ -399,12 +397,12 @@ class EditorStartup {
|
||||
);
|
||||
}
|
||||
const winWh = {
|
||||
width: getWidth(),
|
||||
width: getWidth(),
|
||||
height: getHeight()
|
||||
};
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
Object.entries(winWh).forEach(([type, val]) => {
|
||||
Object.entries(winWh).forEach(([ type, val ]) => {
|
||||
const curval = (type === 'width') ? window.innerWidth - 15 : window.innerHeight;
|
||||
this.workarea['scroll' + (type === 'width' ? 'Left' : 'Top')] -= (curval - val) / 2;
|
||||
winWh[type] = curval;
|
||||
@@ -426,16 +424,16 @@ class EditorStartup {
|
||||
Array.from(elements).forEach(function(element) {
|
||||
element.addEventListener('mousedown', function(event) {
|
||||
if (!event.currentTarget.classList.contains('disabled')) {
|
||||
event.currentTarget.classList.add('push_button_pressed')
|
||||
event.currentTarget.classList.add('push_button_pressed');
|
||||
event.currentTarget.classList.remove('push_button');
|
||||
}
|
||||
});
|
||||
element.addEventListener('mouseout', function(event) {
|
||||
event.currentTarget.classList.add('push_button')
|
||||
event.currentTarget.classList.add('push_button');
|
||||
event.currentTarget.classList.remove('push_button_pressed');
|
||||
});
|
||||
element.addEventListener('mouseup', function(event) {
|
||||
event.currentTarget.classList.add('push_button')
|
||||
event.currentTarget.classList.add('push_button');
|
||||
event.currentTarget.classList.remove('push_button_pressed');
|
||||
});
|
||||
});
|
||||
@@ -577,8 +575,8 @@ class EditorStartup {
|
||||
// showSaveWarning is set to 'false' when the page is saved.
|
||||
if (!this.configObj.curConfig.no_save_warning && this.showSaveWarning) {
|
||||
// Browser already asks question about closing the page
|
||||
e.returnValue = this.uiStrings.notification.unsavedChanges; // Firefox needs this when beforeunload set by addEventListener (even though message is not used)
|
||||
return this.uiStrings.notification.unsavedChanges;
|
||||
e.returnValue = this.i18next.t('notification.unsavedChanges'); // Firefox needs this when beforeunload set by addEventListener (even though message is not used)
|
||||
return this.i18next.t('notification.unsavedChanges');
|
||||
}
|
||||
return true;
|
||||
}.bind(this));
|
||||
@@ -594,7 +592,7 @@ class EditorStartup {
|
||||
*/
|
||||
const editorObj = this;
|
||||
const importImage = function (e) {
|
||||
document.getElementById('se-prompt-dialog').title = editorObj.uiStrings.notification.loadingImage;
|
||||
document.getElementById('se-prompt-dialog').title = editorObj.i18next.t('notification.loadingImage');
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
const file = (e.type === 'drop') ? e.dataTransfer.files[0] : this.files[0];
|
||||
@@ -619,14 +617,14 @@ class EditorStartup {
|
||||
editorObj.svgCanvas.alignSelectedElements('m', 'page');
|
||||
editorObj.svgCanvas.alignSelectedElements('c', 'page');
|
||||
// highlight imported element, otherwise we get strange empty selectbox
|
||||
editorObj.svgCanvas.selectOnly([newElement]);
|
||||
editorObj.svgCanvas.selectOnly([ newElement ]);
|
||||
document.getElementById('se-prompt-dialog').setAttribute('close', true);
|
||||
};
|
||||
reader.readAsText(file);
|
||||
} else {
|
||||
// bitmap handling
|
||||
reader = new FileReader();
|
||||
reader.onloadend = function ({target: {result}}) {
|
||||
reader.onloadend = function ({ target: { result } }) {
|
||||
/**
|
||||
* Insert the new image until we know its dimensions.
|
||||
* @param {Float} imageWidth
|
||||
@@ -646,7 +644,7 @@ class EditorStartup {
|
||||
}
|
||||
});
|
||||
editorObj.svgCanvas.setHref(newImage, result);
|
||||
editorObj.svgCanvas.selectOnly([newImage]);
|
||||
editorObj.svgCanvas.selectOnly([ newImage ]);
|
||||
editorObj.svgCanvas.alignSelectedElements('m', 'page');
|
||||
editorObj.svgCanvas.alignSelectedElements('c', 'page');
|
||||
editorObj.topPanelHandlers.updateContextPanel();
|
||||
@@ -715,8 +713,8 @@ class EditorStartup {
|
||||
*/
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
const imported = await import(`./extensions/${encodeURIComponent(extname)}/${encodeURIComponent(extname)}.js`);
|
||||
const {name = extname, init: initfn} = imported.default;
|
||||
return this.addExtension(name, (initfn && initfn.bind(this)), {$, langParam: 'en'}); /** @todo change to current lng */
|
||||
const { name = extname, init: initfn } = imported.default;
|
||||
return this.addExtension(name, (initfn && initfn.bind(this)), { $, langParam: 'en' }); /** @todo change to current lng */
|
||||
} catch (err) {
|
||||
// Todo: Add config to alert any errors
|
||||
console.error('Extension failed to load: ' + extname + '; ', err);
|
||||
@@ -739,8 +737,8 @@ class EditorStartup {
|
||||
*/
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
const imported = await import(encodeURI(extPathName));
|
||||
const {name, init: initfn} = imported.default;
|
||||
return this.addExtension(name, (initfn && initfn.bind(this)), {$});
|
||||
const { name, init: initfn } = imported.default;
|
||||
return this.addExtension(name, (initfn && initfn.bind(this)), { $ });
|
||||
} catch (err) {
|
||||
// Todo: Add config to alert any errors
|
||||
console.error('Extension failed to load: ' + extPathName + '; ', err);
|
||||
@@ -790,9 +788,8 @@ class EditorStartup {
|
||||
* @fires module:svgcanvas.SvgCanvas#event:message
|
||||
* @returns {void}
|
||||
*/
|
||||
messageListener ({data, origin}) {
|
||||
// console.log('data, origin, extensionsAdded', data, origin, extensionsAdded);
|
||||
const messageObj = {data, origin};
|
||||
messageListener ({ data, origin }) {
|
||||
const messageObj = { data, origin };
|
||||
if (!this.extensionsAdded) {
|
||||
this.messageQueue.push(messageObj);
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* globals seConfirm, seAlert */
|
||||
import SvgCanvas from "../svgcanvas/svgcanvas.js";
|
||||
import {convertUnit, isValidUnit} from '../common/units.js';
|
||||
import {isChrome} from '../common/browser.js';
|
||||
import { convertUnit, isValidUnit } from '../common/units.js';
|
||||
import { isChrome } from '../common/browser.js';
|
||||
|
||||
const { $id } = SvgCanvas;
|
||||
const homePage = 'https://github.com/SVG-Edit/svgedit';
|
||||
@@ -15,6 +15,10 @@ class MainMenu {
|
||||
*/
|
||||
constructor(editor) {
|
||||
this.editor = editor;
|
||||
/**
|
||||
* @type {Integer}
|
||||
*/
|
||||
this.exportWindowCt = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -22,8 +26,8 @@ class MainMenu {
|
||||
* @returns {void}
|
||||
*/
|
||||
async clickClear() {
|
||||
const [x, y] = this.editor.configObj.curConfig.dimensions;
|
||||
const ok = await seConfirm(this.editor.uiStrings.notification.QwantToClear);
|
||||
const [ x, y ] = this.editor.configObj.curConfig.dimensions;
|
||||
const ok = await seConfirm(this.editor.i18next.t('notification.QwantToClear'));
|
||||
if (ok === "Cancel") {
|
||||
return;
|
||||
}
|
||||
@@ -68,15 +72,15 @@ class MainMenu {
|
||||
this.editor.svgCanvas.setDocumentTitle(title);
|
||||
|
||||
if (w !== "fit" && !isValidUnit("width", w)) {
|
||||
seAlert(this.editor.uiStrings.notification.invalidAttrValGiven);
|
||||
seAlert(this.editor.i18next.t('notification.invalidAttrValGiven'));
|
||||
return false;
|
||||
}
|
||||
if (h !== "fit" && !isValidUnit("height", h)) {
|
||||
seAlert(this.editor.uiStrings.notification.invalidAttrValGiven);
|
||||
seAlert(this.editor.i18next.t('notification.invalidAttrValGiven'));
|
||||
return false;
|
||||
}
|
||||
if (!this.editor.svgCanvas.setResolution(w, h)) {
|
||||
seAlert(this.editor.uiStrings.notification.noContentToFitTo);
|
||||
seAlert(this.editor.i18next.t('notification.noContentToFitTo'));
|
||||
return false;
|
||||
}
|
||||
// Set image save option
|
||||
@@ -107,11 +111,8 @@ class MainMenu {
|
||||
|
||||
// set language
|
||||
if (lang && lang !== this.editor.configObj.pref("lang")) {
|
||||
const { langParam, langData } = await this.editor.putLocale(
|
||||
lang,
|
||||
this.editor.goodLangs
|
||||
);
|
||||
await this.editor.svgCanvassetLang(langParam, langData);
|
||||
this.editor.configObj.pref("lang", lang);
|
||||
seAlert('Changing the language needs reload');
|
||||
}
|
||||
|
||||
// set grid setting
|
||||
@@ -126,7 +127,7 @@ class MainMenu {
|
||||
this.editor.configObj.curConfig.baseUnit = baseunit;
|
||||
this.editor.svgCanvas.setConfig(this.editor.configObj.curConfig);
|
||||
this.editor.updateCanvas();
|
||||
this.editor.hidePreferences();
|
||||
this.hidePreferences();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,7 +162,7 @@ class MainMenu {
|
||||
* @returns {void}
|
||||
*/
|
||||
const openExportWindow = () => {
|
||||
const { loadingImage } = this.editor.uiStrings.notification;
|
||||
const loadingImage = this.editor.i18next.t('notification.loadingImage');
|
||||
if (this.editor.configObj.curConfig.exportWindowType === "new") {
|
||||
this.editor.exportWindowCt++;
|
||||
}
|
||||
@@ -179,7 +180,7 @@ class MainMenu {
|
||||
<body><h1>${loadingImage}</h1></body>
|
||||
<html>`;
|
||||
if (typeof URL !== "undefined" && URL.createObjectURL) {
|
||||
const blob = new Blob([popHTML], { type: "text/html" });
|
||||
const blob = new Blob([ popHTML ], { type: "text/html" });
|
||||
popURL = URL.createObjectURL(blob);
|
||||
} else {
|
||||
popURL = "data:text/html;base64;charset=utf-8," + popHTML;
|
||||
@@ -301,7 +302,7 @@ class MainMenu {
|
||||
init() {
|
||||
// add Top panel
|
||||
const template = document.createElement("template");
|
||||
const {i18next} = this.editor
|
||||
const { i18next } = this.editor;
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
template.innerHTML = `
|
||||
<se-menu id="main_button" label="SVG-Edit" src="./images/logo.svg" alt="logo">
|
||||
@@ -330,7 +331,7 @@ class MainMenu {
|
||||
*/
|
||||
|
||||
$id("tool_clear").addEventListener("click", this.clickClear.bind(this));
|
||||
$id("tool_open").addEventListener("click", e => {
|
||||
$id("tool_open").addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
this.clickOpen();
|
||||
window.dispatchEvent(new CustomEvent("openImage"));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {getTypeMap} from '../common/units.js';
|
||||
import { getTypeMap } from '../common/units.js';
|
||||
import rulersTemplate from './templates/rulersTemplate.js';
|
||||
/**
|
||||
*
|
||||
@@ -52,7 +52,7 @@ class Rulers {
|
||||
const dim = isX ? 'x' : 'y';
|
||||
const lentype = isX ? 'width' : 'height';
|
||||
const contentDim = Number(contentElem.getAttribute(dim));
|
||||
const {$id} = this.svgCanvas;
|
||||
const { $id } = this.svgCanvas;
|
||||
const $hcanvOrig = $id('ruler_' + dim).querySelector('canvas');
|
||||
|
||||
// Bit of a hack to fully clear the canvas in Safari & IE9
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {jGraduate} from './jgraduate/jQuery.jGraduate.js';
|
||||
import { jGraduate } from './jgraduate/jQuery.jGraduate.js';
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -67,7 +67,7 @@ class PaintBox {
|
||||
*/
|
||||
static getPaint (svgCanvas, color, opac, type) {
|
||||
// update the editor's fill paint
|
||||
const opts = {alpha: opac};
|
||||
const opts = { alpha: opac };
|
||||
if (color.startsWith('url(#')) {
|
||||
let refElem = svgCanvas.getRefElem(color);
|
||||
refElem = (refElem) ? refElem.cloneNode(true) : document.querySelectorAll('#' + type + '_color defs *')[0];
|
||||
@@ -88,7 +88,7 @@ class PaintBox {
|
||||
update (svgcanvas, selectedElement) {
|
||||
if (!selectedElement) { return null; }
|
||||
|
||||
const {type} = this;
|
||||
const { type } = this;
|
||||
switch (selectedElement.tagName) {
|
||||
case 'use':
|
||||
case 'image':
|
||||
|
||||
@@ -232,7 +232,7 @@ export default class ColorValuePicker {
|
||||
break;
|
||||
case ahex:
|
||||
color.value = 'ahex';
|
||||
ahex.value = color.value.substring(6);
|
||||
ahex.value = color.value.substring(6);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -349,7 +349,7 @@ export default class ColorValuePicker {
|
||||
value = inputs[2],
|
||||
hex = inputs[(inputs.length > 7) ? 7 : 6],
|
||||
ahex = inputs.length > 7 ? inputs[8] : null;
|
||||
Object.assign(that, {destroy});
|
||||
Object.assign(that, { destroy });
|
||||
red.addEventListener('keyup', keyUp);
|
||||
green.addEventListener('keyup', keyUp);
|
||||
blue.addEventListener('keyup', keyUp);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable no-bitwise */
|
||||
import {findPos} from './Util.js';
|
||||
import { findPos } from './Util.js';
|
||||
/**
|
||||
* Whether a value is `null` or `undefined`.
|
||||
* @param {any} val
|
||||
@@ -38,7 +38,7 @@ export default class Slider {
|
||||
*/
|
||||
function mouseDown (e) {
|
||||
const off = findPos(bar);
|
||||
offset = {l: off.left | 0, t: off.top | 0};
|
||||
offset = { l: off.left | 0, t: off.top | 0 };
|
||||
clearTimeout(timeout);
|
||||
// using setTimeout for visual updates - once the style is updated the browser will re-render internally allowing the next Javascript to run
|
||||
timeout = setTimeout(function () {
|
||||
@@ -146,7 +146,7 @@ export default class Slider {
|
||||
case 'x': return x;
|
||||
case 'y': return y;
|
||||
case 'xy':
|
||||
default: return {x, y};
|
||||
default: return { x, y };
|
||||
}
|
||||
}
|
||||
if (!isNullish(context) && context === that) return undefined;
|
||||
@@ -216,12 +216,12 @@ export default class Slider {
|
||||
switch (name.toLowerCase()) {
|
||||
case 'minx': return minX;
|
||||
case 'maxx': return maxX;
|
||||
case 'rangex': return {minX, maxX, rangeX};
|
||||
case 'rangex': return { minX, maxX, rangeX };
|
||||
case 'miny': return minY;
|
||||
case 'maxy': return maxY;
|
||||
case 'rangey': return {minY, maxY, rangeY};
|
||||
case 'rangey': return { minY, maxY, rangeY };
|
||||
case 'all':
|
||||
default: return {minX, maxX, rangeX, minY, maxY, rangeY};
|
||||
default: return { minX, maxX, rangeX, minY, maxY, rangeY };
|
||||
}
|
||||
}
|
||||
let // changed = false,
|
||||
|
||||
@@ -23,7 +23,7 @@ export function isObject(item) {
|
||||
export function mergeDeep(target, source) {
|
||||
let output = Object.assign({}, target);
|
||||
if (isObject(target) && isObject(source)) {
|
||||
Object.keys(source).forEach(key => {
|
||||
Object.keys(source).forEach((key) => {
|
||||
if (isObject(source[key])) {
|
||||
if (!(key in target))
|
||||
Object.assign(output, { [key]: source[key] });
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
* @example $.jGraduate.Paint({hex: '#rrggbb', linearGradient: o}); // throws an exception?
|
||||
*/
|
||||
import Paint from './paint.js';
|
||||
import {jPickerDefaults, jPickerMethod} from './jQuery.jPicker.js';
|
||||
import {findPos} from './Util.js';
|
||||
import { jPickerDefaults, jPickerMethod } from './jQuery.jPicker.js';
|
||||
import { findPos } from './Util.js';
|
||||
|
||||
/**
|
||||
* @todo JFH: This jQuery plugin was adapted to work within a Web Component.
|
||||
@@ -126,11 +126,11 @@ const isGecko = navigator.userAgent.includes('Gecko/');
|
||||
*/
|
||||
function setAttrs (elem, attrs) {
|
||||
if (isGecko) {
|
||||
Object.entries(attrs).forEach(([aname, val]) => {
|
||||
Object.entries(attrs).forEach(([ aname, val ]) => {
|
||||
elem.setAttribute(aname, val);
|
||||
});
|
||||
} else {
|
||||
Object.entries(attrs).forEach(([aname, val]) => {
|
||||
Object.entries(attrs).forEach(([ aname, val ]) => {
|
||||
const prop = elem[aname];
|
||||
if (prop && prop.constructor === 'SVGLength') {
|
||||
prop.baseVal.value = val;
|
||||
@@ -221,7 +221,7 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
|
||||
};
|
||||
Object.assign($this, {
|
||||
// make a copy of the incoming paint
|
||||
paint: new jGraduate.Paint({copy: $settings.paint}),
|
||||
paint: new jGraduate.Paint({ copy: $settings.paint }),
|
||||
okCallback: typeof okCallback === 'function' ? okCallback : null,
|
||||
cancelCallback: typeof cancelCallback === 'function' ? cancelCallback : null
|
||||
});
|
||||
@@ -231,7 +231,7 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
|
||||
const $win = window;
|
||||
|
||||
if ($this.paint.type === 'none') {
|
||||
$this.paint = new jGraduate.Paint({solidColor: 'ffffff'});
|
||||
$this.paint = new jGraduate.Paint({ solidColor: 'ffffff' });
|
||||
}
|
||||
$this.classList.add('jGraduate_Picker');
|
||||
/* eslint-disable max-len */
|
||||
@@ -531,7 +531,7 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
|
||||
$elem.style.top = e.target.value * MAX;
|
||||
}
|
||||
};
|
||||
for (const [, attr] of ['x1', 'y1', 'x2', 'y2', 'cx', 'cy', 'fx', 'fy'].entries()) {
|
||||
for (const [ , attr ] of [ 'x1', 'y1', 'x2', 'y2', 'cx', 'cy', 'fx', 'fy' ].entries()) {
|
||||
const isRadial = isNaN(attr[1]);
|
||||
|
||||
let attrval = curGradient.getAttribute(attr);
|
||||
@@ -620,9 +620,9 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
|
||||
jqPickerElem.style.left = '100px';
|
||||
jqPickerElem.style.bottom = '15px';
|
||||
jPickerMethod(jqPickerElem, {
|
||||
window: {title: 'Pick the start color and opacity for the gradient'},
|
||||
images: {clientPath: $settings.images.clientPath},
|
||||
color: {active: colr, alphaSupport: true}
|
||||
window: { title: 'Pick the start color and opacity for the gradient' },
|
||||
images: { clientPath: $settings.images.clientPath },
|
||||
color: { active: colr, alphaSupport: true }
|
||||
}, function (clr) {
|
||||
stopColor = clr.val('hex') ? ('#' + clr.val('hex')) : 'none';
|
||||
stopOpacity = clr.val('a') !== null ? clr.val('a') / 256 : 1;
|
||||
@@ -752,9 +752,9 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
|
||||
}
|
||||
|
||||
drag.setAttribute('transform', xfStr);
|
||||
const jqpgpath = $this.querySelector('#'+drag.dataset.bg);
|
||||
const jqpgpath = $this.querySelector('#'+drag.dataset.bg);
|
||||
jqpgpath.setAttribute('transform', xfStr);
|
||||
const stop = $this.querySelector('#'+drag.dataset.stop);
|
||||
const stop = $this.querySelector('#'+drag.dataset.stop);
|
||||
const sX = (x - 10) / MAX;
|
||||
|
||||
stop.setAttribute('offset', sX);
|
||||
@@ -795,7 +795,7 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
|
||||
|
||||
stopMakerSVG.addEventListener('click', function (evt) {
|
||||
stopOffset = findPos(stopMakerDiv);
|
||||
const {target} = evt;
|
||||
const { target } = evt;
|
||||
if (target.tagName === 'path') return;
|
||||
let x = evt.pageX - stopOffset.left - 8;
|
||||
x = x < 10 ? 10 : x > MAX + 10 ? MAX + 10 : x;
|
||||
@@ -983,7 +983,7 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
|
||||
let slider;
|
||||
|
||||
const setSlider = function (e) {
|
||||
const {offset: {left}} = slider;
|
||||
const { offset: { left } } = slider;
|
||||
const divi = slider.parent;
|
||||
let x = (e.pageX - left - Number.parseInt(getComputedStyle(divi, null).getPropertyValue('border-left-width')));
|
||||
if (x > SLIDERW) x = SLIDERW;
|
||||
@@ -1088,7 +1088,7 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
|
||||
val: angleVal
|
||||
}
|
||||
};
|
||||
for (const [, [type, data]] of Object.entries(Object.entries(sliders))) {
|
||||
for (const [ , [ type, data ] ] of Object.entries(Object.entries(sliders))) {
|
||||
const handle = $this.querySelector(data.handle);
|
||||
const sInput = $this.querySelector(data.input);
|
||||
handle.addEventListener('mousedown', function (evt) {
|
||||
@@ -1177,15 +1177,15 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
|
||||
}
|
||||
// This should be done somewhere else, probably
|
||||
Object.assign(jPickerDefaults.window, {
|
||||
alphaSupport: true, effects: {type: 'show', speed: 0}
|
||||
alphaSupport: true, effects: { type: 'show', speed: 0 }
|
||||
});
|
||||
|
||||
jPickerMethod(
|
||||
colPicker,
|
||||
{
|
||||
window: {title: $settings.window.pickerTitle},
|
||||
images: {clientPath: $settings.images.clientPath},
|
||||
color: {active: color, alphaSupport: true}
|
||||
window: { title: $settings.window.pickerTitle },
|
||||
images: { clientPath: $settings.images.clientPath },
|
||||
color: { active: color, alphaSupport: true }
|
||||
},
|
||||
function (clr) {
|
||||
$this.paint.type = 'solidColor';
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
/* eslint-disable max-len */
|
||||
import ColorValuePicker from './ColorValuePicker.js';
|
||||
import Slider from './Slider.js';
|
||||
import {findPos,mergeDeep} from './Util.js';
|
||||
import { findPos, mergeDeep } from './Util.js';
|
||||
|
||||
/**
|
||||
* @external Math
|
||||
@@ -121,7 +121,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
if (isNullish(name) || name === '') name = 'all';
|
||||
if (isNullish(r)) return null;
|
||||
switch (name.toLowerCase()) {
|
||||
case 'ahex': return ColorMethods.rgbaToHex({r, g, b, a});
|
||||
case 'ahex': return ColorMethods.rgbaToHex({ r, g, b, a });
|
||||
case 'hex': return val('ahex').substring(0, 6);
|
||||
case 'all': return {
|
||||
r, g, b, a, h, s, v,
|
||||
@@ -131,7 +131,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
default: {
|
||||
ret = {};
|
||||
const nameLength = name.length;
|
||||
[...name].forEach((ch) => {
|
||||
[ ...name ].forEach((ch) => {
|
||||
switch (ch) {
|
||||
case 'r':
|
||||
if (nameLength === 1) ret = r;
|
||||
@@ -234,7 +234,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
if (value.h !== undefined && !name.includes('h')) name += 'h';
|
||||
if (value.s !== undefined && !name.includes('s')) name += 's';
|
||||
if (value.v !== undefined && !name.includes('v')) name += 'v';
|
||||
[...name].forEach((ch) => {
|
||||
[ ...name ].forEach((ch) => {
|
||||
switch (ch) {
|
||||
case 'r':
|
||||
if (hsv) return;
|
||||
@@ -243,7 +243,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
if (newV.r < 0) newV.r = 0;
|
||||
else if (newV.r > 255) newV.r = 255;
|
||||
if (r !== newV.r) {
|
||||
({r} = newV);
|
||||
({ r } = newV);
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
@@ -254,7 +254,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
if (newV.g < 0) newV.g = 0;
|
||||
else if (newV.g > 255) newV.g = 255;
|
||||
if (g !== newV.g) {
|
||||
({g} = newV);
|
||||
({ g } = newV);
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
@@ -265,7 +265,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
if (newV.b < 0) newV.b = 0;
|
||||
else if (newV.b > 255) newV.b = 255;
|
||||
if (b !== newV.b) {
|
||||
({b} = newV);
|
||||
({ b } = newV);
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
@@ -274,7 +274,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
if (newV.a < 0) newV.a = 0;
|
||||
else if (newV.a > 255) newV.a = 255;
|
||||
if (a !== newV.a) {
|
||||
({a} = newV);
|
||||
({ a } = newV);
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
@@ -285,7 +285,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
if (newV.h < 0) newV.h = 0;
|
||||
else if (newV.h > 360) newV.h = 360;
|
||||
if (h !== newV.h) {
|
||||
({h} = newV);
|
||||
({ h } = newV);
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
@@ -296,7 +296,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
if (newV.s < 0) newV.s = 0;
|
||||
else if (newV.s > 100) newV.s = 100;
|
||||
if (s !== newV.s) {
|
||||
({s} = newV);
|
||||
({ s } = newV);
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
@@ -307,7 +307,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
if (newV.v < 0) newV.v = 0;
|
||||
else if (newV.v > 100) newV.v = 100;
|
||||
if (v !== newV.v) {
|
||||
({v} = newV);
|
||||
({ v } = newV);
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
@@ -318,14 +318,14 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
r = r || 0;
|
||||
g = g || 0;
|
||||
b = b || 0;
|
||||
const ret = ColorMethods.rgbToHsv({r, g, b});
|
||||
({h, s, v} = ret);
|
||||
const ret = ColorMethods.rgbToHsv({ r, g, b });
|
||||
({ h, s, v } = ret);
|
||||
} else if (hsv) {
|
||||
h = h || 0;
|
||||
s = !isNullish(s) ? s : 100;
|
||||
v = !isNullish(v) ? v : 100;
|
||||
const ret = ColorMethods.hsvToRgb({h, s, v});
|
||||
({r, g, b} = ret);
|
||||
const ret = ColorMethods.hsvToRgb({ h, s, v });
|
||||
({ r, g, b } = ret);
|
||||
}
|
||||
a = !isNullish(a) ? a : 255;
|
||||
fireChangeEvents.call(that, context || that);
|
||||
@@ -375,7 +375,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
val(
|
||||
(!isNullish(init.a) ? 'a' : '') + 'hex',
|
||||
!isNullish(init.a)
|
||||
? {ahex: init.hex + ColorMethods.intToHex(init.a)}
|
||||
? { ahex: init.hex + ColorMethods.intToHex(init.a) }
|
||||
: init
|
||||
);
|
||||
} else if (!isNullish(init.r) && !isNullish(init.g) && !isNullish(init.b)) {
|
||||
@@ -408,7 +408,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
* @returns {module:jPicker.RGBA}
|
||||
*/
|
||||
hexToRgba (hex) {
|
||||
if (hex === '' || hex === 'none') return {r: null, g: null, b: null, a: null};
|
||||
if (hex === '' || hex === 'none') return { r: null, g: null, b: null, a: null };
|
||||
hex = this.validateHex(hex);
|
||||
let r = '00', g = '00', b = '00', a = '255';
|
||||
if (hex.length === 6) hex += 'ff';
|
||||
@@ -476,7 +476,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
* @returns {module:jPicker.HSV}
|
||||
*/
|
||||
rgbToHsv (rgb) {
|
||||
const r = rgb.r / 255, g = rgb.g / 255, b = rgb.b / 255, hsv = {h: 0, s: 0, v: 0};
|
||||
const r = rgb.r / 255, g = rgb.g / 255, b = rgb.b / 255, hsv = { h: 0, s: 0, v: 0 };
|
||||
let min = 0, max = 0;
|
||||
if (r >= g && r >= b) {
|
||||
max = r;
|
||||
@@ -509,8 +509,8 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
* @returns {module:jPicker.RGB}
|
||||
*/
|
||||
hsvToRgb (hsv) {
|
||||
const rgb = {r: 0, g: 0, b: 0, a: 100};
|
||||
let {h, s, v} = hsv;
|
||||
const rgb = { r: 0, g: 0, b: 0, a: 100 };
|
||||
let { h, s, v } = hsv;
|
||||
if (s === 0) {
|
||||
if (v === 0) rgb.r = rgb.g = rgb.b = 0;
|
||||
else rgb.r = rgb.g = rgb.b = (v * 255 / 100) | 0;
|
||||
@@ -564,7 +564,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
|
||||
}
|
||||
}
|
||||
};
|
||||
const {Color, List, ColorMethods} = jPicker; // local copies for YUI compressor
|
||||
const { Color, List, ColorMethods } = jPicker; // local copies for YUI compressor
|
||||
/**
|
||||
* @function external:jQuery.fn.jPicker
|
||||
* @see {@link external:jQuery.fn.$.fn.jPicker}
|
||||
@@ -617,11 +617,11 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
}
|
||||
});
|
||||
if (that.value === '') {
|
||||
settings.color.active = new Color({hex: null});
|
||||
settings.color.current = new Color({hex: null});
|
||||
settings.color.active = new Color({ hex: null });
|
||||
settings.color.current = new Color({ hex: null });
|
||||
} else if (ColorMethods.validateHex(that.value)) {
|
||||
settings.color.active = new Color({hex: that.value, a: settings.color.active.val('a')});
|
||||
settings.color.current = new Color({hex: that.value, a: settings.color.active.val('a')});
|
||||
settings.color.active = new Color({ hex: that.value, a: settings.color.active.val('a') });
|
||||
settings.color.current = new Color({ hex: that.value, a: settings.color.active.val('a') });
|
||||
}
|
||||
}
|
||||
if (settings.window.expandable) {
|
||||
@@ -646,7 +646,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
* @returns {void}
|
||||
*/
|
||||
function setColorMode (colorMode) {
|
||||
const {active} = color, // local copies for YUI compressor
|
||||
const { active } = color, // local copies for YUI compressor
|
||||
// {clientPath} = images,
|
||||
hex = active.val('hex');
|
||||
let rgbMap, rgbBar;
|
||||
@@ -671,10 +671,10 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
setImgLoc.call(that, colorBarL6, 260);
|
||||
setAlpha.call(that, colorBarL6, 100);
|
||||
}, 0);
|
||||
colorMap.range('all', {minX: 0, maxX: 100, minY: 0, maxY: 100});
|
||||
colorBar.range('rangeY', {minY: 0, maxY: 360});
|
||||
colorMap.range('all', { minX: 0, maxX: 100, minY: 0, maxY: 100 });
|
||||
colorBar.range('rangeY', { minY: 0, maxY: 360 });
|
||||
if (isNullish(active.val('ahex'))) break;
|
||||
colorMap.val('xy', {x: active.val('s'), y: 100 - active.val('v')}, colorMap);
|
||||
colorMap.val('xy', { x: active.val('s'), y: 100 - active.val('v') }, colorMap);
|
||||
colorBar.val('y', 360 - active.val('h'), colorBar);
|
||||
break;
|
||||
case 's':
|
||||
@@ -687,10 +687,10 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
setImgLoc.call(that, colorBarL6, 260);
|
||||
setAlpha.call(that, colorBarL6, 100);
|
||||
}, 0);
|
||||
colorMap.range('all', {minX: 0, maxX: 360, minY: 0, maxY: 100});
|
||||
colorBar.range('rangeY', {minY: 0, maxY: 100});
|
||||
colorMap.range('all', { minX: 0, maxX: 360, minY: 0, maxY: 100 });
|
||||
colorBar.range('rangeY', { minY: 0, maxY: 100 });
|
||||
if (isNullish(active.val('ahex'))) break;
|
||||
colorMap.val('xy', {x: active.val('h'), y: 100 - active.val('v')}, colorMap);
|
||||
colorMap.val('xy', { x: active.val('h'), y: 100 - active.val('v') }, colorMap);
|
||||
colorBar.val('y', 100 - active.val('s'), colorBar);
|
||||
break;
|
||||
case 'v':
|
||||
@@ -705,37 +705,37 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
setImgLoc.call(that, colorBarL6, 260);
|
||||
setAlpha.call(that, colorBarL6, 100);
|
||||
}, 0);
|
||||
colorMap.range('all', {minX: 0, maxX: 360, minY: 0, maxY: 100});
|
||||
colorBar.range('rangeY', {minY: 0, maxY: 100});
|
||||
colorMap.range('all', { minX: 0, maxX: 360, minY: 0, maxY: 100 });
|
||||
colorBar.range('rangeY', { minY: 0, maxY: 100 });
|
||||
if (isNullish(active.val('ahex'))) break;
|
||||
colorMap.val('xy', {x: active.val('h'), y: 100 - active.val('s')}, colorMap);
|
||||
colorMap.val('xy', { x: active.val('h'), y: 100 - active.val('s') }, colorMap);
|
||||
colorBar.val('y', 100 - active.val('v'), colorBar);
|
||||
break;
|
||||
case 'r':
|
||||
rgbMap = -1040;
|
||||
rgbBar = -780;
|
||||
colorMap.range('all', {minX: 0, maxX: 255, minY: 0, maxY: 255});
|
||||
colorBar.range('rangeY', {minY: 0, maxY: 255});
|
||||
colorMap.range('all', { minX: 0, maxX: 255, minY: 0, maxY: 255 });
|
||||
colorBar.range('rangeY', { minY: 0, maxY: 255 });
|
||||
if (isNullish(active.val('ahex'))) break;
|
||||
colorMap.val('xy', {x: active.val('b'), y: 255 - active.val('g')}, colorMap);
|
||||
colorMap.val('xy', { x: active.val('b'), y: 255 - active.val('g') }, colorMap);
|
||||
colorBar.val('y', 255 - active.val('r'), colorBar);
|
||||
break;
|
||||
case 'g':
|
||||
rgbMap = -1560;
|
||||
rgbBar = -1820;
|
||||
colorMap.range('all', {minX: 0, maxX: 255, minY: 0, maxY: 255});
|
||||
colorBar.range('rangeY', {minY: 0, maxY: 255});
|
||||
colorMap.range('all', { minX: 0, maxX: 255, minY: 0, maxY: 255 });
|
||||
colorBar.range('rangeY', { minY: 0, maxY: 255 });
|
||||
if (isNullish(active.val('ahex'))) break;
|
||||
colorMap.val('xy', {x: active.val('b'), y: 255 - active.val('r')}, colorMap);
|
||||
colorMap.val('xy', { x: active.val('b'), y: 255 - active.val('r') }, colorMap);
|
||||
colorBar.val('y', 255 - active.val('g'), colorBar);
|
||||
break;
|
||||
case 'b':
|
||||
rgbMap = -2080;
|
||||
rgbBar = -2860;
|
||||
colorMap.range('all', {minX: 0, maxX: 255, minY: 0, maxY: 255});
|
||||
colorBar.range('rangeY', {minY: 0, maxY: 255});
|
||||
colorMap.range('all', { minX: 0, maxX: 255, minY: 0, maxY: 255 });
|
||||
colorBar.range('rangeY', { minY: 0, maxY: 255 });
|
||||
if (isNullish(active.val('ahex'))) break;
|
||||
colorMap.val('xy', {x: active.val('r'), y: 255 - active.val('g')}, colorMap);
|
||||
colorMap.val('xy', { x: active.val('r'), y: 255 - active.val('g') }, colorMap);
|
||||
colorBar.val('y', 255 - active.val('b'), colorBar);
|
||||
break;
|
||||
case 'a':
|
||||
@@ -749,10 +749,10 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
setImgLoc.call(that, colorBarL6, 0);
|
||||
setAlpha.call(that, colorBarL6, 100);
|
||||
}, 0);
|
||||
colorMap.range('all', {minX: 0, maxX: 360, minY: 0, maxY: 100});
|
||||
colorBar.range('rangeY', {minY: 0, maxY: 255});
|
||||
colorMap.range('all', { minX: 0, maxX: 360, minY: 0, maxY: 100 });
|
||||
colorBar.range('rangeY', { minY: 0, maxY: 255 });
|
||||
if (isNullish(active.val('ahex'))) break;
|
||||
colorMap.val('xy', {x: active.val('h'), y: 100 - active.val('v')}, colorMap);
|
||||
colorMap.val('xy', { x: active.val('h'), y: 100 - active.val('v') }, colorMap);
|
||||
colorBar.val('y', 255 - active.val('a'), colorBar);
|
||||
break;
|
||||
default:
|
||||
@@ -817,28 +817,28 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
* @returns {void}
|
||||
*/
|
||||
function mapValueChanged (ui, context) {
|
||||
const {active} = color;
|
||||
const { active } = color;
|
||||
if (context !== colorMap && isNullish(active.val())) return;
|
||||
const xy = ui.val('all');
|
||||
switch (settings.color.mode) {
|
||||
case 'h':
|
||||
active.val('sv', {s: xy.x, v: 100 - xy.y}, context);
|
||||
active.val('sv', { s: xy.x, v: 100 - xy.y }, context);
|
||||
break;
|
||||
case 's':
|
||||
case 'a':
|
||||
active.val('hv', {h: xy.x, v: 100 - xy.y}, context);
|
||||
active.val('hv', { h: xy.x, v: 100 - xy.y }, context);
|
||||
break;
|
||||
case 'v':
|
||||
active.val('hs', {h: xy.x, s: 100 - xy.y}, context);
|
||||
active.val('hs', { h: xy.x, s: 100 - xy.y }, context);
|
||||
break;
|
||||
case 'r':
|
||||
active.val('gb', {g: 255 - xy.y, b: xy.x}, context);
|
||||
active.val('gb', { g: 255 - xy.y, b: xy.x }, context);
|
||||
break;
|
||||
case 'g':
|
||||
active.val('rb', {r: 255 - xy.y, b: xy.x}, context);
|
||||
active.val('rb', { r: 255 - xy.y, b: xy.x }, context);
|
||||
break;
|
||||
case 'b':
|
||||
active.val('rg', {r: xy.x, g: 255 - xy.y}, context);
|
||||
active.val('rg', { r: xy.x, g: 255 - xy.y }, context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -850,26 +850,26 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
* @returns {void}
|
||||
*/
|
||||
function colorBarValueChanged (ui, context) {
|
||||
const {active} = color;
|
||||
const { active } = color;
|
||||
if (context !== colorBar && isNullish(active.val())) return;
|
||||
switch (settings.color.mode) {
|
||||
case 'h':
|
||||
active.val('h', {h: 360 - ui.val('y')}, context);
|
||||
active.val('h', { h: 360 - ui.val('y') }, context);
|
||||
break;
|
||||
case 's':
|
||||
active.val('s', {s: 100 - ui.val('y')}, context);
|
||||
active.val('s', { s: 100 - ui.val('y') }, context);
|
||||
break;
|
||||
case 'v':
|
||||
active.val('v', {v: 100 - ui.val('y')}, context);
|
||||
active.val('v', { v: 100 - ui.val('y') }, context);
|
||||
break;
|
||||
case 'r':
|
||||
active.val('r', {r: 255 - ui.val('y')}, context);
|
||||
active.val('r', { r: 255 - ui.val('y') }, context);
|
||||
break;
|
||||
case 'g':
|
||||
active.val('g', {g: 255 - ui.val('y')}, context);
|
||||
active.val('g', { g: 255 - ui.val('y') }, context);
|
||||
break;
|
||||
case 'b':
|
||||
active.val('b', {b: 255 - ui.val('y')}, context);
|
||||
active.val('b', { b: 255 - ui.val('y') }, context);
|
||||
break;
|
||||
case 'a':
|
||||
active.val('a', 255 - ui.val('y'), context);
|
||||
@@ -888,29 +888,29 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
switch (settings.color.mode) {
|
||||
case 'h': {
|
||||
const sv = ui.val('sv');
|
||||
colorMap.val('xy', {x: !isNullish(sv) ? sv.s : 100, y: 100 - (!isNullish(sv) ? sv.v : 100)}, context);
|
||||
colorMap.val('xy', { x: !isNullish(sv) ? sv.s : 100, y: 100 - (!isNullish(sv) ? sv.v : 100) }, context);
|
||||
break;
|
||||
} case 's':
|
||||
// Fall through
|
||||
case 'a': {
|
||||
const hv = ui.val('hv');
|
||||
colorMap.val('xy', {x: (hv && hv.h) || 0, y: 100 - (!isNullish(hv) ? hv.v : 100)}, context);
|
||||
colorMap.val('xy', { x: (hv && hv.h) || 0, y: 100 - (!isNullish(hv) ? hv.v : 100) }, context);
|
||||
break;
|
||||
} case 'v': {
|
||||
const hs = ui.val('hs');
|
||||
colorMap.val('xy', {x: (hs && hs.h) || 0, y: 100 - (!isNullish(hs) ? hs.s : 100)}, context);
|
||||
colorMap.val('xy', { x: (hs && hs.h) || 0, y: 100 - (!isNullish(hs) ? hs.s : 100) }, context);
|
||||
break;
|
||||
} case 'r': {
|
||||
const bg = ui.val('bg');
|
||||
colorMap.val('xy', {x: (bg && bg.b) || 0, y: 255 - ((bg && bg.g) || 0)}, context);
|
||||
colorMap.val('xy', { x: (bg && bg.b) || 0, y: 255 - ((bg && bg.g) || 0) }, context);
|
||||
break;
|
||||
} case 'g': {
|
||||
const br = ui.val('br');
|
||||
colorMap.val('xy', {x: (br && br.b) || 0, y: 255 - ((br && br.r) || 0)}, context);
|
||||
colorMap.val('xy', { x: (br && br.b) || 0, y: 255 - ((br && br.r) || 0) }, context);
|
||||
break;
|
||||
} case 'b': {
|
||||
const rg = ui.val('rg');
|
||||
colorMap.val('xy', {x: (rg && rg.r) || 0, y: 255 - ((rg && rg.g) || 0)}, context);
|
||||
colorMap.val('xy', { x: (rg && rg.r) || 0, y: 255 - ((rg && rg.g) || 0) }, context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -963,7 +963,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
function updateMapVisuals (ui) {
|
||||
switch (settings.color.mode) {
|
||||
case 'h':
|
||||
setBG.call(that, colorMapDiv, new Color({h: ui.val('h') || 0, s: 100, v: 100}).val('hex'));
|
||||
setBG.call(that, colorMapDiv, new Color({ h: ui.val('h') || 0, s: 100, v: 100 }).val('hex'));
|
||||
break;
|
||||
case 's':
|
||||
case 'a': {
|
||||
@@ -999,14 +999,14 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
break;
|
||||
} case 's': {
|
||||
const hva = ui.val('hva'),
|
||||
saturatedColor = new Color({h: (hva && hva.h) || 0, s: 100, v: !isNullish(hva) ? hva.v : 100});
|
||||
saturatedColor = new Color({ h: (hva && hva.h) || 0, s: 100, v: !isNullish(hva) ? hva.v : 100 });
|
||||
setBG.call(that, colorBarDiv, saturatedColor.val('hex'));
|
||||
setAlpha.call(that, colorBarL2, 100 - (!isNullish(hva) ? hva.v : 100));
|
||||
setAlpha.call(that, colorBarL5, toFixedNumeric(((255 - ((hva && hva.a) || 0)) * 100) / 255, 4));
|
||||
break;
|
||||
} case 'v': {
|
||||
const hsa = ui.val('hsa'),
|
||||
valueColor = new Color({h: (hsa && hsa.h) || 0, s: !isNullish(hsa) ? hsa.s : 100, v: 100});
|
||||
valueColor = new Color({ h: (hsa && hsa.h) || 0, s: !isNullish(hsa) ? hsa.s : 100, v: 100 });
|
||||
setBG.call(that, colorBarDiv, valueColor.val('hex'));
|
||||
setAlpha.call(that, colorBarL5, toFixedNumeric(((255 - ((hsa && hsa.a) || 0)) * 100) / 255, 4));
|
||||
break;
|
||||
@@ -1368,7 +1368,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
if (!that.querySelectorAll('div.jPicker.Container').length) {
|
||||
document.body.insertBefore(container, document.body.firstChild);
|
||||
} else {
|
||||
that.querySelector('div.jPicker.Container:last').insertAdjacentElement('afterend', container)
|
||||
that.querySelector('div.jPicker.Container:last').insertAdjacentElement('afterend', container);
|
||||
}
|
||||
container.addEventListener('mousedown', function () {
|
||||
container.style.zIndex = 20;
|
||||
@@ -1487,7 +1487,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
for (let i = 0; i < color.quickList.length; i++) {
|
||||
/* if default colors are hex strings, change them to color objects */
|
||||
if ((typeof (color.quickList[i])).toString().toLowerCase() === 'string') {
|
||||
color.quickList[i] = new Color({hex: color.quickList[i]});
|
||||
color.quickList[i] = new Color({ hex: color.quickList[i] });
|
||||
}
|
||||
const alpha = color.quickList[i].val('a');
|
||||
let ahex = color.quickList[i].val('ahex');
|
||||
@@ -1520,7 +1520,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
iconAlpha = that.icon.querySelector('.Alpha');
|
||||
setImg.call(that, iconAlpha, images.clientPath + 'bar-opacity.png');
|
||||
setAlpha.call(that, iconAlpha, toFixedNumeric(((255 - (!isNullish(all) ? all.a : 0)) * 100) / 255, 4));
|
||||
iconImage = that.icon.querySelector('.Image')
|
||||
iconImage = that.icon.querySelector('.Image');
|
||||
iconImage.style.backgroundImage = 'url(\'' + images.clientPath + images.picker.file + '\')';
|
||||
iconImage.addEventListener('click', iconImageClicked);
|
||||
if (win.bindToInput && win.updateInputColor) {
|
||||
@@ -1588,23 +1588,23 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
||||
}
|
||||
}
|
||||
}
|
||||
const {images, localization} = settings; // local copies for YUI compressor
|
||||
const { images, localization } = settings; // local copies for YUI compressor
|
||||
const color = {
|
||||
active: (typeof settings.color.active).toString().toLowerCase() === 'string'
|
||||
? new Color({ahex: !settings.window.alphaSupport && settings.color.active
|
||||
? new Color({ ahex: !settings.window.alphaSupport && settings.color.active
|
||||
? settings.color.active.substring(0, 6) + 'ff'
|
||||
: settings.color.active
|
||||
})
|
||||
: new Color({ahex: !settings.window.alphaSupport &&
|
||||
: new Color({ ahex: !settings.window.alphaSupport &&
|
||||
settings.color.active.val('ahex')
|
||||
? settings.color.active.val('ahex').substring(0, 6) + 'ff'
|
||||
: settings.color.active.val('ahex')
|
||||
}),
|
||||
current: (typeof settings.color.active).toString().toLowerCase() === 'string'
|
||||
? new Color({ahex: !settings.window.alphaSupport && settings.color.active
|
||||
? new Color({ ahex: !settings.window.alphaSupport && settings.color.active
|
||||
? settings.color.active.substring(0, 6) + 'ff'
|
||||
: settings.color.active})
|
||||
: new Color({ahex: !settings.window.alphaSupport &&
|
||||
: settings.color.active })
|
||||
: new Color({ ahex: !settings.window.alphaSupport &&
|
||||
settings.color.active.val('ahex')
|
||||
? settings.color.active.val('ahex').substring(0, 6) + 'ff'
|
||||
: settings.color.active.val('ahex')
|
||||
@@ -1770,79 +1770,79 @@ export const jPickerDefaults = {
|
||||
},
|
||||
color: {
|
||||
mode: 'h',
|
||||
active: new Color({ahex: '#ffcc00ff'}),
|
||||
active: new Color({ ahex: '#ffcc00ff' }),
|
||||
quickList: [
|
||||
new Color({h: 360, s: 33, v: 100}),
|
||||
new Color({h: 360, s: 66, v: 100}),
|
||||
new Color({h: 360, s: 100, v: 100}),
|
||||
new Color({h: 360, s: 100, v: 75}),
|
||||
new Color({h: 360, s: 100, v: 50}),
|
||||
new Color({h: 180, s: 0, v: 100}),
|
||||
new Color({h: 30, s: 33, v: 100}),
|
||||
new Color({h: 30, s: 66, v: 100}),
|
||||
new Color({h: 30, s: 100, v: 100}),
|
||||
new Color({h: 30, s: 100, v: 75}),
|
||||
new Color({h: 30, s: 100, v: 50}),
|
||||
new Color({h: 180, s: 0, v: 90}),
|
||||
new Color({h: 60, s: 33, v: 100}),
|
||||
new Color({h: 60, s: 66, v: 100}),
|
||||
new Color({h: 60, s: 100, v: 100}),
|
||||
new Color({h: 60, s: 100, v: 75}),
|
||||
new Color({h: 60, s: 100, v: 50}),
|
||||
new Color({h: 180, s: 0, v: 80}),
|
||||
new Color({h: 90, s: 33, v: 100}),
|
||||
new Color({h: 90, s: 66, v: 100}),
|
||||
new Color({h: 90, s: 100, v: 100}),
|
||||
new Color({h: 90, s: 100, v: 75}),
|
||||
new Color({h: 90, s: 100, v: 50}),
|
||||
new Color({h: 180, s: 0, v: 70}),
|
||||
new Color({h: 120, s: 33, v: 100}),
|
||||
new Color({h: 120, s: 66, v: 100}),
|
||||
new Color({h: 120, s: 100, v: 100}),
|
||||
new Color({h: 120, s: 100, v: 75}),
|
||||
new Color({h: 120, s: 100, v: 50}),
|
||||
new Color({h: 180, s: 0, v: 60}),
|
||||
new Color({h: 150, s: 33, v: 100}),
|
||||
new Color({h: 150, s: 66, v: 100}),
|
||||
new Color({h: 150, s: 100, v: 100}),
|
||||
new Color({h: 150, s: 100, v: 75}),
|
||||
new Color({h: 150, s: 100, v: 50}),
|
||||
new Color({h: 180, s: 0, v: 50}),
|
||||
new Color({h: 180, s: 33, v: 100}),
|
||||
new Color({h: 180, s: 66, v: 100}),
|
||||
new Color({h: 180, s: 100, v: 100}),
|
||||
new Color({h: 180, s: 100, v: 75}),
|
||||
new Color({h: 180, s: 100, v: 50}),
|
||||
new Color({h: 180, s: 0, v: 40}),
|
||||
new Color({h: 210, s: 33, v: 100}),
|
||||
new Color({h: 210, s: 66, v: 100}),
|
||||
new Color({h: 210, s: 100, v: 100}),
|
||||
new Color({h: 210, s: 100, v: 75}),
|
||||
new Color({h: 210, s: 100, v: 50}),
|
||||
new Color({h: 180, s: 0, v: 30}),
|
||||
new Color({h: 240, s: 33, v: 100}),
|
||||
new Color({h: 240, s: 66, v: 100}),
|
||||
new Color({h: 240, s: 100, v: 100}),
|
||||
new Color({h: 240, s: 100, v: 75}),
|
||||
new Color({h: 240, s: 100, v: 50}),
|
||||
new Color({h: 180, s: 0, v: 20}),
|
||||
new Color({h: 270, s: 33, v: 100}),
|
||||
new Color({h: 270, s: 66, v: 100}),
|
||||
new Color({h: 270, s: 100, v: 100}),
|
||||
new Color({h: 270, s: 100, v: 75}),
|
||||
new Color({h: 270, s: 100, v: 50}),
|
||||
new Color({h: 180, s: 0, v: 10}),
|
||||
new Color({h: 300, s: 33, v: 100}),
|
||||
new Color({h: 300, s: 66, v: 100}),
|
||||
new Color({h: 300, s: 100, v: 100}),
|
||||
new Color({h: 300, s: 100, v: 75}),
|
||||
new Color({h: 300, s: 100, v: 50}),
|
||||
new Color({h: 180, s: 0, v: 0}),
|
||||
new Color({h: 330, s: 33, v: 100}),
|
||||
new Color({h: 330, s: 66, v: 100}),
|
||||
new Color({h: 330, s: 100, v: 100}),
|
||||
new Color({h: 330, s: 100, v: 75}),
|
||||
new Color({h: 330, s: 100, v: 50}),
|
||||
new Color({ h: 360, s: 33, v: 100 }),
|
||||
new Color({ h: 360, s: 66, v: 100 }),
|
||||
new Color({ h: 360, s: 100, v: 100 }),
|
||||
new Color({ h: 360, s: 100, v: 75 }),
|
||||
new Color({ h: 360, s: 100, v: 50 }),
|
||||
new Color({ h: 180, s: 0, v: 100 }),
|
||||
new Color({ h: 30, s: 33, v: 100 }),
|
||||
new Color({ h: 30, s: 66, v: 100 }),
|
||||
new Color({ h: 30, s: 100, v: 100 }),
|
||||
new Color({ h: 30, s: 100, v: 75 }),
|
||||
new Color({ h: 30, s: 100, v: 50 }),
|
||||
new Color({ h: 180, s: 0, v: 90 }),
|
||||
new Color({ h: 60, s: 33, v: 100 }),
|
||||
new Color({ h: 60, s: 66, v: 100 }),
|
||||
new Color({ h: 60, s: 100, v: 100 }),
|
||||
new Color({ h: 60, s: 100, v: 75 }),
|
||||
new Color({ h: 60, s: 100, v: 50 }),
|
||||
new Color({ h: 180, s: 0, v: 80 }),
|
||||
new Color({ h: 90, s: 33, v: 100 }),
|
||||
new Color({ h: 90, s: 66, v: 100 }),
|
||||
new Color({ h: 90, s: 100, v: 100 }),
|
||||
new Color({ h: 90, s: 100, v: 75 }),
|
||||
new Color({ h: 90, s: 100, v: 50 }),
|
||||
new Color({ h: 180, s: 0, v: 70 }),
|
||||
new Color({ h: 120, s: 33, v: 100 }),
|
||||
new Color({ h: 120, s: 66, v: 100 }),
|
||||
new Color({ h: 120, s: 100, v: 100 }),
|
||||
new Color({ h: 120, s: 100, v: 75 }),
|
||||
new Color({ h: 120, s: 100, v: 50 }),
|
||||
new Color({ h: 180, s: 0, v: 60 }),
|
||||
new Color({ h: 150, s: 33, v: 100 }),
|
||||
new Color({ h: 150, s: 66, v: 100 }),
|
||||
new Color({ h: 150, s: 100, v: 100 }),
|
||||
new Color({ h: 150, s: 100, v: 75 }),
|
||||
new Color({ h: 150, s: 100, v: 50 }),
|
||||
new Color({ h: 180, s: 0, v: 50 }),
|
||||
new Color({ h: 180, s: 33, v: 100 }),
|
||||
new Color({ h: 180, s: 66, v: 100 }),
|
||||
new Color({ h: 180, s: 100, v: 100 }),
|
||||
new Color({ h: 180, s: 100, v: 75 }),
|
||||
new Color({ h: 180, s: 100, v: 50 }),
|
||||
new Color({ h: 180, s: 0, v: 40 }),
|
||||
new Color({ h: 210, s: 33, v: 100 }),
|
||||
new Color({ h: 210, s: 66, v: 100 }),
|
||||
new Color({ h: 210, s: 100, v: 100 }),
|
||||
new Color({ h: 210, s: 100, v: 75 }),
|
||||
new Color({ h: 210, s: 100, v: 50 }),
|
||||
new Color({ h: 180, s: 0, v: 30 }),
|
||||
new Color({ h: 240, s: 33, v: 100 }),
|
||||
new Color({ h: 240, s: 66, v: 100 }),
|
||||
new Color({ h: 240, s: 100, v: 100 }),
|
||||
new Color({ h: 240, s: 100, v: 75 }),
|
||||
new Color({ h: 240, s: 100, v: 50 }),
|
||||
new Color({ h: 180, s: 0, v: 20 }),
|
||||
new Color({ h: 270, s: 33, v: 100 }),
|
||||
new Color({ h: 270, s: 66, v: 100 }),
|
||||
new Color({ h: 270, s: 100, v: 100 }),
|
||||
new Color({ h: 270, s: 100, v: 75 }),
|
||||
new Color({ h: 270, s: 100, v: 50 }),
|
||||
new Color({ h: 180, s: 0, v: 10 }),
|
||||
new Color({ h: 300, s: 33, v: 100 }),
|
||||
new Color({ h: 300, s: 66, v: 100 }),
|
||||
new Color({ h: 300, s: 100, v: 100 }),
|
||||
new Color({ h: 300, s: 100, v: 75 }),
|
||||
new Color({ h: 300, s: 100, v: 50 }),
|
||||
new Color({ h: 180, s: 0, v: 0 }),
|
||||
new Color({ h: 330, s: 33, v: 100 }),
|
||||
new Color({ h: 330, s: 66, v: 100 }),
|
||||
new Color({ h: 330, s: 100, v: 100 }),
|
||||
new Color({ h: 330, s: 100, v: 75 }),
|
||||
new Color({ h: 330, s: 100, v: 50 }),
|
||||
new Color()
|
||||
]
|
||||
},
|
||||
|
||||
@@ -51,7 +51,7 @@ export class ToolButton extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
// locate the component
|
||||
this.$div = this._shadowRoot.querySelector('div');
|
||||
@@ -62,7 +62,7 @@ export class ToolButton extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['title', 'src', 'pressed', 'disabled', 'size', 'style'];
|
||||
return [ 'title', 'src', 'pressed', 'disabled', 'size', 'style' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable max-len */
|
||||
import {jGraduate, jGraduateMethod} from './jgraduate/jQuery.jGraduate.js';
|
||||
import { jGraduate, jGraduateMethod } from './jgraduate/jQuery.jGraduate.js';
|
||||
import PaintBox from './PaintBox.js';
|
||||
|
||||
const template = document.createElement('template');
|
||||
@@ -344,7 +344,7 @@ div.jGraduate_Swatch {
|
||||
}
|
||||
div.jGraduate_GradContainer {
|
||||
border: 2px inset #EEE;
|
||||
background-image: url(../images/map-opacity.png);
|
||||
background-image: url(./components/jgraduate/images/map-opacity.png);
|
||||
background-position: 0px 0px;
|
||||
height: 256px;
|
||||
width: 256px;
|
||||
@@ -658,7 +658,7 @@ export class SeColorPicker extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$logo = this._shadowRoot.getElementById('logo');
|
||||
this.$label = this._shadowRoot.getElementById('label');
|
||||
@@ -672,7 +672,7 @@ export class SeColorPicker extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['label', 'src', 'type'];
|
||||
return [ 'label', 'src', 'type' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
@@ -754,9 +754,9 @@ export class SeColorPicker extends HTMLElement {
|
||||
update (svgCanvas, selectedElement, apply) {
|
||||
const paint = this.paintBox.update(svgCanvas, selectedElement);
|
||||
if (paint && apply) {
|
||||
const changeEvent = new CustomEvent('change', {detail: {
|
||||
const changeEvent = new CustomEvent('change', { detail: {
|
||||
paint
|
||||
}});
|
||||
} });
|
||||
this.dispatchEvent(changeEvent);
|
||||
}
|
||||
}
|
||||
@@ -775,21 +775,21 @@ export class SeColorPicker extends HTMLElement {
|
||||
connectedCallback () {
|
||||
this.paintBox = new PaintBox(this.$block, this.type);
|
||||
this.$picker.addEventListener('click', () => {
|
||||
let {paint} = this.paintBox;
|
||||
let { paint } = this.paintBox;
|
||||
jGraduateMethod(
|
||||
this.$color_picker,
|
||||
{
|
||||
images: {clientPath: './components/jgraduate/images/'},
|
||||
images: { clientPath: './components/jgraduate/images/' },
|
||||
paint,
|
||||
window: {pickerTitle: this.label},
|
||||
window: { pickerTitle: this.label },
|
||||
newstop: 'inverse'
|
||||
},
|
||||
(p) => {
|
||||
paint = new jGraduate.Paint(p);
|
||||
this.setPaint(paint);
|
||||
const changeEvent = new CustomEvent('change', {detail: {
|
||||
const changeEvent = new CustomEvent('change', { detail: {
|
||||
paint
|
||||
}});
|
||||
} });
|
||||
this.dispatchEvent(changeEvent);
|
||||
this.$color_picker.style.display = 'none';
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import ListComboBox from 'elix/define/ListComboBox.js';
|
||||
import {defaultState} from 'elix/src/base/internal.js';
|
||||
import {templateFrom, fragmentFrom} from 'elix/src/core/htmlLiterals.js';
|
||||
import {internal} from 'elix';
|
||||
import { defaultState } from 'elix/src/base/internal.js';
|
||||
import { templateFrom, fragmentFrom } from 'elix/src/core/htmlLiterals.js';
|
||||
import { internal } from 'elix';
|
||||
import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js';
|
||||
|
||||
/**
|
||||
@@ -40,7 +40,7 @@ class Dropdown extends ListComboBox {
|
||||
::slotted(*) {
|
||||
padding: 4px;
|
||||
background: #E8E8E8;
|
||||
border: 1px solid #B0B0B0;
|
||||
border: 1px solid #5a6162;
|
||||
width: 100%;
|
||||
}
|
||||
[part~="popup"] {
|
||||
@@ -56,7 +56,7 @@ class Dropdown extends ListComboBox {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['title', 'src', 'inputsize', 'value'];
|
||||
return [ 'title', 'src', 'inputsize', 'value' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
@@ -105,7 +105,7 @@ class Dropdown extends ListComboBox {
|
||||
e.preventDefault();
|
||||
const value = e.detail?.closeResult?.getAttribute('value');
|
||||
if (value) {
|
||||
const closeEvent = new CustomEvent('change', {detail: {value}});
|
||||
const closeEvent = new CustomEvent('change', { detail: { value } });
|
||||
this.dispatchEvent(closeEvent);
|
||||
}
|
||||
});
|
||||
@@ -123,7 +123,7 @@ class Dropdown extends ListComboBox {
|
||||
* @returns {void}
|
||||
*/
|
||||
set src (src) {
|
||||
this[internal.setState]({src});
|
||||
this[internal.setState]({ src });
|
||||
}
|
||||
/**
|
||||
* @function inputsize
|
||||
@@ -137,7 +137,7 @@ class Dropdown extends ListComboBox {
|
||||
* @returns {void}
|
||||
*/
|
||||
set inputsize (inputsize) {
|
||||
this[internal.setState]({inputsize});
|
||||
this[internal.setState]({ inputsize });
|
||||
}
|
||||
/**
|
||||
* @function value
|
||||
@@ -151,7 +151,7 @@ class Dropdown extends ListComboBox {
|
||||
* @returns {void}
|
||||
*/
|
||||
set value (value) {
|
||||
this[internal.setState]({value});
|
||||
this[internal.setState]({ value });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ template.innerHTML = `
|
||||
.menu-item {
|
||||
line-height: 1em;
|
||||
padding: 0.5em;
|
||||
border: 1px solid #B0B0B0;
|
||||
border: 1px solid #5a6162;
|
||||
background: #E8E8E8;
|
||||
margin-bottom: -1px;
|
||||
white-space: nowrap;
|
||||
@@ -107,7 +107,7 @@ export class ExplorerButton extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
// locate the component
|
||||
this.$button = this._shadowRoot.querySelector('.menu-button');
|
||||
@@ -124,7 +124,7 @@ export class ExplorerButton extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['title', 'pressed', 'disabled', 'lib', 'src'];
|
||||
return [ 'title', 'pressed', 'disabled', 'lib', 'src' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
@@ -160,7 +160,7 @@ export class ExplorerButton extends HTMLElement {
|
||||
try {
|
||||
const response = await fetch(`${newValue}index.json`);
|
||||
const json = await response.json();
|
||||
const {lib} = json;
|
||||
const { lib } = json;
|
||||
this.$menu.innerHTML = lib.map((menu, i) => (
|
||||
`<div data-menu="${menu}" class="menu-item ${(i === 0) ? 'pressed' : ''} ">${menu}</div>`
|
||||
)).join('');
|
||||
@@ -295,9 +295,9 @@ export class ExplorerButton extends HTMLElement {
|
||||
const size = json.size ?? 300;
|
||||
const fill = json.fill ? '#333' : 'none';
|
||||
const off = size * 0.05;
|
||||
const vb = [-off, -off, size + off * 2, size + off * 2].join(' ');
|
||||
const vb = [ -off, -off, size + off * 2, size + off * 2 ].join(' ');
|
||||
const stroke = json.fill ? 0 : (size / 30);
|
||||
this.$lib.innerHTML = Object.entries(this.data).map(([key, path]) => {
|
||||
this.$lib.innerHTML = Object.entries(this.data).map(([ key, path ]) => {
|
||||
const encoded = btoa(`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">
|
||||
<svg viewBox="${vb}"><path fill="${fill}" stroke="#000" stroke-width="${stroke}" d="${path}"></path></svg>
|
||||
|
||||
@@ -88,7 +88,7 @@ export class FlyingButton extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
// locate the component
|
||||
this.$button = this._shadowRoot.querySelector('.menu-button');
|
||||
@@ -105,7 +105,7 @@ export class FlyingButton extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['title', 'pressed', 'disabled', 'opened'];
|
||||
return [ 'title', 'pressed', 'disabled', 'opened' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
|
||||
@@ -35,7 +35,7 @@ export class SEInput extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
// locate the component
|
||||
this.$img = this._shadowRoot.querySelector('img');
|
||||
@@ -48,7 +48,7 @@ export class SEInput extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['value', 'label', 'src', 'size'];
|
||||
return [ 'value', 'label', 'src', 'size' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
|
||||
@@ -35,7 +35,7 @@ export class SeList extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$dropdown = this._shadowRoot.querySelector('elix-dropdown-list');
|
||||
this.$label = this._shadowRoot.querySelector('label');
|
||||
@@ -45,7 +45,7 @@ export class SeList extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['label', 'width', 'height'];
|
||||
return [ 'label', 'width', 'height' ];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +128,7 @@ export class SeList extends HTMLElement {
|
||||
e.preventDefault();
|
||||
if (e?.detail?.selectedIndex !== undefined) {
|
||||
const value = this.$dropdown.selectedItem.getAttribute('value');
|
||||
const closeEvent = new CustomEvent('change', {detail: {value}});
|
||||
const closeEvent = new CustomEvent('change', { detail: { value } });
|
||||
currentObj.dispatchEvent(closeEvent);
|
||||
currentObj.value = value;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ export class SeListItem extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$menuitem = this._shadowRoot.querySelector('elix-option');
|
||||
this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark');
|
||||
@@ -36,7 +36,7 @@ export class SeListItem extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['option'];
|
||||
return [ 'option' ];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,7 +39,7 @@ export class SeMenu extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$menu = this._shadowRoot.querySelector('elix-menu-button');
|
||||
this.$label = this.$menu.shadowRoot.querySelector('#popupToggle').shadowRoot;
|
||||
@@ -49,7 +49,7 @@ export class SeMenu extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['label', 'src'];
|
||||
return [ 'label', 'src' ];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,7 +22,7 @@ export class SeMenuItem extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$img = this._shadowRoot.querySelector('img');
|
||||
this.$label = this._shadowRoot.querySelector('span');
|
||||
@@ -35,7 +35,7 @@ export class SeMenuItem extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['label', 'src'];
|
||||
return [ 'label', 'src' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
|
||||
@@ -92,21 +92,21 @@ export class SEPalette extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$strip = this._shadowRoot.querySelector('#js-se-palette');
|
||||
palette.forEach((rgb) => {
|
||||
const newDiv = document.createElement('div');
|
||||
newDiv.classList.add('square');
|
||||
if(rgb === 'none') {
|
||||
const img = document.createElement('img');
|
||||
const img = document.createElement('img');
|
||||
img.src = `data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgY2xhc3M9InN2Z19pY29uIj48c3ZnIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgICA8bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiNkNDAwMDAiIGlkPSJzdmdfOTAiIHkyPSIyNCIgeDI9IjI0IiB5MT0iMCIgeDE9IjAiLz4KICAgIDxsaW5lIGlkPSJzdmdfOTIiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2Q0MDAwMCIgeTI9IjI0IiB4Mj0iMCIgeTE9IjAiIHgxPSIyNCIvPgogIDwvc3ZnPjwvc3ZnPg==`;
|
||||
img.style.width = "15px";
|
||||
img.style.height = "15px";
|
||||
newDiv.append(img);
|
||||
} else {
|
||||
newDiv.style.backgroundColor = rgb;
|
||||
}
|
||||
}
|
||||
newDiv.dataset.rgb = rgb;
|
||||
newDiv.addEventListener('click', (evt) => {
|
||||
evt.preventDefault();
|
||||
@@ -117,7 +117,7 @@ export class SEPalette extends HTMLElement {
|
||||
if (color === 'none' || color === 'transparent' || color === 'initial') {
|
||||
color = 'none';
|
||||
}
|
||||
const paletteEvent = new CustomEvent('change', {detail: {picker, color}, bubbles: false});
|
||||
const paletteEvent = new CustomEvent('change', { detail: { picker, color }, bubbles: false });
|
||||
this.dispatchEvent(paletteEvent);
|
||||
});
|
||||
this.$strip.append(newDiv);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {template} from 'elix/src/base/internal.js';
|
||||
import {fragmentFrom} from 'elix/src/core/htmlLiterals.js';
|
||||
import { template } from 'elix/src/base/internal.js';
|
||||
import { fragmentFrom } from 'elix/src/core/htmlLiterals.js';
|
||||
import PlainButton from 'elix/src/plain/PlainButton.js';
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import PlainMenuButton from 'elix/src/plain/PlainMenuButton.js';
|
||||
import {defaultState} from 'elix/src/base/internal.js';
|
||||
import { defaultState } from 'elix/src/base/internal.js';
|
||||
import sePlainBorderButton from './sePlainBorderButton.js';
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,7 +19,7 @@ template.innerHTML = `
|
||||
elix-number-spin-box {
|
||||
background-color: var(--input-color);
|
||||
border-radius: 3px;
|
||||
height: 20px !important;
|
||||
height: 20px;
|
||||
margin-top: 1px;
|
||||
vertical-align: top;
|
||||
}
|
||||
@@ -49,7 +49,7 @@ export class SESpinInput extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
// locate the component
|
||||
this.$img = this._shadowRoot.querySelector('img');
|
||||
@@ -62,7 +62,7 @@ export class SESpinInput extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['value', 'label', 'src', 'size', 'min', 'max', 'step'];
|
||||
return [ 'value', 'label', 'src', 'size', 'min', 'max', 'step' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import ListComboBox from 'elix/define/ListComboBox.js';
|
||||
import * as internal from 'elix/src/base/internal.js';
|
||||
import {templateFrom, fragmentFrom} from 'elix/src/core/htmlLiterals.js';
|
||||
import { templateFrom, fragmentFrom } from 'elix/src/core/htmlLiterals.js';
|
||||
import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js';
|
||||
|
||||
/**
|
||||
@@ -66,7 +66,7 @@ class Zoom extends ListComboBox {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['title', 'src', 'inputsize', 'value'];
|
||||
return [ 'title', 'src', 'inputsize', 'value' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
@@ -115,7 +115,7 @@ class Zoom extends ListComboBox {
|
||||
e.preventDefault();
|
||||
const value = e.detail?.closeResult?.getAttribute('value');
|
||||
if (value) {
|
||||
const closeEvent = new CustomEvent('change', {detail: {value}});
|
||||
const closeEvent = new CustomEvent('change', { detail: { value } });
|
||||
this.dispatchEvent(closeEvent);
|
||||
}
|
||||
});
|
||||
@@ -133,7 +133,7 @@ class Zoom extends ListComboBox {
|
||||
* @returns {void}
|
||||
*/
|
||||
set src (src) {
|
||||
this[internal.setState]({src});
|
||||
this[internal.setState]({ src });
|
||||
}
|
||||
/**
|
||||
* @function inputsize
|
||||
@@ -147,7 +147,7 @@ class Zoom extends ListComboBox {
|
||||
* @returns {void}
|
||||
*/
|
||||
set inputsize (inputsize) {
|
||||
this[internal.setState]({inputsize});
|
||||
this[internal.setState]({ inputsize });
|
||||
}
|
||||
/**
|
||||
* @function value
|
||||
@@ -161,7 +161,7 @@ class Zoom extends ListComboBox {
|
||||
* @returns {void}
|
||||
*/
|
||||
set value (value) {
|
||||
this[internal.setState]({value});
|
||||
this[internal.setState]({ value });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ export const add = function (menuItem) {
|
||||
throw new Error('Cannot add extension "' + menuItem.id + '", an extension by that name already exists"');
|
||||
}
|
||||
// Register menuItem action, see below for deferred menu dom injection
|
||||
console.log('Registered contextmenu item: {id:' + menuItem.id + ', label:' + menuItem.label + '}');
|
||||
contextMenuExtensions[menuItem.id] = menuItem;
|
||||
// TODO: Need to consider how to handle custom enable/disable behavior
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import PlainAlertDialog from 'elix/src/plain/PlainAlertDialog.js';
|
||||
import {template} from 'elix/src/base/internal.js';
|
||||
import {fragmentFrom} from 'elix/src/core/htmlLiterals.js';
|
||||
import { template } from 'elix/src/base/internal.js';
|
||||
import { fragmentFrom } from 'elix/src/core/htmlLiterals.js';
|
||||
|
||||
/**
|
||||
* @class SePlainAlertDialog
|
||||
@@ -52,7 +52,7 @@ export default class SePlainAlertDialog extends PlainAlertDialog {
|
||||
background: #DDD;
|
||||
overflow: auto;
|
||||
text-align: left;
|
||||
border: 1px solid #B0B0B0;
|
||||
border: 1px solid #5a6162;
|
||||
padding: 1em;
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
|
||||
@@ -127,7 +127,7 @@ export class SeCMenuDialog extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this._workarea = document.getElementById('workarea');
|
||||
this.$dialog = this._shadowRoot.querySelector('#cmenu_canvas');
|
||||
@@ -148,7 +148,7 @@ export class SeCMenuDialog extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['disableallmenu', 'enablemenuitems', 'disablemenuitems'];
|
||||
return [ 'disableallmenu', 'enablemenuitems', 'disablemenuitems' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
@@ -251,9 +251,9 @@ export class SeCMenuDialog extends HTMLElement {
|
||||
}
|
||||
};
|
||||
const onMenuClickHandler = (e, action) => {
|
||||
const triggerEvent = new CustomEvent('change', {detail: {
|
||||
const triggerEvent = new CustomEvent('change', { detail: {
|
||||
trigger: action
|
||||
}});
|
||||
} });
|
||||
this.dispatchEvent(triggerEvent);
|
||||
};
|
||||
this._workarea.addEventListener('contextmenu', onMenuOpenHandler);
|
||||
|
||||
@@ -80,7 +80,7 @@ export class SeCMenuLayerDialog extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.source = '';
|
||||
this._workarea = undefined;
|
||||
@@ -96,7 +96,7 @@ export class SeCMenuLayerDialog extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['value', 'leftclick'];
|
||||
return [ 'value', 'leftclick' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
@@ -168,10 +168,10 @@ export class SeCMenuLayerDialog extends HTMLElement {
|
||||
}
|
||||
};
|
||||
const onMenuClickHandler = (e, action, id) => {
|
||||
const triggerEvent = new CustomEvent('change', {detail: {
|
||||
const triggerEvent = new CustomEvent('change', { detail: {
|
||||
trigger: action,
|
||||
source: id
|
||||
}});
|
||||
} });
|
||||
this.dispatchEvent(triggerEvent);
|
||||
current.$dialog.style.display = 'none';
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'elix/define/Dialog.js';
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
@@ -71,7 +70,8 @@ template.innerHTML = `
|
||||
}
|
||||
#svg_prefs #svg_prefs_container {
|
||||
padding: 10px;
|
||||
background-color: #B0B0B0;
|
||||
background-color: #5a6162;
|
||||
color: #c5c5c5;
|
||||
border: 1px outset #777;
|
||||
opacity: 1.0;
|
||||
font-family: Verdana, Helvetica, sans-serif;
|
||||
@@ -83,6 +83,17 @@ template.innerHTML = `
|
||||
margin-left: 1em;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#tool_prefs_save {
|
||||
width: 30%;
|
||||
background-color: #c79605;
|
||||
margin-left: 20%;
|
||||
}
|
||||
|
||||
#tool_prefs_cancel {
|
||||
width: 30%;
|
||||
background-color: #c8c8c8;
|
||||
}
|
||||
|
||||
#svg_prefs #svg_docprops_prefs {
|
||||
float: left;
|
||||
@@ -138,11 +149,9 @@ template.innerHTML = `
|
||||
<div id="svg_prefs_container">
|
||||
<div id="tool_prefs_back" class="toolbar_button">
|
||||
<button id="tool_prefs_save">
|
||||
<img class="svg_icon" src="./images/ok.svg" alt="icon" width="16" height="16" />
|
||||
OK
|
||||
</button>
|
||||
<button id="tool_prefs_cancel">
|
||||
<img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
@@ -241,8 +250,8 @@ export class SeEditPrefsDialog extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this.colorBlocks = ['#FFF', '#888', '#000', 'chessboard'];
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this.colorBlocks = [ '#FFF', '#888', '#000', 'chessboard' ];
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$dialog = this._shadowRoot.querySelector('#svg_prefs');
|
||||
this.$saveBtn = this._shadowRoot.querySelector('#tool_prefs_save');
|
||||
@@ -263,7 +272,7 @@ export class SeEditPrefsDialog extends HTMLElement {
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
// eslint-disable-next-line max-len
|
||||
return ['dialog', 'lang', 'iconsize', 'canvasbg', 'bgurl', 'gridsnappingon', 'gridsnappingstep', 'gridcolor', 'showrulers', 'baseunit'];
|
||||
return [ 'dialog', 'lang', 'iconsize', 'canvasbg', 'bgurl', 'gridsnappingon', 'gridsnappingstep', 'gridcolor', 'showrulers', 'baseunit' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
@@ -484,14 +493,14 @@ export class SeEditPrefsDialog extends HTMLElement {
|
||||
*/
|
||||
connectedCallback () {
|
||||
const onCancelHandler = () => {
|
||||
const closeEvent = new CustomEvent('change', {detail: {
|
||||
const closeEvent = new CustomEvent('change', { detail: {
|
||||
dialog: 'closed'
|
||||
}});
|
||||
} });
|
||||
this.dispatchEvent(closeEvent);
|
||||
};
|
||||
const onSaveHandler = () => {
|
||||
const color = this.$bgBlocks.querySelector('.cur_background').dataset.bgColor || '#FFF';
|
||||
const closeEvent = new CustomEvent('change', {detail: {
|
||||
const closeEvent = new CustomEvent('change', { detail: {
|
||||
lang: this.$langSelect.value,
|
||||
dialog: 'close',
|
||||
iconsize: this.$iconSize.value,
|
||||
@@ -501,7 +510,7 @@ export class SeEditPrefsDialog extends HTMLElement {
|
||||
gridsnappingstep: this.$gridSnappingStep.value,
|
||||
showrulers: this.$showRulers.checked,
|
||||
baseunit: this.$baseUnit.value
|
||||
}});
|
||||
} });
|
||||
this.dispatchEvent(closeEvent);
|
||||
};
|
||||
// Set up editor background functionality
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'elix/define/Dialog.js';
|
||||
import './se-elix/define/NumberSpinBox.js';
|
||||
|
||||
const template = document.createElement('template');
|
||||
@@ -7,10 +6,10 @@ template.innerHTML = `
|
||||
|
||||
#dialog_content {
|
||||
margin: 10px 10px 5px 10px;
|
||||
background: #DDD;
|
||||
background: #5a6162;
|
||||
overflow: auto;
|
||||
text-align: left;
|
||||
border: 1px solid #B0B0B0;
|
||||
border: 1px solid #c8c8c8;
|
||||
}
|
||||
|
||||
#dialog_content p, #dialog_content select, #dialog_content label {
|
||||
@@ -25,7 +24,7 @@ template.innerHTML = `
|
||||
top: 50%;
|
||||
max-width: 400px;
|
||||
z-index: 50001;
|
||||
background: #CCC;
|
||||
background: #5a6162;
|
||||
border: 1px outset #777;
|
||||
font-family:Verdana,Helvetica,sans-serif;
|
||||
font-size:0.8em;
|
||||
@@ -73,11 +72,9 @@ template.innerHTML = `
|
||||
</div>
|
||||
<div id="dialog_buttons">
|
||||
<button id="export_ok">
|
||||
<img class="svg_icon" src="./images/ok.svg" alt="icon" width="16" height="16" />
|
||||
Ok
|
||||
</button>
|
||||
<button id="export_cancel">
|
||||
<img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
@@ -94,7 +91,7 @@ export class SeExportDialog extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$dialog = this._shadowRoot.querySelector('#export_box');
|
||||
this.$okBtn = this._shadowRoot.querySelector('#export_ok');
|
||||
@@ -109,7 +106,7 @@ export class SeExportDialog extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['dialog'];
|
||||
return [ 'dialog' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
@@ -164,11 +161,11 @@ export class SeExportDialog extends HTMLElement {
|
||||
if (action === 'cancel') {
|
||||
document.getElementById('se-export-dialog').setAttribute('dialog', 'close');
|
||||
} else {
|
||||
const triggerEvent = new CustomEvent('change', {detail: {
|
||||
const triggerEvent = new CustomEvent('change', { detail: {
|
||||
trigger: action,
|
||||
imgType: this.$exportOption.value,
|
||||
quality: this.value
|
||||
}});
|
||||
} });
|
||||
this.dispatchEvent(triggerEvent);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'elix/define/Dialog.js';
|
||||
import {isValidUnit} from '../../common/units.js';
|
||||
import { isValidUnit } from '../../common/units.js';
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
@@ -17,7 +16,8 @@ template.innerHTML = `
|
||||
}
|
||||
#svg_docprops #svg_docprops_container {
|
||||
padding: 10px;
|
||||
background-color: #B0B0B0;
|
||||
background-color: #5a6162;
|
||||
color: #c5c5c5;
|
||||
border: 1px outset #777;
|
||||
opacity: 1.0;
|
||||
font-family: Verdana, Helvetica, sans-serif;
|
||||
@@ -127,7 +127,7 @@ export class SeImgPropDialog extends HTMLElement {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this.eventlisten = false;
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$saveBtn = this._shadowRoot.querySelector('#tool_docprops_save');
|
||||
this.$cancelBtn = this._shadowRoot.querySelector('#tool_docprops_cancel');
|
||||
@@ -144,7 +144,7 @@ export class SeImgPropDialog extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['title', 'width', 'height', 'save', 'dialog', 'embed'];
|
||||
return [ 'title', 'width', 'height', 'save', 'dialog', 'embed' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
@@ -343,22 +343,22 @@ export class SeImgPropDialog extends HTMLElement {
|
||||
if (this.$imageOptRef.getAttribute('checked') === 'true') {
|
||||
saveOpt = 'ref';
|
||||
}
|
||||
const closeEvent = new CustomEvent('change', {detail: {
|
||||
const closeEvent = new CustomEvent('change', { detail: {
|
||||
title: this.$canvasTitle.value,
|
||||
w: this.$canvasWidth.value,
|
||||
h: this.$canvasHeight.value,
|
||||
save: saveOpt,
|
||||
dialog: 'close'
|
||||
}});
|
||||
} });
|
||||
this.$canvasWidth.removeAttribute('disabled');
|
||||
this.$canvasHeight.removeAttribute('disabled');
|
||||
this.$resolution.selectedIndex = 0;
|
||||
this.dispatchEvent(closeEvent);
|
||||
};
|
||||
const onCancelHandler = () => {
|
||||
const closeEvent = new CustomEvent('change', {detail: {
|
||||
const closeEvent = new CustomEvent('change', { detail: {
|
||||
dialog: 'closed'
|
||||
}});
|
||||
} });
|
||||
this.$canvasWidth.removeAttribute('disabled');
|
||||
this.$canvasHeight.removeAttribute('disabled');
|
||||
this.$resolution.selectedIndex = 0;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'elix/define/Dialog.js';
|
||||
import './imagePropertiesDialog.js';
|
||||
import './editorPreferencesDialog.js';
|
||||
import './svgSourceDialog.js';
|
||||
|
||||
@@ -3,7 +3,7 @@ import SePlainAlertDialog from './SePlainAlertDialog.js';
|
||||
const seAlert = (text) => {
|
||||
const dialog = new SePlainAlertDialog();
|
||||
dialog.textContent = text;
|
||||
dialog.choices = ['Ok'];
|
||||
dialog.choices = [ 'Ok' ];
|
||||
dialog.open();
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import SePlainAlertDialog from './SePlainAlertDialog.js';
|
||||
const seConfirm = async (text, choices) => {
|
||||
const dialog = new SePlainAlertDialog();
|
||||
dialog.textContent = text;
|
||||
dialog.choices = (choices === undefined) ? ['Ok', 'Cancel'] : choices;
|
||||
dialog.choices = (choices === undefined) ? [ 'Ok', 'Cancel' ] : choices;
|
||||
dialog.open();
|
||||
const response = await dialog.whenClosed();
|
||||
return response.choice;
|
||||
|
||||
@@ -9,7 +9,7 @@ export class SePromptDialog extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this.dialog = new SePlainAlertDialog();
|
||||
}
|
||||
/**
|
||||
@@ -17,7 +17,7 @@ export class SePromptDialog extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['title', 'close'];
|
||||
return [ 'title', 'close' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
@@ -33,7 +33,7 @@ export class SePromptDialog extends HTMLElement {
|
||||
this.dialog.close();
|
||||
}
|
||||
this.dialog.textContent = newValue;
|
||||
this.dialog.choices = ['Cancel'];
|
||||
this.dialog.choices = [ 'Cancel' ];
|
||||
this.dialog.open();
|
||||
break;
|
||||
case 'close':
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import 'elix/define/Dialog.js';
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
@@ -16,7 +14,8 @@ template.innerHTML = `
|
||||
}
|
||||
|
||||
#svg_source_editor #svg_source_container {
|
||||
background-color: #B0B0B0;
|
||||
background-color: #5a6162;
|
||||
color: #c5c5c5;
|
||||
opacity: 1.0;
|
||||
text-align: center;
|
||||
border: 1px outset #777;
|
||||
@@ -44,18 +43,27 @@ template.innerHTML = `
|
||||
|
||||
#svg_source_editor #tool_source_back {
|
||||
text-align: left;
|
||||
margin: 5px 10px;
|
||||
height: 30px;
|
||||
}
|
||||
#tool_source_save {
|
||||
width: 20%;
|
||||
background-color: #c79605;
|
||||
margin-left: 30%;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#tool_source_cancel {
|
||||
width: 20%;
|
||||
background-color: #c8c8c8;
|
||||
}
|
||||
</style>
|
||||
<elix-dialog id="svg_source_editor" aria-label="SVG Source Editor" closed>
|
||||
<div id="svg_source_container">
|
||||
<div id="tool_source_back" class="toolbar_button">
|
||||
<button id="tool_source_save">
|
||||
<img class="svg_icon" src="./images/ok.svg" alt="icon" width="16" height="16" />
|
||||
Apply Changes
|
||||
</button>
|
||||
<button id="tool_source_cancel">
|
||||
<img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
@@ -81,7 +89,7 @@ export class SeSvgSourceEditorDialog extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$dialog = this._shadowRoot.querySelector('#svg_source_editor');
|
||||
this.$copyBtn = this._shadowRoot.querySelector('#copy_save_done');
|
||||
@@ -96,7 +104,7 @@ export class SeSvgSourceEditorDialog extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['dialog', 'value', 'applysec', 'copysec'];
|
||||
return [ 'dialog', 'value', 'applysec', 'copysec' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
@@ -205,9 +213,9 @@ export class SeSvgSourceEditorDialog extends HTMLElement {
|
||||
*/
|
||||
connectedCallback () {
|
||||
const onCancelHandler = () => {
|
||||
const closeEvent = new CustomEvent('change', {detail: {
|
||||
const closeEvent = new CustomEvent('change', { detail: {
|
||||
dialog: 'closed'
|
||||
}});
|
||||
} });
|
||||
this.dispatchEvent(closeEvent);
|
||||
};
|
||||
const onCopyHandler = () => {
|
||||
@@ -220,10 +228,10 @@ export class SeSvgSourceEditorDialog extends HTMLElement {
|
||||
this.dispatchEvent(closeEvent);
|
||||
};
|
||||
const onSaveHandler = () => {
|
||||
const closeEvent = new CustomEvent('change', {detail: {
|
||||
const closeEvent = new CustomEvent('change', { detail: {
|
||||
value: this.$sourceTxt.value,
|
||||
dialog: 'close'
|
||||
}});
|
||||
} });
|
||||
this.dispatchEvent(closeEvent);
|
||||
};
|
||||
this.$copyBtn.addEventListener('click', onCopyHandler);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @module EmbeddedSVGEditDOM
|
||||
*/
|
||||
import EmbeddedSVGEdit from './embedapi.js';
|
||||
import {isChrome} from '../common/browser.js';
|
||||
import { isChrome } from '../common/browser.js';
|
||||
|
||||
let svgCanvas = null;
|
||||
|
||||
@@ -106,8 +106,8 @@ iframe.src = frameBase + framePath +
|
||||
: ''); // Append arguments to this file onto the iframe
|
||||
|
||||
iframe.addEventListener('load', function () {
|
||||
svgCanvas = new EmbeddedSVGEdit(frame, [new URL(frameBase).origin]);
|
||||
const {$id} = svgCanvas;
|
||||
svgCanvas = new EmbeddedSVGEdit(frame, [ new URL(frameBase).origin ]);
|
||||
const { $id } = svgCanvas;
|
||||
// Hide main button, as we will be controlling new, load, save, etc. from the host document
|
||||
let doc;
|
||||
try {
|
||||
|
||||
@@ -43,7 +43,7 @@ function getCallbackSetter (funcName) {
|
||||
* @param {Integer} data.id
|
||||
* @returns {void}
|
||||
*/
|
||||
function addCallback (t, {result, error, id: callbackID}) {
|
||||
function addCallback (t, { result, error, id: callbackID }) {
|
||||
if (typeof callbackID === 'number' && t.callbacks[callbackID]) {
|
||||
// These should be safe both because we check `cbid` is numeric and
|
||||
// because the calls are from trusted origins
|
||||
@@ -62,10 +62,10 @@ function addCallback (t, {result, error, id: callbackID}) {
|
||||
function messageListener (e) {
|
||||
// We accept and post strings as opposed to objects for the sake of IE9 support; this
|
||||
// will most likely be changed in the future
|
||||
if (!e.data || !['string', 'object'].includes(typeof e.data)) {
|
||||
if (!e.data || ![ 'string', 'object' ].includes(typeof e.data)) {
|
||||
return;
|
||||
}
|
||||
const {allowedOrigins} = this,
|
||||
const { allowedOrigins } = this,
|
||||
data = typeof e.data === 'object' ? e.data : JSON.parse(e.data);
|
||||
if (!data || typeof data !== 'object' || data.namespace !== 'svg-edit' ||
|
||||
e.source !== this.frame.contentWindow ||
|
||||
@@ -329,10 +329,10 @@ class EmbeddedSVGEdit {
|
||||
// Older IE may need a polyfill for addEventListener, but so it would for SVG
|
||||
window.addEventListener('message', getMessageListener(this));
|
||||
window.addEventListener('keydown', (e) => {
|
||||
const {type, key} = e;
|
||||
const { type, key } = e;
|
||||
if (key === 'Backspace') {
|
||||
e.preventDefault();
|
||||
const keyboardEvent = new KeyboardEvent(type, {key});
|
||||
const keyboardEvent = new KeyboardEvent(type, { key });
|
||||
that.frame.contentDocument.dispatchEvent(keyboardEvent);
|
||||
}
|
||||
});
|
||||
@@ -372,8 +372,8 @@ class EmbeddedSVGEdit {
|
||||
// of the current JSON-based communication API (e.g., not passing
|
||||
// callbacks). We might be able to address these shortcomings; see
|
||||
// the todo elsewhere in this file.
|
||||
const message = {id: callbackID},
|
||||
{svgEditor: {canvas: svgCanvas}} = that.frame.contentWindow;
|
||||
const message = { id: callbackID },
|
||||
{ svgEditor: { canvas: svgCanvas } } = that.frame.contentWindow;
|
||||
try {
|
||||
message.result = svgCanvas[name](...args);
|
||||
} catch (err) {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
const loadExtensionTranslation = async function (svgEditor) {
|
||||
let translationModule;
|
||||
const lang = svgEditor.configObj.pref('lang')
|
||||
const lang = svgEditor.configObj.pref('lang');
|
||||
try {
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
|
||||
@@ -26,11 +26,11 @@ export default {
|
||||
async init (S) {
|
||||
const svgEditor = this;
|
||||
const strings = await loadExtensionTranslation(svgEditor);
|
||||
const {svgCanvas} = svgEditor;
|
||||
const {$id} = svgCanvas;
|
||||
const { svgCanvas } = svgEditor;
|
||||
const { $id } = svgCanvas;
|
||||
const
|
||||
addElem = svgCanvas.addSVGElementFromJson,
|
||||
{nonce} = S,
|
||||
{ nonce } = S,
|
||||
prefix = 'se_arrow_';
|
||||
|
||||
let selElems, arrowprefix, randomizeIds = S.randomize_ids;
|
||||
@@ -64,8 +64,8 @@ export default {
|
||||
arrowprefix = (randomizeIds) ? `${prefix}${nonce}_` : prefix;
|
||||
|
||||
const pathdata = {
|
||||
fw: {d: 'm0,0l10,5l-10,5l5,-5l-5,-5z', refx: 8, id: arrowprefix + 'fw'},
|
||||
bk: {d: 'm10,0l-10,5l10,5l-5,-5l5,-5z', refx: 2, id: arrowprefix + 'bk'}
|
||||
fw: { d: 'm0,0l10,5l-10,5l5,-5l-5,-5z', refx: 8, id: arrowprefix + 'fw' },
|
||||
bk: { d: 'm10,0l-10,5l10,5l-5,-5l5,-5z', refx: 2, id: arrowprefix + 'bk' }
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -214,14 +214,14 @@ export default {
|
||||
*/
|
||||
function colorChanged (elem) {
|
||||
const color = elem.getAttribute('stroke');
|
||||
const mtypes = ['start', 'mid', 'end'];
|
||||
const mtypes = [ 'start', 'mid', 'end' ];
|
||||
const defs = svgCanvas.findDefs();
|
||||
|
||||
mtypes.forEach(function(type){
|
||||
const marker = getLinked(elem, 'marker-' + type);
|
||||
if (!marker) { return; }
|
||||
|
||||
const curColor = marker.children.getAttribute('fill');
|
||||
const curColor = marker.children.getAttribute('fill');
|
||||
const curD = marker.children.getAttribute('d');
|
||||
if (curColor === color) { return; }
|
||||
|
||||
@@ -290,12 +290,12 @@ export default {
|
||||
}),
|
||||
callback () {
|
||||
$id("arrow_panel").style.display = 'none';
|
||||
|
||||
|
||||
// Set ID so it can be translated in locale file
|
||||
$id('arrow_list option').setAttribute('id', 'connector_no_arrow');
|
||||
},
|
||||
async addLangData ({_lang, importLocale}) {
|
||||
const {langList} = await importLocale();
|
||||
async addLangData ({ _lang, importLocale }) {
|
||||
const { langList } = await importLocale();
|
||||
return {
|
||||
data: langList
|
||||
};
|
||||
@@ -304,7 +304,7 @@ export default {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
const markerElems = ['line', 'path', 'polyline', 'polygon'];
|
||||
const markerElems = [ 'line', 'path', 'polyline', 'polygon' ];
|
||||
let i = selElems.length;
|
||||
while (i--) {
|
||||
const elem = selElems[i];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export default {
|
||||
name: 'Arrows',
|
||||
langList: [
|
||||
{id: 'arrow_none', textContent: 'No arrow'}
|
||||
{ id: 'arrow_none', textContent: 'No arrow' }
|
||||
],
|
||||
contextTools: [
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export default {
|
||||
name: 'Arrows',
|
||||
langList: [
|
||||
{id: 'arrow_none', textContent: 'Sans flèche'}
|
||||
{ id: 'arrow_none', textContent: 'Sans flèche' }
|
||||
],
|
||||
contextTools: [
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export default {
|
||||
name: '箭头',
|
||||
langList: [
|
||||
{id: 'arrow_none', textContent: '无箭头'}
|
||||
{ id: 'arrow_none', textContent: '无箭头' }
|
||||
],
|
||||
contextTools: [
|
||||
{
|
||||
|
||||
@@ -24,10 +24,10 @@ const loadExtensionTranslation = async function (lang) {
|
||||
// The button toggles whether the path is open or closed
|
||||
export default {
|
||||
name: 'closepath',
|
||||
async init ({_importLocale}) {
|
||||
async init ({ _importLocale }) {
|
||||
const svgEditor = this;
|
||||
const {svgCanvas} = svgEditor;
|
||||
const {$id} = svgCanvas;
|
||||
const { svgCanvas } = svgEditor;
|
||||
const { $id } = svgCanvas;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
let selElems;
|
||||
const updateButton = function (path) {
|
||||
|
||||
@@ -79,7 +79,7 @@ export default {
|
||||
x: midX + lenX * ratio,
|
||||
y: midY + lenY * ratio
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {"start"|"end"} side
|
||||
@@ -92,7 +92,7 @@ export default {
|
||||
// TODO: Make this number (5) be based on marker width/height
|
||||
const size = line.getAttribute('stroke-width') * 5;
|
||||
return giveOffset ? size : 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} on
|
||||
@@ -108,7 +108,7 @@ export default {
|
||||
connRules.textContent = (!on ? '' : '#tool_clone, #tool_topath, #tool_angle, #xy_panel { display: none !important; }');
|
||||
if ($id('connector_panel'))
|
||||
$id('connector_panel').style.display = (on) ? 'block' : 'none';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Element} elem
|
||||
@@ -144,7 +144,7 @@ export default {
|
||||
const ptEnd = pts.getItem(pts.numberOfItems - 1);
|
||||
setPoint(elem, 1, (ptEnd.x + ptStart.x) / 2, (ptEnd.y + ptStart.y) / 2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Float} diffX
|
||||
@@ -184,7 +184,7 @@ export default {
|
||||
const pt2 = getBBintersect(pt.x, pt.y, dataStorage.get(line, altPre + '_bb'), getOffset(altPre, line));
|
||||
setPoint(line, conn.is_start ? 'end' : 0, pt2.x, pt2.y, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -202,7 +202,7 @@ export default {
|
||||
let addThis;
|
||||
// Grab the ends
|
||||
const parts = [];
|
||||
['start', 'end'].forEach(function (pos, i) {
|
||||
[ 'start', 'end' ].forEach(function (pos, i) {
|
||||
const key = 'c_' + pos;
|
||||
let part = dataStorage.get(ethis, key);
|
||||
if (part === null || part === undefined) { // Does this ever return nullish values?
|
||||
@@ -210,7 +210,7 @@ export default {
|
||||
ethis.attributes['se:connector'].value.split(' ')[i]
|
||||
);
|
||||
dataStorage.put(ethis, 'c_' + pos, part.id);
|
||||
dataStorage.put(ethis, pos + '_bb', svgCanvas.getStrokedBBox([part]));
|
||||
dataStorage.put(ethis, pos + '_bb', svgCanvas.getStrokedBBox([ part ]));
|
||||
} else part = document.getElementById(part);
|
||||
parts.push(part);
|
||||
}, ethis);
|
||||
@@ -233,7 +233,7 @@ export default {
|
||||
continue;
|
||||
}
|
||||
if (elems.includes(cElem) || addThis) {
|
||||
const bb = svgCanvas.getStrokedBBox([cElem]);
|
||||
const bb = svgCanvas.getStrokedBBox([ cElem ]);
|
||||
connections.push({
|
||||
elem: cElem,
|
||||
connector: ethis,
|
||||
@@ -244,7 +244,7 @@ export default {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Element[]} [elems=selElems]
|
||||
@@ -268,7 +268,7 @@ export default {
|
||||
const pre = conn.is_start ? 'start' : 'end';
|
||||
|
||||
// Update bbox for this element
|
||||
const bb = svgCanvas.getStrokedBBox([elem]);
|
||||
const bb = svgCanvas.getStrokedBBox([ elem ]);
|
||||
bb.x = conn.start_x;
|
||||
bb.y = conn.start_y;
|
||||
dataStorage.put(line, pre + '_bb', bb);
|
||||
@@ -302,7 +302,7 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Do once
|
||||
(function () {
|
||||
@@ -338,8 +338,8 @@ export default {
|
||||
if (conn) {
|
||||
curthis.setAttribute('class', 'se_connector');
|
||||
const connData = conn.split(' ');
|
||||
const sbb = svgCanvas.getStrokedBBox([getElem(connData[0])]);
|
||||
const ebb = svgCanvas.getStrokedBBox([getElem(connData[1])]);
|
||||
const sbb = svgCanvas.getStrokedBBox([ getElem(connData[0]) ]);
|
||||
const ebb = svgCanvas.getStrokedBBox([ getElem(connData[1]) ]);
|
||||
dataStorage.put(curthis, 'c_start', connData[0]);
|
||||
dataStorage.put(curthis, 'c_end', connData[1]);
|
||||
dataStorage.put(curthis, 'start_bb', sbb);
|
||||
@@ -347,7 +347,7 @@ export default {
|
||||
svgCanvas.getEditorNS(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
return {
|
||||
@@ -359,7 +359,7 @@ export default {
|
||||
const buttonTemplate = document.createElement("template");
|
||||
buttonTemplate.innerHTML = `
|
||||
<se-button id="mode_connect" title="Connect two objects" src="./images/conn.svg"></se-button>
|
||||
`
|
||||
`;
|
||||
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
||||
$id('mode_connect').addEventListener("click", () => {
|
||||
svgCanvas.setMode('connector');
|
||||
@@ -393,7 +393,7 @@ export default {
|
||||
startElem = fo ? fo : mouseTarget;
|
||||
|
||||
// Get center of source element
|
||||
const bb = svgCanvas.getStrokedBBox([startElem]);
|
||||
const bb = svgCanvas.getStrokedBBox([ startElem ]);
|
||||
const x = bb.x + bb.width / 2;
|
||||
const y = bb.y + bb.height / 2;
|
||||
|
||||
@@ -453,7 +453,7 @@ export default {
|
||||
// Look for selected connector elements
|
||||
if (elem && dataStorage.has(elem, 'c_start')) {
|
||||
// Remove the "translate" transform given to move
|
||||
svgCanvas.removeFromSelection([elem]);
|
||||
svgCanvas.removeFromSelection([ elem ]);
|
||||
svgCanvas.getTransformList(elem).clear();
|
||||
}
|
||||
}
|
||||
@@ -520,7 +520,7 @@ export default {
|
||||
};
|
||||
}
|
||||
|
||||
const bb = svgCanvas.getStrokedBBox([endElem]);
|
||||
const bb = svgCanvas.getStrokedBBox([ endElem ]);
|
||||
|
||||
const pt = getBBintersect(startX, startY, bb, getOffset('start', curLine));
|
||||
setPoint(curLine, 'end', pt.x, pt.y, true);
|
||||
@@ -531,7 +531,7 @@ export default {
|
||||
curLine.setAttributeNS(seNs, 'se:connector', connStr);
|
||||
curLine.setAttribute('class', 'se_connector');
|
||||
curLine.setAttribute('opacity', 1);
|
||||
svgCanvas.addToSelection([curLine]);
|
||||
svgCanvas.addToSelection([ curLine ]);
|
||||
svgCanvas.moveToBottomSelectedElement();
|
||||
selManager.requestSelector(curLine).showGrips(false);
|
||||
started = false;
|
||||
@@ -618,14 +618,14 @@ export default {
|
||||
elem.remove();
|
||||
svgCanvas.clearSelection();
|
||||
pline.id = id;
|
||||
svgCanvas.addToSelection([pline]);
|
||||
svgCanvas.addToSelection([ pline ]);
|
||||
elem = pline;
|
||||
}
|
||||
}
|
||||
// Update line if it's a connector
|
||||
if (elem.getAttribute('class') === 'se_connector') {
|
||||
const start = getElem(dataStorage.get(elem, 'c_start'));
|
||||
updateConnectors([start]);
|
||||
updateConnectors([ start ]);
|
||||
} else {
|
||||
updateConnectors();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export default {
|
||||
name: 'Connector',
|
||||
langList: [
|
||||
{id: 'mode_connect', title: 'Connect two objects'}
|
||||
{ id: 'mode_connect', title: 'Connect two objects' }
|
||||
],
|
||||
buttons: [
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export default {
|
||||
name: 'Connector',
|
||||
langList: [
|
||||
{id: 'mode_connect', title: 'Connecter deux objets'}
|
||||
{ id: 'mode_connect', title: 'Connecter deux objets' }
|
||||
],
|
||||
buttons: [
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export default {
|
||||
name: '连接器',
|
||||
langList: [
|
||||
{id: 'mode_connect', title: '连接两个对象'}
|
||||
{ id: 'mode_connect', title: '连接两个对象' }
|
||||
],
|
||||
buttons: [
|
||||
{
|
||||
|
||||
@@ -4,27 +4,32 @@
|
||||
* @license MIT
|
||||
*
|
||||
* @copyright 2010 Jeff Schiller
|
||||
* @copyright 2021 OptimistikSAS
|
||||
*
|
||||
*/
|
||||
|
||||
const loadExtensionTranslation = async function (lang) {
|
||||
const name = "eyedropper";
|
||||
|
||||
const loadExtensionTranslation = async function (svgEditor) {
|
||||
let translationModule;
|
||||
const lang = svgEditor.configObj.pref('lang');
|
||||
try {
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
|
||||
translationModule = await import(`./locale/${lang}.js`);
|
||||
} catch (_error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`Missing translation (${lang}) - using 'en'`);
|
||||
console.warn(`Missing translation (${lang}) for ${name} - using 'en'`);
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
translationModule = await import(`./locale/en.js`);
|
||||
}
|
||||
return translationModule.default;
|
||||
svgEditor.i18next.addResourceBundle(lang, name, translationModule.default);
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'eyedropper',
|
||||
name,
|
||||
async init(S) {
|
||||
const svgEditor = this;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
await loadExtensionTranslation(svgEditor);
|
||||
const { ChangeElementCommand } = S, // , svgcontent,
|
||||
// svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||
{ svgCanvas } = svgEditor,
|
||||
@@ -53,7 +58,7 @@ export default {
|
||||
// enable-eye-dropper if one element is selected
|
||||
let elem = null;
|
||||
if (!opts.multiselected && opts.elems[0] &&
|
||||
!['svg', 'g', 'use'].includes(opts.elems[0].nodeName)
|
||||
![ 'svg', 'g', 'use' ].includes(opts.elems[0].nodeName)
|
||||
) {
|
||||
elem = opts.elems[0];
|
||||
tool.classList.remove('disabled');
|
||||
@@ -71,16 +76,19 @@ export default {
|
||||
} else {
|
||||
tool.classList.add('disabled');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
name: strings.name,
|
||||
name: svgEditor.i18next.t(`${name}:name`),
|
||||
callback() {
|
||||
// Add the button and its handler(s)
|
||||
const buttonTemplate = document.createElement("template");
|
||||
const title = svgEditor.i18next.t(`${name}:buttons.0.title`);
|
||||
const key = svgEditor.i18next.t(`${name}:buttons.0.key`);
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
buttonTemplate.innerHTML = `
|
||||
<se-button id="tool_eyedropper" title="Eye Dropper Tool" src="./images/eye_dropper.svg" shortcut="I"></se-button>
|
||||
`
|
||||
<se-button id="tool_eyedropper" title="${title}" src="./images/eye_dropper.svg" shortcut=${key}></se-button>
|
||||
`;
|
||||
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
||||
$id('tool_eyedropper').addEventListener("click", () => {
|
||||
svgCanvas.setMode('eyedropper');
|
||||
@@ -94,7 +102,7 @@ export default {
|
||||
if (mode === 'eyedropper') {
|
||||
const e = opts.event;
|
||||
const { target } = e;
|
||||
if (!['svg', 'g', 'use'].includes(target.nodeName)) {
|
||||
if (![ 'svg', 'g', 'use' ].includes(target.nodeName)) {
|
||||
const changes = {};
|
||||
|
||||
const change = function (elem, attrname, newvalue) {
|
||||
|
||||
9
src/editor/extensions/ext-eyedropper/locale/fr.js
Normal file
@@ -0,0 +1,9 @@
|
||||
export default {
|
||||
name: 'pipette',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Outil pipette',
|
||||
key: 'I'
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -24,9 +24,9 @@ export default {
|
||||
name: 'foreignobject',
|
||||
async init (S) {
|
||||
const svgEditor = this;
|
||||
const {text2xml, NS} = S;
|
||||
const {svgCanvas} = svgEditor;
|
||||
const {$id} = svgCanvas;
|
||||
const { text2xml, NS } = S;
|
||||
const { svgCanvas } = svgEditor;
|
||||
const { $id } = svgCanvas;
|
||||
const
|
||||
// {svgcontent} = S,
|
||||
// addElem = svgCanvas.addSVGElementFromJson,
|
||||
@@ -49,7 +49,7 @@ export default {
|
||||
if (!fcRules) {
|
||||
fcRules = document.createElement('style');
|
||||
fcRules.setAttribute('id', 'fc_rules');
|
||||
document.getElementsByTagName("head")[0].appendChild(fcRules);
|
||||
document.getElementsByTagName("head")[0].appendChild(fcRules);
|
||||
}
|
||||
fcRules.textContent = !on ? '' : ' #tool_topath { display: none !important; }';
|
||||
$id('foreignObject_panel').style.display = (on) ? 'block' : 'none';
|
||||
@@ -85,11 +85,11 @@ export default {
|
||||
// run it through our sanitizer to remove anything we do not support
|
||||
svgCanvas.sanitizeSvg(newDoc.documentElement);
|
||||
elt.replaceWith(svgdoc.importNode(newDoc.documentElement.firstChild, true));
|
||||
svgCanvas.call('changed', [elt]);
|
||||
svgCanvas.call('changed', [ elt ]);
|
||||
svgCanvas.clearSelection();
|
||||
} catch (e) {
|
||||
// Todo: Surface error to user
|
||||
console.log(e);
|
||||
console.log(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ export default {
|
||||
svgCanvas.call('changed', selElems);
|
||||
}
|
||||
|
||||
const buttons = [{
|
||||
const buttons = [ {
|
||||
id: 'tool_foreign',
|
||||
icon: 'foreignobject-tool.png',
|
||||
type: 'mode',
|
||||
@@ -143,7 +143,7 @@ export default {
|
||||
showForeignEditor();
|
||||
}
|
||||
}
|
||||
}];
|
||||
} ];
|
||||
|
||||
const contextTools = [
|
||||
{
|
||||
@@ -277,9 +277,9 @@ export default {
|
||||
const attrs = {
|
||||
width: newFO.getAttribute('width'),
|
||||
height: newFO.getAttribute('height'),
|
||||
}
|
||||
};
|
||||
const keep = (attrs.width !== '0' || attrs.height !== '0');
|
||||
svgCanvas.addToSelection([newFO], true);
|
||||
svgCanvas.addToSelection([ newFO ], true);
|
||||
|
||||
return {
|
||||
keep,
|
||||
|
||||
@@ -7,32 +7,36 @@
|
||||
*
|
||||
*/
|
||||
|
||||
const loadExtensionTranslation = async function (lang) {
|
||||
const name = "grid";
|
||||
|
||||
const loadExtensionTranslation = async function (svgEditor) {
|
||||
let translationModule;
|
||||
const lang = svgEditor.configObj.pref('lang');
|
||||
try {
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
|
||||
translationModule = await import(`./locale/${lang}.js`);
|
||||
} catch (_error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`Missing translation (${lang}) - using 'en'`);
|
||||
console.warn(`Missing translation (${lang}) for ${name} - using 'en'`);
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
translationModule = await import(`./locale/en.js`);
|
||||
}
|
||||
return translationModule.default;
|
||||
svgEditor.i18next.addResourceBundle(lang, name, translationModule.default);
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'grid',
|
||||
async init ({NS, getTypeMap}) {
|
||||
name,
|
||||
async init ({ NS, getTypeMap }) {
|
||||
const svgEditor = this;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
const {svgCanvas} = svgEditor;
|
||||
const {$id} = svgCanvas;
|
||||
await loadExtensionTranslation(svgEditor);
|
||||
const { svgCanvas } = svgEditor;
|
||||
const { $id } = svgCanvas;
|
||||
const svgdoc = document.getElementById('svgcanvas').ownerDocument;
|
||||
const {assignAttributes} = svgCanvas;
|
||||
const { assignAttributes } = svgCanvas;
|
||||
const hcanvas = document.createElement('canvas');
|
||||
const canvBG = $id('canvasBackground');
|
||||
const units = getTypeMap(); // Assumes prior `init()` call on `units.js` module
|
||||
const intervals = [0.01, 0.1, 1, 10, 100, 1000];
|
||||
const intervals = [ 0.01, 0.1, 1, 10, 100, 1000 ];
|
||||
let showGrid = svgEditor.configObj.curConfig.showGrid || false;
|
||||
|
||||
hcanvas.style.display = 'none';
|
||||
@@ -138,7 +142,7 @@ export default {
|
||||
gridimg.parentNode.setAttribute('width', bigInt);
|
||||
gridimg.parentNode.setAttribute('height', bigInt);
|
||||
svgCanvas.setHref(gridimg, datauri);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -150,23 +154,26 @@ export default {
|
||||
}
|
||||
$id('canvasGrid').style.display = (showGrid) ? 'block' : 'none';
|
||||
document.getElementById('view_grid').pressed = showGrid;
|
||||
}
|
||||
};
|
||||
return {
|
||||
name: strings.name,
|
||||
name: svgEditor.i18next.t(`${name}:name`),
|
||||
zoomChanged (zoom) {
|
||||
if (showGrid) { updateGrid(zoom); }
|
||||
},
|
||||
callback () {
|
||||
// Add the button and its handler(s)
|
||||
const buttonTemplate = document.createElement("template");
|
||||
const title = svgEditor.i18next.t(`${name}:buttons.0.title`);
|
||||
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
buttonTemplate.innerHTML = `
|
||||
<se-button id="view_grid" title="Show grid" src="./images/grid.svg"></se-button>
|
||||
`
|
||||
<se-button id="view_grid" title="${title}" src="./images/grid.svg"></se-button>
|
||||
`;
|
||||
$id('editor_panel').append(buttonTemplate.content.cloneNode(true));
|
||||
$id('view_grid').addEventListener("click", () => {
|
||||
svgEditor.configObj.curConfig.showGrid = showGrid = !showGrid;
|
||||
gridUpdate();
|
||||
});
|
||||
});
|
||||
|
||||
if (showGrid) {
|
||||
gridUpdate();
|
||||
|
||||
8
src/editor/extensions/ext-grid/locale/fr.js
Normal file
@@ -0,0 +1,8 @@
|
||||
export default {
|
||||
name: 'Grille',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Afficher/Cacher Grille'
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -13,39 +13,45 @@
|
||||
* will show the user the point on the canvas that was clicked on.
|
||||
*/
|
||||
|
||||
const loadExtensionTranslation = async function (lang) {
|
||||
const name = "helloworld";
|
||||
|
||||
const loadExtensionTranslation = async function (svgEditor) {
|
||||
let translationModule;
|
||||
const lang = svgEditor.configObj.pref('lang');
|
||||
try {
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
|
||||
translationModule = await import(`./locale/${lang}.js`);
|
||||
} catch (_error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`Missing translation (${lang}) - using 'en'`);
|
||||
console.warn(`Missing translation (${lang}) for ${name} - using 'en'`);
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
translationModule = await import(`./locale/en.js`);
|
||||
}
|
||||
return translationModule.default;
|
||||
svgEditor.i18next.addResourceBundle(lang, name, translationModule.default);
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'helloworld',
|
||||
async init ({_importLocale}) {
|
||||
name,
|
||||
async init ({ _importLocale }) {
|
||||
const svgEditor = this;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
const {svgCanvas} = svgEditor;
|
||||
await loadExtensionTranslation(svgEditor);
|
||||
const { svgCanvas } = svgEditor;
|
||||
const { $id } = svgCanvas;
|
||||
return {
|
||||
name: strings.name,
|
||||
events: [{
|
||||
// Must match the icon ID in helloworld-icon.xml
|
||||
id: 'hello_world',
|
||||
// Tooltip text
|
||||
title: strings.buttons[0].title,
|
||||
click () {
|
||||
// The action taken when the button is clicked on.
|
||||
// For "mode" buttons, any other button will
|
||||
// automatically be de-pressed.
|
||||
name: svgEditor.i18next.t(`${name}:name`),
|
||||
callback() {
|
||||
// Add the button and its handler(s)
|
||||
const buttonTemplate = document.createElement("template");
|
||||
const title = svgEditor.i18next.t(`${name}:buttons.0.title`);
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
buttonTemplate.innerHTML = `
|
||||
<se-button id="hello_world" title="${title}" src="./images/hello_world.svg"></se-button>
|
||||
`;
|
||||
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
||||
$id('hello_world').addEventListener("click", () => {
|
||||
svgCanvas.setMode('hello_world');
|
||||
}
|
||||
}],
|
||||
});
|
||||
},
|
||||
// This is triggered when the main mouse button is pressed down
|
||||
// on the editor canvas (not the tool panels)
|
||||
mouseDown () {
|
||||
@@ -53,7 +59,7 @@ export default {
|
||||
if (svgCanvas.getMode() === 'hello_world') {
|
||||
// The returned object must include "started" with
|
||||
// a value of true in order for mouseUp to be triggered
|
||||
return {started: true};
|
||||
return { started: true };
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
@@ -70,16 +76,9 @@ export default {
|
||||
const y = opts.mouse_y / zoom;
|
||||
|
||||
// We do our own formatting
|
||||
let {text} = strings;
|
||||
[
|
||||
['x', x],
|
||||
['y', y]
|
||||
].forEach(([prop, val]) => {
|
||||
text = text.replace('{' + prop + '}', val);
|
||||
});
|
||||
|
||||
let text = svgEditor.i18next.t(`${name}:text`, { x, y });
|
||||
// Show the text using the custom alert function
|
||||
alert(text);
|
||||
alert(text);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export default {
|
||||
name: 'Hello World',
|
||||
text: 'Hello World!\n\nYou clicked here: {x}, {y}',
|
||||
text: 'Hello World!\n\nYou clicked here: {{x}}, {{y}}',
|
||||
buttons: [
|
||||
{
|
||||
title: "Say 'Hello World'"
|
||||
|
||||
9
src/editor/extensions/ext-helloworld/locale/fr.js
Normal file
@@ -0,0 +1,9 @@
|
||||
export default {
|
||||
name: 'Bonjour le Monde',
|
||||
text: 'Bonjour le Monde!\n\nVous avez cliqué ici: {{x}}, {{y}}',
|
||||
buttons: [
|
||||
{
|
||||
title: "Dire 'Bonjour le Monde'"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
export default {
|
||||
name: 'Hello World',
|
||||
text: 'Hello World!\n\n 请点击: {x}, {y}',
|
||||
text: 'Hello World!\n\n 请点击: {{x}}, {{y}}',
|
||||
buttons: [
|
||||
{
|
||||
title: "输出 'Hello World'"
|
||||
|
||||
@@ -29,7 +29,7 @@ export default {
|
||||
const { $id } = svgEditor.svgCanvas;
|
||||
const imagelibStrings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
|
||||
const { uiStrings, svgCanvas } = svgEditor;
|
||||
const { svgCanvas } = svgEditor;
|
||||
|
||||
const allowedImageLibOrigins = imagelibStrings.imgLibs.map(({ url }) => {
|
||||
try {
|
||||
@@ -46,7 +46,7 @@ export default {
|
||||
const closeBrowser = () => {
|
||||
$id("imgbrowse_holder").style.display = 'none';
|
||||
document.activeElement.blur(); // make sure focus is the body to correct issue #417
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
@@ -65,9 +65,9 @@ export default {
|
||||
}
|
||||
});
|
||||
svgCanvas.clearSelection();
|
||||
svgCanvas.addToSelection([newImage]);
|
||||
svgCanvas.addToSelection([ newImage ]);
|
||||
svgCanvas.setImageURL(url);
|
||||
}
|
||||
};
|
||||
|
||||
const pending = {};
|
||||
|
||||
@@ -112,8 +112,9 @@ export default {
|
||||
* @param {ImageLibMetaMessage|ImageLibMessage|string} cfg.data String is deprecated when parsed to JSON `ImageLibMessage`
|
||||
* @returns {void}
|
||||
*/
|
||||
async function onMessage({ origin, data: response }) {
|
||||
if (!response || !['string', 'object'].includes(typeof response)) {
|
||||
async function onMessage({ origin, data }) {
|
||||
let response = data;
|
||||
if (!response || ![ 'string', 'object' ].includes(typeof response)) {
|
||||
// Do nothing
|
||||
return;
|
||||
}
|
||||
@@ -129,7 +130,7 @@ export default {
|
||||
}
|
||||
if (!allowedImageLibOrigins.includes('*') && !allowedImageLibOrigins.includes(origin)) {
|
||||
// Todo: Surface this error to user?
|
||||
console.log(`Origin ${origin} not whitelisted for posting to ${window.origin}`);
|
||||
console.error(`Origin ${origin} not whitelisted for posting to ${window.origin}`);
|
||||
return;
|
||||
}
|
||||
const hasName = 'name' in response;
|
||||
@@ -184,7 +185,7 @@ export default {
|
||||
|
||||
const name = (curMeta.name || 'file');
|
||||
|
||||
const message = uiStrings.notification.retrieving.replace('%s', name);
|
||||
const message = svgEditor.i18next.t('notification.retrieving').replace('%s', name);
|
||||
|
||||
if (mode !== 'm') {
|
||||
await seConfirm(message);
|
||||
@@ -250,7 +251,7 @@ export default {
|
||||
break;
|
||||
case 'm': {
|
||||
// Import multiple
|
||||
multiArr.push([(svgStr ? 'svg' : 'img'), response]);
|
||||
multiArr.push([ (svgStr ? 'svg' : 'img'), response ]);
|
||||
curMeta = pending[id];
|
||||
let title;
|
||||
if (svgStr) {
|
||||
@@ -290,7 +291,7 @@ export default {
|
||||
const img = document.createElement("img");
|
||||
img.src = curMeta.preview_url;
|
||||
entry.appendChild(img);
|
||||
entry.appendChild(document.createTextNode(title))
|
||||
entry.appendChild(document.createTextNode(title));
|
||||
} else {
|
||||
entry = document.createElement("img");
|
||||
entry.src = response;
|
||||
@@ -330,7 +331,7 @@ export default {
|
||||
|
||||
const insertAfter = (referenceNode, newNode) => {
|
||||
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleMultiLoop = () => {
|
||||
multiArr.forEach(function(item, i){
|
||||
@@ -347,7 +348,7 @@ export default {
|
||||
preview.removeChild(preview.firstChild);
|
||||
multiArr = [];
|
||||
$id("imgbrowse_holder").style.display = 'none';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} show
|
||||
@@ -375,7 +376,7 @@ export default {
|
||||
submit.style.display = (show) ? 'block' : 'none';
|
||||
preview.style.display = (show) ? 'block' : 'none';
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -411,7 +412,7 @@ export default {
|
||||
|
||||
const button = document.createElement('button');
|
||||
// eslint-disable-next-line max-len
|
||||
button.innerHTML = '<img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />' + uiStrings.common.cancel;
|
||||
button.innerHTML = '<img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />' + svgEditor.i18next.t('common.cancel');
|
||||
browser.appendChild(button);
|
||||
button.addEventListener('click', function () {
|
||||
$id("imgbrowse_holder").style.display = 'none';
|
||||
@@ -496,7 +497,7 @@ export default {
|
||||
} else {
|
||||
$id("imgbrowse_holder").style.display = 'block';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
svgicons: 'ext-imagelib.xml',
|
||||
@@ -529,7 +530,7 @@ export default {
|
||||
'bottom: 25px;' +
|
||||
'min-width: 300px;' +
|
||||
'min-height: 200px;' +
|
||||
'background: #B0B0B0;' +
|
||||
'background: #5a6162;' +
|
||||
'border: 1px outset #777;' +
|
||||
'}' +
|
||||
'#imgbrowse h1 {' +
|
||||
@@ -567,7 +568,7 @@ export default {
|
||||
'list-style: none;' +
|
||||
'padding: .5em;' +
|
||||
'background: #E8E8E8;' +
|
||||
'border-bottom: 1px solid #B0B0B0;' +
|
||||
'border-bottom: 1px solid #5a6162;' +
|
||||
'line-height: 1.2em;' +
|
||||
'font-style: sans-serif;' +
|
||||
'}' +
|
||||
|
||||
@@ -48,5 +48,5 @@ Array.prototype.forEach.call(atags, function (aEle) {
|
||||
}, 'html'); // 'html' is necessary to keep returned data as a string
|
||||
}
|
||||
return false;
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import {jml, body, nbsp} from 'jamilih';
|
||||
import { jml, body, nbsp } from 'jamilih';
|
||||
import $ from 'query-result';
|
||||
import {manipulation} from 'qr-manipulation';
|
||||
import { manipulation } from 'qr-manipulation';
|
||||
|
||||
manipulation($, jml);
|
||||
|
||||
@@ -20,32 +20,31 @@ async function processResults (url) {
|
||||
* @returns {external:JamilihArray}
|
||||
*/
|
||||
function queryLink (query) {
|
||||
return ['a', {
|
||||
return [ 'a', {
|
||||
href: jsVoid,
|
||||
dataset: {value: query},
|
||||
$on: {click (e) {
|
||||
dataset: { value: query },
|
||||
$on: { click (e) {
|
||||
e.preventDefault();
|
||||
const {value} = this.dataset;
|
||||
const { value } = this.dataset;
|
||||
$('#query')[0].$set(value);
|
||||
$('#openclipart')[0].$submit();
|
||||
}}
|
||||
}, [query]];
|
||||
} }
|
||||
}, [ query ] ];
|
||||
}
|
||||
|
||||
const r = await fetch(url);
|
||||
const json = await r.json();
|
||||
// console.log('json', json);
|
||||
|
||||
if (!json || json.msg !== 'success') {
|
||||
// Todo: This could use a generic alert library instead
|
||||
alert('There was a problem downloading the results');
|
||||
alert('There was a problem downloading the results');
|
||||
return;
|
||||
}
|
||||
const {payload, info: {
|
||||
const { payload, info: {
|
||||
results: numResults,
|
||||
pages,
|
||||
current_page: currentPage
|
||||
}} = json;
|
||||
} } = json;
|
||||
|
||||
// $('#page')[0].value = currentPage;
|
||||
// $('#page')[0].max = pages;
|
||||
@@ -60,21 +59,21 @@ async function processResults (url) {
|
||||
// - `svg`'s: `png_thumb`, `png_full_lossy`, `png_2400px`
|
||||
const semiColonSep = '; ' + nbsp;
|
||||
$('#results').jml('div', [
|
||||
['span', [
|
||||
[ 'span', [
|
||||
'Number of results: ',
|
||||
numResults
|
||||
]],
|
||||
] ],
|
||||
semiColonSep,
|
||||
['span', [
|
||||
[ 'span', [
|
||||
'page ',
|
||||
currentPage,
|
||||
' out of ',
|
||||
pages
|
||||
]],
|
||||
] ],
|
||||
...payload.map(({
|
||||
title, description, id,
|
||||
uploader, created,
|
||||
svg: {url: svgURL},
|
||||
svg: { url: svgURL },
|
||||
detail_link: detailLink,
|
||||
tags_array: tagsArray,
|
||||
downloaded_by: downloadedBy,
|
||||
@@ -82,12 +81,11 @@ async function processResults (url) {
|
||||
}) => {
|
||||
const imgHW = '100px';
|
||||
const colonSep = ': ' + nbsp;
|
||||
return ['div', [
|
||||
['button', {style: 'margin-right: 8px; border: 2px solid black;', dataset: {id, value: svgURL}, $on: {
|
||||
return [ 'div', [
|
||||
[ 'button', { style: 'margin-right: 8px; border: 2px solid black;', dataset: { id, value: svgURL }, $on: {
|
||||
async click (e) {
|
||||
e.preventDefault();
|
||||
const {value: svgurl} = this.dataset;
|
||||
// console.log('this', id, svgurl);
|
||||
const { value: svgurl } = this.dataset;
|
||||
const post = (message) => {
|
||||
// Todo: Make origin customizable as set by opening window
|
||||
// Todo: If dropping IE9, avoid stringifying
|
||||
@@ -103,79 +101,78 @@ async function processResults (url) {
|
||||
});
|
||||
const result = await fetch(svgurl);
|
||||
const svg = await result.text();
|
||||
// console.log('url and svg', svgurl, svg);
|
||||
post({
|
||||
href: svgurl,
|
||||
data: svg
|
||||
});
|
||||
}
|
||||
}}, [
|
||||
} }, [
|
||||
// If we wanted interactive versions despite security risk:
|
||||
// ['object', {data: svgURL, type: 'image/svg+xml'}]
|
||||
['img', {src: svgURL, style: `width: ${imgHW}; height: ${imgHW};`}]
|
||||
]],
|
||||
['b', [title]],
|
||||
[ 'img', { src: svgURL, style: `width: ${imgHW}; height: ${imgHW};` } ]
|
||||
] ],
|
||||
[ 'b', [ title ] ],
|
||||
' ',
|
||||
['i', [description]],
|
||||
[ 'i', [ description ] ],
|
||||
' ',
|
||||
['span', [
|
||||
[ 'span', [
|
||||
'(ID: ',
|
||||
['a', {
|
||||
[ 'a', {
|
||||
href: jsVoid,
|
||||
dataset: {value: id},
|
||||
dataset: { value: id },
|
||||
$on: {
|
||||
click (e) {
|
||||
e.preventDefault();
|
||||
const {value} = this.dataset;
|
||||
const { value } = this.dataset;
|
||||
$('#byids')[0].$set(value);
|
||||
$('#openclipart')[0].$submit();
|
||||
}
|
||||
}
|
||||
}, [id]],
|
||||
}, [ id ] ],
|
||||
')'
|
||||
]],
|
||||
] ],
|
||||
' ',
|
||||
['i', [
|
||||
['a', {
|
||||
[ 'i', [
|
||||
[ 'a', {
|
||||
href: detailLink,
|
||||
target: '_blank'
|
||||
}, ['Details']]
|
||||
]],
|
||||
['br'],
|
||||
['span', [
|
||||
['u', ['Uploaded by']], colonSep,
|
||||
}, [ 'Details' ] ]
|
||||
] ],
|
||||
[ 'br' ],
|
||||
[ 'span', [
|
||||
[ 'u', [ 'Uploaded by' ] ], colonSep,
|
||||
queryLink(uploader),
|
||||
semiColonSep
|
||||
]],
|
||||
['span', [
|
||||
['u', ['Download count']], colonSep,
|
||||
] ],
|
||||
[ 'span', [
|
||||
[ 'u', [ 'Download count' ] ], colonSep,
|
||||
downloadedBy,
|
||||
semiColonSep
|
||||
]],
|
||||
['span', [
|
||||
['u', ['Times used as favorite']], colonSep,
|
||||
] ],
|
||||
[ 'span', [
|
||||
[ 'u', [ 'Times used as favorite' ] ], colonSep,
|
||||
totalFavorites,
|
||||
semiColonSep
|
||||
]],
|
||||
['span', [
|
||||
['u', ['Created date']], colonSep,
|
||||
] ],
|
||||
[ 'span', [
|
||||
[ 'u', [ 'Created date' ] ], colonSep,
|
||||
created
|
||||
]],
|
||||
['br'],
|
||||
['u', ['Tags']], colonSep,
|
||||
] ],
|
||||
[ 'br' ],
|
||||
[ 'u', [ 'Tags' ] ], colonSep,
|
||||
...tagsArray.map((tag) => {
|
||||
return ['span', [
|
||||
return [ 'span', [
|
||||
' ',
|
||||
queryLink(tag)
|
||||
]];
|
||||
] ];
|
||||
})
|
||||
]];
|
||||
] ];
|
||||
}),
|
||||
['br'], ['br'],
|
||||
[ 'br' ], [ 'br' ],
|
||||
(currentPage === 1 || pages <= 2
|
||||
? ''
|
||||
: ['span', [
|
||||
['a', {
|
||||
: [ 'span', [
|
||||
[ 'a', {
|
||||
href: jsVoid,
|
||||
$on: {
|
||||
click (e) {
|
||||
@@ -184,14 +181,14 @@ async function processResults (url) {
|
||||
$('#openclipart')[0].$submit();
|
||||
}
|
||||
}
|
||||
}, ['First']],
|
||||
}, [ 'First' ] ],
|
||||
' '
|
||||
]]
|
||||
] ]
|
||||
),
|
||||
(currentPage === 1
|
||||
? ''
|
||||
: ['span', [
|
||||
['a', {
|
||||
: [ 'span', [
|
||||
[ 'a', {
|
||||
href: jsVoid,
|
||||
$on: {
|
||||
click (e) {
|
||||
@@ -200,14 +197,14 @@ async function processResults (url) {
|
||||
$('#openclipart')[0].$submit();
|
||||
}
|
||||
}
|
||||
}, ['Prev']],
|
||||
}, [ 'Prev' ] ],
|
||||
' '
|
||||
]]
|
||||
] ]
|
||||
),
|
||||
(currentPage === pages
|
||||
? ''
|
||||
: ['span', [
|
||||
['a', {
|
||||
: [ 'span', [
|
||||
[ 'a', {
|
||||
href: jsVoid,
|
||||
$on: {
|
||||
click (e) {
|
||||
@@ -216,14 +213,14 @@ async function processResults (url) {
|
||||
$('#openclipart')[0].$submit();
|
||||
}
|
||||
}
|
||||
}, ['Next']],
|
||||
}, [ 'Next' ] ],
|
||||
' '
|
||||
]]
|
||||
] ]
|
||||
),
|
||||
(currentPage === pages || pages <= 2
|
||||
? ''
|
||||
: ['span', [
|
||||
['a', {
|
||||
: [ 'span', [
|
||||
[ 'a', {
|
||||
href: jsVoid,
|
||||
$on: {
|
||||
click (e) {
|
||||
@@ -232,20 +229,20 @@ async function processResults (url) {
|
||||
$('#openclipart')[0].$submit();
|
||||
}
|
||||
}
|
||||
}, ['Last']],
|
||||
}, [ 'Last' ] ],
|
||||
' '
|
||||
]]
|
||||
] ]
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
jml('div', [
|
||||
['style', [
|
||||
[ 'style', [
|
||||
`.control {
|
||||
padding-top: 10px;
|
||||
}`
|
||||
]],
|
||||
['form', {
|
||||
] ],
|
||||
[ 'form', {
|
||||
id: 'openclipart',
|
||||
$custom: {
|
||||
async $submit () {
|
||||
@@ -253,7 +250,7 @@ jml('div', [
|
||||
[
|
||||
'query', 'sort', 'amount', 'page', 'byids'
|
||||
].forEach((prop) => {
|
||||
const {value} = $('#' + prop)[0];
|
||||
const { value } = $('#' + prop)[0];
|
||||
if (value) {
|
||||
url.searchParams.set(prop, value);
|
||||
}
|
||||
@@ -269,12 +266,12 @@ jml('div', [
|
||||
}
|
||||
}, [
|
||||
// Todo: i18nize
|
||||
['fieldset', [
|
||||
['legend', ['Search terms']],
|
||||
['div', {class: 'control'}, [
|
||||
['label', [
|
||||
[ 'fieldset', [
|
||||
[ 'legend', [ 'Search terms' ] ],
|
||||
[ 'div', { class: 'control' }, [
|
||||
[ 'label', [
|
||||
'Query (Title, description, uploader, or tag): ',
|
||||
['input', {id: 'query', name: 'query', placeholder: 'cat', $custom: {
|
||||
[ 'input', { id: 'query', name: 'query', placeholder: 'cat', $custom: {
|
||||
$set (value) {
|
||||
$('#byids')[0].value = '';
|
||||
this.value = value;
|
||||
@@ -283,16 +280,16 @@ jml('div', [
|
||||
change () {
|
||||
$('#byids')[0].value = '';
|
||||
}
|
||||
}}]
|
||||
]]
|
||||
]],
|
||||
['br'],
|
||||
} } ]
|
||||
] ]
|
||||
] ],
|
||||
[ 'br' ],
|
||||
' OR ',
|
||||
['br'],
|
||||
['div', {class: 'control'}, [
|
||||
['label', [
|
||||
[ 'br' ],
|
||||
[ 'div', { class: 'control' }, [
|
||||
[ 'label', [
|
||||
'IDs (single or comma-separated): ',
|
||||
['input', {id: 'byids', name: 'ids', placeholder: '271380, 265741', $custom: {
|
||||
[ 'input', { id: 'byids', name: 'ids', placeholder: '271380, 265741', $custom: {
|
||||
$set (value) {
|
||||
$('#query')[0].value = '';
|
||||
this.value = value;
|
||||
@@ -301,47 +298,47 @@ jml('div', [
|
||||
change () {
|
||||
$('#query')[0].value = '';
|
||||
}
|
||||
}}]
|
||||
]]
|
||||
]]
|
||||
]],
|
||||
['fieldset', [
|
||||
['legend', ['Configuring results']],
|
||||
['div', {class: 'control'}, [
|
||||
['label', [
|
||||
} } ]
|
||||
] ]
|
||||
] ]
|
||||
] ],
|
||||
[ 'fieldset', [
|
||||
[ 'legend', [ 'Configuring results' ] ],
|
||||
[ 'div', { class: 'control' }, [
|
||||
[ 'label', [
|
||||
'Sort by: ',
|
||||
['select', {id: 'sort'}, [
|
||||
[ 'select', { id: 'sort' }, [
|
||||
// Todo: i18nize first values
|
||||
['Date', 'date'],
|
||||
['Downloads', 'downloads'],
|
||||
['Favorited', 'favorites']
|
||||
].map(([text, value = text]) => {
|
||||
return ['option', {value}, [text]];
|
||||
})]
|
||||
]]
|
||||
]],
|
||||
['div', {class: 'control'}, [
|
||||
['label', [
|
||||
[ 'Date', 'date' ],
|
||||
[ 'Downloads', 'downloads' ],
|
||||
[ 'Favorited', 'favorites' ]
|
||||
].map(([ text, value = text ]) => {
|
||||
return [ 'option', { value }, [ text ] ];
|
||||
}) ]
|
||||
] ]
|
||||
] ],
|
||||
[ 'div', { class: 'control' }, [
|
||||
[ 'label', [
|
||||
'Results per page: ',
|
||||
['input', {
|
||||
[ 'input', {
|
||||
id: 'amount', name: 'amount', value: 10,
|
||||
type: 'number', min: 1, max: 200, step: 1, pattern: '\\d+'}]
|
||||
]]
|
||||
]],
|
||||
['div', {class: 'control'}, [
|
||||
['label', [
|
||||
type: 'number', min: 1, max: 200, step: 1, pattern: '\\d+' } ]
|
||||
] ]
|
||||
] ],
|
||||
[ 'div', { class: 'control' }, [
|
||||
[ 'label', [
|
||||
'Page number: ',
|
||||
['input', {
|
||||
[ 'input', {
|
||||
// max: 1, // We'll change this based on available results
|
||||
id: 'page', name: 'page', value: 1, style: 'width: 40px;',
|
||||
type: 'number', min: 1, step: 1, pattern: '\\d+'
|
||||
}]
|
||||
]]
|
||||
]]
|
||||
]],
|
||||
['div', {class: 'control'}, [
|
||||
['input', {type: 'submit'}]
|
||||
]]
|
||||
]],
|
||||
['div', {id: 'results'}]
|
||||
} ]
|
||||
] ]
|
||||
] ]
|
||||
] ],
|
||||
[ 'div', { class: 'control' }, [
|
||||
[ 'input', { type: 'submit' } ]
|
||||
] ]
|
||||
] ],
|
||||
[ 'div', { id: 'results' } ]
|
||||
], body);
|
||||
|
||||
@@ -47,12 +47,12 @@ export default {
|
||||
async init (S) {
|
||||
const svgEditor = this;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
const {$} = S;
|
||||
const {svgCanvas} = svgEditor;
|
||||
const {$id} = svgCanvas;
|
||||
const { $ } = S;
|
||||
const { svgCanvas } = svgEditor;
|
||||
const { $id } = svgCanvas;
|
||||
const // {svgcontent} = S,
|
||||
addElem = svgCanvas.addSVGElementFromJson;
|
||||
const mtypes = ['start', 'mid', 'end'];
|
||||
const mtypes = [ 'start', 'mid', 'end' ];
|
||||
const markerPrefix = 'se_marker_';
|
||||
const idPrefix = 'mkr_';
|
||||
|
||||
@@ -64,35 +64,35 @@ export default {
|
||||
const markerTypes = {
|
||||
nomarker: {},
|
||||
leftarrow:
|
||||
{element: 'path', attr: {d: 'M0,50 L100,90 L70,50 L100,10 Z'}},
|
||||
{ element: 'path', attr: { d: 'M0,50 L100,90 L70,50 L100,10 Z' } },
|
||||
rightarrow:
|
||||
{element: 'path', attr: {d: 'M100,50 L0,90 L30,50 L0,10 Z'}},
|
||||
{ element: 'path', attr: { d: 'M100,50 L0,90 L30,50 L0,10 Z' } },
|
||||
textmarker:
|
||||
{element: 'text', attr: {
|
||||
{ element: 'text', attr: {
|
||||
x: 0, y: 0, 'stroke-width': 0, stroke: 'none',
|
||||
'font-size': 75, 'font-family': 'serif', 'text-anchor': 'left',
|
||||
'xml:space': 'preserve'
|
||||
}},
|
||||
} },
|
||||
forwardslash:
|
||||
{element: 'path', attr: {d: 'M30,100 L70,0'}},
|
||||
{ element: 'path', attr: { d: 'M30,100 L70,0' } },
|
||||
reverseslash:
|
||||
{element: 'path', attr: {d: 'M30,0 L70,100'}},
|
||||
{ element: 'path', attr: { d: 'M30,0 L70,100' } },
|
||||
verticalslash:
|
||||
{element: 'path', attr: {d: 'M50,0 L50,100'}},
|
||||
{ element: 'path', attr: { d: 'M50,0 L50,100' } },
|
||||
box:
|
||||
{element: 'path', attr: {d: 'M20,20 L20,80 L80,80 L80,20 Z'}},
|
||||
{ element: 'path', attr: { d: 'M20,20 L20,80 L80,80 L80,20 Z' } },
|
||||
star:
|
||||
{element: 'path', attr: {d: 'M10,30 L90,30 L20,90 L50,10 L80,90 Z'}},
|
||||
{ element: 'path', attr: { d: 'M10,30 L90,30 L20,90 L50,10 L80,90 Z' } },
|
||||
xmark:
|
||||
{element: 'path', attr: {d: 'M20,80 L80,20 M80,80 L20,20'}},
|
||||
{ element: 'path', attr: { d: 'M20,80 L80,20 M80,80 L20,20' } },
|
||||
triangle:
|
||||
{element: 'path', attr: {d: 'M10,80 L50,20 L80,80 Z'}},
|
||||
{ element: 'path', attr: { d: 'M10,80 L50,20 L80,80 Z' } },
|
||||
mcircle:
|
||||
{element: 'circle', attr: {r: 30, cx: 50, cy: 50}}
|
||||
{ element: 'circle', attr: { r: 30, cx: 50, cy: 50 } }
|
||||
};
|
||||
|
||||
// duplicate shapes to support unfilled (open) marker types with an _o suffix
|
||||
['leftarrow', 'rightarrow', 'box', 'star', 'mcircle', 'triangle'].forEach((v) => {
|
||||
[ 'leftarrow', 'rightarrow', 'box', 'star', 'mcircle', 'triangle' ].forEach((v) => {
|
||||
markerTypes[v + '_o'] = markerTypes[v];
|
||||
});
|
||||
|
||||
@@ -123,8 +123,6 @@ export default {
|
||||
function setIcon (pos, id) {
|
||||
if (id.substr(0, 1) !== '\\') { id = '\\textmarker'; }
|
||||
const ci = idPrefix + pos + '_' + id.substr(1);
|
||||
console.log(ci)
|
||||
console.log('cur_' + pos + '_marker_list')
|
||||
svgEditor.setIcon('cur_' + pos + '_marker_list', $id(ci).children);
|
||||
$id(ci).classList.add('current');
|
||||
const siblings = Array.prototype.filter.call($id(ci).parentNode.children, function(child){
|
||||
@@ -288,7 +286,7 @@ export default {
|
||||
const x2 = Number(elem.getAttribute('x2'));
|
||||
const y1 = Number(elem.getAttribute('y1'));
|
||||
const y2 = Number(elem.getAttribute('y2'));
|
||||
const {id} = elem;
|
||||
const { id } = elem;
|
||||
|
||||
const midPt = (' ' + ((x1 + x2) / 2) + ',' + ((y1 + y2) / 2) + ' ');
|
||||
const pline = addElem({
|
||||
@@ -315,7 +313,7 @@ export default {
|
||||
elem.remove();
|
||||
svgCanvas.clearSelection();
|
||||
pline.id = id;
|
||||
svgCanvas.addToSelection([pline]);
|
||||
svgCanvas.addToSelection([ pline ]);
|
||||
S.addCommandToHistory(batchCmd);
|
||||
return pline;
|
||||
}
|
||||
@@ -325,7 +323,7 @@ export default {
|
||||
* @returns {void}
|
||||
*/
|
||||
function setMarker () {
|
||||
const poslist = {start_marker: 'start', mid_marker: 'mid', end_marker: 'end'};
|
||||
const poslist = { start_marker: 'start', mid_marker: 'mid', end_marker: 'end' };
|
||||
const pos = poslist[this.id];
|
||||
const markerName = 'marker-' + pos;
|
||||
const el = selElems[0];
|
||||
@@ -471,7 +469,7 @@ export default {
|
||||
* @returns {string}
|
||||
*/
|
||||
function getTitle (id) {
|
||||
const {langList} = strings;
|
||||
const { langList } = strings;
|
||||
const item = langList.find((itm) => {
|
||||
return itm.id === id;
|
||||
});
|
||||
@@ -519,7 +517,7 @@ export default {
|
||||
icon: id + '.svg',
|
||||
title,
|
||||
type: 'context',
|
||||
events: {click: setArrowFromButton},
|
||||
events: { click: setArrowFromButton },
|
||||
panel: 'marker_panel',
|
||||
list: listname,
|
||||
isDefault: def
|
||||
@@ -536,38 +534,38 @@ export default {
|
||||
panel: 'marker_panel',
|
||||
id: 'start_marker',
|
||||
size: 3,
|
||||
events: {change: setMarker}
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
id: 'start_marker_list',
|
||||
colnum: 3,
|
||||
events: {change: setArrowFromButton}
|
||||
events: { change: setArrowFromButton }
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'marker_panel',
|
||||
id: 'mid_marker',
|
||||
defval: '',
|
||||
size: 3,
|
||||
events: {change: setMarker}
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
id: 'mid_marker_list',
|
||||
colnum: 3,
|
||||
events: {change: setArrowFromButton}
|
||||
events: { change: setArrowFromButton }
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'marker_panel',
|
||||
id: 'end_marker',
|
||||
size: 3,
|
||||
events: {change: setMarker}
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
id: 'end_marker_list',
|
||||
colnum: 3,
|
||||
events: {change: setArrowFromButton}
|
||||
events: { change: setArrowFromButton }
|
||||
}
|
||||
];
|
||||
|
||||
@@ -580,15 +578,14 @@ export default {
|
||||
$id("marker_panel").style.display = 'none';
|
||||
}
|
||||
},
|
||||
/* async */ addLangData ({_importLocale, _lang}) {
|
||||
return {data: strings.langList};
|
||||
/* async */ addLangData ({ _importLocale, _lang }) {
|
||||
return { data: strings.langList };
|
||||
},
|
||||
selectedChanged (opts) {
|
||||
// Use this to update the current selected elements
|
||||
// console.log('selectChanged',opts);
|
||||
selElems = opts.elems;
|
||||
|
||||
const markerElems = ['line', 'path', 'polyline', 'polygon'];
|
||||
const markerElems = [ 'line', 'path', 'polyline', 'polygon' ];
|
||||
|
||||
let i = selElems.length;
|
||||
while (i--) {
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
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'}
|
||||
{ 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: [
|
||||
{
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
export default {
|
||||
name: '标记',
|
||||
langList: [
|
||||
{id: 'nomarker', title: '无标记'},
|
||||
{id: 'leftarrow', title: '左箭头'},
|
||||
{id: 'rightarrow', title: '右箭头'},
|
||||
{id: 'textmarker', title: '文本'},
|
||||
{id: 'forwardslash', title: '斜杠'},
|
||||
{id: 'reverseslash', title: '反斜杠'},
|
||||
{id: 'verticalslash', title: '垂直线'},
|
||||
{id: 'box', title: '方块'},
|
||||
{id: 'star', title: '星形'},
|
||||
{id: 'xmark', title: 'X'},
|
||||
{id: 'triangle', title: '三角形'},
|
||||
{id: 'mcircle', title: '圆形'},
|
||||
{id: 'leftarrow_o', title: '左箭头(空心)'},
|
||||
{id: 'rightarrow_o', title: '右箭头(空心)'},
|
||||
{id: 'box_o', title: '方块(空心)'},
|
||||
{id: 'star_o', title: '星形(空心)'},
|
||||
{id: 'triangle_o', title: '三角形(空心)'},
|
||||
{id: 'mcircle_o', title: '圆形(空心)'}
|
||||
{ id: 'nomarker', title: '无标记' },
|
||||
{ id: 'leftarrow', title: '左箭头' },
|
||||
{ id: 'rightarrow', title: '右箭头' },
|
||||
{ id: 'textmarker', title: '文本' },
|
||||
{ id: 'forwardslash', title: '斜杠' },
|
||||
{ id: 'reverseslash', title: '反斜杠' },
|
||||
{ id: 'verticalslash', title: '垂直线' },
|
||||
{ id: 'box', title: '方块' },
|
||||
{ id: 'star', title: '星形' },
|
||||
{ id: 'xmark', title: 'X' },
|
||||
{ id: 'triangle', title: '三角形' },
|
||||
{ id: 'mcircle', title: '圆形' },
|
||||
{ id: 'leftarrow_o', title: '左箭头(空心)' },
|
||||
{ id: 'rightarrow_o', title: '右箭头(空心)' },
|
||||
{ id: 'box_o', title: '方块(空心)' },
|
||||
{ id: 'star_o', title: '星形(空心)' },
|
||||
{ id: 'triangle_o', title: '三角形(空心)' },
|
||||
{ id: 'mcircle_o', title: '圆形(空心)' }
|
||||
],
|
||||
contextTools: [
|
||||
{
|
||||
|
||||
@@ -23,11 +23,11 @@ const loadExtensionTranslation = async function (lang) {
|
||||
|
||||
export default {
|
||||
name: 'mathjax',
|
||||
async init ({$}) {
|
||||
async init ({ $ }) {
|
||||
const svgEditor = this;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
const {svgCanvas} = svgEditor;
|
||||
const {$id} = svgCanvas;
|
||||
const { svgCanvas } = svgEditor;
|
||||
const { $id } = svgCanvas;
|
||||
|
||||
// Configuration of the MathJax extention.
|
||||
|
||||
@@ -57,7 +57,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
|
||||
{uiStrings} = svgEditor;
|
||||
{ uiStrings } = svgEditor;
|
||||
let
|
||||
math,
|
||||
locationX,
|
||||
@@ -86,7 +86,7 @@ export default {
|
||||
const code = $id('mathjax_code_textarea').value;
|
||||
// displaystyle to force MathJax NOT to use the inline style. Because it is
|
||||
// less fancy!
|
||||
MathJax.Hub.queue.Push(['Text', math, '\\displaystyle{' + code + '}']);
|
||||
MathJax.Hub.queue.Push([ 'Text', math, '\\displaystyle{' + code + '}' ]);
|
||||
|
||||
/*
|
||||
* The MathJax library doesn't want to bloat your webpage so it creates
|
||||
@@ -134,7 +134,7 @@ export default {
|
||||
);
|
||||
}
|
||||
|
||||
const buttons = [{
|
||||
const buttons = [ {
|
||||
id: 'tool_mathjax',
|
||||
type: 'mode',
|
||||
icon: 'mathjax.png',
|
||||
@@ -167,7 +167,7 @@ export default {
|
||||
'</span></label>' +
|
||||
'<textarea id="mathjax_code_textarea" spellcheck="false"></textarea>' +
|
||||
'</fieldset>' +
|
||||
'</div>';
|
||||
'</div>';
|
||||
$id('svg_prefs').parentNode.insertBefore(div, $id('svg_prefs').nextSibling);
|
||||
div.style.display = 'none';
|
||||
// Add functionality and picture to cancel button.
|
||||
@@ -191,19 +191,18 @@ export default {
|
||||
// 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');
|
||||
console.info('MathJax Loaded');
|
||||
});
|
||||
} catch (e) {
|
||||
console.log('Failed loading MathJax.');
|
||||
console.warn('Failed loading MathJax.');
|
||||
// eslint-disable-next-line no-alert
|
||||
alert('Failed loading MathJax. You will not be able to change the mathematics.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}];
|
||||
} ];
|
||||
|
||||
return {
|
||||
name: strings.name,
|
||||
@@ -214,7 +213,7 @@ export default {
|
||||
|
||||
mouseDown () {
|
||||
if (svgCanvas.getMode() === 'mathjax') {
|
||||
return {started: true};
|
||||
return { started: true };
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
@@ -227,7 +226,7 @@ export default {
|
||||
locationY = opts.mouse_y / zoom;
|
||||
|
||||
$id("mathjax").style.display = 'block';
|
||||
return {started: false}; // Otherwise the last selected object dissapears.
|
||||
return { started: false }; // Otherwise the last selected object dissapears.
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
@@ -260,7 +259,7 @@ export default {
|
||||
'position: absolute;' +
|
||||
'top: 50px;' +
|
||||
'padding: 10px;' +
|
||||
'background-color: #B0B0B0;' +
|
||||
'background-color: #5a6162;' +
|
||||
'border: 1px outset #777;' +
|
||||
'opacity: 1.0;' +
|
||||
'font-family: Verdana, Helvetica, sans-serif;' +
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
export default {
|
||||
name: 'opensave',
|
||||
init ({encode64}) {
|
||||
init ({ encode64 }) {
|
||||
const svgEditor = this;
|
||||
|
||||
svgEditor.setCustomHandlers({
|
||||
@@ -44,7 +44,7 @@ export default {
|
||||
const done = this.configObj.pref('save_notice_done');
|
||||
|
||||
if (done !== 'all') {
|
||||
const note = svgEditor.i18next.t('notification.saveFromBrowser', { type: 'SVG'});
|
||||
const note = svgEditor.i18next.t('notification.saveFromBrowser', { type: 'SVG' });
|
||||
|
||||
this.configObj.pref('save_notice_done', 'all');
|
||||
if (done !== 'part') {
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
// https://github.com/knadh/dragmove.js
|
||||
// Kailash Nadh (c) 2020.
|
||||
// MIT License.
|
||||
// can't use npm version as the dragmove is different.
|
||||
|
||||
let _loaded = false;
|
||||
let _callbacks = [];
|
||||
const _isTouch = window.ontouchstart !== undefined;
|
||||
|
||||
export const dragmove = function(target, handler, parent, onStart, onEnd, onDrag) {
|
||||
// Register a global event to capture mouse moves (once).
|
||||
if (!_loaded) {
|
||||
document.addEventListener(_isTouch ? "touchmove" : "mousemove", function(e) {
|
||||
let c = e;
|
||||
if (e.touches) {
|
||||
c = e.touches[0];
|
||||
}
|
||||
|
||||
// On mouse move, dispatch the coords to all registered callbacks.
|
||||
for (let i = 0; i < _callbacks.length; i++) {
|
||||
_callbacks[i](c.clientX, c.clientY);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_loaded = true;
|
||||
let isMoving = false, hasStarted = false;
|
||||
let startX = 0, startY = 0, lastX = 0, lastY = 0;
|
||||
|
||||
// On the first click and hold, record the offset of the pointer in relation
|
||||
// to the point of click inside the element.
|
||||
handler.addEventListener(_isTouch ? "touchstart" : "mousedown", function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (target.dataset.dragEnabled === "false") {
|
||||
return;
|
||||
}
|
||||
|
||||
let c = e;
|
||||
if (e.touches) {
|
||||
c = e.touches[0];
|
||||
}
|
||||
|
||||
isMoving = true;
|
||||
startX = target.offsetLeft - c.clientX;
|
||||
startY = target.offsetTop - c.clientY;
|
||||
});
|
||||
|
||||
// On leaving click, stop moving.
|
||||
document.addEventListener(_isTouch ? "touchend" : "mouseup", function() {
|
||||
if (onEnd && hasStarted) {
|
||||
onEnd(target, parent, parseInt(target.style.left), parseInt(target.style.top));
|
||||
}
|
||||
|
||||
isMoving = false;
|
||||
hasStarted = false;
|
||||
});
|
||||
|
||||
// On leaving click, stop moving.
|
||||
document.addEventListener(_isTouch ? "touchmove" : "mousemove", function() {
|
||||
if (onDrag && hasStarted) {
|
||||
onDrag(target, parseInt(target.style.left), parseInt(target.style.top));
|
||||
}
|
||||
});
|
||||
|
||||
// Register mouse-move callback to move the element.
|
||||
_callbacks.push(function move(x, y) {
|
||||
if (!isMoving) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasStarted) {
|
||||
hasStarted = true;
|
||||
if (onStart) {
|
||||
onStart(target, lastX, lastY);
|
||||
}
|
||||
}
|
||||
|
||||
lastX = x + startX;
|
||||
lastY = y + startY;
|
||||
|
||||
// If boundary checking is on, don't let the element cross the viewport.
|
||||
if (target.dataset.dragBoundary === "true") {
|
||||
if (lastX < 1 || lastX >= window.innerWidth - target.offsetWidth) {
|
||||
return;
|
||||
}
|
||||
if (lastY < 1 || lastY >= window.innerHeight - target.offsetHeight) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
target.style.left = lastX + "px";
|
||||
target.style.top = lastY + "px";
|
||||
});
|
||||
};
|
||||
|
||||
export { dragmove as default };
|
||||
@@ -7,13 +7,13 @@
|
||||
* @copyright 2013 James Sacksteder
|
||||
*
|
||||
*/
|
||||
import { dragmove } from '../../../editor/dragmove/dragmove.js';
|
||||
import { dragmove } from './dragmove/dragmove.js';
|
||||
|
||||
export default {
|
||||
name: 'overview_window',
|
||||
init ({_$, isChrome}) {
|
||||
init ({ _$, isChrome }) {
|
||||
const svgEditor = this;
|
||||
const {$id} = svgEditor.svgCanvas;
|
||||
const { $id } = svgEditor.svgCanvas;
|
||||
const overviewWindowGlobals = {};
|
||||
// Disabled in Chrome 48-, see https://github.com/SVG-Edit/svgedit/issues/26 and
|
||||
// https://code.google.com/p/chromium/issues/detail?id=565120.
|
||||
@@ -119,12 +119,12 @@ export default {
|
||||
if((el.offsetLeft + el.offsetWidth) > parseFloat(getComputedStyle(parent, null).width.replace("px", ""))){
|
||||
el.style.left = (parseFloat(getComputedStyle(parent, null).width.replace("px", "")) - el.offsetWidth) + 'px';
|
||||
} else if(el.offsetLeft < 0){
|
||||
el.style.left = "0px"
|
||||
el.style.left = "0px";
|
||||
}
|
||||
if((el.offsetTop + el.offsetHeight) > parseFloat(getComputedStyle(parent, null).height.replace("px", ""))){
|
||||
el.style.top = (parseFloat(getComputedStyle(parent, null).height.replace("px", "")) - el.offsetHeight) + 'px';
|
||||
} else if(el.offsetTop < 0){
|
||||
el.style.top = "0px"
|
||||
el.style.top = "0px";
|
||||
}
|
||||
overviewWindowGlobals.viewBoxDragging = false;
|
||||
updateViewPortFromViewBox();
|
||||
@@ -136,7 +136,7 @@ export default {
|
||||
const parentElem = document.querySelector("#overviewMiniView");
|
||||
dragmove(dragElem, dragElem, parentElem, onStart, onEnd, onDrag);
|
||||
|
||||
$id("overviewMiniView").addEventListener("click", evt => {
|
||||
$id("overviewMiniView").addEventListener("click", (evt) => {
|
||||
// Firefox doesn't support evt.offsetX and evt.offsetY.
|
||||
const mouseX = (evt.offsetX || evt.originalEvent.layerX);
|
||||
const mouseY = (evt.offsetY || evt.originalEvent.layerY);
|
||||
|
||||
@@ -36,7 +36,7 @@ export default {
|
||||
} = svgCanvas;
|
||||
const insertAfter = (referenceNode, newNode) => {
|
||||
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
|
||||
}
|
||||
};
|
||||
return {
|
||||
newUI: true,
|
||||
name: strings.name,
|
||||
|
||||
@@ -23,8 +23,8 @@ export default {
|
||||
name: 'placemark',
|
||||
async init (_S) {
|
||||
const svgEditor = this;
|
||||
const {svgCanvas} = svgEditor;
|
||||
const {$id} = svgCanvas;
|
||||
const { svgCanvas } = svgEditor;
|
||||
const { $id } = svgCanvas;
|
||||
const addElem = svgCanvas.addSVGElementFromJson;
|
||||
let
|
||||
selElems,
|
||||
@@ -40,29 +40,29 @@ export default {
|
||||
const markerTypes = {
|
||||
nomarker: {},
|
||||
forwardslash:
|
||||
{element: 'path', attr: {d: 'M30,100 L70,0'}},
|
||||
{ element: 'path', attr: { d: 'M30,100 L70,0' } },
|
||||
reverseslash:
|
||||
{element: 'path', attr: {d: 'M30,0 L70,100'}},
|
||||
{ element: 'path', attr: { d: 'M30,0 L70,100' } },
|
||||
verticalslash:
|
||||
{element: 'path', attr: {d: 'M50,0 L50,100'}},
|
||||
{ element: 'path', attr: { d: 'M50,0 L50,100' } },
|
||||
xmark:
|
||||
{element: 'path', attr: {d: 'M20,80 L80,20 M80,80 L20,20'}},
|
||||
{ element: 'path', attr: { d: 'M20,80 L80,20 M80,80 L20,20' } },
|
||||
leftarrow:
|
||||
{element: 'path', attr: {d: 'M0,50 L100,90 L70,50 L100,10 Z'}},
|
||||
{ element: 'path', attr: { d: 'M0,50 L100,90 L70,50 L100,10 Z' } },
|
||||
rightarrow:
|
||||
{element: 'path', attr: {d: 'M100,50 L0,90 L30,50 L0,10 Z'}},
|
||||
{ element: 'path', attr: { d: 'M100,50 L0,90 L30,50 L0,10 Z' } },
|
||||
box:
|
||||
{element: 'path', attr: {d: 'M20,20 L20,80 L80,80 L80,20 Z'}},
|
||||
{ element: 'path', attr: { d: 'M20,20 L20,80 L80,80 L80,20 Z' } },
|
||||
star:
|
||||
{element: 'path', attr: {d: 'M10,30 L90,30 L20,90 L50,10 L80,90 Z'}},
|
||||
{ element: 'path', attr: { d: 'M10,30 L90,30 L20,90 L50,10 L80,90 Z' } },
|
||||
mcircle:
|
||||
{element: 'circle', attr: {r: 30, cx: 50, cy: 50}},
|
||||
{ element: 'circle', attr: { r: 30, cx: 50, cy: 50 } },
|
||||
triangle:
|
||||
{element: 'path', attr: {d: 'M10,80 L50,20 L80,80 Z'}}
|
||||
{ element: 'path', attr: { d: 'M10,80 L50,20 L80,80 Z' } }
|
||||
};
|
||||
|
||||
// duplicate shapes to support unfilled (open) marker types with an _o suffix
|
||||
['leftarrow', 'rightarrow', 'box', 'star', 'mcircle', 'triangle'].forEach((v) => {
|
||||
[ 'leftarrow', 'rightarrow', 'box', 'star', 'mcircle', 'triangle' ].forEach((v) => {
|
||||
markerTypes[v + '_o'] = markerTypes[v];
|
||||
});
|
||||
|
||||
@@ -106,7 +106,7 @@ export default {
|
||||
if (elem && elem.getAttribute('class').includes('placemark')) {
|
||||
var elements = elem.children;
|
||||
Array.prototype.forEach.call(elements, function(i, _){
|
||||
const [, , type, n] = i.id.split('_');
|
||||
const [ , , type, n ] = i.id.split('_');
|
||||
if (type === 'txt') {
|
||||
txt.textContent = items[n];
|
||||
}
|
||||
@@ -127,7 +127,7 @@ export default {
|
||||
if (elem && elem.getAttribute('class').includes('placemark')) {
|
||||
var elements = elem.children;
|
||||
Array.prototype.forEach.call(elements, function(i, _){
|
||||
const [, , type] = i.id.split('_');
|
||||
const [ , , type ] = i.id.split('_');
|
||||
if (type === 'txt') {
|
||||
i.style.cssText = 'font-family:' + font + ';font-size:'+fontSize+';';
|
||||
}
|
||||
@@ -204,14 +204,14 @@ export default {
|
||||
if (marker) { marker.remove(); }
|
||||
el.removeAttribute(markerName);
|
||||
if (val === 'nomarker') {
|
||||
svgCanvas.call('changed', [el]);
|
||||
svgCanvas.call('changed', [ el ]);
|
||||
return;
|
||||
}
|
||||
// Set marker on element
|
||||
const id = 'placemark_marker_' + el.id;
|
||||
addMarker(id, val);
|
||||
el.setAttribute(markerName, 'url(#' + id + ')');
|
||||
svgCanvas.call('changed', [el]);
|
||||
svgCanvas.call('changed', [ el ]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,7 +223,6 @@ export default {
|
||||
function colorChanged (el) {
|
||||
const color = el.getAttribute('stroke');
|
||||
const marker = getLinked(el, 'marker-start');
|
||||
// console.log(marker);
|
||||
if (!marker) { return; }
|
||||
if (!marker.attributes.class) { return; } // not created by this extension
|
||||
const ch = marker.lastElementChild;
|
||||
@@ -273,7 +272,7 @@ export default {
|
||||
* @returns {string}
|
||||
*/
|
||||
function getTitle (id) {
|
||||
const {langList} = strings;
|
||||
const { langList } = strings;
|
||||
const item = langList.find((itm) => {
|
||||
return itm.id === id;
|
||||
});
|
||||
@@ -294,7 +293,7 @@ export default {
|
||||
icon: 'markers-' + id + '.png',
|
||||
title,
|
||||
type: 'context',
|
||||
events: {click: setArrowFromButton},
|
||||
events: { click: setArrowFromButton },
|
||||
panel: 'placemark_panel',
|
||||
list: 'placemark_marker',
|
||||
isDefault: id === 'leftarrow'
|
||||
@@ -303,7 +302,7 @@ export default {
|
||||
return buttons;
|
||||
}
|
||||
|
||||
const buttons = [{
|
||||
const buttons = [ {
|
||||
id: 'tool_placemark',
|
||||
icon: 'placemark.png',
|
||||
type: 'mode',
|
||||
@@ -314,14 +313,14 @@ export default {
|
||||
svgCanvas.setMode('placemark');
|
||||
}
|
||||
}
|
||||
}];
|
||||
} ];
|
||||
const contextTools = [
|
||||
{
|
||||
type: 'button-select',
|
||||
panel: 'placemark_panel',
|
||||
id: 'placemark_marker',
|
||||
colnum: 3,
|
||||
events: {change: setArrowFromButton}
|
||||
events: { change: setArrowFromButton }
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
@@ -375,7 +374,7 @@ export default {
|
||||
font = font.join(' ');
|
||||
const x0 = opts.start_x + 10, y0 = opts.start_y + 10;
|
||||
let maxlen = 0;
|
||||
const children = [{
|
||||
const children = [ {
|
||||
element: 'line',
|
||||
attr: {
|
||||
id: id + '_pline_0',
|
||||
@@ -388,7 +387,7 @@ export default {
|
||||
x2: x0,
|
||||
y2: y0
|
||||
}
|
||||
}];
|
||||
} ];
|
||||
items.forEach((i, n) => {
|
||||
maxlen = Math.max(maxlen, i.length);
|
||||
children.push({
|
||||
@@ -418,7 +417,7 @@ export default {
|
||||
'font-size': fontSize,
|
||||
'text-anchor': 'start'
|
||||
},
|
||||
children: [i]
|
||||
children: [ i ]
|
||||
});
|
||||
});
|
||||
if (items.length > 0) {
|
||||
@@ -479,7 +478,7 @@ export default {
|
||||
newPM.setAttribute('y', y);
|
||||
const elements = newPM.children;
|
||||
Array.prototype.forEach.call(elements, function(i, _){
|
||||
const [, , type, n] = i.id.split('_');
|
||||
const [ , , type, n ] = i.id.split('_');
|
||||
const y0 = y + (fontSize + 6) * n,
|
||||
x0 = x + maxlen * fontSize * 0.5 + fontSize;
|
||||
const nx = (x + (x0 - x) / 2 < px) ? x0 : x;
|
||||
@@ -534,7 +533,7 @@ export default {
|
||||
const txt = [];
|
||||
const elements = elem.children;
|
||||
Array.prototype.forEach.call(elements, function(i){
|
||||
const [, , type] = i.id.split('_');
|
||||
const [ , , type ] = i.id.split('_');
|
||||
if (type === 'txt') {
|
||||
$id('placemarkFont').value = (
|
||||
i.getAttribute('font-family') + ' ' + i.getAttribute('font-size')
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
export default {
|
||||
name: 'placemark',
|
||||
langList: [
|
||||
{id: 'nomarker', title: 'No Marker'},
|
||||
{id: 'leftarrow', title: 'Left Arrow'},
|
||||
{id: 'rightarrow', title: 'Right Arrow'},
|
||||
{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'}
|
||||
{ id: 'nomarker', title: 'No Marker' },
|
||||
{ id: 'leftarrow', title: 'Left Arrow' },
|
||||
{ id: 'rightarrow', title: 'Right Arrow' },
|
||||
{ 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' }
|
||||
],
|
||||
buttons: [
|
||||
{
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
/**
|
||||
* @file ext-polygon.js
|
||||
*
|
||||
*
|
||||
* @copyright 2010 CloudCanvas, Inc. All rights reserved
|
||||
*
|
||||
*/
|
||||
|
||||
const loadExtensionTranslation = async function (lang) {
|
||||
let translationModule;
|
||||
try {
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
|
||||
} catch (_error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`Missing translation (${lang}) - using 'en'`);
|
||||
translationModule = await import(`./locale/en.js`);
|
||||
}
|
||||
return translationModule.default;
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'polygon',
|
||||
async init (_S) {
|
||||
const svgEditor = this;
|
||||
const {svgCanvas} = svgEditor;
|
||||
const {$id} = svgCanvas;
|
||||
// const editingitex = false;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
let selElems;
|
||||
let started;
|
||||
let newFO;
|
||||
/**
|
||||
* @param {boolean} on
|
||||
* @returns {void}
|
||||
*/
|
||||
const showPanel = (on) => {
|
||||
$id('polygon_panel').style.display = (on) ? 'block' : 'none';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} attr
|
||||
* @param {string|Float} val
|
||||
* @returns {void}
|
||||
*/
|
||||
const setAttr = (attr, val) => {
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
svgCanvas.call('changed', selElems);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Float} n
|
||||
* @returns {Float}
|
||||
*/
|
||||
const cot = (n) => (1 / Math.tan(n));
|
||||
|
||||
/**
|
||||
* @param {Float} n
|
||||
* @returns {Float}
|
||||
*/
|
||||
const sec = (n) => (1 / Math.cos(n));
|
||||
|
||||
return {
|
||||
name: strings.name,
|
||||
// The callback should be used to load the DOM with the appropriate UI items
|
||||
callback () {
|
||||
// Add the button and its handler(s)
|
||||
// Note: the star extension may also add the same flying button so we check first
|
||||
if ($id('tools_polygon') === null) {
|
||||
const buttonTemplate = document.createElement("template");
|
||||
buttonTemplate.innerHTML = `
|
||||
<se-flyingbutton id="tools_polygon" title="Polygone/Star Tool">
|
||||
<se-button id="tool_polygon" title="Polygon Tool" src="./images/polygon.svg"></se-button>
|
||||
<se-button id="tool_star" title="Star Tool" src="./images/star.svg"></se-button>
|
||||
</se-flyingbutton>
|
||||
`
|
||||
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
||||
}
|
||||
$id('tool_polygon').addEventListener("click", () => {
|
||||
if (this.leftPanel.updateLeftPanel('tool_polygon')) {
|
||||
svgCanvas.setMode('polygon');
|
||||
showPanel(true);
|
||||
}
|
||||
});
|
||||
|
||||
// Add the context panel and its handler(s)
|
||||
const panelTemplate = document.createElement("template");
|
||||
panelTemplate.innerHTML = `
|
||||
<div id="polygon_panel">
|
||||
<se-spin-input size="3" id="polySides" min=1 step=1 value=5 label="sides">
|
||||
</se-spin-input>
|
||||
</div>
|
||||
`
|
||||
$id('tools_top').appendChild(panelTemplate.content.cloneNode(true));
|
||||
$id("polygon_panel").style.display = 'none';
|
||||
$id("polySides").addEventListener("change", (event) => {
|
||||
setAttr('sides', event.target.value);
|
||||
});
|
||||
},
|
||||
mouseDown (opts) {
|
||||
if (svgCanvas.getMode() !== 'polygon') {
|
||||
return undefined;
|
||||
}
|
||||
// const e = opts.event;
|
||||
const rgb = svgCanvas.getColor('fill');
|
||||
// const ccRgbEl = rgb.substring(1, rgb.length);
|
||||
const sRgb = svgCanvas.getColor('stroke');
|
||||
// ccSRgbEl = sRgb.substring(1, rgb.length);
|
||||
const sWidth = svgCanvas.getStrokeWidth();
|
||||
|
||||
started = true;
|
||||
|
||||
newFO = svgCanvas.addSVGElementFromJson({
|
||||
element: 'polygon',
|
||||
attr: {
|
||||
cx: opts.start_x,
|
||||
cy: opts.start_y,
|
||||
id: svgCanvas.getNextId(),
|
||||
shape: 'regularPoly',
|
||||
sides: document.getElementById('polySides').value,
|
||||
orient: 'x',
|
||||
edge: 0,
|
||||
fill: rgb,
|
||||
strokecolor: sRgb,
|
||||
strokeWidth: sWidth
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
},
|
||||
mouseMove (opts) {
|
||||
if (!started || svgCanvas.getMode() !== 'polygon') {
|
||||
return undefined;
|
||||
}
|
||||
const cx = Number(newFO.getAttribute('cx'));
|
||||
const cy = Number(newFO.getAttribute('cy'));
|
||||
const sides = Number(newFO.getAttribute('sides'));
|
||||
// const orient = newFO.getAttribute('orient');
|
||||
const fill = newFO.getAttribute('fill');
|
||||
const strokecolor = newFO.getAttribute('strokecolor');
|
||||
const strokeWidth = Number(newFO.getAttribute('strokeWidth'));
|
||||
|
||||
let x = opts.mouse_x;
|
||||
let y = opts.mouse_y;
|
||||
|
||||
const edg = (Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy))) / 1.5;
|
||||
newFO.setAttribute('edge', edg);
|
||||
|
||||
const inradius = (edg / 2) * cot(Math.PI / sides);
|
||||
const circumradius = inradius * sec(Math.PI / sides);
|
||||
let points = '';
|
||||
for (let s = 0; sides >= s; s++) {
|
||||
const angle = 2.0 * Math.PI * s / sides;
|
||||
x = (circumradius * Math.cos(angle)) + cx;
|
||||
y = (circumradius * Math.sin(angle)) + cy;
|
||||
|
||||
points += x + ',' + y + ' ';
|
||||
}
|
||||
|
||||
// const poly = newFO.createElementNS(NS.SVG, 'polygon');
|
||||
newFO.setAttribute('points', points);
|
||||
newFO.setAttribute('fill', fill);
|
||||
newFO.setAttribute('stroke', strokecolor);
|
||||
newFO.setAttribute('stroke-width', strokeWidth);
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
},
|
||||
|
||||
mouseUp () {
|
||||
if (svgCanvas.getMode() !== 'polygon') {
|
||||
return undefined;
|
||||
}
|
||||
const edge = newFO.getAttribute('edge');
|
||||
const keep = (edge !== '0');
|
||||
// svgCanvas.addToSelection([newFO], true);
|
||||
return {
|
||||
keep,
|
||||
element: newFO
|
||||
};
|
||||
},
|
||||
selectedChanged (opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
let i = selElems.length;
|
||||
while (i--) {
|
||||
const elem = selElems[i];
|
||||
if (elem && elem.getAttribute('shape') === 'regularPoly') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
$id('polySides').value = elem.getAttribute('sides');
|
||||
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
elementChanged () {
|
||||
// const elem = opts.elems[0];
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
export default {
|
||||
name: 'polygon',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Polygon Tool'
|
||||
}
|
||||
],
|
||||
contextTools: [
|
||||
{
|
||||
title: 'Number of Sides',
|
||||
label: 'sides'
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
export default {
|
||||
name: '多边形',
|
||||
buttons: [
|
||||
{
|
||||
title: '多边形工具'
|
||||
}
|
||||
],
|
||||
contextTools: [
|
||||
{
|
||||
title: '边数',
|
||||
label: '边数'
|
||||
}
|
||||
]
|
||||
};
|
||||
360
src/editor/extensions/ext-polystar/ext-polystar.js
Normal file
@@ -0,0 +1,360 @@
|
||||
/**
|
||||
* @file ext-polystar.js
|
||||
*
|
||||
*
|
||||
* @copyright 2010 CloudCanvas, Inc. All rights reserved
|
||||
* @copyright 2021 Optimistik SAS, Inc. All rights reserved
|
||||
* @license MIT
|
||||
*
|
||||
*/
|
||||
|
||||
const name = "polystar";
|
||||
|
||||
const loadExtensionTranslation = async function (svgEditor) {
|
||||
let translationModule;
|
||||
const lang = svgEditor.configObj.pref('lang');
|
||||
try {
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
translationModule = await import(`./locale/${lang}.js`);
|
||||
} catch (_error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(`Missing translation (${lang}) for ${name} - using 'en'`);
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
translationModule = await import(`./locale/en.js`);
|
||||
}
|
||||
svgEditor.i18next.addResourceBundle(lang, name, translationModule.default);
|
||||
};
|
||||
|
||||
export default {
|
||||
name,
|
||||
async init(_S) {
|
||||
const svgEditor = this;
|
||||
const { svgCanvas } = svgEditor;
|
||||
const { $id } = svgCanvas;
|
||||
let selElems;
|
||||
let started;
|
||||
let newFO;
|
||||
await loadExtensionTranslation(svgEditor);
|
||||
|
||||
/**
|
||||
* @param {boolean} on true=display
|
||||
* @param {string} tool "star" or "polygone"
|
||||
* @returns {void}
|
||||
*/
|
||||
const showPanel = (on, tool) => {
|
||||
$id(`${tool}_panel`).style.display = on ? "block" : "none";
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} attr attribute to change
|
||||
* @param {string|Float} val new value
|
||||
* @returns {void}
|
||||
*/
|
||||
const setAttr = (attr, val) => {
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
svgCanvas.call("changed", selElems);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Float} n angle
|
||||
* @return {Float} cotangeante
|
||||
*/
|
||||
const cot = (n) => 1 / Math.tan(n);
|
||||
|
||||
/**
|
||||
* @param {Float} n angle
|
||||
* @returns {Float} sec
|
||||
*/
|
||||
const sec = (n) => 1 / Math.cos(n);
|
||||
|
||||
return {
|
||||
name: svgEditor.i18next.t(`${name}:name`),
|
||||
// The callback should be used to load the DOM with the appropriate UI items
|
||||
callback() {
|
||||
// Add the button and its handler(s)
|
||||
// Note: the star extension needs to be loaded before the polygon extension
|
||||
const fbtitle = svgEditor.i18next.t(`${name}:title`);
|
||||
const title_star = svgEditor.i18next.t(`${name}:buttons.0.title`);
|
||||
const title_polygon = svgEditor.i18next.t(`${name}:buttons.1.title`);
|
||||
const buttonTemplate = document.createElement("template");
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
buttonTemplate.innerHTML = `
|
||||
<se-flyingbutton id="tools_polygon" title="${fbtitle}">
|
||||
<se-button id="tool_star" title="${title_star}" src="./images/star.svg">
|
||||
</se-button>
|
||||
<se-button id="tool_polygon" title="${title_polygon}" src="./images/polygon.svg">
|
||||
</se-button>
|
||||
</se-flyingbutton>
|
||||
`;
|
||||
$id("tools_left").append(buttonTemplate.content.cloneNode(true));
|
||||
// handler
|
||||
$id("tool_star").addEventListener("click", () => {
|
||||
if (this.leftPanel.updateLeftPanel("tool_star")) {
|
||||
svgCanvas.setMode("star");
|
||||
showPanel(true, "star");
|
||||
showPanel(false, "polygon");
|
||||
}
|
||||
});
|
||||
$id("tool_polygon").addEventListener("click", () => {
|
||||
if (this.leftPanel.updateLeftPanel("tool_polygon")) {
|
||||
svgCanvas.setMode("polygon");
|
||||
showPanel(true, "polygon");
|
||||
showPanel(false, "star");
|
||||
}
|
||||
});
|
||||
|
||||
const label0 = svgEditor.i18next.t(`${name}:contextTools.0.label`);
|
||||
const title0 = svgEditor.i18next.t(`${name}:contextTools.0.title`);
|
||||
const label1 = svgEditor.i18next.t(`${name}:contextTools.1.label`);
|
||||
const title1 = svgEditor.i18next.t(`${name}:contextTools.1.title`);
|
||||
const label2 = svgEditor.i18next.t(`${name}:contextTools.2.label`);
|
||||
const title2 = svgEditor.i18next.t(`${name}:contextTools.2.title`);
|
||||
const label3 = svgEditor.i18next.t(`${name}:contextTools.3.label`);
|
||||
const title3 = svgEditor.i18next.t(`${name}:contextTools.3.title`);
|
||||
// Add the context panel and its handler(s)
|
||||
const panelTemplate = document.createElement("template");
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
panelTemplate.innerHTML = `
|
||||
<div id="star_panel">
|
||||
<se-spin-input id="starNumPoints" label="${label0}" min=1 step=1 value=5 title="${title0}">
|
||||
</se-spin-input>
|
||||
<se-spin-input id="RadiusMultiplier" label="${label1}" min=1 step=2.5 value=3 title="${title1}">
|
||||
</se-spin-input>
|
||||
<se-spin-input id="radialShift" min=0 step=1 value=0 label="${label2}" title="${title2}">
|
||||
</se-spin-input>
|
||||
</div>
|
||||
<div id="polygon_panel">
|
||||
<se-spin-input size="3" id="polySides" min=1 step=1 value=5 label="${label3}" title="${title3}">
|
||||
</se-spin-input>
|
||||
</div>
|
||||
`;
|
||||
//add handlers for the panel
|
||||
$id("tools_top").appendChild(panelTemplate.content.cloneNode(true));
|
||||
// don't display the panels on start
|
||||
showPanel(false, "star");
|
||||
showPanel(false, "polygon");
|
||||
$id("starNumPoints").addEventListener("change", (event) => {
|
||||
setAttr("point", event.target.value);
|
||||
});
|
||||
$id("RadiusMultiplier").addEventListener("change", (event) => {
|
||||
setAttr("starRadiusMultiplier", event.target.value);
|
||||
});
|
||||
$id("radialShift").addEventListener("change", (event) => {
|
||||
setAttr("radialshift", event.target.value);
|
||||
});
|
||||
$id("polySides").addEventListener("change", (event) => {
|
||||
setAttr("sides", event.target.value);
|
||||
});
|
||||
},
|
||||
mouseDown(opts) {
|
||||
if (svgCanvas.getMode() === "star") {
|
||||
const rgb = svgCanvas.getColor("fill");
|
||||
const sRgb = svgCanvas.getColor("stroke");
|
||||
const sWidth = svgCanvas.getStrokeWidth();
|
||||
started = true;
|
||||
newFO = svgCanvas.addSVGElementFromJson({
|
||||
element: "polygon",
|
||||
attr: {
|
||||
cx: opts.start_x,
|
||||
cy: opts.start_y,
|
||||
id: svgCanvas.getNextId(),
|
||||
shape: "star",
|
||||
point: document.getElementById("starNumPoints").value,
|
||||
r: 0,
|
||||
radialshift: document.getElementById("radialShift").value,
|
||||
r2: 0,
|
||||
orient: "point",
|
||||
fill: rgb,
|
||||
strokecolor: sRgb,
|
||||
strokeWidth: sWidth
|
||||
}
|
||||
});
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
if (svgCanvas.getMode() === "polygon") {
|
||||
// const e = opts.event;
|
||||
const rgb = svgCanvas.getColor("fill");
|
||||
// const ccRgbEl = rgb.substring(1, rgb.length);
|
||||
const sRgb = svgCanvas.getColor("stroke");
|
||||
// ccSRgbEl = sRgb.substring(1, rgb.length);
|
||||
const sWidth = svgCanvas.getStrokeWidth();
|
||||
started = true;
|
||||
newFO = svgCanvas.addSVGElementFromJson({
|
||||
element: "polygon",
|
||||
attr: {
|
||||
cx: opts.start_x,
|
||||
cy: opts.start_y,
|
||||
id: svgCanvas.getNextId(),
|
||||
shape: "regularPoly",
|
||||
sides: document.getElementById("polySides").value,
|
||||
orient: "x",
|
||||
edge: 0,
|
||||
fill: rgb,
|
||||
strokecolor: sRgb,
|
||||
strokeWidth: sWidth
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
mouseMove(opts) {
|
||||
if (!started) {
|
||||
return undefined;
|
||||
}
|
||||
if (svgCanvas.getMode() === "star") {
|
||||
const cx = Number(newFO.getAttribute("cx"));
|
||||
const cy = Number(newFO.getAttribute("cy"));
|
||||
const point = Number(newFO.getAttribute("point"));
|
||||
const orient = newFO.getAttribute("orient");
|
||||
const fill = newFO.getAttribute("fill");
|
||||
const strokecolor = newFO.getAttribute("strokecolor");
|
||||
const strokeWidth = Number(newFO.getAttribute("strokeWidth"));
|
||||
const radialshift = Number(newFO.getAttribute("radialshift"));
|
||||
|
||||
let x = opts.mouse_x;
|
||||
let y = opts.mouse_y;
|
||||
|
||||
const circumradius =
|
||||
Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy)) / 1.5;
|
||||
const inradius =
|
||||
circumradius / document.getElementById("RadiusMultiplier").value;
|
||||
newFO.setAttribute("r", circumradius);
|
||||
newFO.setAttribute("r2", inradius);
|
||||
|
||||
let polyPoints = "";
|
||||
for (let s = 0; point >= s; s++) {
|
||||
let angle = 2.0 * Math.PI * (s / point);
|
||||
if (orient === "point") {
|
||||
angle -= Math.PI / 2;
|
||||
} else if (orient === "edge") {
|
||||
angle = angle + Math.PI / point - Math.PI / 2;
|
||||
}
|
||||
|
||||
x = circumradius * Math.cos(angle) + cx;
|
||||
y = circumradius * Math.sin(angle) + cy;
|
||||
|
||||
polyPoints += x + "," + y + " ";
|
||||
|
||||
if (!isNaN(inradius)) {
|
||||
angle = 2.0 * Math.PI * (s / point) + Math.PI / point;
|
||||
if (orient === "point") {
|
||||
angle -= Math.PI / 2;
|
||||
} else if (orient === "edge") {
|
||||
angle = angle + Math.PI / point - Math.PI / 2;
|
||||
}
|
||||
angle += radialshift;
|
||||
|
||||
x = inradius * Math.cos(angle) + cx;
|
||||
y = inradius * Math.sin(angle) + cy;
|
||||
|
||||
polyPoints += x + "," + y + " ";
|
||||
}
|
||||
}
|
||||
newFO.setAttribute("points", polyPoints);
|
||||
newFO.setAttribute("fill", fill);
|
||||
newFO.setAttribute("stroke", strokecolor);
|
||||
newFO.setAttribute("stroke-width", strokeWidth);
|
||||
/* const shape = */ newFO.getAttribute("shape");
|
||||
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
if (svgCanvas.getMode() === "polygon") {
|
||||
const cx = Number(newFO.getAttribute("cx"));
|
||||
const cy = Number(newFO.getAttribute("cy"));
|
||||
const sides = Number(newFO.getAttribute("sides"));
|
||||
// const orient = newFO.getAttribute('orient');
|
||||
const fill = newFO.getAttribute("fill");
|
||||
const strokecolor = newFO.getAttribute("strokecolor");
|
||||
const strokeWidth = Number(newFO.getAttribute("strokeWidth"));
|
||||
|
||||
let x = opts.mouse_x;
|
||||
let y = opts.mouse_y;
|
||||
|
||||
const edg =
|
||||
Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy)) / 1.5;
|
||||
newFO.setAttribute("edge", edg);
|
||||
|
||||
const inradius = (edg / 2) * cot(Math.PI / sides);
|
||||
const circumradius = inradius * sec(Math.PI / sides);
|
||||
let points = "";
|
||||
for (let s = 0; sides >= s; s++) {
|
||||
const angle = (2.0 * Math.PI * s) / sides;
|
||||
x = circumradius * Math.cos(angle) + cx;
|
||||
y = circumradius * Math.sin(angle) + cy;
|
||||
|
||||
points += x + "," + y + " ";
|
||||
}
|
||||
|
||||
// const poly = newFO.createElementNS(NS.SVG, 'polygon');
|
||||
newFO.setAttribute("points", points);
|
||||
newFO.setAttribute("fill", fill);
|
||||
newFO.setAttribute("stroke", strokecolor);
|
||||
newFO.setAttribute("stroke-width", strokeWidth);
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
mouseUp() {
|
||||
if (svgCanvas.getMode() === "star") {
|
||||
const r = newFO.getAttribute("r");
|
||||
return {
|
||||
keep: r !== "0",
|
||||
element: newFO
|
||||
};
|
||||
}
|
||||
if (svgCanvas.getMode() === "polygon") {
|
||||
const edge = newFO.getAttribute("edge");
|
||||
const keep = edge !== "0";
|
||||
// svgCanvas.addToSelection([newFO], true);
|
||||
return {
|
||||
keep,
|
||||
element: newFO
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
selectedChanged(opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
let i = selElems.length;
|
||||
while (i--) {
|
||||
const elem = selElems[i];
|
||||
if (elem && elem.getAttribute("shape") === "star") {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
$id("starNumPoints").value = elem.getAttribute("point");
|
||||
$id("radialShift").value = elem.getAttribute("radialshift");
|
||||
showPanel(true, "star");
|
||||
} else {
|
||||
showPanel(false, "star");
|
||||
}
|
||||
} else if (elem && elem.getAttribute("shape") === "regularPoly") {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
$id("polySides").value = elem.getAttribute("sides");
|
||||
showPanel(true, "polygon");
|
||||
} else {
|
||||
showPanel(false, "polygon");
|
||||
}
|
||||
} else {
|
||||
showPanel(false, "star");
|
||||
showPanel(false, "polygon");
|
||||
}
|
||||
}
|
||||
},
|
||||
elementChanged(_opts) {
|
||||
// const elem = opts.elems[0];
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -1,8 +1,12 @@
|
||||
export default {
|
||||
name: 'star',
|
||||
title: 'Polygone/Star Tool',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Star Tool'
|
||||
},
|
||||
{
|
||||
title: 'Polygon Tool'
|
||||
}
|
||||
],
|
||||
contextTools: [
|
||||
@@ -17,6 +21,10 @@ export default {
|
||||
{
|
||||
title: 'Twists the star',
|
||||
label: 'Radial Shift'
|
||||
},
|
||||
{
|
||||
title: 'Number of Sides',
|
||||
label: 'sides'
|
||||
}
|
||||
]
|
||||
};
|
||||
30
src/editor/extensions/ext-polystar/locale/fr.js
Normal file
@@ -0,0 +1,30 @@
|
||||
export default {
|
||||
name: 'etoile',
|
||||
title: 'Outil Polygone/Etoile',
|
||||
buttons: [
|
||||
{
|
||||
title: 'Outil Etoile'
|
||||
},
|
||||
{
|
||||
title: 'Outil Polygone'
|
||||
}
|
||||
],
|
||||
contextTools: [
|
||||
{
|
||||
title: 'Nombre de côtés',
|
||||
label: 'points'
|
||||
},
|
||||
{
|
||||
title: 'Précision',
|
||||
label: 'Précision'
|
||||
},
|
||||
{
|
||||
title: 'Torsion Etoile',
|
||||
label: 'Décalage Radial'
|
||||
},
|
||||
{
|
||||
title: 'Nombre de côtés',
|
||||
label: 'côtés'
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -1,8 +1,12 @@
|
||||
export default {
|
||||
name: '星形',
|
||||
title: 'Polygone/Star Tool',
|
||||
buttons: [
|
||||
{
|
||||
title: '星形工具'
|
||||
},
|
||||
{
|
||||
title: '多边形工具'
|
||||
}
|
||||
],
|
||||
contextTools: [
|
||||
@@ -17,6 +21,10 @@ export default {
|
||||
{
|
||||
title: '径向',
|
||||
label: '径向'
|
||||
},
|
||||
{
|
||||
title: '边数',
|
||||
label: '边数'
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -7,7 +7,7 @@
|
||||
* 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 as canvg} from 'canvg';
|
||||
import { Canvg as canvg } from 'canvg';
|
||||
|
||||
const loadExtensionTranslation = async function (lang) {
|
||||
let translationModule;
|
||||
@@ -24,11 +24,11 @@ const loadExtensionTranslation = async function (lang) {
|
||||
|
||||
export default {
|
||||
name: 'server_moinsave',
|
||||
async init ({encode64}) {
|
||||
async init ({ encode64 }) {
|
||||
const svgEditor = this;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
const {svgCanvas} = svgEditor;
|
||||
const {$id} = svgCanvas;
|
||||
const { svgCanvas } = svgEditor;
|
||||
const { $id } = svgCanvas;
|
||||
const saveSvgAction = '/+modify';
|
||||
|
||||
// Create upload target (hidden iframe)
|
||||
@@ -44,7 +44,7 @@ export default {
|
||||
svgEditor.setCustomHandlers({
|
||||
async save (win, data) {
|
||||
const svg = '<?xml version="1.0"?>\n' + data;
|
||||
const {pathname} = new URL(location);
|
||||
const { pathname } = new URL(location);
|
||||
const name = pathname.replace(/\/+get\//, '');
|
||||
const svgData = encode64(svg);
|
||||
if (!$id('export_canvas')) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
export default {
|
||||
name: 'php_savefile',
|
||||
init ({$}) {
|
||||
init ({ $ }) {
|
||||
const svgEditor = this;
|
||||
const {
|
||||
canvas: svgCanvas
|
||||
@@ -22,7 +22,7 @@ export default {
|
||||
const svg = '<?xml version="1.0" encoding="UTF-8"?>\n' + data,
|
||||
filename = getFileNameFromTitle();
|
||||
|
||||
$.post(saveSvgAction, {output_svg: svg, filename});
|
||||
$.post(saveSvgAction, { output_svg: svg, filename });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @copyright 2010 Alexis Deveria
|
||||
*
|
||||
*/
|
||||
import {Canvg as canvg} from 'canvg';
|
||||
import { Canvg as canvg } from 'canvg';
|
||||
|
||||
const loadExtensionTranslation = async function (lang) {
|
||||
let translationModule;
|
||||
@@ -23,7 +23,7 @@ const loadExtensionTranslation = async function (lang) {
|
||||
|
||||
export default {
|
||||
name: 'server_opensave',
|
||||
async init ({$, decode64, encode64}) {
|
||||
async init ({ $, decode64, encode64 }) {
|
||||
const svgEditor = this;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
const {
|
||||
@@ -33,7 +33,7 @@ export default {
|
||||
},
|
||||
canvas: svgCanvas
|
||||
} = svgEditor;
|
||||
const {$id} = svgCanvas;
|
||||
const { $id } = svgCanvas;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -96,7 +96,8 @@ export default {
|
||||
|
||||
svgEditor.setCustomHandlers({
|
||||
save (win, data) {
|
||||
const svg = '<?xml version="1.0" encoding="UTF-8"?>\n' + data, // Firefox doesn't seem to know it is UTF-8 (no matter whether we use or skip the clientDownload code) despite the Content-Disposition header containing UTF-8, but adding the encoding works
|
||||
// Firefox doesn't seem to know it is UTF-8 (no matter whether we use or skip the clientDownload code) despite the Content-Disposition header containing UTF-8, but adding the encoding works
|
||||
const svg = '<?xml version="1.0" encoding="UTF-8"?>\n' + data,
|
||||
filename = getFileNameFromTitle();
|
||||
|
||||
if (clientDownloadSupport(filename, '.svg', 'data:image/svg+xml;charset=UTF-8;base64,' + encode64(svg))) {
|
||||
@@ -130,11 +131,11 @@ export default {
|
||||
<input type="hidden" name="filename" value="${xhtmlEscape(filename)}">`;
|
||||
document.body.append(form);
|
||||
form.submit();
|
||||
form.remove();
|
||||
form.remove();
|
||||
},
|
||||
// Todo: Integrate this extension with a new built-in exportWindowType, "download"
|
||||
async exportImage (win, data) {
|
||||
const {issues, mimeType, quality} = data;
|
||||
const { issues, mimeType, quality } = data;
|
||||
|
||||
if (!$id('export_canvas')) {
|
||||
const canvasx = document.createElement("CANVAS");
|
||||
@@ -148,7 +149,6 @@ export default {
|
||||
c.style.height = svgCanvas.contentH;
|
||||
await canvg(c, data.svg);
|
||||
const datauri = quality ? c.toDataURL(mimeType, quality) : c.toDataURL(mimeType);
|
||||
// {uiStrings} = svgEditor;
|
||||
|
||||
// Check if there are issues
|
||||
let pre, note = '';
|
||||
@@ -227,7 +227,6 @@ export default {
|
||||
openSvgForm.enctype = 'multipart/form-data';
|
||||
openSvgForm.method = 'post';
|
||||
openSvgForm.target = 'output_frame';
|
||||
|
||||
|
||||
// Create import form
|
||||
const importSvgForm = openSvgForm.cloneNode(true);
|
||||
|
||||
@@ -12,7 +12,7 @@ export default {
|
||||
init () {
|
||||
const svgEditor = this;
|
||||
const canv = svgEditor.svgCanvas;
|
||||
const {$id} = canv;
|
||||
const { $id } = canv;
|
||||
const svgroot = canv.getRootElem();
|
||||
let lastBBox = {};
|
||||
|
||||
@@ -30,9 +30,9 @@ export default {
|
||||
buttonTemplate.innerHTML = `
|
||||
<se-explorerbutton id="tool_shapelib" title="Shape library" lib="./extensions/ext-shapes/shapelib/"
|
||||
src="./images/shapelib.svg"></se-explorerbutton>
|
||||
`
|
||||
`;
|
||||
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
||||
$id('tool_shapelib').addEventListener("click", () => {
|
||||
$id('tool_shapelib').addEventListener("click", () => {
|
||||
canv.setMode(modeId);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,231 +0,0 @@
|
||||
/**
|
||||
* @file ext-star.js
|
||||
*
|
||||
*
|
||||
* @copyright 2010 CloudCanvas, Inc. All rights reserved
|
||||
*
|
||||
*/
|
||||
|
||||
const loadExtensionTranslation = async function (lang) {
|
||||
let translationModule;
|
||||
try {
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
|
||||
} catch (_error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`Missing translation (${lang}) - using 'en'`);
|
||||
translationModule = await import(`./locale/en.js`);
|
||||
}
|
||||
return translationModule.default;
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'star',
|
||||
async init (_S) {
|
||||
const svgEditor = this;
|
||||
const {svgCanvas} = svgEditor;
|
||||
const {$id} = svgCanvas;
|
||||
let selElems;
|
||||
let started;
|
||||
let newFO;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {boolean} on
|
||||
* @returns {void}
|
||||
*/
|
||||
const showPanel = (on) => {
|
||||
$id('star_panel').style.display = (on) ? 'block' : 'none';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} attr
|
||||
* @param {string|Float} val
|
||||
* @returns {void}
|
||||
*/
|
||||
const setAttr = (attr, val) => {
|
||||
svgCanvas.changeSelectedAttribute(attr, val);
|
||||
svgCanvas.call('changed', selElems);
|
||||
}
|
||||
|
||||
return {
|
||||
name: strings.name,
|
||||
// The callback should be used to load the DOM with the appropriate UI items
|
||||
callback () {
|
||||
// Add the button and its handler(s)
|
||||
// Note: the star extension may also add the same flying button so we check first
|
||||
if ($id('tools_polygon') === null) {
|
||||
const buttonTemplate = document.createElement("template");
|
||||
buttonTemplate.innerHTML = `
|
||||
<se-flyingbutton id="tools_polygon" title="Polygone/Star Tool">
|
||||
<se-button id="tool_polygon" title="Polygon Tool" src="./images/polygon.svg"></se-button>
|
||||
<se-button id="tool_star" title="Star Tool" src="./images/star.svg"></se-button>
|
||||
</se-flyingbutton>
|
||||
`
|
||||
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
||||
}
|
||||
$id('tool_star').addEventListener("click", () => { showPanel(true);
|
||||
if (this.leftPanel.updateLeftPanel('tool_polygon')) {
|
||||
svgCanvas.setMode('star');
|
||||
showPanel(true);
|
||||
}
|
||||
});
|
||||
|
||||
// Add the context panel and its handler(s)
|
||||
const panelTemplate = document.createElement("template");
|
||||
panelTemplate.innerHTML = `
|
||||
<div id="star_panel">
|
||||
<se-spin-input id="starNumPoints" label="points" min=1 step=1 value=5 title="Change rotation angle">
|
||||
</se-spin-input>
|
||||
<se-spin-input id="RadiusMultiplier" label="Radis multiplier" min=1 step=2.5 value=5 title="Change rotation angle">
|
||||
</se-spin-input>
|
||||
<se-spin-input id="radialShift" min=0 step=1 value=0 label="radial shift" title="Change rotation angle">
|
||||
</se-spin-input>
|
||||
</div>
|
||||
`
|
||||
//add handlers for the panel
|
||||
$id('tools_top').appendChild(panelTemplate.content.cloneNode(true));
|
||||
$id("starNumPoints").addEventListener("change", (event) => {
|
||||
setAttr('point', event.target.value);
|
||||
});
|
||||
$id("RadiusMultiplier").addEventListener("change", (event) => {
|
||||
setAttr('starRadiusMultiplier', event.target.value);
|
||||
});
|
||||
$id("radialShift").addEventListener("change", (event) => {
|
||||
setAttr('radialshift', event.target.value);
|
||||
});
|
||||
// don't display the star panel on start
|
||||
$id("star_panel").style.display = 'none';
|
||||
},
|
||||
mouseDown (opts) {
|
||||
const rgb = svgCanvas.getColor('fill');
|
||||
const sRgb = svgCanvas.getColor('stroke');
|
||||
const sWidth = svgCanvas.getStrokeWidth();
|
||||
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
started = true;
|
||||
|
||||
newFO = svgCanvas.addSVGElementFromJson({
|
||||
element: 'polygon',
|
||||
attr: {
|
||||
cx: opts.start_x,
|
||||
cy: opts.start_y,
|
||||
id: svgCanvas.getNextId(),
|
||||
shape: 'star',
|
||||
point: document.getElementById('starNumPoints').value,
|
||||
r: 0,
|
||||
radialshift: document.getElementById('radialShift').value,
|
||||
r2: 0,
|
||||
orient: 'point',
|
||||
fill: rgb,
|
||||
strokecolor: sRgb,
|
||||
strokeWidth: sWidth
|
||||
}
|
||||
});
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
mouseMove (opts) {
|
||||
if (!started) {
|
||||
return undefined;
|
||||
}
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
const cx = Number(newFO.getAttribute('cx'));
|
||||
const cy = Number(newFO.getAttribute('cy'));
|
||||
const point = Number(newFO.getAttribute('point'));
|
||||
const orient = newFO.getAttribute('orient');
|
||||
const fill = newFO.getAttribute('fill');
|
||||
const strokecolor = newFO.getAttribute('strokecolor');
|
||||
const strokeWidth = Number(newFO.getAttribute('strokeWidth'));
|
||||
const radialshift = Number(newFO.getAttribute('radialshift'));
|
||||
|
||||
let x = opts.mouse_x;
|
||||
let y = opts.mouse_y;
|
||||
|
||||
const circumradius = (Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy))) / 1.5;
|
||||
const inradius = circumradius / document.getElementById('RadiusMultiplier').value;
|
||||
newFO.setAttribute('r', circumradius);
|
||||
newFO.setAttribute('r2', inradius);
|
||||
|
||||
let polyPoints = '';
|
||||
for (let s = 0; point >= s; s++) {
|
||||
let angle = 2.0 * Math.PI * (s / point);
|
||||
if (orient === 'point') {
|
||||
angle -= (Math.PI / 2);
|
||||
} else if (orient === 'edge') {
|
||||
angle = (angle + (Math.PI / point)) - (Math.PI / 2);
|
||||
}
|
||||
|
||||
x = (circumradius * Math.cos(angle)) + cx;
|
||||
y = (circumradius * Math.sin(angle)) + cy;
|
||||
|
||||
polyPoints += x + ',' + y + ' ';
|
||||
|
||||
if (!isNaN(inradius)) {
|
||||
angle = (2.0 * Math.PI * (s / point)) + (Math.PI / point);
|
||||
if (orient === 'point') {
|
||||
angle -= (Math.PI / 2);
|
||||
} else if (orient === 'edge') {
|
||||
angle = (angle + (Math.PI / point)) - (Math.PI / 2);
|
||||
}
|
||||
angle += radialshift;
|
||||
|
||||
x = (inradius * Math.cos(angle)) + cx;
|
||||
y = (inradius * Math.sin(angle)) + cy;
|
||||
|
||||
polyPoints += x + ',' + y + ' ';
|
||||
}
|
||||
}
|
||||
newFO.setAttribute('points', polyPoints);
|
||||
newFO.setAttribute('fill', fill);
|
||||
newFO.setAttribute('stroke', strokecolor);
|
||||
newFO.setAttribute('stroke-width', strokeWidth);
|
||||
/* const shape = */ newFO.getAttribute('shape');
|
||||
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
mouseUp () {
|
||||
if (svgCanvas.getMode() === 'star') {
|
||||
const r = newFO.getAttribute('r');
|
||||
return {
|
||||
keep: (r !== '0'),
|
||||
element: newFO
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
selectedChanged (opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
let i = selElems.length;
|
||||
while (i--) {
|
||||
const elem = selElems[i];
|
||||
if (elem && elem.getAttribute('shape') === 'star') {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
$id('starNumPoints').value = elem.getAttribute('point');
|
||||
$id('radialShift').value = elem.getAttribute('radialshift');
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
elementChanged (_opts) {
|
||||
// const elem = opts.elems[0];
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -58,7 +58,7 @@ export default {
|
||||
name: 'storage',
|
||||
init () {
|
||||
const svgEditor = this;
|
||||
const {svgCanvas, storage} = svgEditor;
|
||||
const { svgCanvas, storage } = svgEditor;
|
||||
|
||||
// We could empty any already-set data for users when they decline storage,
|
||||
// but it would be a risk for users who wanted to store but accidentally
|
||||
@@ -157,12 +157,12 @@ export default {
|
||||
setSVGContentStorage(svgCanvas.getSvgString());
|
||||
}
|
||||
|
||||
svgEditor.setConfig({no_save_warning: true}); // No need for explicit saving at all once storage is on
|
||||
svgEditor.setConfig({ no_save_warning: true }); // No need for explicit saving at all once storage is on
|
||||
// svgEditor.showSaveWarning = false;
|
||||
|
||||
const {curPrefs} = svgEditor.configObj;
|
||||
const { curPrefs } = svgEditor.configObj;
|
||||
|
||||
Object.entries(curPrefs).forEach(([key, val]) => {
|
||||
Object.entries(curPrefs).forEach(([ key, val ]) => {
|
||||
const store = (val !== undefined);
|
||||
key = 'svg-edit-' + key;
|
||||
if (!store) {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/* eslint-disable max-len */
|
||||
import 'elix/define/Dialog.js';
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
@@ -10,7 +9,7 @@ template.innerHTML = `
|
||||
background: #DDD;
|
||||
overflow: auto;
|
||||
text-align: left;
|
||||
border: 1px solid #B0B0B0;
|
||||
border: 1px solid #5a6162;
|
||||
}
|
||||
|
||||
#dialog_content p, #dialog_content select, #dialog_content label {
|
||||
@@ -25,7 +24,7 @@ template.innerHTML = `
|
||||
top: 50%;
|
||||
max-width: 400px;
|
||||
z-index: 50001;
|
||||
background: #CCC;
|
||||
background: #5a6162;
|
||||
border: 1px outset #777;
|
||||
font-family:Verdana,Helvetica,sans-serif;
|
||||
font-size:0.8em;
|
||||
@@ -86,7 +85,7 @@ export class SeStorageDialog extends HTMLElement {
|
||||
constructor () {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$dialog = this._shadowRoot.querySelector('#dialog_box');
|
||||
this.$storage = this._shadowRoot.querySelector('#js-storage');
|
||||
@@ -100,7 +99,7 @@ export class SeStorageDialog extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['dialog', 'storage'];
|
||||
return [ 'dialog', 'storage' ];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
@@ -150,11 +149,11 @@ export class SeStorageDialog extends HTMLElement {
|
||||
*/
|
||||
connectedCallback () {
|
||||
const onSubmitHandler = (e, action) => {
|
||||
const triggerEvent = new CustomEvent('change', {detail: {
|
||||
const triggerEvent = new CustomEvent('change', { detail: {
|
||||
trigger: action,
|
||||
select: this.$storageInput.value,
|
||||
checkbox: this.$rememberInput.checked
|
||||
}});
|
||||
} });
|
||||
this.dispatchEvent(triggerEvent);
|
||||
};
|
||||
this.$okBtn.addEventListener('click', (evt) => onSubmitHandler(evt, 'ok'));
|
||||
|
||||
@@ -26,27 +26,24 @@ export default {
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
const saveMessage = 'save',
|
||||
readMessage = 'read',
|
||||
excludedMessages = [readMessage, saveMessage];
|
||||
excludedMessages = [ readMessage, saveMessage ];
|
||||
|
||||
let pathID;
|
||||
this.canvas.bind(
|
||||
'message',
|
||||
/**
|
||||
* @param {external:Window} win
|
||||
* @param {PlainObject} info
|
||||
* @param {module:svgcanvas.SvgCanvas#event:message} info.data
|
||||
* @param {string} info.origin
|
||||
* @listens module:svgcanvas.SvgCanvas#event:message
|
||||
* @throws {Error} Unexpected event type
|
||||
* @returns {void}
|
||||
*/
|
||||
(win, {data, origin}) => {
|
||||
// console.log('data, origin', data, origin);
|
||||
*
|
||||
* @param {external:Window} win external Window handler
|
||||
* @param {*} param1 info
|
||||
* @returns {void}
|
||||
*/
|
||||
(win, { data, origin }) => {
|
||||
let type, content;
|
||||
try {
|
||||
({type, pathID, content} = data.webappfind); // May throw if data is not an object
|
||||
({ 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)
|
||||
// Avoid our post below (other msgs might be possible which may need to be excluded if code makes assumptions on the type of message)
|
||||
excludedMessages.includes(type)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@@ -81,7 +78,7 @@ export default {
|
||||
: window.location.origin
|
||||
);
|
||||
*/
|
||||
const buttons = [{
|
||||
const buttons = [ {
|
||||
id: 'webappfind_save', //
|
||||
icon: 'webappfind.png',
|
||||
type: 'app_menu',
|
||||
@@ -106,7 +103,7 @@ export default {
|
||||
);
|
||||
}
|
||||
}
|
||||
}];
|
||||
} ];
|
||||
|
||||
return {
|
||||
name: strings.name,
|
||||
|
||||
@@ -8,11 +8,11 @@ export default {
|
||||
name: 'xdomain-messaging',
|
||||
init () {
|
||||
const svgEditor = this;
|
||||
const {svgCanvas} = svgEditor;
|
||||
const { svgCanvas } = svgEditor;
|
||||
try {
|
||||
window.addEventListener('message', function (e) {
|
||||
// We accept and post strings for the sake of IE9 support
|
||||
if (!e.data || !['string', 'object'].includes(typeof e.data) || e.data.charAt() === '|') {
|
||||
if (!e.data || ![ 'string', 'object' ].includes(typeof e.data) || e.data.charAt() === '|') {
|
||||
return;
|
||||
}
|
||||
const data = typeof e.data === 'object' ? e.data : JSON.parse(e.data);
|
||||
@@ -22,13 +22,13 @@ export default {
|
||||
// The default is not to allow any origins, including even the same domain or
|
||||
// if run on a `file:///` URL. See `svgedit-config-es.js` for an example of how
|
||||
// to configure
|
||||
const {allowedOrigins} = svgEditor.configObj.curConfig;
|
||||
const { allowedOrigins } = svgEditor.configObj.curConfig;
|
||||
if (!allowedOrigins.includes('*') && !allowedOrigins.includes(e.origin)) {
|
||||
console.log(`Origin ${e.origin} not whitelisted for posting to ${window.origin}`);
|
||||
console.log(`Origin ${e.origin} not whitelisted for posting to ${window.origin}`);
|
||||
return;
|
||||
}
|
||||
const cbid = data.id;
|
||||
const {name, args} = data;
|
||||
const { name, args } = data;
|
||||
const message = {
|
||||
namespace: 'svg-edit',
|
||||
id: cbid
|
||||
@@ -43,7 +43,7 @@ export default {
|
||||
e.source.postMessage(JSON.stringify(message), '*');
|
||||
});
|
||||
} catch (err) {
|
||||
console.log('Error with xdomain message listener: ' + err);
|
||||
console.log('Error with xdomain message listener: ' + err);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
Before Width: | Height: | Size: 637 B |
|
Before Width: | Height: | Size: 474 B |
11
src/editor/images/hello_world.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
<svg width="102" height="102" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit -->
|
||||
<g>
|
||||
<title>Layer 1</title>
|
||||
<rect ry="30" rx="30" x="2.5" y="2.5" width="97" height="97" id="svg_3" fill="#008000" stroke="#000000" stroke-width="5"/>
|
||||
<text x="52.668" y="42.5" id="svg_1" fill="#ffffff" stroke="#000000" stroke-width="0" font-size="24" font-family="Monospace" text-anchor="middle" xml:space="preserve">Hello</text>
|
||||
<text x="52.668" y="71.5" fill="#ffffff" stroke="#000000" stroke-width="0" font-size="24" font-family="Monospace" text-anchor="middle" xml:space="preserve" id="svg_2">World!</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 725 B |
@@ -1,21 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<!--
|
||||
Sample icons file. This file looks like an SVG file with groups as its
|
||||
children. Each group element has an ID that must match the ID of the button given
|
||||
in the extension. The SVG inside the group makes up the actual icon, and
|
||||
needs use a viewBox instead of width/height for it to scale properly.
|
||||
|
||||
Multiple icons can be included, each within their own group.
|
||||
-->
|
||||
<g id="hello_world">
|
||||
<svg width="102" height="102" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit -->
|
||||
<g>
|
||||
<title>Layer 1</title>
|
||||
<rect ry="30" rx="30" x="2.5" y="2.5" width="97" height="97" id="svg_3" fill="#008000" stroke="#000000" stroke-width="5"/>
|
||||
<text x="52.668" y="42.5" id="svg_1" fill="#ffffff" stroke="#000000" stroke-width="0" font-size="24" font-family="Monospace" text-anchor="middle" xml:space="preserve">Hello</text>
|
||||
<text x="52.668" y="71.5" fill="#ffffff" stroke="#000000" stroke-width="0" font-size="24" font-family="Monospace" text-anchor="middle" xml:space="preserve" id="svg_2">World!</text>
|
||||
</g>
|
||||
</svg>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,110 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit -->
|
||||
<g id="nomarker">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-50,0l100,0"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="leftarrow">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-50,0l100,40l-30,-40l30,-40z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="rightarrow">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m50,0l-100,40l30,-40l-30,-40z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="leftarrow_o">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-50,0l100,40l-30,-40l30,-40z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="rightarrow_o">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m50,0l-100,40l30,-40l-30,-40z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="forwardslash">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-20,50l40,-100"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="reverseslash">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-20,-50l40,100"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="verticalslash">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m0,-50l0,100"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="mcircle">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle stroke-width="10" stroke="#f9bc01" fill="#f9bc01" cy="0" cx="0" r="30"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="mcircle_o">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle stroke-width="10" stroke="#f9bc01" fill="none" cy="0" cx="0" r="30"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="xmark">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-30,30l60,-60m0,60l-60,-60"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="box">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-30,-30l0,60l60,0l0,-60z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="box_o">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-30,-30l0,60l60,0l0,-60z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="star_o">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-40,-20l80,0l-70,60l30,-80l30,80z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="triangle_o">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="M-30,30 L0,-30 L30,30 Z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="triangle">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="M-30,30 L0,-30 L30,30 Z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="textmarker">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<text xml:space="preserve" text-anchor="middle" font-family="serif" font-size="120" y="40" x="0" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="mkr_markers_off">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<line y2="0" x2="50" y1="0" x1="-50" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="mkr_markers_dimension">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<line y2="0" x2="40" y1="0" x1="20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||
<line y2="0" x2="-40" y1="0" x1="-20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||
<text text-anchor="middle" font-family="serif" font-size="80" y="20" x="0" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M-50,0 L-30,-15 L-30,15 Z"/>
|
||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M50,0 L30,-15 L30,15 Z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="mkr_markers_label">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<line y2="0" x2="40" y1="0" x1="-20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||
<text text-anchor="middle" font-family="serif" font-size="80" y="20" x="-40" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M50,0 L30,-15 L30,15 Z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="svg_eof"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.1 KiB |
7
src/editor/images/mkr_markers_dimension.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<line y2="0" x2="40" y1="0" x1="20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||
<line y2="0" x2="-40" y1="0" x1="-20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||
<text text-anchor="middle" font-family="serif" font-size="80" y="20" x="0" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M-50,0 L-30,-15 L-30,15 Z"/>
|
||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M50,0 L30,-15 L30,15 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 598 B |
5
src/editor/images/mkr_markers_label.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<line y2="0" x2="40" y1="0" x1="-20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||
<text text-anchor="middle" font-family="serif" font-size="80" y="20" x="-40" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M50,0 L30,-15 L30,15 Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 390 B |
3
src/editor/images/mkr_markers_off.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<line y2="0" x2="50" y1="0" x1="-50" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 162 B |
@@ -1,138 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit -->
|
||||
<g id="nomarker">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-50,0l100,0"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="leftarrow">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-50,0l100,40l-30,-40l30,-40z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="rightarrow">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m50,0l-100,40l30,-40l-30,-40z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="leftarrow_o">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-50,0l100,40l-30,-40l30,-40z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="rightarrow_o">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m50,0l-100,40l30,-40l-30,-40z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="forwardslash">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-20,50l40,-100"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="reverseslash">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-20,-50l40,100"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="verticalslash">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m0,-50l0,100"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="mcircle">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle stroke-width="10" stroke="#f9bc01" fill="#f9bc01" cy="0" cx="0" r="30"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="mcircle_o">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle stroke-width="10" stroke="#f9bc01" fill="none" cy="0" cx="0" r="30"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="xmark">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-30,30l60,-60m0,60l-60,-60"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="box">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-30,-30l0,60l60,0l0,-60z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="star">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-40,-20l80,0l-70,60l30,-80l30,80z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="box_o">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-30,-30l0,60l60,0l0,-60z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="star_o">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-40,-20l80,0l-70,60l30,-80l30,80z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="triangle_o">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="M-30,30 L0,-30 L30,30 Z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="triangle">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="M-30,30 L0,-30 L30,30 Z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="textmarker">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<text xml:space="preserve" text-anchor="middle" font-family="serif" font-size="120" y="40" x="0" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="textmarker_top">
|
||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="4" stroke="#f9bc01" fill="none" d="M 0 60 h 100 z M 30 30 h 40 v 20 h -40 z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="textmarker_bottom">
|
||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke-width="4" stroke="#f9bc01" fill="none" d="M 0 30 h 100 z M 30 40 h 40 v 20 h -40 z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="tool_placemark">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-1 -1 110 110">
|
||||
<line fill="none" id="svg_4" marker-start="url(#se_marker_start_svg_4)" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="5" x1="0" x2="42.58373" y1="0" y2="56.42415"/>
|
||||
<line fill="none" id="svg_5" stroke="#000000" stroke-linecap="round" stroke-width="5" x1="99.99999" x2="42.58373" y1="56.42415" y2="56.42415"/>
|
||||
<rect fill="none" height="26.47059" id="svg_2" stroke="#000000" stroke-dasharray="10,10" stroke-linecap="round" stroke-linejoin="round" stroke-width="5" width="55.02392" x="44.01914" y="16.71827"/>
|
||||
<rect fill="none" height="32.73994" id="svg_3" stroke="#000000" stroke-dasharray="10,10" stroke-linecap="round" stroke-linejoin="null" stroke-width="5" width="55.98086" x="44.01914" y="67.56966"/>
|
||||
<defs>
|
||||
<marker class="leftarrow" id="se_marker_start_svg_4" markerHeight="5" markerUnits="strokeWidth" markerWidth="5" orient="auto" refX="0" refY="50" viewBox="0 0 100 100">
|
||||
<path d="m0,50l100,40l-30,-40l30,-40l-100,40z" fill="#000000" id="svg_1" stroke="#000000" stroke-width="10"/>
|
||||
</marker>
|
||||
</defs>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="mkr_markers_off">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<line y2="0" x2="50" y1="0" x1="-50" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="mkr_markers_dimension">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<line y2="0" x2="40" y1="0" x1="20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||
<line y2="0" x2="-40" y1="0" x1="-20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||
<text text-anchor="middle" font-family="serif" font-size="80" y="20" x="0" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M-50,0 L-30,-15 L-30,15 Z"/>
|
||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M50,0 L30,-15 L30,15 Z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="mkr_markers_label">
|
||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<line y2="0" x2="40" y1="0" x1="-20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||
<text text-anchor="middle" font-family="serif" font-size="80" y="20" x="-40" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M50,0 L30,-15 L30,15 Z"/>
|
||||
</svg>
|
||||
</g>
|
||||
<g id="svg_eof"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 7.0 KiB |