Merge pull request #507 from SVG-Edit/V7-dev

V7 dev
This commit is contained in:
JFH
2021-05-15 18:38:34 +02:00
committed by GitHub
183 changed files with 2934 additions and 3038 deletions

View File

@@ -11,7 +11,7 @@ module.exports = {
"plugin:sonarjs/recommended",
"eslint:recommended"
],
plugins: ["jsdoc", "promise", "html", "import", "sonarjs"],
plugins: [ "jsdoc", "promise", "html", "import", "sonarjs" ],
parserOptions: {
ecmaVersion: 2020,
sourceType: "module"
@@ -21,32 +21,46 @@ module.exports = {
es6: true
},
rules: {
/** @todo len should probably more 120-150 */
"max-len": [ "warn", { "code": 250 } ],
/** @todo jsdoc should be made warn or error */
"valid-jsdoc": "off",
/** @todo cognitive complexity should be much lower (25-50?) */
"sonarjs/cognitive-complexity": [ "warn", 200 ],
"node/no-unsupported-features/es-syntax": 0,
"no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"sonarjs/cognitive-complexity": ["warn", 40],
"no-unused-vars": [ "error", { "argsIgnorePattern": "^_" } ],
"sonarjs/no-duplicate-string": 0,
"semi" : "error",
"no-trailing-spaces": "error",
"array-bracket-spacing": [ "error", "always" ],
"comma-spacing": "error",
"object-curly-spacing": [ "error", "always" ],
"no-console": [
"warn",
{ "allow": [ "warn", "error", "info", "table" ] }
],
"no-param-reassign": [ "warn", { "props": false } ],
"arrow-parens": [ "error", "always" ],
},
overrides: [
{
files: [ 'cypress/**/*'],
extends: [
files: [ 'cypress/**/*' ],
extends: [
"plugin:cypress/recommended"
],
env: {
mocha: true,
node: true
},
globals: {
"assert": true
},
globals: { "assert": true },
rules: {
// with ci, instrumented is not created before linter
"import/no-unresolved": [2, { ignore: ['instrumented'] }],
"import/no-unresolved": [ 2, { ignore: [ 'instrumented' ] } ],
"node/no-missing-import": 0
}
},
{
files: [ 'docs/**/*'],
files: [ 'docs/**/*' ],
rules: { // md files have example that don't need a strict checking
"no-undef": 0,
"import/no-unresolved": 0,

View File

@@ -623,12 +623,12 @@ exports[`use various parts of svg-edit > check tool_star #0`] = `
point="5"
r="66.66666666666667"
radialshift="0"
r2="13.333333333333334"
r2="22.222222222222225"
orient="point"
fill="#ffff00"
strokecolor="#000000"
strokewidth="0"
points="370,135.33333333333331 377.83713669723295,191.21310674166736 433.40376775301024,181.39886704167017 382.68075355060205,206.12022659166595 409.18568348616486,255.93446629166317 370,215.33333333333334 330.81431651383514,255.93446629166317 357.31924644939795,206.12022659166595 306.59623224698976,181.39886704167017 362.16286330276705,191.21310674166736 370,135.33333333333331 377.83713669723295,191.21310674166736 "
points="370,135.33333333333331 383.0618944953883,184.02184456944562 433.40376775301024,181.39886704167017 391.13458925100343,208.86704431944327 409.18568348616486,255.93446629166317 370,224.22222222222223 330.81431651383514,255.93446629166317 348.86541074899657,208.86704431944327 306.59623224698976,181.39886704167017 356.9381055046117,184.02184456944562 370,135.33333333333331 383.0618944953883,184.02184456944562 "
stroke="#000000"
stroke-width="0"
>
@@ -713,12 +713,12 @@ exports[`use various parts of svg-edit > check tool_polygon #0`] = `
point="5"
r="66.66666666666667"
radialshift="0"
r2="13.333333333333334"
r2="22.222222222222225"
orient="point"
fill="#ffff00"
strokecolor="#000000"
strokewidth="0"
points="370,135.33333333333331 377.83713669723295,191.21310674166736 433.40376775301024,181.39886704167017 382.68075355060205,206.12022659166595 409.18568348616486,255.93446629166317 370,215.33333333333334 330.81431651383514,255.93446629166317 357.31924644939795,206.12022659166595 306.59623224698976,181.39886704167017 362.16286330276705,191.21310674166736 370,135.33333333333331 377.83713669723295,191.21310674166736 "
points="370,135.33333333333331 383.0618944953883,184.02184456944562 433.40376775301024,181.39886704167017 391.13458925100343,208.86704431944327 409.18568348616486,255.93446629166317 370,224.22222222222223 330.81431651383514,255.93446629166317 348.86541074899657,208.86704431944327 306.59623224698976,181.39886704167017 356.9381055046117,184.02184456944562 370,135.33333333333331 383.0618944953883,184.02184456944562 "
stroke="#000000"
stroke-width="0"
fill-opacity="1"

View File

@@ -13,10 +13,10 @@ describe('UI - Accessibility', function () {
cy.configureAxe({
// Todo: Reenable when have time to fix
// See https://www.deque.com/axe/axe-for-web/documentation/api-documentation/#user-content-parameters-1
rules: [{
rules: [ {
id: 'meta-viewport',
enabled: false
}]
} ]
/*
branding: {
brand: String,
@@ -32,10 +32,10 @@ describe('UI - Accessibility', function () {
{},
{
rules: {
'label-title-only': {enabled: false},
'page-has-heading-one': {enabled: false},
region: {enabled: false},
'scrollable-region-focusable': {enabled: false}
'label-title-only': { enabled: false },
'page-has-heading-one': { enabled: false },
region: { enabled: false },
'scrollable-region-focusable': { enabled: false }
}
}
);

View File

@@ -11,13 +11,13 @@ describe('UI - Clipboard', function () {
cy.get('#tool_source').click();
cy.get('#svg_source_textarea')
.type('{selectall}', {force: true})
.type('{selectall}', { force: true })
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<g class="layer">
<title>Layer 1</title>
<circle cx="100" cy="100" r="50" fill="#FF0000" id="testCircle" stroke="#000000" stroke-width="5"/>
</g>
</svg>`, {force: true, parseSpecialCharSequences: false});
</svg>`, { force: true, parseSpecialCharSequences: false });
cy.get('#tool_source_save').click();
cy.get('#testCircle').should('exist');
cy.get('#svg_1').should('not.exist');
@@ -25,20 +25,20 @@ describe('UI - Clipboard', function () {
// Copy.
cy.get('#testCircle').click().rightclick();
cy.get('#cmenu_canvas a[href="#copy"]').click({force: true});
cy.get('#cmenu_canvas a[href="#copy"]').click({ force: true });
// Paste.
// Scrollbars fail to recenter in Cypress test. Works fine in reality.
// Thus forcing click is needed since workspace is mostly offscreen.
cy.get('#svgroot').rightclick({force: true});
cy.get('#cmenu_canvas a[href="#paste"]').click({force: true});
cy.get('#svgroot').rightclick({ force: true });
cy.get('#cmenu_canvas a[href="#paste"]').click({ force: true });
cy.get('#testCircle').should('exist');
cy.get('#svg_1').should('exist');
cy.get('#svg_2').should('not.exist');
// Cut.
cy.get('#testCircle').click().rightclick();
cy.get('#cmenu_canvas a[href="#cut"]').click({force: true});
cy.get('#cmenu_canvas a[href="#cut"]').click({ force: true });
cy.get('#testCircle').should('not.exist');
cy.get('#svg_1').should('exist');
cy.get('#svg_2').should('not.exist');
@@ -46,17 +46,17 @@ describe('UI - Clipboard', function () {
// Paste.
// Scrollbars fail to recenter in Cypress test. Works fine in reality.
// Thus forcing click is needed since workspace is mostly offscreen.
cy.get('#svgroot').rightclick({force: true});
cy.get('#cmenu_canvas a[href="#paste"]').click({force: true});
cy.get('#svgroot').rightclick({ force: true });
cy.get('#cmenu_canvas a[href="#paste"]').click({ force: true });
cy.get('#testCircle').should('not.exist');
cy.get('#svg_1').should('exist');
cy.get('#svg_2').should('exist');
// Delete.
cy.get('#svg_2').click().rightclick();
cy.get('#cmenu_canvas a[href="#delete"]').click({force: true});
cy.get('#cmenu_canvas a[href="#delete"]').click({ force: true });
cy.get('#svg_1').click().rightclick();
cy.get('#cmenu_canvas a[href="#delete"]').click({force: true});
cy.get('#cmenu_canvas a[href="#delete"]').click({ force: true });
cy.get('#svg_1').should('not.exist');
cy.get('#svg_2').should('not.exist');
});

View File

@@ -11,23 +11,23 @@ describe('UI - Control Points', function () {
const randomOffset = () => 2 + Math.round(10 + Math.random() * 40);
cy.get('#tool_source').click();
cy.get('#svg_source_textarea')
.type('{selectall}', {force: true})
.type('{selectall}', { force: true })
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<g class="layer">
<title>Layer 1</title>
<path d="m187,194a114,62 0 1 0 219,2" id="svg_1" fill="#FF0000" stroke="#000000" stroke-width="5"/>
</g>
</svg>`, {force: true, parseSpecialCharSequences: false});
cy.get('#tool_source_save').click({force: true});
</svg>`, { force: true, parseSpecialCharSequences: false });
cy.get('#tool_source_save').click({ force: true });
cy.get('#svg_1').click({force: true}).click({force: true});
cy.get('#svg_1').click({ force: true }).click({ force: true });
cy.get('#pathpointgrip_0').trigger('mousedown', {which: 1, force: true})
.trigger('mousemove', randomOffset(), randomOffset(), {force: true})
.trigger('mouseup', {force: true});
cy.get('#pathpointgrip_1').trigger('mousedown', {which: 1, force: true})
.trigger('mousemove', randomOffset(), randomOffset(), {force: true})
.trigger('mouseup', {force: true});
cy.get('#pathpointgrip_0').trigger('mousedown', { which: 1, force: true })
.trigger('mousemove', randomOffset(), randomOffset(), { force: true })
.trigger('mouseup', { force: true });
cy.get('#pathpointgrip_1').trigger('mousedown', { which: 1, force: true })
.trigger('mousemove', randomOffset(), randomOffset(), { force: true })
.trigger('mouseup', { force: true });
cy.get('#svg_1[d]').should('not.contain', 'NaN');
});

View File

@@ -14,7 +14,7 @@ describe('UI - Export tests', function () {
it('Editor - No parameters: Export button clicking; dialog opens', () => {
openMainMenu();
cy.get('#tool_export').click({force: true});
cy.get('#tool_export').click({ force: true });
cy.get('#dialog_content select');
});
});

View File

@@ -11,13 +11,13 @@ describe('Fix issue 359', function () {
it('can undo without throwing', function () {
cy.get('#tool_source').click();
cy.get('#svg_source_textarea')
.type('{selectall}', {force: true})
.type('{selectall}', { force: true })
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<g class="layer">
<title>Layer 1</title>
<rect fill="#ffff00" height="70" width="165" x="179.5" y="146.5"/>
</g>
</svg>`, {parseSpecialCharSequences: false, force: true});
</svg>`, { parseSpecialCharSequences: false, force: true });
cy.get('#tool_source_save').click();
cy.get('#tool_undo').click();
cy.get('#tool_redo').click(); // test also redo to make the test more comprehensive

View File

@@ -11,7 +11,7 @@ describe('Fix issue 407', function () {
it('can enter edit on text child', function () {
cy.get('#tool_source').click();
cy.get('#svg_source_textarea')
.type('{selectall}', {force: true})
.type('{selectall}', { force: true })
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<g class="layer">
<title>Layer 1</title>
@@ -20,16 +20,16 @@ describe('Fix issue 407', function () {
<text fill="#000000" id="a_text" text-anchor="middle" x="260.5" xml:space="preserve" y="192.5">hello</text>
</g>
</g>
</svg>`, {force: true, parseSpecialCharSequences: false});
</svg>`, { force: true, parseSpecialCharSequences: false });
cy.get('#tool_source_save').click();
cy.get('#svg_1').click().dblclick();
cy.get('#a_text').should('exist');
cy.get('#a_text')
.trigger('mousedown', {which: 1, force: true})
.trigger('mouseup', {force: true})
.dblclick({force: true});
.trigger('mousedown', { which: 1, force: true })
.trigger('mouseup', { force: true })
.dblclick({ force: true });
// svgedit use the #text text field to capture the text
cy.get('#text').type('1234', {force: true});
cy.get('#text').type('1234', { force: true });
cy.get('#a_text').should('have.text', 'he1234llo');
});
});

View File

@@ -11,7 +11,7 @@ describe('Fix issue 408', function () {
it('should not throw when showing/saving svg content', function () {
cy.get('#tool_source').click();
cy.get('#svg_source_textarea')
.type('{selectall}', {force: true})
.type('{selectall}', { force: true })
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<g class="layer">
<title>Layer 1</title>
@@ -20,7 +20,7 @@ describe('Fix issue 408', function () {
<circle cx="117.5" cy="87.5" fill="#ffff00" r="19.84943" stroke="#000000" />
</g>
</g>
</svg>`, {force: true, parseSpecialCharSequences: false});
</svg>`, { force: true, parseSpecialCharSequences: false });
cy.get('#tool_source_save').click();
cy.get('#svg_6').click().dblclick(); // change context
cy.get('#tool_source').click(); // reopen tool_source

View File

@@ -11,7 +11,7 @@ describe('Fix issue 423', function () {
it('should not throw when undoing the move', function () {
cy.get('#tool_source').click();
cy.get('#svg_source_textarea')
.type('{selectall}', {force: true})
.type('{selectall}', { force: true })
.type(`<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<g class="layer">
<title>Layer 1</title>
@@ -22,12 +22,12 @@ describe('Fix issue 423', function () {
<rect clip-path="url(#svg_2)" fill="#0033b5" height="174.9" id="TANK1" width="78" x="77.5" y="29"/>
</g>
</g>
</svg>`, {parseSpecialCharSequences: false, force: true});
cy.get('#tool_source_save').click({force: true});
</svg>`, { parseSpecialCharSequences: false, force: true });
cy.get('#tool_source_save').click({ force: true });
cy.get('#TANK1')
.trigger('mousedown', {force: true})
.trigger('mousemove', 50, 0, {force: true})
.trigger('mouseup', {force: true});
cy.get('#tool_undo').click({force: true});
.trigger('mousedown', { force: true })
.trigger('mousemove', 50, 0, { force: true })
.trigger('mouseup', { force: true });
cy.get('#tool_undo').click({ force: true });
});
});

View File

@@ -12,97 +12,97 @@ describe('use various parts of svg-edit', function () {
});
it('check tool_source', function () {
cy.get('#tool_source').click({force: true});
cy.get('#tool_source').click({ force: true });
cy.get('#svg_source_textarea')
.type('{selectall}', {force: true})
.type('{selectall}', { force: true })
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<g class="layer">
<title>Layer 1</title>
<rect id="rect" fill="#FF0000" height="70" stroke="#000000" stroke-width="5" width="94" x="69.5" y="51.5"/>
</g>
</svg>`, {force: true, parseSpecialCharSequences: false});
cy.get('#tool_source_save').click({force: true});
</svg>`, { force: true, parseSpecialCharSequences: false });
cy.get('#tool_source_save').click({ force: true });
testSnapshot();
});
it('check tool_fhpath', function () {
cy.get('#tool_fhpath')
.click({force: true});
.click({ force: true });
cy.get('#rect')
.trigger('mousemove', 200, 200, {force: true})
.trigger('mousedown', 200, 200, {force: true})
.trigger('mousemove', 20, 20, {force: true})
.trigger('mouseup', {force: true});
.trigger('mousemove', 200, 200, { force: true })
.trigger('mousedown', 200, 200, { force: true })
.trigger('mousemove', 20, 20, { force: true })
.trigger('mouseup', { force: true });
cy.get('#svgcontent').toMatchSnapshot();
});
it('check tool_text', function () {
cy.get('#tool_text')
.click({force: true});
.click({ force: true });
cy.get('#rect')
.trigger('mousedown', 46, 35, {force: true})
.trigger('mouseup', {force: true});
.trigger('mousedown', 46, 35, { force: true })
.trigger('mouseup', { force: true });
// svgedit use the #text text field to capture the text
cy.get('#text').type('AB', {force: true});
cy.get('#text').type('AB', { force: true });
testSnapshot();
});
it('check tool_clone', function () {
cy.get('#svg_1').click({force: true});
cy.get('#svg_1').click({ force: true });
cy.get('#tool_clone')
.click({force: true});
.click({ force: true });
testSnapshot();
});
it('check tool_italic', function () {
cy.get('#svg_1').click({force: true});
cy.get('#svg_1').click({ force: true });
cy.get('#tool_italic')
.click({force: true});
.click({ force: true });
testSnapshot();
});
it('check tool_bold', function () {
cy.get('#svg_1').click({force: true});
cy.get('#svg_1').click({ force: true });
cy.get('#tool_bold')
.click({force: true});
.click({ force: true });
testSnapshot();
});
it('check change color', function () {
cy.get('#svg_1').click({force: true});
cy.get('#svg_1').click({ force: true });
cy.get('[data-rgb="#ffff00"]')
.click({force: true});
.click({ force: true });
testSnapshot();
});
it('check tool_text_anchor_start', function () {
cy.get('#svg_1').click({force: true});
cy.get('#svg_1').click({ force: true });
cy.get('#tool_text_anchor_start')
.click({force: true});
.click({ force: true });
testSnapshot();
});
it('check tool_text_anchor_middle', function () {
cy.get('#svg_1').click({force: true});
cy.get('#svg_1').click({ force: true });
cy.get('#tool_text_anchor_middle')
.click({force: true});
.click({ force: true });
testSnapshot();
});
it('check tool_text_anchor_end', function () {
cy.get('#svg_1').click({force: true});
cy.get('#svg_1').click({ force: true });
cy.get('#tool_text_anchor_end')
.click({force: true});
.click({ force: true });
testSnapshot();
});
it('check tool_star', function () {
cy.get('#tool_star')
.click({force: true});
.click({ force: true });
cy.get('#svgcontent')
.trigger('mousedown', 300, 150, {force: true})
.trigger('mousemove', 300, 250, {force: true})
.trigger('mouseup', {force: true});
.trigger('mousedown', 300, 150, { force: true })
.trigger('mousemove', 300, 250, { force: true })
.trigger('mouseup', { force: true });
testSnapshot();
});
it('check tool_polygon', function () {
cy.get('#tool_polygon')
.click({force: true});
.click({ force: true });
cy.get('#svgcontent')
.trigger('mousedown', 350, 250, {force: true})
.trigger('mousemove', 350, 370, {force: true})
.trigger('mouseup', {force: true});
.trigger('mousedown', 350, 250, { force: true })
.trigger('mousemove', 350, 370, { force: true })
.trigger('mouseup', { force: true });
testSnapshot();
});
});

View File

@@ -11,7 +11,7 @@ describe('UI - Tool selection', function () {
cy.get('#tools_rect')
.should('not.have.attr', 'pressed');
cy.get('#tools_rect')
.trigger('click', {force: true})
.trigger('click', { force: true })
.should('have.attr', 'pressed');
});
});

View File

@@ -19,26 +19,26 @@ describe('contextmenu', function () {
it('Test svgedit.contextmenu does not add invalid menu item', function () {
assert.throws(
() => contextmenu.add({id: 'justanid'}),
() => contextmenu.add({ id: 'justanid' }),
null, null,
'menu item with just an id is invalid'
);
assert.throws(
() => contextmenu.add({id: 'idandlabel', label: 'anicelabel'}),
() => contextmenu.add({ id: 'idandlabel', label: 'anicelabel' }),
null, null,
'menu item with just an id and label is invalid'
);
assert.throws(
() => contextmenu.add({id: 'idandlabel', label: 'anicelabel', action: 'notafunction'}),
() => contextmenu.add({ id: 'idandlabel', label: 'anicelabel', action: 'notafunction' }),
null, null,
'menu item with action that is not a function is invalid'
);
});
it('Test svgedit.contextmenu adds valid menu item', function () {
const validItem = {id: 'valid', label: 'anicelabel', action () { /* empty fn */ }};
const validItem = { id: 'valid', label: 'anicelabel', action () { /* empty fn */ } };
contextmenu.add(validItem);
assert.ok(contextmenu.hasCustomHandler('valid'), 'Valid menu item is added.');
@@ -46,8 +46,8 @@ describe('contextmenu', function () {
});
it('Test svgedit.contextmenu rejects valid duplicate menu item id', function () {
const validItem1 = {id: 'valid', label: 'anicelabel', action () { /* empty fn */ }};
const validItem2 = {id: 'valid', label: 'anicelabel', action () { /* empty fn */ }};
const validItem1 = { id: 'valid', label: 'anicelabel', action () { /* empty fn */ } };
const validItem2 = { id: 'valid', label: 'anicelabel', action () { /* empty fn */ } };
contextmenu.add(validItem1);
assert.throws(

View File

@@ -1,6 +1,6 @@
import '../../../instrumented/editor/jquery.min.js';
import {NS} from '../../../instrumented/common/namespaces.js';
import { NS } from '../../../instrumented/common/namespaces.js';
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
import * as coords from '../../../instrumented/svgcanvas/coords.js';

View File

@@ -1,6 +1,6 @@
import '../../../instrumented/editor/jquery.min.js';
import {NS} from '../../../instrumented/common/namespaces.js';
import { NS } from '../../../instrumented/common/namespaces.js';
import * as draw from '../../../instrumented/svgcanvas/draw.js';
import * as units from '../../../instrumented/common/units.js';
@@ -61,7 +61,7 @@ describe('draw.Drawing', function () {
*/
function createSVGElement (jsonMap) {
const elem = document.createElementNS(NS.SVG, jsonMap.element);
Object.entries(jsonMap.attr).forEach(([attr, value]) => {
Object.entries(jsonMap.attr).forEach(([ attr, value ]) => {
elem.setAttribute(attr, value);
});
return elem;
@@ -86,7 +86,7 @@ describe('draw.Drawing', function () {
layer3.append(layer3Title);
svgElem.append(layer3);
return [layer1, layer2, layer3];
return [ layer1, layer2, layer3 ];
};
const createSomeElementsInGroup = function (group) {
@@ -101,11 +101,11 @@ describe('draw.Drawing', function () {
// }),
createSVGElement({
element: 'rect',
attr: {x: '0', y: '1', width: '5', height: '10'}
attr: { x: '0', y: '1', width: '5', height: '10' }
}),
createSVGElement({
element: 'line',
attr: {x1: '0', y1: '1', x2: '5', y2: '6'}
attr: { x1: '0', y1: '1', x2: '5', y2: '6' }
})
);
@@ -115,7 +115,7 @@ describe('draw.Drawing', function () {
});
g.append(createSVGElement({
element: 'rect',
attr: {x: '0', y: '1', width: '5', height: '10'}
attr: { x: '0', y: '1', width: '5', height: '10' }
}));
group.append(g);
return 4;
@@ -727,7 +727,6 @@ describe('draw.Drawing', function () {
drawing.setLayerOpacity(LAYER3, -1.4);
assert.strictEqual(drawing.getLayerOpacity(LAYER1), 0.4);
// console.log('layer2 opacity ' + drawing.getLayerOpacity(LAYER2));
assert.strictEqual(drawing.getLayerOpacity(LAYER2), 1.0);
assert.strictEqual(drawing.getLayerOpacity(LAYER3), 1.0);

View File

@@ -1,6 +1,6 @@
import '../../../instrumented/editor/jquery.min.js';
import {NS} from '../../../instrumented/common/namespaces.js';
import { NS } from '../../../instrumented/common/namespaces.js';
import * as transformlist from '../../../instrumented/svgcanvas/svgtransformlist.js';
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
import * as hstory from '../../../instrumented/svgcanvas/history.js';
@@ -402,7 +402,7 @@ describe('history', function () {
it('Test ChangeElementCommand', function () {
this.div1.setAttribute('title', 'new title');
let change = new hstory.ChangeElementCommand(this.div1,
{title: 'old title', class: 'foo'});
{ title: 'old title', class: 'foo' });
assert.ok(change.unapply);
assert.ok(change.apply);
assert.equal(typeof change.unapply, typeof function () { /* empty fn */ });
@@ -418,7 +418,7 @@ describe('history', function () {
this.div1.textContent = 'inner text';
change = new hstory.ChangeElementCommand(this.div1,
{'#text': null});
{ '#text': null });
change.unapply();
assert.ok(!this.div1.textContent);
@@ -428,7 +428,7 @@ describe('history', function () {
this.div1.textContent = '';
change = new hstory.ChangeElementCommand(this.div1,
{'#text': 'old text'});
{ '#text': 'old text' });
change.unapply();
assert.equal(this.div1.textContent, 'old text');
@@ -457,7 +457,7 @@ describe('history', function () {
gethrefvalue = '#newhref';
change = new hstory.ChangeElementCommand(rect,
{'#href': '#oldhref'});
{ '#href': '#oldhref' });
assert.equal(justCalled, 'getHref');
justCalled = null;
@@ -472,7 +472,7 @@ describe('history', function () {
const line = document.createElementNS(NS.SVG, 'line');
line.setAttribute('class', 'newClass');
change = new hstory.ChangeElementCommand(line, {class: 'oldClass'});
change = new hstory.ChangeElementCommand(line, { class: 'oldClass' });
assert.ok(change.unapply);
assert.ok(change.apply);

View File

@@ -1,6 +1,6 @@
import '../../../instrumented/editor/jquery.min.js';
import {NS} from '../../../instrumented/common/namespaces.js';
import { NS } from '../../../instrumented/common/namespaces.js';
import * as math from '../../../instrumented/svgcanvas/math.js';
describe('math', function () {
@@ -17,7 +17,7 @@ describe('math', function () {
});
it('Test svgedit.math.transformPoint() function', function () {
const {transformPoint} = math;
const { transformPoint } = math;
const m = svg.createSVGMatrix();
m.a = 1; m.b = 0;
@@ -51,7 +51,7 @@ describe('math', function () {
it('Test svgedit.math.matrixMultiply() function', function () {
const mult = math.matrixMultiply;
const {isIdentity} = math;
const { isIdentity } = math;
// translate there and back
const tr1 = svg.createSVGMatrix().translate(100, 50),
@@ -84,7 +84,7 @@ describe('math', function () {
});
it('Test svgedit.math.transformBox() function', function () {
const {transformBox} = math;
const { transformBox } = math;
const m = svg.createSVGMatrix();
m.a = 1; m.b = 0;

View File

@@ -3,11 +3,11 @@ import 'pathseg';
import '../../../instrumented/editor/jquery.min.js';
import {NS} from '../../../instrumented/common/namespaces.js';
import { NS } from '../../../instrumented/common/namespaces.js';
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
import * as pathModule from '../../../instrumented/svgcanvas/path.js';
import {Path, Segment} from '../../../instrumented/svgcanvas/path-method.js';
import {init as unitsInit} from '../../../instrumented/common/units.js';
import { Path, Segment } from '../../../instrumented/svgcanvas/path-method.js';
import { init as unitsInit } from '../../../instrumented/common/units.js';
describe('path', function () {
/**
@@ -48,7 +48,7 @@ describe('path', function () {
const path = document.createElementNS(NS.SVG, 'path');
path.setAttribute('d', 'M0,0 L10,11 L20,21Z');
const [mockPathContext, mockUtilitiesContext] = getMockContexts();
const [ mockPathContext, mockUtilitiesContext ] = getMockContexts();
pathModule.init(mockPathContext);
utilities.init(mockUtilitiesContext);
new Path(path); // eslint-disable-line no-new
@@ -57,7 +57,7 @@ describe('path', function () {
assert.equal(path.pathSegList.getItem(1).x, 10);
assert.equal(path.pathSegList.getItem(1).y, 11);
pathModule.replacePathSeg(SVGPathSeg.PATHSEG_LINETO_REL, 1, [30, 31], path);
pathModule.replacePathSeg(SVGPathSeg.PATHSEG_LINETO_REL, 1, [ 30, 31 ], path);
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'l');
assert.equal(path.pathSegList.getItem(1).x, 30);
@@ -68,7 +68,7 @@ describe('path', function () {
const path = document.createElementNS(NS.SVG, 'path');
path.setAttribute('d', 'M0,0 L10,11 L20,21Z');
const [mockPathContext, mockUtilitiesContext] = getMockContexts();
const [ mockPathContext, mockUtilitiesContext ] = getMockContexts();
pathModule.init(mockPathContext);
utilities.init(mockUtilitiesContext);
new Path(path); // eslint-disable-line no-new
@@ -78,7 +78,7 @@ describe('path', function () {
assert.equal(path.pathSegList.getItem(1).y, 11);
const segment = new Segment(1, path.pathSegList.getItem(1));
segment.setType(SVGPathSeg.PATHSEG_LINETO_REL, [30, 31]);
segment.setType(SVGPathSeg.PATHSEG_LINETO_REL, [ 30, 31 ]);
assert.equal(segment.item.pathSegTypeAsLetter, 'l');
assert.equal(segment.item.x, 30);
assert.equal(segment.item.y, 31);
@@ -96,7 +96,7 @@ describe('path', function () {
path.setAttribute('d', 'M0,0 C11,12 13,14 15,16 Z');
svg.append(path);
const [mockPathContext, mockUtilitiesContext] = getMockContexts(svg);
const [ mockPathContext, mockUtilitiesContext ] = getMockContexts(svg);
pathModule.init(mockPathContext);
utilities.init(mockUtilitiesContext);
const segment = new Segment(1, path.pathSegList.getItem(1));
@@ -110,7 +110,7 @@ describe('path', function () {
assert.equal(path.pathSegList.getItem(1).x, 15);
assert.equal(path.pathSegList.getItem(1).y, 16);
segment.setType(SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, [30, 31, 32, 33, 34, 35]);
segment.setType(SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, [ 30, 31, 32, 33, 34, 35 ]);
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'c');
assert.equal(path.pathSegList.getItem(1).x1, 32);
assert.equal(path.pathSegList.getItem(1).y1, 33);
@@ -124,7 +124,7 @@ describe('path', function () {
const path = document.createElementNS(NS.SVG, 'path');
path.setAttribute('d', 'M0,0 L10,11 L20,21Z');
const [mockPathContext, mockUtilitiesContext] = getMockContexts();
const [ mockPathContext, mockUtilitiesContext ] = getMockContexts();
pathModule.init(mockPathContext);
utilities.init(mockUtilitiesContext);
new Path(path); // eslint-disable-line no-new
@@ -144,7 +144,7 @@ describe('path', function () {
const path = document.createElementNS(NS.SVG, 'path');
path.setAttribute('d', 'M0,0 C11,12 13,14 15,16 Z');
const [mockPathContext, mockUtilitiesContext] = getMockContexts();
const [ mockPathContext, mockUtilitiesContext ] = getMockContexts();
pathModule.init(mockPathContext);
utilities.init(mockUtilitiesContext);
new Path(path); // eslint-disable-line no-new

View File

@@ -1,6 +1,6 @@
import '../../../instrumented/editor/jquery.min.js';
import {NS} from '../../../instrumented/common/namespaces.js';
import { NS } from '../../../instrumented/common/namespaces.js';
import * as sanitize from '../../../instrumented/svgcanvas/sanitize.js';
describe('sanitize', function () {

View File

@@ -1,7 +1,7 @@
import '../../../instrumented/editor/jquery.min.js';
import * as select from '../../../instrumented/svgcanvas/select.js';
import {NS} from '../../../instrumented/common/namespaces.js';
import { NS } from '../../../instrumented/common/namespaces.js';
describe('select', function () {
const sandbox = document.createElement('div');
@@ -10,7 +10,7 @@ describe('select', function () {
let svgroot;
let svgcontent;
const mockConfig = {
dimensions: [640, 480]
dimensions: [ 640, 480 ]
};
const dataStorage = {
_storage: new WeakMap(),
@@ -33,7 +33,7 @@ describe('select', function () {
}
return ret;
}
};
};
/**
* @implements {module:select.SVGFactory}
@@ -41,7 +41,7 @@ describe('select', function () {
const mockFactory = {
createSVGElement (jsonMap) {
const elem = document.createElementNS(NS.SVG, jsonMap.element);
Object.entries(jsonMap.attr).forEach(([attr, value]) => {
Object.entries(jsonMap.attr).forEach(([ attr, value ]) => {
elem.setAttribute(attr, value);
});
return elem;
@@ -58,11 +58,11 @@ describe('select', function () {
beforeEach(() => {
svgroot = mockFactory.createSVGElement({
element: 'svg',
attr: {id: 'svgroot'}
attr: { id: 'svgroot' }
});
svgcontent = mockFactory.createSVGElement({
element: 'svg',
attr: {id: 'svgcontent'}
attr: { id: 'svgcontent' }
});
svgroot.append(svgcontent);

View File

@@ -1,8 +1,8 @@
import '../../../instrumented/editor/jquery.min.js';
import {NS} from '../../../instrumented/common/namespaces.js';
import { NS } from '../../../instrumented/common/namespaces.js';
import * as transformlist from '../../../instrumented/svgcanvas/svgtransformlist.js';
import {disableSupportsNativeTransformLists} from '../../../instrumented/common/browser.js';
import { disableSupportsNativeTransformLists } from '../../../instrumented/common/browser.js';
import almostEqualsPlugin from '../../support/assert-almostEquals.js';
import expectOutOfBoundsExceptionPlugin from '../../support/assert-expectOutOfBoundsException.js';

View File

@@ -34,14 +34,14 @@ describe('Basic Module', function () {
workarea.append(svgcanvas);
const toolsLeft = document.createElement('div');
toolsLeft.id = 'tools_left';
svgEditor.append(workarea, toolsLeft);
document.body.append(svgEditor);
svgCanvas = new SvgCanvas(
document.getElementById('svgcanvas'), {
canvas_expansion: 3,
dimensions: [640, 480],
dimensions: [ 640, 480 ],
initFill: {
color: 'FF0000', // solid red
opacity: 1
@@ -55,7 +55,7 @@ describe('Basic Module', function () {
imgPath: '../editor/images/',
langPath: 'locale/',
extPath: 'extensions/',
extensions: ['ext-arrows.js', 'ext-connector.js', 'ext-eyedropper.js'],
extensions: [ 'ext-arrows.js', 'ext-connector.js', 'ext-eyedropper.js' ],
initTool: 'select',
wireframe: false
}
@@ -159,8 +159,6 @@ describe('Basic Module', function () {
assert.strictEqual(attrVal, 'bar', true, 'Preserved namespaced attribute on import');
const output = svgCanvas.getSvgString();
// } catch(e) {console.log(e)}
// console.log('output',output);
const hasXlink = output.includes('xmlns:xlink="http://www.w3.org/1999/xlink"');
const hasSe = output.includes('xmlns:se=');
const hasFoo = output.includes('xmlns:foo=');

View File

@@ -51,7 +51,7 @@ describe('units', function () {
assert.ok(units.shortFloat);
assert.equal(typeof units.shortFloat, typeof function () { /* empty fn */ });
const {shortFloat} = units;
const { shortFloat } = units;
assert.equal(shortFloat(0.00000001), 0);
assert.equal(shortFloat(1), 1);
assert.equal(shortFloat(3.45678), 3.4568);
@@ -63,7 +63,7 @@ describe('units', function () {
assert.ok(units.isValidUnit);
assert.equal(typeof units.isValidUnit, typeof function () { /* empty fn */ });
const {isValidUnit} = units;
const { isValidUnit } = units;
assert.ok(isValidUnit('0'));
assert.ok(isValidUnit('1'));
assert.ok(isValidUnit('1.1'));

View File

@@ -3,7 +3,7 @@ import 'pathseg';
import '../../../instrumented/editor/jquery.min.js';
import {NS} from '../../../instrumented/common/namespaces.js';
import { NS } from '../../../instrumented/common/namespaces.js';
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
import * as transformlist from '../../../instrumented/svgcanvas/svgtransformlist.js';
import * as math from '../../../instrumented/svgcanvas/math.js';
@@ -20,7 +20,7 @@ describe('utilities bbox', function () {
*/
function mockCreateSVGElement (jsonMap) {
const elem = document.createElementNS(NS.SVG, jsonMap.element);
Object.entries(jsonMap.attr).forEach(([attr, value]) => {
Object.entries(jsonMap.attr).forEach(([ attr, value ]) => {
elem.setAttribute(attr, value);
});
return elem;
@@ -55,7 +55,7 @@ describe('utilities bbox', function () {
const type = seg.pathSegType;
if (type === 1) { continue; }
const pts = [];
['', 1, 2].forEach(function (n) {
[ '', 1, 2 ].forEach(function (n) {
const x = seg['x' + n], y = seg['y' + n];
if (x !== undefined && y !== undefined) {
const pt = math.transformPoint(x, y, m);
@@ -82,7 +82,7 @@ describe('utilities bbox', function () {
svgroot = mockCreateSVGElement({
element: 'svg',
attr: {id: 'svgroot'}
attr: { id: 'svgroot' }
});
sandbox.append(svgroot);
@@ -101,41 +101,41 @@ describe('utilities bbox', function () {
});
it('Test getBBoxWithTransform and no transform', function () {
const {getBBoxWithTransform} = utilities;
const { getBBoxWithTransform } = utilities;
let elem = mockCreateSVGElement({
element: 'path',
attr: {id: 'path', d: 'M0,1 L2,3'}
attr: { id: 'path', d: 'M0,1 L2,3' }
});
svgroot.append(elem);
let bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 2, height: 2});
assert.deepEqual(bbox, { x: 0, y: 1, width: 2, height: 2 });
assert.equal(mockaddSVGElementFromJsonCallCount, 0);
elem.remove();
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect', x: '0', y: '1', width: '5', height: '10'}
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
});
svgroot.append(elem);
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 5, height: 10});
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
assert.equal(mockaddSVGElementFromJsonCallCount, 0);
elem.remove();
elem = mockCreateSVGElement({
element: 'line',
attr: {id: 'line', x1: '0', y1: '1', x2: '5', y2: '6'}
attr: { id: 'line', x1: '0', y1: '1', x2: '5', y2: '6' }
});
svgroot.append(elem);
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 5, height: 5});
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 });
assert.equal(mockaddSVGElementFromJsonCallCount, 0);
elem.remove();
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect', x: '0', y: '1', width: '5', height: '10'}
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
});
const g = mockCreateSVGElement({
element: 'g',
@@ -144,17 +144,17 @@ describe('utilities bbox', function () {
g.append(elem);
svgroot.append(g);
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 5, height: 10});
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
assert.equal(mockaddSVGElementFromJsonCallCount, 0);
g.remove();
});
it.skip('Test getBBoxWithTransform and a rotation transform', function () {
const {getBBoxWithTransform} = utilities;
const { getBBoxWithTransform } = utilities;
let elem = mockCreateSVGElement({
element: 'path',
attr: {id: 'path', d: 'M10,10 L20,20', transform: 'rotate(45 10,10)'}
attr: { id: 'path', d: 'M10,10 L20,20', transform: 'rotate(45 10,10)' }
});
svgroot.append(elem);
let bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
@@ -166,7 +166,7 @@ describe('utilities bbox', function () {
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect', x: '10', y: '10', width: '10', height: '20', transform: 'rotate(90 15,20)'}
attr: { id: 'rect', x: '10', y: '10', width: '10', height: '20', transform: 'rotate(90 15,20)' }
});
svgroot.append(elem);
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
@@ -177,12 +177,12 @@ describe('utilities bbox', function () {
assert.equal(mockaddSVGElementFromJsonCallCount, 1);
elem.remove();
const rect = {x: 10, y: 10, width: 10, height: 20};
const rect = { x: 10, y: 10, width: 10, height: 20 };
const angle = 45;
const origin = {x: 15, y: 20}; // eslint-disable-line no-shadow
const origin = { x: 15, y: 20 }; // eslint-disable-line no-shadow
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect2', x: rect.x, y: rect.y, width: rect.width, height: rect.height, transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ')'}
attr: { id: 'rect2', x: rect.x, y: rect.y, width: rect.width, height: rect.height, transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ')' }
});
svgroot.append(elem);
mockaddSVGElementFromJsonCallCount = 0;
@@ -198,11 +198,11 @@ describe('utilities bbox', function () {
// Same as previous but wrapped with g and the transform is with the g.
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect3', x: rect.x, y: rect.y, width: rect.width, height: rect.height}
attr: { id: 'rect3', x: rect.x, y: rect.y, width: rect.width, height: rect.height }
});
const g = mockCreateSVGElement({
element: 'g',
attr: {transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ')'}
attr: { transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ')' }
});
g.append(elem);
svgroot.append(g);
@@ -217,7 +217,7 @@ describe('utilities bbox', function () {
elem = mockCreateSVGElement({
element: 'ellipse',
attr: {id: 'ellipse1', cx: '100', cy: '100', rx: '50', ry: '50', transform: 'rotate(45 100,100)'}
attr: { id: 'ellipse1', cx: '100', cy: '100', rx: '50', ry: '50', transform: 'rotate(45 100,100)' }
});
svgroot.append(elem);
mockaddSVGElementFromJsonCallCount = 0;
@@ -232,7 +232,7 @@ describe('utilities bbox', function () {
});
it.skip('Test getBBoxWithTransform with rotation and matrix transforms', function () {
const {getBBoxWithTransform} = utilities;
const { getBBoxWithTransform } = utilities;
let tx = 10; // tx right
let ty = 10; // tx down
@@ -241,7 +241,7 @@ describe('utilities bbox', function () {
let matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')';
let elem = mockCreateSVGElement({
element: 'path',
attr: {id: 'path', d: 'M10,10 L20,20', transform: 'rotate(45 10,10) ' + matrix}
attr: { id: 'path', d: 'M10,10 L20,20', transform: 'rotate(45 10,10) ' + matrix }
});
svgroot.append(elem);
let bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
@@ -256,7 +256,7 @@ describe('utilities bbox', function () {
matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')';
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect', x: '10', y: '10', width: '10', height: '20', transform: 'rotate(90 15,20) ' + matrix}
attr: { id: 'rect', x: '10', y: '10', width: '10', height: '20', transform: 'rotate(90 15,20) ' + matrix }
});
svgroot.append(elem);
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
@@ -266,9 +266,9 @@ describe('utilities bbox', function () {
assert.close(bbox.height, 10, EPSILON);
elem.remove();
const rect = {x: 10, y: 10, width: 10, height: 20};
const rect = { x: 10, y: 10, width: 10, height: 20 };
const angle = 45;
const origin = {x: 15, y: 20}; // eslint-disable-line no-shadow
const origin = { x: 15, y: 20 }; // eslint-disable-line no-shadow
tx = 10; // tx right
ty = 10; // tx down
txInRotatedSpace = Math.sqrt(tx * tx + ty * ty); // translate in rotated 45 space.
@@ -276,7 +276,7 @@ describe('utilities bbox', function () {
matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')';
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect2', x: rect.x, y: rect.y, width: rect.width, height: rect.height, transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ') ' + matrix}
attr: { id: 'rect2', x: rect.x, y: rect.y, width: rect.width, height: rect.height, transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ') ' + matrix }
});
svgroot.append(elem);
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
@@ -290,11 +290,11 @@ describe('utilities bbox', function () {
// Same as previous but wrapped with g and the transform is with the g.
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect3', x: rect.x, y: rect.y, width: rect.width, height: rect.height}
attr: { id: 'rect3', x: rect.x, y: rect.y, width: rect.width, height: rect.height }
});
const g = mockCreateSVGElement({
element: 'g',
attr: {transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ') ' + matrix}
attr: { transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ') ' + matrix }
});
g.append(elem);
svgroot.append(g);
@@ -307,7 +307,7 @@ describe('utilities bbox', function () {
elem = mockCreateSVGElement({
element: 'ellipse',
attr: {id: 'ellipse1', cx: '100', cy: '100', rx: '50', ry: '50', transform: 'rotate(45 100,100) ' + matrix}
attr: { id: 'ellipse1', cx: '100', cy: '100', rx: '50', ry: '50', transform: 'rotate(45 100,100) ' + matrix }
});
svgroot.append(elem);
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
@@ -320,39 +320,39 @@ describe('utilities bbox', function () {
});
it('Test getStrokedBBox with stroke-width 10', function () {
const {getStrokedBBox} = utilities;
const { getStrokedBBox } = utilities;
const strokeWidth = 10;
let elem = mockCreateSVGElement({
element: 'path',
attr: {id: 'path', d: 'M0,1 L2,3', 'stroke-width': strokeWidth}
attr: { id: 'path', d: 'M0,1 L2,3', 'stroke-width': strokeWidth }
});
svgroot.append(elem);
let bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 2 + strokeWidth, height: 2 + strokeWidth});
let bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 2 + strokeWidth, height: 2 + strokeWidth });
elem.remove();
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect', x: '0', y: '1', width: '5', height: '10', 'stroke-width': strokeWidth}
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10', 'stroke-width': strokeWidth }
});
svgroot.append(elem);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 10 + strokeWidth});
bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 10 + strokeWidth });
elem.remove();
elem = mockCreateSVGElement({
element: 'line',
attr: {id: 'line', x1: '0', y1: '1', x2: '5', y2: '6', 'stroke-width': strokeWidth}
attr: { id: 'line', x1: '0', y1: '1', x2: '5', y2: '6', 'stroke-width': strokeWidth }
});
svgroot.append(elem);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 5 + strokeWidth});
bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 5 + strokeWidth });
elem.remove();
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect', x: '0', y: '1', width: '5', height: '10', 'stroke-width': strokeWidth}
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10', 'stroke-width': strokeWidth }
});
const g = mockCreateSVGElement({
element: 'g',
@@ -360,44 +360,44 @@ describe('utilities bbox', function () {
});
g.append(elem);
svgroot.append(g);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 10 + strokeWidth});
bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 10 + strokeWidth });
g.remove();
});
it("Test getStrokedBBox with stroke-width 'none'", function () {
const {getStrokedBBox} = utilities;
const { getStrokedBBox } = utilities;
let elem = mockCreateSVGElement({
element: 'path',
attr: {id: 'path', d: 'M0,1 L2,3', 'stroke-width': 'none'}
attr: { id: 'path', d: 'M0,1 L2,3', 'stroke-width': 'none' }
});
svgroot.append(elem);
let bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 2, height: 2});
let bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, { x: 0, y: 1, width: 2, height: 2 });
elem.remove();
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect', x: '0', y: '1', width: '5', height: '10', 'stroke-width': 'none'}
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10', 'stroke-width': 'none' }
});
svgroot.append(elem);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 5, height: 10});
bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
elem.remove();
elem = mockCreateSVGElement({
element: 'line',
attr: {id: 'line', x1: '0', y1: '1', x2: '5', y2: '6', 'stroke-width': 'none'}
attr: { id: 'line', x1: '0', y1: '1', x2: '5', y2: '6', 'stroke-width': 'none' }
});
svgroot.append(elem);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 5, height: 5});
bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 });
elem.remove();
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect', x: '0', y: '1', width: '5', height: '10', 'stroke-width': 'none'}
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10', 'stroke-width': 'none' }
});
const g = mockCreateSVGElement({
element: 'g',
@@ -405,44 +405,44 @@ describe('utilities bbox', function () {
});
g.append(elem);
svgroot.append(g);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 5, height: 10});
bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
g.remove();
});
it('Test getStrokedBBox with no stroke-width attribute', function () {
const {getStrokedBBox} = utilities;
const { getStrokedBBox } = utilities;
let elem = mockCreateSVGElement({
element: 'path',
attr: {id: 'path', d: 'M0,1 L2,3'}
attr: { id: 'path', d: 'M0,1 L2,3' }
});
svgroot.append(elem);
let bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 2, height: 2});
let bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, { x: 0, y: 1, width: 2, height: 2 });
elem.remove();
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect', x: '0', y: '1', width: '5', height: '10'}
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
});
svgroot.append(elem);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 5, height: 10});
bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
elem.remove();
elem = mockCreateSVGElement({
element: 'line',
attr: {id: 'line', x1: '0', y1: '1', x2: '5', y2: '6'}
attr: { id: 'line', x1: '0', y1: '1', x2: '5', y2: '6' }
});
svgroot.append(elem);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 5, height: 5});
bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 });
elem.remove();
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect', x: '0', y: '1', width: '5', height: '10'}
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
});
const g = mockCreateSVGElement({
element: 'g',
@@ -450,8 +450,8 @@ describe('utilities bbox', function () {
});
g.append(elem);
svgroot.append(g);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 5, height: 10});
bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
g.remove();
});
@@ -473,7 +473,7 @@ describe('utilities bbox', function () {
*/
function rotatePoint (point, angle, origin) { // eslint-disable-line no-shadow
if (!origin) {
origin = {x: 0, y: 0};
origin = { x: 0, y: 0 };
}
const x = point.x - origin.x;
const y = point.y - origin.y;
@@ -491,10 +491,10 @@ describe('utilities bbox', function () {
* @returns {module:utilities.BBoxObject}
*/
function rotateRect (rect, angle, origin) { // eslint-disable-line no-shadow
const tl = rotatePoint({x: rect.x, y: rect.y}, angle, origin);
const tr = rotatePoint({x: rect.x + rect.width, y: rect.y}, angle, origin);
const br = rotatePoint({x: rect.x + rect.width, y: rect.y + rect.height}, angle, origin);
const bl = rotatePoint({x: rect.x, y: rect.y + rect.height}, angle, origin);
const tl = rotatePoint({ x: rect.x, y: rect.y }, angle, origin);
const tr = rotatePoint({ x: rect.x + rect.width, y: rect.y }, angle, origin);
const br = rotatePoint({ x: rect.x + rect.width, y: rect.y + rect.height }, angle, origin);
const bl = rotatePoint({ x: rect.x, y: rect.y + rect.height }, angle, origin);
const minx = Math.min(tl.x, tr.x, bl.x, br.x);
const maxx = Math.max(tl.x, tr.x, bl.x, br.x);

View File

@@ -2,7 +2,7 @@
import 'pathseg';
import '../../../instrumented/editor/jquery.min.js';
import {NS} from '../../../instrumented/common/namespaces.js';
import { NS } from '../../../instrumented/common/namespaces.js';
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
import * as transformlist from '../../../instrumented/svgcanvas/svgtransformlist.js';
import * as math from '../../../instrumented/svgcanvas/math.js';
@@ -82,7 +82,7 @@ describe('utilities performance', function () {
*/
function mockCreateSVGElement (jsonMap) {
const elem = document.createElementNS(NS.SVG, jsonMap.element);
Object.entries(jsonMap.attr).forEach(([attr, value]) => {
Object.entries(jsonMap.attr).forEach(([ attr, value ]) => {
elem.setAttribute(attr, value);
});
return elem;
@@ -111,7 +111,7 @@ describe('utilities performance', function () {
const clone = elem.cloneNode(true); // t: deep clone
// Make sure you set a unique ID like a real document.
clone.setAttribute('id', elemId + index);
const {parentNode} = elem;
const { parentNode } = elem;
parentNode.append(clone);
}
}
@@ -135,7 +135,7 @@ describe('utilities performance', function () {
continue;
}
const pts = [];
['', 1, 2].forEach(function (n) {
[ '', 1, 2 ].forEach(function (n) {
const x = seg['x' + n],
y = seg['y' + n];
if (x !== undefined && y !== undefined) {
@@ -183,8 +183,8 @@ describe('utilities performance', function () {
// Pass2 svgCanvas.getStrokedBBox total ms 17, ave ms 0.2, min/max 0 23
it('Test svgCanvas.getStrokedBBox() performance with matrix transforms', function () {
const {getStrokedBBox} = utilities;
const {children} = currentLayer;
const { getStrokedBBox } = utilities;
const { children } = currentLayer;
let lastTime, now,
min = Number.MAX_VALUE,
@@ -200,7 +200,7 @@ describe('utilities performance', function () {
// Skip the first child which is the title.
for (let index = 1; index < count; index++) {
const child = children[index];
/* const obj = */ getStrokedBBox([child], mockaddSVGElementFromJson, mockPathActions);
/* const obj = */ getStrokedBBox([ child ], mockaddSVGElementFromJson, mockPathActions);
now = Date.now(); const delta = now - lastTime; lastTime = now;
total += delta;
min = Math.min(min, delta);
@@ -220,7 +220,7 @@ describe('utilities performance', function () {
// Skip the first child which is the title.
for (let index = 1; index < ct; index++) {
const child = children[index];
/* const obj = */ getStrokedBBox([child], mockaddSVGElementFromJson, mockPathActions);
/* const obj = */ getStrokedBBox([ child ], mockaddSVGElementFromJson, mockPathActions);
now = Date.now(); const delta = now - lastTime; lastTime = now;
total += delta;
min = Math.min(min, delta);

View File

@@ -3,7 +3,7 @@ import '../../../instrumented/editor/jquery.min.js';
import * as browser from '../../../instrumented/common/browser.js';
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
import {NS} from '../../../instrumented/common/namespaces.js';
import { NS } from '../../../instrumented/common/namespaces.js';
describe('utilities', function () {
/**
@@ -13,7 +13,7 @@ describe('utilities', function () {
*/
function mockCreateSVGElement (jsonMap) {
const elem = document.createElementNS(NS.SVG, jsonMap.element);
Object.entries(jsonMap.attr).forEach(([attr, value]) => {
Object.entries(jsonMap.attr).forEach(([ attr, value ]) => {
elem.setAttribute(attr, value);
});
return elem;
@@ -28,7 +28,7 @@ describe('utilities', function () {
svgroot.append(elem);
return elem;
}
const mockPathActions = {resetOrientation () { /* empty fn */ }};
const mockPathActions = { resetOrientation () { /* empty fn */ } };
let mockHistorySubCommands = [];
const mockHistory = {
BatchCommand: class {
@@ -92,7 +92,7 @@ describe('utilities', function () {
svg = document.createElementNS(NS.SVG, 'svg');
svgroot = mockCreateSVGElement({
element: 'svg',
attr: {id: 'svgroot'}
attr: { id: 'svgroot' }
});
sandbox.append(svgroot);
document.body.append(sandbox);
@@ -105,7 +105,7 @@ describe('utilities', function () {
});
it('Test svgedit.utilities.toXml() function', function () {
const {toXml} = utilities;
const { toXml } = utilities;
assert.equal(toXml('a'), 'a');
assert.equal(toXml('ABC_'), 'ABC_');
@@ -116,7 +116,7 @@ describe('utilities', function () {
});
it('Test svgedit.utilities.fromXml() function', function () {
const {fromXml} = utilities;
const { fromXml } = utilities;
assert.equal(fromXml('a'), 'a');
assert.equal(fromXml('ABC_'), 'ABC_');
@@ -127,7 +127,7 @@ describe('utilities', function () {
});
it('Test svgedit.utilities.encode64() function', function () {
const {encode64} = utilities;
const { encode64 } = utilities;
assert.equal(encode64('abcdef'), 'YWJjZGVm');
assert.equal(encode64('12345'), 'MTIzNDU=');
@@ -136,7 +136,7 @@ describe('utilities', function () {
});
it('Test svgedit.utilities.decode64() function', function () {
const {decode64} = utilities;
const { decode64 } = utilities;
assert.equal(decode64('YWJjZGVm'), 'abcdef');
assert.equal(decode64('MTIzNDU='), '12345');
@@ -151,7 +151,7 @@ describe('utilities', function () {
});
it('Test svgedit.utilities.bboxToObj() function', function () {
const {bboxToObj} = utilities;
const { bboxToObj } = utilities;
const rect = svg.createSVGRect();
rect.x = 1;
@@ -188,38 +188,38 @@ describe('utilities', function () {
});
it('Test getPathDFromSegments', function () {
const {getPathDFromSegments} = utilities;
const { getPathDFromSegments } = utilities;
const doc = utilities.text2xml('<svg></svg>');
const path = doc.createElementNS(NS.SVG, 'path');
path.setAttribute('d', 'm0,0l5,0l0,5l-5,0l0,-5z');
let d = getPathDFromSegments([
['M', [1, 2]],
['Z', []]
[ 'M', [ 1, 2 ] ],
[ 'Z', [] ]
]);
assert.equal(d, 'M1,2 Z');
d = getPathDFromSegments([
['M', [1, 2]],
['M', [3, 4]],
['Z', []]
[ 'M', [ 1, 2 ] ],
[ 'M', [ 3, 4 ] ],
[ 'Z', [] ]
]);
assert.equal(d, 'M1,2 M3,4 Z');
d = getPathDFromSegments([
['M', [1, 2]],
['C', [3, 4, 5, 6]],
['Z', []]
[ 'M', [ 1, 2 ] ],
[ 'C', [ 3, 4, 5, 6 ] ],
[ 'Z', [] ]
]);
assert.equal(d, 'M1,2 C3,4 5,6 Z');
});
it('Test getPathDFromElement', function () {
const {getPathDFromElement} = utilities;
const { getPathDFromElement } = utilities;
let elem = mockCreateSVGElement({
element: 'path',
attr: {id: 'path', d: 'M0,1 Z'}
attr: { id: 'path', d: 'M0,1 Z' }
});
svgroot.append(elem);
assert.equal(getPathDFromElement(elem), 'M0,1 Z');
@@ -227,7 +227,7 @@ describe('utilities', function () {
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect', x: '0', y: '1', width: '5', height: '10'}
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
});
svgroot.append(elem);
assert.equal(getPathDFromElement(elem), 'M0,1 L5,1 L5,11 L0,11 L0,1 Z');
@@ -235,7 +235,7 @@ describe('utilities', function () {
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'roundrect', x: '0', y: '1', rx: '2', ry: '3', width: '10', height: '11'}
attr: { id: 'roundrect', x: '0', y: '1', rx: '2', ry: '3', width: '10', height: '11' }
});
svgroot.append(elem);
const closeEnough = /M0,13 C0,2.3\d* 0.9\d*,1 02,1 L8,1 C9.0\d*,1 10,2.3\d* 10,13 L10,9 C10,10.6\d* 9.08675799086758,12 8,12 L02,12 C0.9\d*,12 0,10.6\d* 0,9 L0,13 Z/;
@@ -244,7 +244,7 @@ describe('utilities', function () {
elem = mockCreateSVGElement({
element: 'line',
attr: {id: 'line', x1: '0', y1: '1', x2: '5', y2: '6'}
attr: { id: 'line', x1: '0', y1: '1', x2: '5', y2: '6' }
});
svgroot.append(elem);
assert.equal(getPathDFromElement(elem), 'M0,1L5,6');
@@ -252,7 +252,7 @@ describe('utilities', function () {
elem = mockCreateSVGElement({
element: 'circle',
attr: {id: 'circle', cx: '10', cy: '11', rx: '5', ry: '10'}
attr: { id: 'circle', cx: '10', cy: '11', rx: '5', ry: '10' }
});
svgroot.append(elem);
assert.equal(getPathDFromElement(elem), 'M5,11 C5,5.475138121546961 7.237569060773481,1 10,1 C102.7624309392265194,1 105,5.475138121546961 105,11 C105,115.524861878453039 102.7624309392265194,1110 10,1110 C7.237569060773481,1110 5,115.524861878453039 5,11 Z');
@@ -260,13 +260,13 @@ describe('utilities', function () {
elem = mockCreateSVGElement({
element: 'polyline',
attr: {id: 'polyline', points: '0,1 5,1 5,11 0,11'}
attr: { id: 'polyline', points: '0,1 5,1 5,11 0,11' }
});
svgroot.append(elem);
assert.equal(getPathDFromElement(elem), 'M0,1 5,1 5,11 0,11');
elem.remove();
assert.equal(getPathDFromElement({tagName: 'something unknown'}), undefined);
assert.equal(getPathDFromElement({ tagName: 'something unknown' }), undefined);
});
it('Test getBBoxOfElementAsPath', function () {
@@ -281,36 +281,36 @@ describe('utilities', function () {
let elem = mockCreateSVGElement({
element: 'path',
attr: {id: 'path', d: 'M0,1 Z'}
attr: { id: 'path', d: 'M0,1 Z' }
});
svgroot.append(elem);
let bbox = getBBoxOfElementAsPath(elem, mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 0, height: 0});
assert.deepEqual(bbox, { x: 0, y: 1, width: 0, height: 0 });
elem.remove();
elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect', x: '0', y: '1', width: '5', height: '10'}
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
});
svgroot.append(elem);
bbox = getBBoxOfElementAsPath(elem, mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 5, height: 10});
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
elem.remove();
elem = mockCreateSVGElement({
element: 'line',
attr: {id: 'line', x1: '0', y1: '1', x2: '5', y2: '6'}
attr: { id: 'line', x1: '0', y1: '1', x2: '5', y2: '6' }
});
svgroot.append(elem);
bbox = getBBoxOfElementAsPath(elem, mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0, y: 1, width: 5, height: 5});
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 });
elem.remove();
// TODO: test element with transform. Need resetOrientation above to be working or mock it.
});
it('Test convertToPath rect', function () {
const {convertToPath} = utilities;
const { convertToPath } = utilities;
const attrs = {
fill: 'red',
stroke: 'white',
@@ -320,7 +320,7 @@ describe('utilities', function () {
const elem = mockCreateSVGElement({
element: 'rect',
attr: {id: 'rect', x: '0', y: '1', width: '5', height: '10'}
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
});
svgroot.append(elem);
const path = convertToPath(elem, attrs, mockaddSVGElementFromJson, mockPathActions, mockClearSelection, mockAddToSelection, mockHistory, mockAddCommandToHistory);
@@ -337,7 +337,7 @@ describe('utilities', function () {
});
it('Test convertToPath unknown element', function () {
const {convertToPath} = utilities;
const { convertToPath } = utilities;
const attrs = {
fill: 'red',
stroke: 'white',

View File

@@ -11,6 +11,6 @@
// ***********************************************************
require('@babel/register')({
plugins: ['@babel/plugin-transform-modules-commonjs']
plugins: [ '@babel/plugin-transform-modules-commonjs' ]
});
module.exports = require('./main.js').default;

View File

@@ -12,7 +12,7 @@ const NEAR_ZERO = 5e-6; // 0.000005, Firefox fails at higher levels of precision
function almostEquals (actual, expected, message) {
message = message || (actual + ' did not equal ' + expected);
const result = Math.abs(actual - expected) < NEAR_ZERO;
return {result, message, actual, expected};
return { result, message, actual, expected };
}
/**

View File

@@ -25,7 +25,7 @@ function close (actual, expected, maxDifference, message) {
const actualDiff = (actual === expected) ? 0 : Math.abs(actual - expected),
result = actualDiff <= maxDifference;
message = message || (actual + ' should be within ' + maxDifference + ' (inclusive) of ' + expected + (result ? '' : '. Actual: ' + actualDiff));
return {result, message, actual, expected};
return { result, message, actual, expected };
}
/**
@@ -55,7 +55,7 @@ function closePercent (actual, expected, maxPercentDifference, message) {
}
message = message || (actual + ' should be within ' + maxPercentDifference + '% (inclusive) of ' + expected + (result ? '' : '. Actual: ' + actualDiff + '%'));
return {result, message, actual, expected};
return { result, message, actual, expected };
}
/**
@@ -74,7 +74,7 @@ function notClose (actual, expected, minDifference, message) {
const actualDiff = Math.abs(actual - expected),
result = actualDiff > minDifference;
message = message || (actual + ' should not be within ' + minDifference + ' (exclusive) of ' + expected + (result ? '' : '. Actual: ' + actualDiff));
return {result, message, actual, expected};
return { result, message, actual, expected };
}
/**
@@ -104,7 +104,7 @@ function notClosePercent (actual, expected, minPercentDifference, message) {
}
message = message || (actual + ' should not be within ' + minPercentDifference + '% (exclusive) of ' + expected + (result ? '' : '. Actual: ' + actualDiff + '%'));
return {result, message, actual, expected};
return { result, message, actual, expected };
}
/**

View File

@@ -19,7 +19,7 @@ function expectOutOfBoundsException (obj, fn, arg1) {
}
}
const actual = result;
return {result, message, actual, expected};
return { result, message, actual, expected };
}
/**

View File

@@ -6,7 +6,7 @@
function setAssertionMethods (_chai, _utils) {
return (method) => {
return (...args) => {
const {result, message, actual, expected} = method(...args);
const { result, message, actual, expected } = method(...args);
const assertion = new _chai.Assertion();
assertion.assert(result, `Expected ${actual} to be ${expected}`, message);
};

View File

@@ -25,7 +25,7 @@
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
// remove the style attributes that is causing differences in snapshots
const ngAttributes = ['style'];
const ngAttributes = [ 'style' ];
Cypress.Commands.add(
'cleanSnapshot',

View File

@@ -9,7 +9,7 @@ export const visitAndApproveStorage = () => {
};
export const openMainMenu = () => {
return cy.get('#main_button').click({force: true});
return cy.get('#main_button').click({ force: true });
};
export const openEditorPreferences = () => {

View File

@@ -28,17 +28,17 @@
import SvgCanvas from '../src/svgcanvas/svgcanvas.js';
const container = document.querySelector('#editorContainer');
const {width, height} = {width: 500, height: 300};
const { width, height } = { width: 500, height: 300 };
window.width = width;
window.height = height;
const config = {
initFill: {color: 'FFFFFF', opacity: 1},
initStroke: {color: '000000', opacity: 1, width: 1},
text: {stroke_width: 0, font_size: 24, font_family: 'serif'},
initFill: { color: 'FFFFFF', opacity: 1 },
initStroke: { color: '000000', opacity: 1, width: 1 },
text: { stroke_width: 0, font_size: 24, font_family: 'serif' },
initOpacity: 1,
imgPath: 'editor/images/',
dimensions: [width, height],
dimensions: [ width, height ],
baseUnit: 'px'
};

View File

@@ -2,59 +2,8 @@
'use strict';
module.exports = {
plugins: ['plugins/markdown'],
markdown: {
// tags: ['examples']
/*
// "The highlighter function should escape the code block's contents and wrap them in <pre><code> tags"
highlight (code, language) {
function ret () {
// Default:
return '<pre><code>' + code + ' in this language: ' + language + '</code></pre>';
}
if (language !== 'js') { // E.g., we have one URL in some tutorial Markdown
// Seems to be only for full triple-backticked fences
// console.log('lll', code);
return ret();
}
// Programmatic ESLint API: https://eslint.org/docs/developer-guide/nodejs-api
const {CLIEngine} = require('eslint');
const cli = new CLIEngine({
useEslintrc: true,
rules: {
'no-undef': 0, // Many variables in examples will be undefined
'padded-blocks': 0 // Can look nicer
}
});
// Undo escaping done by node_modules/jsdoc/lib/jsdoc/util/markdown.js
code = code
.replace(/\s+$/, '')
.replace(/&#39;/g, "'")
.replace(/(https?):\\\/\\\//g, '$1://')
.replace(/\{@[^}\r\n]+\}/g, function (wholeMatch) {
return wholeMatch.replace(/&quot;/g, '"');
});
// lint the supplied text and optionally set
// a filename that is displayed in the report
const report = cli.executeOnText(code + '\n');
if (!report.errorCount && !report.warningCount) {
return ret();
}
// Although we don't get the file, at least we can report the source code
const {messages} = report.results[0];
messages.forEach(({message, line, column, severity, ruleId}) => {
console.log(`${ruleId}: ${message} (Severity: ${severity}; ${line}:${column})`);
});
console.log('\n' + code);
return ret();
}
*/
},
plugins: [ 'plugins/markdown' ],
markdown: {},
recurseDepth: 10,
source: {
exclude: [

View File

@@ -43,7 +43,7 @@ repository editor code
```js
svgEditor.setConfig({
dimensions: [320, 240],
dimensions: [ 320, 240 ],
canvas_expansion: 5,
initFill: {
color: '0000FF'
@@ -160,7 +160,7 @@ To add your own stylesheets along with the default stylesheets, ensure
`"@default"` is present in the array along with your own. For example:
```js
svgEditor.setConfig({stylesheets: ['@default', 'myStylesheet.css']});
svgEditor.setConfig({ stylesheets: [ '@default', 'myStylesheet.css' ] });
```
(In version 2.8, the CSS file `editor/custom.css` was included by default,

View File

@@ -79,7 +79,7 @@ export default {
init () {
return {
svgicons: 'extensions/helloworld-icon.xml',
buttons: [{ /* ... */ }],
buttons: [ { /* ... */ } ],
mouseDown () {
// ...
},
@@ -139,7 +139,7 @@ property should follow the format
naming conflicts in the non-modular version of SVGEdit.
```js
import {importSetGlobalDefault} from '../external/dynamic-import-polyfill/importModule.js';
import { importSetGlobalDefault } from '../external/dynamic-import-polyfill/importModule.js';
// ...

View File

@@ -119,7 +119,7 @@ these files). The default behavior is equivalent to this:
```js
svgEditor.setConfig({
stylesheets: ['@default', '../svgedit-custom.css']
stylesheets: [ '@default', '../svgedit-custom.css' ]
});
```

1468
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -117,8 +117,8 @@
"svg2pdf.js": "2.1.0"
},
"devDependencies": {
"@babel/core": "7.14.0",
"@babel/preset-env": "7.14.1",
"@babel/core": "7.14.2",
"@babel/preset-env": "7.14.2",
"@babel/register": "7.13.16",
"@babel/runtime-corejs3": "7.14.0",
"@cypress/code-coverage": "3.9.5",
@@ -140,7 +140,7 @@
"coveradge": "0.6.0",
"cp-cli": "2.0.0",
"cross-var": "1.1.0",
"cypress": "7.2.0",
"cypress": "7.3.0",
"cypress-axe": "0.12.2",
"cypress-multi-reporters": "1.5.0",
"cypress-plugin-snapshots": "1.4.4",
@@ -149,13 +149,13 @@
"eslint-plugin-array-func": "3.1.7",
"eslint-plugin-chai-expect": "2.2.0",
"eslint-plugin-chai-expect-keywords": "2.1.0",
"eslint-plugin-chai-friendly": "0.6.0",
"eslint-plugin-chai-friendly": "0.7.1",
"eslint-plugin-compat": "^3.9.0",
"eslint-plugin-cypress": "2.11.3",
"eslint-plugin-eslint-comments": "3.2.0",
"eslint-plugin-html": "^6.1.2",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsdoc": "^33.1.1",
"eslint-plugin-import": "2.23.0",
"eslint-plugin-jsdoc": "34.2.2",
"eslint-plugin-markdown": "^2.1.0",
"eslint-plugin-mocha": "8.1.0",
"eslint-plugin-mocha-cleanup": "1.9.1",
@@ -165,7 +165,7 @@
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-sonarjs": "^0.7.0",
"eslint-plugin-standard": "4.1.0",
"eslint-plugin-unicorn": "32.0.0",
"eslint-plugin-unicorn": "32.0.1",
"imageoptim-cli": "3.0.2",
"jamilih": "0.54.0",
"jsdoc": "3.6.6",
@@ -193,8 +193,8 @@
"rollup-plugin-re": "1.0.7",
"rollup-plugin-terser": "7.0.2",
"stackblur-canvas": "2.5.0",
"start-server-and-test": "^1.12.1",
"systemjs": "6.8.3",
"start-server-and-test": "^1.12.2",
"systemjs": "6.9.0",
"typescript": "4.2.4",
"underscore": "1.13.1"
}

View File

@@ -4,16 +4,16 @@
// 'npm run build'
import path from 'path';
import {lstatSync, readdirSync} from 'fs';
import { lstatSync, readdirSync } from 'fs';
import rimraf from 'rimraf';
import babel from '@rollup/plugin-babel';
import copy from 'rollup-plugin-copy';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import nodePolyfills from 'rollup-plugin-node-polyfills';
import url from '@rollup/plugin-url'; // for XML/SVG files
import dynamicImportVars from '@rollup/plugin-dynamic-import-vars';
import {terser} from 'rollup-plugin-terser';
import { terser } from 'rollup-plugin-terser';
// import progress from 'rollup-plugin-progress';
import filesize from 'rollup-plugin-filesize';
@@ -28,15 +28,16 @@ const getDirectories = (source) => {
// capture the list of files to build for extensions and ext-locales
const extensionDirs = getDirectories('src/editor/extensions');
const dest = ['dist/editor', 'dist/editor/system'];
/** @todo should we support systemjs? */
const dest = [ 'dist/editor' ];
// remove existing distribution
// eslint-disable-next-line no-console
rimraf('./dist', () => console.info('recreating dist'));
// config for svgedit core module
const config = [{
input: ['src/editor/index.js'],
const config = [ {
input: [ 'src/editor/index.js' ],
output: [
{
format: 'es',
@@ -50,15 +51,16 @@ const config = [{
sourcemap: true,
file: 'dist/editor/xdomain-index.js',
intro: 'const XDOMAIN = true;'
},
}
/*
{
format: 'system',
dir: 'dist/editor/system',
inlineDynamicImports: true
}
*/
],
plugins: [
// progress(),
copy({
targets: [
{
@@ -72,6 +74,7 @@ const config = [{
transform: (contents) => contents.toString()
.replace('<script type="module" src="index.js">', '<script type="module" src="xdomain-index.js">')
},
/*
{
src: 'src/editor/index.html',
dest: ['dist/editor/system'],
@@ -91,15 +94,14 @@ const config = [{
src: ['node_modules/systemjs/dist/s.min.js', 'node_modules/systemjs/dist/s.min.js.map'],
dest: 'dist/editor/system'
},
{src: 'src/editor/images', dest},
{src: 'src/editor/extensions/ext-shapes/shapelib', dest: dest.map((d) => `${d}/extensions/ext-shapes`)},
{src: 'src/editor/jgraduate', dest},
{src: 'src/editor/spinbtn', dest},
{src: 'src/editor/embedapi.html', dest},
{src: 'src/editor/embedapi.js', dest},
{src: 'src/editor/browser-not-supported.html', dest},
{src: 'src/editor/redirect-on-lacking-support.js', dest},
{src: 'src/editor/svgedit.css', dest}
*/
{ src: 'src/editor/images', dest },
{ src: 'src/editor/extensions/ext-shapes/shapelib', dest: dest.map((d) => `${d}/extensions/ext-shapes`) },
{ src: 'src/editor/embedapi.html', dest },
{ src: 'src/editor/embedapi.js', dest },
{ src: 'src/editor/browser-not-supported.html', dest },
{ src: 'src/editor/browser-not-supported.js', dest },
{ src: 'src/editor/svgedit.css', dest }
]
}),
nodeResolve({
@@ -107,13 +109,13 @@ const config = [{
preferBuiltins: false
}),
commonjs(),
dynamicImportVars({include: `src/editor/locale.js`}),
babel({babelHelpers: 'bundled', exclude: [/\/core-js\//]}), // exclude core-js to avoid circular dependencies.
dynamicImportVars({ include: `src/editor/locale.js` }),
babel({ babelHelpers: 'bundled', exclude: [ /\/core-js\// ] }), // exclude core-js to avoid circular dependencies.
nodePolyfills(),
terser({keep_fnames: true}), // keep_fnames is needed to avoid an error when calling extensions.
terser({ keep_fnames: true }), // keep_fnames is needed to avoid an error when calling extensions.
filesize()
]
}];
} ];
// config for dynamic extensions
extensionDirs.forEach((extensionDir) => {
@@ -127,17 +129,19 @@ extensionDirs.forEach((extensionDir) => {
dir: `dist/editor/extensions/${extensionName}`,
inlineDynamicImports: true,
sourcemap: true
},
}
/*
,
{
format: 'system',
dir: `dist/editor/system/extensions/${extensionName}`,
inlineDynamicImports: true
}
*/
],
plugins: [
// progress(),
url({
include: ['**/*.svg', '**/*.png', '**/*.jpg', '**/*.gif', '**/*.xml'],
include: [ '**/*.svg', '**/*.png', '**/*.jpg', '**/*.gif', '**/*.xml' ],
limit: 0,
fileName: '[name][extname]'
}),
@@ -145,11 +149,11 @@ extensionDirs.forEach((extensionDir) => {
browser: true,
preferBuiltins: true
}),
commonjs({exclude: `src/editor/extensions/${extensionName}/${extensionName}.js`}),
dynamicImportVars({include: `src/editor/extensions/${extensionName}/${extensionName}.js`}),
babel({babelHelpers: 'bundled', exclude: [/\/core-js\//]}),
commonjs({ exclude: `src/editor/extensions/${extensionName}/${extensionName}.js` }),
dynamicImportVars({ include: `src/editor/extensions/${extensionName}/${extensionName}.js` }),
babel({ babelHelpers: 'bundled', exclude: [ /\/core-js\// ] }),
nodePolyfills(),
terser({keep_fnames: true})
terser({ keep_fnames: true })
]
}
);

View File

@@ -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

View File

@@ -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;

View File

@@ -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' ]
};
/**

View File

@@ -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)
)
) {

View File

@@ -52,7 +52,7 @@ class Editor extends EditorStartup {
* @type {"ignore"|"waiting"|"closed"}
*/
this.storagePromptState = 'ignore';
this.svgCanvas = null;
this.isReady = false;
this.customExportImage = false;
@@ -67,7 +67,7 @@ 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+');
this.shortcuts = [
// Shortcuts not associated with buttons
@@ -79,26 +79,26 @@ class Editor extends EditorStartup {
{ 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: [ 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: [ '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(); } },
@@ -294,8 +294,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) => {
@@ -350,9 +350,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) {
@@ -384,7 +384,7 @@ class Editor extends EditorStartup {
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) {
@@ -775,7 +775,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()
@@ -1083,7 +1083,7 @@ class Editor extends EditorStartup {
resolve(cb());
return;
}
this.callbacks.push([cb, resolve, reject]);
this.callbacks.push([ cb, resolve, reject ]);
});
}
@@ -1094,16 +1094,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;

View File

@@ -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,7 +158,7 @@ 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
}
@@ -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)
);
@@ -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');
});
});
@@ -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 {

View File

@@ -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';
@@ -26,7 +26,7 @@ class MainMenu {
* @returns {void}
*/
async clickClear() {
const [x, y] = this.editor.configObj.curConfig.dimensions;
const [ x, y ] = this.editor.configObj.curConfig.dimensions;
const ok = await seConfirm(this.editor.i18next.t('notification.QwantToClear'));
if (ok === "Cancel") {
return;
@@ -111,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
@@ -130,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();
}
/**
@@ -183,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;
@@ -305,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">
@@ -334,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"));

View File

@@ -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

View File

@@ -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':

View File

@@ -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);

View File

@@ -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,

View File

@@ -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] });

View File

@@ -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';

View File

@@ -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()
]
},

View File

@@ -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

View File

@@ -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';
},

View File

@@ -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 });
}
}

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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' ];
}
/**

View File

@@ -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' ];
}
/**

View File

@@ -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

View File

@@ -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);

View File

@@ -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';
/**

View File

@@ -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';
/**

View File

@@ -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

View File

@@ -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 });
}
}

View File

@@ -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
};

View File

@@ -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;

View File

@@ -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);

View File

@@ -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';
};

View File

@@ -71,7 +71,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 +84,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 +150,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 +251,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 +273,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 +494,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 +511,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

View File

@@ -6,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 {
@@ -24,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;
@@ -72,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>
@@ -93,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');
@@ -108,7 +106,7 @@ export class SeExportDialog extends HTMLElement {
* @returns {any} observed
*/
static get observedAttributes () {
return ['dialog'];
return [ 'dialog' ];
}
/**
* @function attributeChangedCallback
@@ -163,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);
}
};

View File

@@ -1,4 +1,4 @@
import {isValidUnit} from '../../common/units.js';
import { isValidUnit } from '../../common/units.js';
const template = document.createElement('template');
template.innerHTML = `
@@ -16,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;
@@ -126,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');
@@ -143,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
@@ -342,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;

View File

@@ -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();
};

View File

@@ -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;

View File

@@ -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':

View File

@@ -14,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;
@@ -42,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>
@@ -79,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');
@@ -94,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
@@ -203,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 = () => {
@@ -218,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);

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -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; }
@@ -236,7 +236,7 @@ export default {
newMarker = marker;
}
});
if (!newMarker) {
// Create a new marker with this color
const lastId = marker.id;
@@ -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];

View File

@@ -1,7 +1,7 @@
export default {
name: 'Arrows',
langList: [
{id: 'arrow_none', textContent: 'No arrow'}
{ id: 'arrow_none', textContent: 'No arrow' }
],
contextTools: [
{

View File

@@ -1,7 +1,7 @@
export default {
name: 'Arrows',
langList: [
{id: 'arrow_none', textContent: 'Sans flèche'}
{ id: 'arrow_none', textContent: 'Sans flèche' }
],
contextTools: [
{

View File

@@ -1,7 +1,7 @@
export default {
name: '箭头',
langList: [
{id: 'arrow_none', textContent: '无箭头'}
{ id: 'arrow_none', textContent: '无箭头' }
],
contextTools: [
{

View File

@@ -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) {

View File

@@ -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();
}

View File

@@ -1,7 +1,7 @@
export default {
name: 'Connector',
langList: [
{id: 'mode_connect', title: 'Connect two objects'}
{ id: 'mode_connect', title: 'Connect two objects' }
],
buttons: [
{

View File

@@ -1,7 +1,7 @@
export default {
name: 'Connector',
langList: [
{id: 'mode_connect', title: 'Connecter deux objets'}
{ id: 'mode_connect', title: 'Connecter deux objets' }
],
buttons: [
{

View File

@@ -1,7 +1,7 @@
export default {
name: '连接器',
langList: [
{id: 'mode_connect', title: '连接两个对象'}
{ id: 'mode_connect', title: '连接两个对象' }
],
buttons: [
{

View File

@@ -4,27 +4,19 @@
* @license MIT
*
* @copyright 2010 Jeff Schiller
* @copyright 2021 OptimistikSAS
*
*/
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;
};
import { loadExtensionTranslation } from '../../locale.js';
const name = "eyedropper";
export default {
name: 'eyedropper',
name,
async init(S) {
const svgEditor = this;
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
await loadExtensionTranslation(svgEditor, name);
const { ChangeElementCommand } = S, // , svgcontent,
// svgdoc = S.svgroot.parentNode.ownerDocument,
{ svgCanvas } = svgEditor,
@@ -53,7 +45,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 +63,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 +89,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) {

View File

@@ -0,0 +1,9 @@
export default {
name: 'pipette',
buttons: [
{
title: 'Outil pipette',
key: 'I'
}
]
};

View File

@@ -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,

View File

@@ -7,32 +7,23 @@
*
*/
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;
};
import { loadExtensionTranslation } from '../../locale.js';
const name = "grid";
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, name);
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 +129,7 @@ export default {
gridimg.parentNode.setAttribute('width', bigInt);
gridimg.parentNode.setAttribute('height', bigInt);
svgCanvas.setHref(gridimg, datauri);
}
};
/**
*
@@ -150,23 +141,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();

View File

@@ -0,0 +1,8 @@
export default {
name: 'Grille',
buttons: [
{
title: 'Afficher/Cacher Grille'
}
]
};

View File

@@ -13,39 +13,32 @@
* will show the user the point on the canvas that was clicked on.
*/
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;
};
import { loadExtensionTranslation } from '../../locale.js';
const name = "helloworld";
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, name);
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 +46,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 +63,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);
}
}
};

View File

@@ -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'"

Some files were not shown because too many files have changed in this diff Show More