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", "plugin:sonarjs/recommended",
"eslint:recommended" "eslint:recommended"
], ],
plugins: ["jsdoc", "promise", "html", "import", "sonarjs"], plugins: [ "jsdoc", "promise", "html", "import", "sonarjs" ],
parserOptions: { parserOptions: {
ecmaVersion: 2020, ecmaVersion: 2020,
sourceType: "module" sourceType: "module"
@@ -21,32 +21,46 @@ module.exports = {
es6: true es6: true
}, },
rules: { 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, "node/no-unsupported-features/es-syntax": 0,
"no-unused-vars": ["error", { "argsIgnorePattern": "^_" }], "no-unused-vars": [ "error", { "argsIgnorePattern": "^_" } ],
"sonarjs/cognitive-complexity": ["warn", 40],
"sonarjs/no-duplicate-string": 0, "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: [ overrides: [
{ {
files: [ 'cypress/**/*'], files: [ 'cypress/**/*' ],
extends: [ extends: [
"plugin:cypress/recommended" "plugin:cypress/recommended"
], ],
env: { env: {
mocha: true, mocha: true,
node: true node: true
}, },
globals: { globals: { "assert": true },
"assert": true
},
rules: { rules: {
// with ci, instrumented is not created before linter // 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 "node/no-missing-import": 0
} }
}, },
{ {
files: [ 'docs/**/*'], files: [ 'docs/**/*' ],
rules: { // md files have example that don't need a strict checking rules: { // md files have example that don't need a strict checking
"no-undef": 0, "no-undef": 0,
"import/no-unresolved": 0, "import/no-unresolved": 0,

View File

@@ -623,12 +623,12 @@ exports[`use various parts of svg-edit > check tool_star #0`] = `
point="5" point="5"
r="66.66666666666667" r="66.66666666666667"
radialshift="0" radialshift="0"
r2="13.333333333333334" r2="22.222222222222225"
orient="point" orient="point"
fill="#ffff00" fill="#ffff00"
strokecolor="#000000" strokecolor="#000000"
strokewidth="0" 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="#000000"
stroke-width="0" stroke-width="0"
> >
@@ -713,12 +713,12 @@ exports[`use various parts of svg-edit > check tool_polygon #0`] = `
point="5" point="5"
r="66.66666666666667" r="66.66666666666667"
radialshift="0" radialshift="0"
r2="13.333333333333334" r2="22.222222222222225"
orient="point" orient="point"
fill="#ffff00" fill="#ffff00"
strokecolor="#000000" strokecolor="#000000"
strokewidth="0" 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="#000000"
stroke-width="0" stroke-width="0"
fill-opacity="1" fill-opacity="1"

View File

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

View File

@@ -11,13 +11,13 @@ describe('UI - Clipboard', function () {
cy.get('#tool_source').click(); cy.get('#tool_source').click();
cy.get('#svg_source_textarea') 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"> .type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<g class="layer"> <g class="layer">
<title>Layer 1</title> <title>Layer 1</title>
<circle cx="100" cy="100" r="50" fill="#FF0000" id="testCircle" stroke="#000000" stroke-width="5"/> <circle cx="100" cy="100" r="50" fill="#FF0000" id="testCircle" stroke="#000000" stroke-width="5"/>
</g> </g>
</svg>`, {force: true, parseSpecialCharSequences: false}); </svg>`, { force: true, parseSpecialCharSequences: false });
cy.get('#tool_source_save').click(); cy.get('#tool_source_save').click();
cy.get('#testCircle').should('exist'); cy.get('#testCircle').should('exist');
cy.get('#svg_1').should('not.exist'); cy.get('#svg_1').should('not.exist');
@@ -25,20 +25,20 @@ describe('UI - Clipboard', function () {
// Copy. // Copy.
cy.get('#testCircle').click().rightclick(); 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. // Paste.
// Scrollbars fail to recenter in Cypress test. Works fine in reality. // Scrollbars fail to recenter in Cypress test. Works fine in reality.
// Thus forcing click is needed since workspace is mostly offscreen. // Thus forcing click is needed since workspace is mostly offscreen.
cy.get('#svgroot').rightclick({force: true}); cy.get('#svgroot').rightclick({ force: true });
cy.get('#cmenu_canvas a[href="#paste"]').click({force: true}); cy.get('#cmenu_canvas a[href="#paste"]').click({ force: true });
cy.get('#testCircle').should('exist'); cy.get('#testCircle').should('exist');
cy.get('#svg_1').should('exist'); cy.get('#svg_1').should('exist');
cy.get('#svg_2').should('not.exist'); cy.get('#svg_2').should('not.exist');
// Cut. // Cut.
cy.get('#testCircle').click().rightclick(); 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('#testCircle').should('not.exist');
cy.get('#svg_1').should('exist'); cy.get('#svg_1').should('exist');
cy.get('#svg_2').should('not.exist'); cy.get('#svg_2').should('not.exist');
@@ -46,17 +46,17 @@ describe('UI - Clipboard', function () {
// Paste. // Paste.
// Scrollbars fail to recenter in Cypress test. Works fine in reality. // Scrollbars fail to recenter in Cypress test. Works fine in reality.
// Thus forcing click is needed since workspace is mostly offscreen. // Thus forcing click is needed since workspace is mostly offscreen.
cy.get('#svgroot').rightclick({force: true}); cy.get('#svgroot').rightclick({ force: true });
cy.get('#cmenu_canvas a[href="#paste"]').click({force: true}); cy.get('#cmenu_canvas a[href="#paste"]').click({ force: true });
cy.get('#testCircle').should('not.exist'); cy.get('#testCircle').should('not.exist');
cy.get('#svg_1').should('exist'); cy.get('#svg_1').should('exist');
cy.get('#svg_2').should('exist'); cy.get('#svg_2').should('exist');
// Delete. // Delete.
cy.get('#svg_2').click().rightclick(); 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('#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_1').should('not.exist');
cy.get('#svg_2').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); const randomOffset = () => 2 + Math.round(10 + Math.random() * 40);
cy.get('#tool_source').click(); cy.get('#tool_source').click();
cy.get('#svg_source_textarea') 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"> .type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<g class="layer"> <g class="layer">
<title>Layer 1</title> <title>Layer 1</title>
<path d="m187,194a114,62 0 1 0 219,2" id="svg_1" fill="#FF0000" stroke="#000000" stroke-width="5"/> <path d="m187,194a114,62 0 1 0 219,2" id="svg_1" fill="#FF0000" stroke="#000000" stroke-width="5"/>
</g> </g>
</svg>`, {force: true, parseSpecialCharSequences: false}); </svg>`, { force: true, parseSpecialCharSequences: false });
cy.get('#tool_source_save').click({force: true}); 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}) cy.get('#pathpointgrip_0').trigger('mousedown', { which: 1, force: true })
.trigger('mousemove', randomOffset(), randomOffset(), {force: true}) .trigger('mousemove', randomOffset(), randomOffset(), { force: true })
.trigger('mouseup', {force: true}); .trigger('mouseup', { force: true });
cy.get('#pathpointgrip_1').trigger('mousedown', {which: 1, force: true}) cy.get('#pathpointgrip_1').trigger('mousedown', { which: 1, force: true })
.trigger('mousemove', randomOffset(), randomOffset(), {force: true}) .trigger('mousemove', randomOffset(), randomOffset(), { force: true })
.trigger('mouseup', {force: true}); .trigger('mouseup', { force: true });
cy.get('#svg_1[d]').should('not.contain', 'NaN'); 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', () => { it('Editor - No parameters: Export button clicking; dialog opens', () => {
openMainMenu(); openMainMenu();
cy.get('#tool_export').click({force: true}); cy.get('#tool_export').click({ force: true });
cy.get('#dialog_content select'); cy.get('#dialog_content select');
}); });
}); });

View File

@@ -11,13 +11,13 @@ describe('Fix issue 359', function () {
it('can undo without throwing', function () { it('can undo without throwing', function () {
cy.get('#tool_source').click(); cy.get('#tool_source').click();
cy.get('#svg_source_textarea') 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"> .type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<g class="layer"> <g class="layer">
<title>Layer 1</title> <title>Layer 1</title>
<rect fill="#ffff00" height="70" width="165" x="179.5" y="146.5"/> <rect fill="#ffff00" height="70" width="165" x="179.5" y="146.5"/>
</g> </g>
</svg>`, {parseSpecialCharSequences: false, force: true}); </svg>`, { parseSpecialCharSequences: false, force: true });
cy.get('#tool_source_save').click(); cy.get('#tool_source_save').click();
cy.get('#tool_undo').click(); cy.get('#tool_undo').click();
cy.get('#tool_redo').click(); // test also redo to make the test more comprehensive 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 () { it('can enter edit on text child', function () {
cy.get('#tool_source').click(); cy.get('#tool_source').click();
cy.get('#svg_source_textarea') 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"> .type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<g class="layer"> <g class="layer">
<title>Layer 1</title> <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> <text fill="#000000" id="a_text" text-anchor="middle" x="260.5" xml:space="preserve" y="192.5">hello</text>
</g> </g>
</g> </g>
</svg>`, {force: true, parseSpecialCharSequences: false}); </svg>`, { force: true, parseSpecialCharSequences: false });
cy.get('#tool_source_save').click(); cy.get('#tool_source_save').click();
cy.get('#svg_1').click().dblclick(); cy.get('#svg_1').click().dblclick();
cy.get('#a_text').should('exist'); cy.get('#a_text').should('exist');
cy.get('#a_text') cy.get('#a_text')
.trigger('mousedown', {which: 1, force: true}) .trigger('mousedown', { which: 1, force: true })
.trigger('mouseup', {force: true}) .trigger('mouseup', { force: true })
.dblclick({force: true}); .dblclick({ force: true });
// svgedit use the #text text field to capture the text // 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'); 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 () { it('should not throw when showing/saving svg content', function () {
cy.get('#tool_source').click(); cy.get('#tool_source').click();
cy.get('#svg_source_textarea') 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"> .type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<g class="layer"> <g class="layer">
<title>Layer 1</title> <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" /> <circle cx="117.5" cy="87.5" fill="#ffff00" r="19.84943" stroke="#000000" />
</g> </g>
</g> </g>
</svg>`, {force: true, parseSpecialCharSequences: false}); </svg>`, { force: true, parseSpecialCharSequences: false });
cy.get('#tool_source_save').click(); cy.get('#tool_source_save').click();
cy.get('#svg_6').click().dblclick(); // change context cy.get('#svg_6').click().dblclick(); // change context
cy.get('#tool_source').click(); // reopen tool_source 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 () { it('should not throw when undoing the move', function () {
cy.get('#tool_source').click(); cy.get('#tool_source').click();
cy.get('#svg_source_textarea') 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"> .type(`<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<g class="layer"> <g class="layer">
<title>Layer 1</title> <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"/> <rect clip-path="url(#svg_2)" fill="#0033b5" height="174.9" id="TANK1" width="78" x="77.5" y="29"/>
</g> </g>
</g> </g>
</svg>`, {parseSpecialCharSequences: false, force: true}); </svg>`, { parseSpecialCharSequences: false, force: true });
cy.get('#tool_source_save').click({force: true}); cy.get('#tool_source_save').click({ force: true });
cy.get('#TANK1') cy.get('#TANK1')
.trigger('mousedown', {force: true}) .trigger('mousedown', { force: true })
.trigger('mousemove', 50, 0, {force: true}) .trigger('mousemove', 50, 0, { force: true })
.trigger('mouseup', {force: true}); .trigger('mouseup', { force: true });
cy.get('#tool_undo').click({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 () { it('check tool_source', function () {
cy.get('#tool_source').click({force: true}); cy.get('#tool_source').click({ force: true });
cy.get('#svg_source_textarea') 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"> .type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<g class="layer"> <g class="layer">
<title>Layer 1</title> <title>Layer 1</title>
<rect id="rect" fill="#FF0000" height="70" stroke="#000000" stroke-width="5" width="94" x="69.5" y="51.5"/> <rect id="rect" fill="#FF0000" height="70" stroke="#000000" stroke-width="5" width="94" x="69.5" y="51.5"/>
</g> </g>
</svg>`, {force: true, parseSpecialCharSequences: false}); </svg>`, { force: true, parseSpecialCharSequences: false });
cy.get('#tool_source_save').click({force: true}); cy.get('#tool_source_save').click({ force: true });
testSnapshot(); testSnapshot();
}); });
it('check tool_fhpath', function () { it('check tool_fhpath', function () {
cy.get('#tool_fhpath') cy.get('#tool_fhpath')
.click({force: true}); .click({ force: true });
cy.get('#rect') cy.get('#rect')
.trigger('mousemove', 200, 200, {force: true}) .trigger('mousemove', 200, 200, { force: true })
.trigger('mousedown', 200, 200, {force: true}) .trigger('mousedown', 200, 200, { force: true })
.trigger('mousemove', 20, 20, {force: true}) .trigger('mousemove', 20, 20, { force: true })
.trigger('mouseup', {force: true}); .trigger('mouseup', { force: true });
cy.get('#svgcontent').toMatchSnapshot(); cy.get('#svgcontent').toMatchSnapshot();
}); });
it('check tool_text', function () { it('check tool_text', function () {
cy.get('#tool_text') cy.get('#tool_text')
.click({force: true}); .click({ force: true });
cy.get('#rect') cy.get('#rect')
.trigger('mousedown', 46, 35, {force: true}) .trigger('mousedown', 46, 35, { force: true })
.trigger('mouseup', {force: true}); .trigger('mouseup', { force: true });
// svgedit use the #text text field to capture the text // 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(); testSnapshot();
}); });
it('check tool_clone', function () { it('check tool_clone', function () {
cy.get('#svg_1').click({force: true}); cy.get('#svg_1').click({ force: true });
cy.get('#tool_clone') cy.get('#tool_clone')
.click({force: true}); .click({ force: true });
testSnapshot(); testSnapshot();
}); });
it('check tool_italic', function () { it('check tool_italic', function () {
cy.get('#svg_1').click({force: true}); cy.get('#svg_1').click({ force: true });
cy.get('#tool_italic') cy.get('#tool_italic')
.click({force: true}); .click({ force: true });
testSnapshot(); testSnapshot();
}); });
it('check tool_bold', function () { it('check tool_bold', function () {
cy.get('#svg_1').click({force: true}); cy.get('#svg_1').click({ force: true });
cy.get('#tool_bold') cy.get('#tool_bold')
.click({force: true}); .click({ force: true });
testSnapshot(); testSnapshot();
}); });
it('check change color', function () { it('check change color', function () {
cy.get('#svg_1').click({force: true}); cy.get('#svg_1').click({ force: true });
cy.get('[data-rgb="#ffff00"]') cy.get('[data-rgb="#ffff00"]')
.click({force: true}); .click({ force: true });
testSnapshot(); testSnapshot();
}); });
it('check tool_text_anchor_start', function () { 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') cy.get('#tool_text_anchor_start')
.click({force: true}); .click({ force: true });
testSnapshot(); testSnapshot();
}); });
it('check tool_text_anchor_middle', function () { 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') cy.get('#tool_text_anchor_middle')
.click({force: true}); .click({ force: true });
testSnapshot(); testSnapshot();
}); });
it('check tool_text_anchor_end', function () { 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') cy.get('#tool_text_anchor_end')
.click({force: true}); .click({ force: true });
testSnapshot(); testSnapshot();
}); });
it('check tool_star', function () { it('check tool_star', function () {
cy.get('#tool_star') cy.get('#tool_star')
.click({force: true}); .click({ force: true });
cy.get('#svgcontent') cy.get('#svgcontent')
.trigger('mousedown', 300, 150, {force: true}) .trigger('mousedown', 300, 150, { force: true })
.trigger('mousemove', 300, 250, {force: true}) .trigger('mousemove', 300, 250, { force: true })
.trigger('mouseup', {force: true}); .trigger('mouseup', { force: true });
testSnapshot(); testSnapshot();
}); });
it('check tool_polygon', function () { it('check tool_polygon', function () {
cy.get('#tool_polygon') cy.get('#tool_polygon')
.click({force: true}); .click({ force: true });
cy.get('#svgcontent') cy.get('#svgcontent')
.trigger('mousedown', 350, 250, {force: true}) .trigger('mousedown', 350, 250, { force: true })
.trigger('mousemove', 350, 370, {force: true}) .trigger('mousemove', 350, 370, { force: true })
.trigger('mouseup', {force: true}); .trigger('mouseup', { force: true });
testSnapshot(); testSnapshot();
}); });
}); });

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
import '../../../instrumented/editor/jquery.min.js'; 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 utilities from '../../../instrumented/svgcanvas/utilities.js';
import * as coords from '../../../instrumented/svgcanvas/coords.js'; import * as coords from '../../../instrumented/svgcanvas/coords.js';

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
import '../../../instrumented/editor/jquery.min.js'; 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'; import * as sanitize from '../../../instrumented/svgcanvas/sanitize.js';
describe('sanitize', function () { describe('sanitize', function () {

View File

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

View File

@@ -1,8 +1,8 @@
import '../../../instrumented/editor/jquery.min.js'; 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 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 almostEqualsPlugin from '../../support/assert-almostEquals.js';
import expectOutOfBoundsExceptionPlugin from '../../support/assert-expectOutOfBoundsException.js'; import expectOutOfBoundsExceptionPlugin from '../../support/assert-expectOutOfBoundsException.js';

View File

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

View File

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

View File

@@ -3,7 +3,7 @@ import 'pathseg';
import '../../../instrumented/editor/jquery.min.js'; 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 utilities from '../../../instrumented/svgcanvas/utilities.js';
import * as transformlist from '../../../instrumented/svgcanvas/svgtransformlist.js'; import * as transformlist from '../../../instrumented/svgcanvas/svgtransformlist.js';
import * as math from '../../../instrumented/svgcanvas/math.js'; import * as math from '../../../instrumented/svgcanvas/math.js';
@@ -20,7 +20,7 @@ describe('utilities bbox', function () {
*/ */
function mockCreateSVGElement (jsonMap) { function mockCreateSVGElement (jsonMap) {
const elem = document.createElementNS(NS.SVG, jsonMap.element); 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); elem.setAttribute(attr, value);
}); });
return elem; return elem;
@@ -55,7 +55,7 @@ describe('utilities bbox', function () {
const type = seg.pathSegType; const type = seg.pathSegType;
if (type === 1) { continue; } if (type === 1) { continue; }
const pts = []; const pts = [];
['', 1, 2].forEach(function (n) { [ '', 1, 2 ].forEach(function (n) {
const x = seg['x' + n], y = seg['y' + n]; const x = seg['x' + n], y = seg['y' + n];
if (x !== undefined && y !== undefined) { if (x !== undefined && y !== undefined) {
const pt = math.transformPoint(x, y, m); const pt = math.transformPoint(x, y, m);
@@ -82,7 +82,7 @@ describe('utilities bbox', function () {
svgroot = mockCreateSVGElement({ svgroot = mockCreateSVGElement({
element: 'svg', element: 'svg',
attr: {id: 'svgroot'} attr: { id: 'svgroot' }
}); });
sandbox.append(svgroot); sandbox.append(svgroot);
@@ -101,41 +101,41 @@ describe('utilities bbox', function () {
}); });
it('Test getBBoxWithTransform and no transform', function () { it('Test getBBoxWithTransform and no transform', function () {
const {getBBoxWithTransform} = utilities; const { getBBoxWithTransform } = utilities;
let elem = mockCreateSVGElement({ let elem = mockCreateSVGElement({
element: 'path', element: 'path',
attr: {id: 'path', d: 'M0,1 L2,3'} attr: { id: 'path', d: 'M0,1 L2,3' }
}); });
svgroot.append(elem); svgroot.append(elem);
let bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions); 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); assert.equal(mockaddSVGElementFromJsonCallCount, 0);
elem.remove(); elem.remove();
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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); svgroot.append(elem);
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions); 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); assert.equal(mockaddSVGElementFromJsonCallCount, 0);
elem.remove(); elem.remove();
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'line', 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); svgroot.append(elem);
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions); 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); assert.equal(mockaddSVGElementFromJsonCallCount, 0);
elem.remove(); elem.remove();
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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({ const g = mockCreateSVGElement({
element: 'g', element: 'g',
@@ -144,17 +144,17 @@ describe('utilities bbox', function () {
g.append(elem); g.append(elem);
svgroot.append(g); svgroot.append(g);
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions); 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); assert.equal(mockaddSVGElementFromJsonCallCount, 0);
g.remove(); g.remove();
}); });
it.skip('Test getBBoxWithTransform and a rotation transform', function () { it.skip('Test getBBoxWithTransform and a rotation transform', function () {
const {getBBoxWithTransform} = utilities; const { getBBoxWithTransform } = utilities;
let elem = mockCreateSVGElement({ let elem = mockCreateSVGElement({
element: 'path', 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); svgroot.append(elem);
let bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions); let bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
@@ -166,7 +166,7 @@ describe('utilities bbox', function () {
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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); svgroot.append(elem);
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions); bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
@@ -177,12 +177,12 @@ describe('utilities bbox', function () {
assert.equal(mockaddSVGElementFromJsonCallCount, 1); assert.equal(mockaddSVGElementFromJsonCallCount, 1);
elem.remove(); 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 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({ elem = mockCreateSVGElement({
element: 'rect', 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); svgroot.append(elem);
mockaddSVGElementFromJsonCallCount = 0; mockaddSVGElementFromJsonCallCount = 0;
@@ -198,11 +198,11 @@ describe('utilities bbox', function () {
// Same as previous but wrapped with g and the transform is with the g. // Same as previous but wrapped with g and the transform is with the g.
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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({ const g = mockCreateSVGElement({
element: 'g', element: 'g',
attr: {transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ')'} attr: { transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ')' }
}); });
g.append(elem); g.append(elem);
svgroot.append(g); svgroot.append(g);
@@ -217,7 +217,7 @@ describe('utilities bbox', function () {
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'ellipse', 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); svgroot.append(elem);
mockaddSVGElementFromJsonCallCount = 0; mockaddSVGElementFromJsonCallCount = 0;
@@ -232,7 +232,7 @@ describe('utilities bbox', function () {
}); });
it.skip('Test getBBoxWithTransform with rotation and matrix transforms', function () { it.skip('Test getBBoxWithTransform with rotation and matrix transforms', function () {
const {getBBoxWithTransform} = utilities; const { getBBoxWithTransform } = utilities;
let tx = 10; // tx right let tx = 10; // tx right
let ty = 10; // tx down let ty = 10; // tx down
@@ -241,7 +241,7 @@ describe('utilities bbox', function () {
let matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')'; let matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')';
let elem = mockCreateSVGElement({ let elem = mockCreateSVGElement({
element: 'path', 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); svgroot.append(elem);
let bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions); let bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
@@ -256,7 +256,7 @@ describe('utilities bbox', function () {
matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')'; matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')';
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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); svgroot.append(elem);
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions); bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
@@ -266,9 +266,9 @@ describe('utilities bbox', function () {
assert.close(bbox.height, 10, EPSILON); assert.close(bbox.height, 10, EPSILON);
elem.remove(); 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 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 tx = 10; // tx right
ty = 10; // tx down ty = 10; // tx down
txInRotatedSpace = Math.sqrt(tx * tx + ty * ty); // translate in rotated 45 space. 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 + ')'; matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')';
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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); svgroot.append(elem);
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions); 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. // Same as previous but wrapped with g and the transform is with the g.
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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({ const g = mockCreateSVGElement({
element: 'g', element: 'g',
attr: {transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ') ' + matrix} attr: { transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ') ' + matrix }
}); });
g.append(elem); g.append(elem);
svgroot.append(g); svgroot.append(g);
@@ -307,7 +307,7 @@ describe('utilities bbox', function () {
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'ellipse', 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); svgroot.append(elem);
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions); bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
@@ -320,39 +320,39 @@ describe('utilities bbox', function () {
}); });
it('Test getStrokedBBox with stroke-width 10', function () { it('Test getStrokedBBox with stroke-width 10', function () {
const {getStrokedBBox} = utilities; const { getStrokedBBox } = utilities;
const strokeWidth = 10; const strokeWidth = 10;
let elem = mockCreateSVGElement({ let elem = mockCreateSVGElement({
element: 'path', 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); svgroot.append(elem);
let bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions); let bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 2 + strokeWidth, height: 2 + strokeWidth}); assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 2 + strokeWidth, height: 2 + strokeWidth });
elem.remove(); elem.remove();
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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); svgroot.append(elem);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions); bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 10 + strokeWidth}); assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 10 + strokeWidth });
elem.remove(); elem.remove();
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'line', 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); svgroot.append(elem);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions); bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 5 + strokeWidth}); assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 5 + strokeWidth });
elem.remove(); elem.remove();
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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({ const g = mockCreateSVGElement({
element: 'g', element: 'g',
@@ -360,44 +360,44 @@ describe('utilities bbox', function () {
}); });
g.append(elem); g.append(elem);
svgroot.append(g); svgroot.append(g);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions); bbox = getStrokedBBox([ elem ], mockaddSVGElementFromJson, mockPathActions);
assert.deepEqual(bbox, {x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 10 + strokeWidth}); assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 10 + strokeWidth });
g.remove(); g.remove();
}); });
it("Test getStrokedBBox with stroke-width 'none'", function () { it("Test getStrokedBBox with stroke-width 'none'", function () {
const {getStrokedBBox} = utilities; const { getStrokedBBox } = utilities;
let elem = mockCreateSVGElement({ let elem = mockCreateSVGElement({
element: 'path', 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); svgroot.append(elem);
let bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions); let bbox = getStrokedBBox([ 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 });
elem.remove(); elem.remove();
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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); svgroot.append(elem);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions); bbox = getStrokedBBox([ 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.remove();
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'line', 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); svgroot.append(elem);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions); bbox = getStrokedBBox([ 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(); elem.remove();
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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({ const g = mockCreateSVGElement({
element: 'g', element: 'g',
@@ -405,44 +405,44 @@ describe('utilities bbox', function () {
}); });
g.append(elem); g.append(elem);
svgroot.append(g); svgroot.append(g);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions); bbox = getStrokedBBox([ 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 });
g.remove(); g.remove();
}); });
it('Test getStrokedBBox with no stroke-width attribute', function () { it('Test getStrokedBBox with no stroke-width attribute', function () {
const {getStrokedBBox} = utilities; const { getStrokedBBox } = utilities;
let elem = mockCreateSVGElement({ let elem = mockCreateSVGElement({
element: 'path', element: 'path',
attr: {id: 'path', d: 'M0,1 L2,3'} attr: { id: 'path', d: 'M0,1 L2,3' }
}); });
svgroot.append(elem); svgroot.append(elem);
let bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions); let bbox = getStrokedBBox([ 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 });
elem.remove(); elem.remove();
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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); svgroot.append(elem);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions); bbox = getStrokedBBox([ 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.remove();
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'line', 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); svgroot.append(elem);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions); bbox = getStrokedBBox([ 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(); elem.remove();
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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({ const g = mockCreateSVGElement({
element: 'g', element: 'g',
@@ -450,8 +450,8 @@ describe('utilities bbox', function () {
}); });
g.append(elem); g.append(elem);
svgroot.append(g); svgroot.append(g);
bbox = getStrokedBBox([elem], mockaddSVGElementFromJson, mockPathActions); bbox = getStrokedBBox([ 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 });
g.remove(); g.remove();
}); });
@@ -473,7 +473,7 @@ describe('utilities bbox', function () {
*/ */
function rotatePoint (point, angle, origin) { // eslint-disable-line no-shadow function rotatePoint (point, angle, origin) { // eslint-disable-line no-shadow
if (!origin) { if (!origin) {
origin = {x: 0, y: 0}; origin = { x: 0, y: 0 };
} }
const x = point.x - origin.x; const x = point.x - origin.x;
const y = point.y - origin.y; const y = point.y - origin.y;
@@ -491,10 +491,10 @@ describe('utilities bbox', function () {
* @returns {module:utilities.BBoxObject} * @returns {module:utilities.BBoxObject}
*/ */
function rotateRect (rect, angle, origin) { // eslint-disable-line no-shadow function rotateRect (rect, angle, origin) { // eslint-disable-line no-shadow
const tl = rotatePoint({x: rect.x, y: rect.y}, 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 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 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 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 minx = Math.min(tl.x, tr.x, bl.x, br.x);
const maxx = Math.max(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 'pathseg';
import '../../../instrumented/editor/jquery.min.js'; 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 utilities from '../../../instrumented/svgcanvas/utilities.js';
import * as transformlist from '../../../instrumented/svgcanvas/svgtransformlist.js'; import * as transformlist from '../../../instrumented/svgcanvas/svgtransformlist.js';
import * as math from '../../../instrumented/svgcanvas/math.js'; import * as math from '../../../instrumented/svgcanvas/math.js';
@@ -82,7 +82,7 @@ describe('utilities performance', function () {
*/ */
function mockCreateSVGElement (jsonMap) { function mockCreateSVGElement (jsonMap) {
const elem = document.createElementNS(NS.SVG, jsonMap.element); 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); elem.setAttribute(attr, value);
}); });
return elem; return elem;
@@ -111,7 +111,7 @@ describe('utilities performance', function () {
const clone = elem.cloneNode(true); // t: deep clone const clone = elem.cloneNode(true); // t: deep clone
// Make sure you set a unique ID like a real document. // Make sure you set a unique ID like a real document.
clone.setAttribute('id', elemId + index); clone.setAttribute('id', elemId + index);
const {parentNode} = elem; const { parentNode } = elem;
parentNode.append(clone); parentNode.append(clone);
} }
} }
@@ -135,7 +135,7 @@ describe('utilities performance', function () {
continue; continue;
} }
const pts = []; const pts = [];
['', 1, 2].forEach(function (n) { [ '', 1, 2 ].forEach(function (n) {
const x = seg['x' + n], const x = seg['x' + n],
y = seg['y' + n]; y = seg['y' + n];
if (x !== undefined && y !== undefined) { 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 // Pass2 svgCanvas.getStrokedBBox total ms 17, ave ms 0.2, min/max 0 23
it('Test svgCanvas.getStrokedBBox() performance with matrix transforms', function () { it('Test svgCanvas.getStrokedBBox() performance with matrix transforms', function () {
const {getStrokedBBox} = utilities; const { getStrokedBBox } = utilities;
const {children} = currentLayer; const { children } = currentLayer;
let lastTime, now, let lastTime, now,
min = Number.MAX_VALUE, min = Number.MAX_VALUE,
@@ -200,7 +200,7 @@ describe('utilities performance', function () {
// Skip the first child which is the title. // Skip the first child which is the title.
for (let index = 1; index < count; index++) { for (let index = 1; index < count; index++) {
const child = children[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; now = Date.now(); const delta = now - lastTime; lastTime = now;
total += delta; total += delta;
min = Math.min(min, delta); min = Math.min(min, delta);
@@ -220,7 +220,7 @@ describe('utilities performance', function () {
// Skip the first child which is the title. // Skip the first child which is the title.
for (let index = 1; index < ct; index++) { for (let index = 1; index < ct; index++) {
const child = children[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; now = Date.now(); const delta = now - lastTime; lastTime = now;
total += delta; total += delta;
min = Math.min(min, 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 browser from '../../../instrumented/common/browser.js';
import * as utilities from '../../../instrumented/svgcanvas/utilities.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 () { describe('utilities', function () {
/** /**
@@ -13,7 +13,7 @@ describe('utilities', function () {
*/ */
function mockCreateSVGElement (jsonMap) { function mockCreateSVGElement (jsonMap) {
const elem = document.createElementNS(NS.SVG, jsonMap.element); 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); elem.setAttribute(attr, value);
}); });
return elem; return elem;
@@ -28,7 +28,7 @@ describe('utilities', function () {
svgroot.append(elem); svgroot.append(elem);
return elem; return elem;
} }
const mockPathActions = {resetOrientation () { /* empty fn */ }}; const mockPathActions = { resetOrientation () { /* empty fn */ } };
let mockHistorySubCommands = []; let mockHistorySubCommands = [];
const mockHistory = { const mockHistory = {
BatchCommand: class { BatchCommand: class {
@@ -92,7 +92,7 @@ describe('utilities', function () {
svg = document.createElementNS(NS.SVG, 'svg'); svg = document.createElementNS(NS.SVG, 'svg');
svgroot = mockCreateSVGElement({ svgroot = mockCreateSVGElement({
element: 'svg', element: 'svg',
attr: {id: 'svgroot'} attr: { id: 'svgroot' }
}); });
sandbox.append(svgroot); sandbox.append(svgroot);
document.body.append(sandbox); document.body.append(sandbox);
@@ -105,7 +105,7 @@ describe('utilities', function () {
}); });
it('Test svgedit.utilities.toXml() function', function () { it('Test svgedit.utilities.toXml() function', function () {
const {toXml} = utilities; const { toXml } = utilities;
assert.equal(toXml('a'), 'a'); assert.equal(toXml('a'), 'a');
assert.equal(toXml('ABC_'), 'ABC_'); assert.equal(toXml('ABC_'), 'ABC_');
@@ -116,7 +116,7 @@ describe('utilities', function () {
}); });
it('Test svgedit.utilities.fromXml() function', function () { it('Test svgedit.utilities.fromXml() function', function () {
const {fromXml} = utilities; const { fromXml } = utilities;
assert.equal(fromXml('a'), 'a'); assert.equal(fromXml('a'), 'a');
assert.equal(fromXml('ABC_'), 'ABC_'); assert.equal(fromXml('ABC_'), 'ABC_');
@@ -127,7 +127,7 @@ describe('utilities', function () {
}); });
it('Test svgedit.utilities.encode64() function', function () { it('Test svgedit.utilities.encode64() function', function () {
const {encode64} = utilities; const { encode64 } = utilities;
assert.equal(encode64('abcdef'), 'YWJjZGVm'); assert.equal(encode64('abcdef'), 'YWJjZGVm');
assert.equal(encode64('12345'), 'MTIzNDU='); assert.equal(encode64('12345'), 'MTIzNDU=');
@@ -136,7 +136,7 @@ describe('utilities', function () {
}); });
it('Test svgedit.utilities.decode64() function', function () { it('Test svgedit.utilities.decode64() function', function () {
const {decode64} = utilities; const { decode64 } = utilities;
assert.equal(decode64('YWJjZGVm'), 'abcdef'); assert.equal(decode64('YWJjZGVm'), 'abcdef');
assert.equal(decode64('MTIzNDU='), '12345'); assert.equal(decode64('MTIzNDU='), '12345');
@@ -151,7 +151,7 @@ describe('utilities', function () {
}); });
it('Test svgedit.utilities.bboxToObj() function', function () { it('Test svgedit.utilities.bboxToObj() function', function () {
const {bboxToObj} = utilities; const { bboxToObj } = utilities;
const rect = svg.createSVGRect(); const rect = svg.createSVGRect();
rect.x = 1; rect.x = 1;
@@ -188,38 +188,38 @@ describe('utilities', function () {
}); });
it('Test getPathDFromSegments', function () { it('Test getPathDFromSegments', function () {
const {getPathDFromSegments} = utilities; const { getPathDFromSegments } = utilities;
const doc = utilities.text2xml('<svg></svg>'); const doc = utilities.text2xml('<svg></svg>');
const path = doc.createElementNS(NS.SVG, 'path'); const path = doc.createElementNS(NS.SVG, 'path');
path.setAttribute('d', 'm0,0l5,0l0,5l-5,0l0,-5z'); path.setAttribute('d', 'm0,0l5,0l0,5l-5,0l0,-5z');
let d = getPathDFromSegments([ let d = getPathDFromSegments([
['M', [1, 2]], [ 'M', [ 1, 2 ] ],
['Z', []] [ 'Z', [] ]
]); ]);
assert.equal(d, 'M1,2 Z'); assert.equal(d, 'M1,2 Z');
d = getPathDFromSegments([ d = getPathDFromSegments([
['M', [1, 2]], [ 'M', [ 1, 2 ] ],
['M', [3, 4]], [ 'M', [ 3, 4 ] ],
['Z', []] [ 'Z', [] ]
]); ]);
assert.equal(d, 'M1,2 M3,4 Z'); assert.equal(d, 'M1,2 M3,4 Z');
d = getPathDFromSegments([ d = getPathDFromSegments([
['M', [1, 2]], [ 'M', [ 1, 2 ] ],
['C', [3, 4, 5, 6]], [ 'C', [ 3, 4, 5, 6 ] ],
['Z', []] [ 'Z', [] ]
]); ]);
assert.equal(d, 'M1,2 C3,4 5,6 Z'); assert.equal(d, 'M1,2 C3,4 5,6 Z');
}); });
it('Test getPathDFromElement', function () { it('Test getPathDFromElement', function () {
const {getPathDFromElement} = utilities; const { getPathDFromElement } = utilities;
let elem = mockCreateSVGElement({ let elem = mockCreateSVGElement({
element: 'path', element: 'path',
attr: {id: 'path', d: 'M0,1 Z'} attr: { id: 'path', d: 'M0,1 Z' }
}); });
svgroot.append(elem); svgroot.append(elem);
assert.equal(getPathDFromElement(elem), 'M0,1 Z'); assert.equal(getPathDFromElement(elem), 'M0,1 Z');
@@ -227,7 +227,7 @@ describe('utilities', function () {
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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); svgroot.append(elem);
assert.equal(getPathDFromElement(elem), 'M0,1 L5,1 L5,11 L0,11 L0,1 Z'); assert.equal(getPathDFromElement(elem), 'M0,1 L5,1 L5,11 L0,11 L0,1 Z');
@@ -235,7 +235,7 @@ describe('utilities', function () {
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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); 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/; 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({ elem = mockCreateSVGElement({
element: 'line', 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); svgroot.append(elem);
assert.equal(getPathDFromElement(elem), 'M0,1L5,6'); assert.equal(getPathDFromElement(elem), 'M0,1L5,6');
@@ -252,7 +252,7 @@ describe('utilities', function () {
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'circle', 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); 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'); 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({ elem = mockCreateSVGElement({
element: 'polyline', 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); svgroot.append(elem);
assert.equal(getPathDFromElement(elem), 'M0,1 5,1 5,11 0,11'); assert.equal(getPathDFromElement(elem), 'M0,1 5,1 5,11 0,11');
elem.remove(); elem.remove();
assert.equal(getPathDFromElement({tagName: 'something unknown'}), undefined); assert.equal(getPathDFromElement({ tagName: 'something unknown' }), undefined);
}); });
it('Test getBBoxOfElementAsPath', function () { it('Test getBBoxOfElementAsPath', function () {
@@ -281,36 +281,36 @@ describe('utilities', function () {
let elem = mockCreateSVGElement({ let elem = mockCreateSVGElement({
element: 'path', element: 'path',
attr: {id: 'path', d: 'M0,1 Z'} attr: { id: 'path', d: 'M0,1 Z' }
}); });
svgroot.append(elem); svgroot.append(elem);
let bbox = getBBoxOfElementAsPath(elem, mockaddSVGElementFromJson, mockPathActions); 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.remove();
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'rect', 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); svgroot.append(elem);
bbox = getBBoxOfElementAsPath(elem, mockaddSVGElementFromJson, mockPathActions); 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.remove();
elem = mockCreateSVGElement({ elem = mockCreateSVGElement({
element: 'line', 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); svgroot.append(elem);
bbox = getBBoxOfElementAsPath(elem, mockaddSVGElementFromJson, mockPathActions); 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(); elem.remove();
// TODO: test element with transform. Need resetOrientation above to be working or mock it. // TODO: test element with transform. Need resetOrientation above to be working or mock it.
}); });
it('Test convertToPath rect', function () { it('Test convertToPath rect', function () {
const {convertToPath} = utilities; const { convertToPath } = utilities;
const attrs = { const attrs = {
fill: 'red', fill: 'red',
stroke: 'white', stroke: 'white',
@@ -320,7 +320,7 @@ describe('utilities', function () {
const elem = mockCreateSVGElement({ const elem = mockCreateSVGElement({
element: 'rect', 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); svgroot.append(elem);
const path = convertToPath(elem, attrs, mockaddSVGElementFromJson, mockPathActions, mockClearSelection, mockAddToSelection, mockHistory, mockAddCommandToHistory); const path = convertToPath(elem, attrs, mockaddSVGElementFromJson, mockPathActions, mockClearSelection, mockAddToSelection, mockHistory, mockAddCommandToHistory);
@@ -337,7 +337,7 @@ describe('utilities', function () {
}); });
it('Test convertToPath unknown element', function () { it('Test convertToPath unknown element', function () {
const {convertToPath} = utilities; const { convertToPath } = utilities;
const attrs = { const attrs = {
fill: 'red', fill: 'red',
stroke: 'white', stroke: 'white',

View File

@@ -11,6 +11,6 @@
// *********************************************************** // ***********************************************************
require('@babel/register')({ require('@babel/register')({
plugins: ['@babel/plugin-transform-modules-commonjs'] plugins: [ '@babel/plugin-transform-modules-commonjs' ]
}); });
module.exports = require('./main.js').default; 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) { function almostEquals (actual, expected, message) {
message = message || (actual + ' did not equal ' + expected); message = message || (actual + ' did not equal ' + expected);
const result = Math.abs(actual - expected) < NEAR_ZERO; 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), const actualDiff = (actual === expected) ? 0 : Math.abs(actual - expected),
result = actualDiff <= maxDifference; result = actualDiff <= maxDifference;
message = message || (actual + ' should be within ' + maxDifference + ' (inclusive) of ' + expected + (result ? '' : '. Actual: ' + actualDiff)); 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 + '%')); 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), const actualDiff = Math.abs(actual - expected),
result = actualDiff > minDifference; result = actualDiff > minDifference;
message = message || (actual + ' should not be within ' + minDifference + ' (exclusive) of ' + expected + (result ? '' : '. Actual: ' + actualDiff)); 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 + '%')); 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; const actual = result;
return {result, message, actual, expected}; return { result, message, actual, expected };
} }
/** /**

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,59 +2,8 @@
'use strict'; 'use strict';
module.exports = { module.exports = {
plugins: ['plugins/markdown'], plugins: [ 'plugins/markdown' ],
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();
}
*/
},
recurseDepth: 10, recurseDepth: 10,
source: { source: {
exclude: [ exclude: [

View File

@@ -43,7 +43,7 @@ repository editor code
```js ```js
svgEditor.setConfig({ svgEditor.setConfig({
dimensions: [320, 240], dimensions: [ 320, 240 ],
canvas_expansion: 5, canvas_expansion: 5,
initFill: { initFill: {
color: '0000FF' 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: `"@default"` is present in the array along with your own. For example:
```js ```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, (In version 2.8, the CSS file `editor/custom.css` was included by default,

View File

@@ -79,7 +79,7 @@ export default {
init () { init () {
return { return {
svgicons: 'extensions/helloworld-icon.xml', svgicons: 'extensions/helloworld-icon.xml',
buttons: [{ /* ... */ }], buttons: [ { /* ... */ } ],
mouseDown () { mouseDown () {
// ... // ...
}, },
@@ -139,7 +139,7 @@ property should follow the format
naming conflicts in the non-modular version of SVGEdit. naming conflicts in the non-modular version of SVGEdit.
```js ```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 ```js
svgEditor.setConfig({ 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" "svg2pdf.js": "2.1.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "7.14.0", "@babel/core": "7.14.2",
"@babel/preset-env": "7.14.1", "@babel/preset-env": "7.14.2",
"@babel/register": "7.13.16", "@babel/register": "7.13.16",
"@babel/runtime-corejs3": "7.14.0", "@babel/runtime-corejs3": "7.14.0",
"@cypress/code-coverage": "3.9.5", "@cypress/code-coverage": "3.9.5",
@@ -140,7 +140,7 @@
"coveradge": "0.6.0", "coveradge": "0.6.0",
"cp-cli": "2.0.0", "cp-cli": "2.0.0",
"cross-var": "1.1.0", "cross-var": "1.1.0",
"cypress": "7.2.0", "cypress": "7.3.0",
"cypress-axe": "0.12.2", "cypress-axe": "0.12.2",
"cypress-multi-reporters": "1.5.0", "cypress-multi-reporters": "1.5.0",
"cypress-plugin-snapshots": "1.4.4", "cypress-plugin-snapshots": "1.4.4",
@@ -149,13 +149,13 @@
"eslint-plugin-array-func": "3.1.7", "eslint-plugin-array-func": "3.1.7",
"eslint-plugin-chai-expect": "2.2.0", "eslint-plugin-chai-expect": "2.2.0",
"eslint-plugin-chai-expect-keywords": "2.1.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-compat": "^3.9.0",
"eslint-plugin-cypress": "2.11.3", "eslint-plugin-cypress": "2.11.3",
"eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-eslint-comments": "3.2.0",
"eslint-plugin-html": "^6.1.2", "eslint-plugin-html": "^6.1.2",
"eslint-plugin-import": "^2.22.1", "eslint-plugin-import": "2.23.0",
"eslint-plugin-jsdoc": "^33.1.1", "eslint-plugin-jsdoc": "34.2.2",
"eslint-plugin-markdown": "^2.1.0", "eslint-plugin-markdown": "^2.1.0",
"eslint-plugin-mocha": "8.1.0", "eslint-plugin-mocha": "8.1.0",
"eslint-plugin-mocha-cleanup": "1.9.1", "eslint-plugin-mocha-cleanup": "1.9.1",
@@ -165,7 +165,7 @@
"eslint-plugin-promise": "^5.1.0", "eslint-plugin-promise": "^5.1.0",
"eslint-plugin-sonarjs": "^0.7.0", "eslint-plugin-sonarjs": "^0.7.0",
"eslint-plugin-standard": "4.1.0", "eslint-plugin-standard": "4.1.0",
"eslint-plugin-unicorn": "32.0.0", "eslint-plugin-unicorn": "32.0.1",
"imageoptim-cli": "3.0.2", "imageoptim-cli": "3.0.2",
"jamilih": "0.54.0", "jamilih": "0.54.0",
"jsdoc": "3.6.6", "jsdoc": "3.6.6",
@@ -193,8 +193,8 @@
"rollup-plugin-re": "1.0.7", "rollup-plugin-re": "1.0.7",
"rollup-plugin-terser": "7.0.2", "rollup-plugin-terser": "7.0.2",
"stackblur-canvas": "2.5.0", "stackblur-canvas": "2.5.0",
"start-server-and-test": "^1.12.1", "start-server-and-test": "^1.12.2",
"systemjs": "6.8.3", "systemjs": "6.9.0",
"typescript": "4.2.4", "typescript": "4.2.4",
"underscore": "1.13.1" "underscore": "1.13.1"
} }

View File

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

View File

@@ -8,7 +8,7 @@
import 'pathseg'; import 'pathseg';
import {NS} from './namespaces.js'; import { NS } from './namespaces.js';
const supportsSVG_ = (function () { const supportsSVG_ = (function () {
return Boolean(document.createElementNS && document.createElementNS(NS.SVG, 'svg').createSVGRect); 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_; export const supportsSvg = () => supportsSVG_;
const {userAgent} = navigator; const { userAgent } = navigator;
const svg = document.createElementNS(NS.SVG, 'svg'); const svg = document.createElementNS(NS.SVG, 'svg');
// Note: Browser sniffing should only be used if no other detection method is possible // 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 () { export const getReverseNS = function () {
const reverseNS = {}; const reverseNS = {};
Object.entries(NS).forEach(([name, URI]) => { Object.entries(NS).forEach(([ name, URI ]) => {
reverseNS[URI] = name.toLowerCase(); reverseNS[URI] = name.toLowerCase();
}); });
return reverseNS; return reverseNS;

View File

@@ -6,11 +6,11 @@
* @copyright 2010 Alexis Deveria, 2010 Jeff Schiller * @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 wAttrs = [ 'x', 'x1', 'cx', 'rx', 'width' ];
const hAttrs = ['y', 'y1', 'cy', 'ry', 'height']; const hAttrs = [ 'y', 'y1', 'cy', 'ry', 'height' ];
const unitAttrs = ['r', 'radius', ...wAttrs, ...hAttrs]; const unitAttrs = [ 'r', 'radius', ...wAttrs, ...hAttrs ];
// unused // unused
/* /*
const unitNumMap = { const unitNumMap = {
@@ -202,14 +202,14 @@ export const setUnitAttr = function (elem, attr, val) {
}; };
const attrsToConvert = { const attrsToConvert = {
line: ['x1', 'x2', 'y1', 'y2'], line: [ 'x1', 'x2', 'y1', 'y2' ],
circle: ['cx', 'cy', 'r'], circle: [ 'cx', 'cy', 'r' ],
ellipse: ['cx', 'cy', 'rx', 'ry'], ellipse: [ 'cx', 'cy', 'rx', 'ry' ],
foreignObject: ['x', 'y', 'width', 'height'], foreignObject: [ 'x', 'y', 'width', 'height' ],
rect: ['x', 'y', 'width', 'height'], rect: [ 'x', 'y', 'width', 'height' ],
image: ['x', 'y', 'width', 'height'], image: [ 'x', 'y', 'width', 'height' ],
use: ['x', 'y', 'width', 'height'], use: [ 'x', 'y', 'width', 'height' ],
text: ['x', 'y'] text: [ 'x', 'y' ]
}; };
/** /**

View File

@@ -1,6 +1,6 @@
// eslint-disable-next-line node/no-unpublished-import // eslint-disable-next-line node/no-unpublished-import
import deparam from 'deparam'; 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. * Escapes special characters in a regular expression.
@@ -126,7 +126,7 @@ export default class ConfigObj {
imgPath: './images/', imgPath: './images/',
// DOCUMENT PROPERTIES // DOCUMENT PROPERTIES
// Change the following to a preference (already in the Document Properties dialog)? // Change the following to a preference (already in the Document Properties dialog)?
dimensions: [640, 480], dimensions: [ 640, 480 ],
// EDITOR OPTIONS // EDITOR OPTIONS
// Change the following to preferences (already in the Editor Options dialog)? // Change the following to preferences (already in the Editor Options dialog)?
gridSnapping: false, gridSnapping: false,
@@ -170,11 +170,11 @@ export default class ConfigObj {
// 'ext-markers', // 'ext-markers',
'ext-overview_window', 'ext-overview_window',
'ext-panning', 'ext-panning',
'ext-polygon',
'ext-shapes', 'ext-shapes',
'ext-star', 'ext-polystar',
'ext-storage', 'ext-storage',
'ext-opensave' 'ext-opensave',
// 'ext-helloworld',
]; ];
this.curConfig = { this.curConfig = {
// We do not put on defaultConfig to simplify object copying // We do not put on defaultConfig to simplify object copying
@@ -204,7 +204,7 @@ export default class ConfigObj {
* @returns {void} * @returns {void}
*/ */
setupCurPrefs () { 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 // Export updated prefs
this.curPrefs = curPrefs; this.curPrefs = curPrefs;
} }
@@ -213,11 +213,11 @@ export default class ConfigObj {
* @returns {void} * @returns {void}
*/ */
setupCurConfig () { 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 // Now deal with extensions and other array config
if (!curConfig.noDefaultExtensions) { if (!curConfig.noDefaultExtensions) {
curConfig.extensions = [...this.defaultExtensions]; curConfig.extensions = [ ...this.defaultExtensions ];
} }
// Export updated config // Export updated config
this.curConfig = curConfig; this.curConfig = curConfig;
@@ -227,12 +227,12 @@ export default class ConfigObj {
* @returns {void} * @returns {void}
*/ */
loadFromURL () { loadFromURL () {
const {search, searchParams} = new URL(location); const { search, searchParams } = new URL(location);
if (search) { if (search) {
this.urldata = deparam(searchParams.toString()); this.urldata = deparam(searchParams.toString());
['initStroke', 'initFill'].forEach((prop) => { [ 'initStroke', 'initFill' ].forEach((prop) => {
if (searchParams.has(`${prop}[color]`)) { if (searchParams.has(`${prop}[color]`)) {
// Restore back to original non-deparamed value to avoid color // Restore back to original non-deparamed value to avoid color
// strings being converted to numbers // strings being converted to numbers
@@ -260,7 +260,7 @@ export default class ConfigObj {
// security reasons, even for same-domain // security reasons, even for same-domain
// ones given potential to interact in undesirable // ones given potential to interact in undesirable
// ways with other script resources // ways with other script resources
['userExtensions', 'imgPath'] [ 'userExtensions', 'imgPath' ]
.forEach(function (pathConfig) { .forEach(function (pathConfig) {
if (this.urldata[pathConfig]) { if (this.urldata[pathConfig]) {
delete 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 // Note: `source` and `url` (as with `storagePrompt` later) are not
// set on config but are used below // set on config but are used below
this.setConfig(this.urldata, {overwrite: false}); this.setConfig(this.urldata, { overwrite: false });
this.setupCurConfig(); this.setupCurConfig();
if (!this.curConfig.preventURLContentLoading) { if (!this.curConfig.preventURLContentLoading) {
let {source} = this.urldata; let { source } = this.urldata;
if (!source) { // urldata.source may have been null if it ended with '=' if (!source) { // urldata.source may have been null if it ended with '='
const src = searchParams.get('source'); const src = searchParams.get('source');
if (src && src.startsWith('data:')) { if (src && src.startsWith('data:')) {
@@ -396,7 +396,7 @@ export default class ConfigObj {
cfgObj[key] = val; cfgObj[key] = val;
} }
}; };
Object.entries(opts).forEach(([key, val]) => { Object.entries(opts).forEach(([ key, val ]) => {
// Only allow prefs defined in configObj.defaultPrefs or... // Only allow prefs defined in configObj.defaultPrefs or...
if (this.defaultPrefs[key]) { if (this.defaultPrefs[key]) {
if (cfgCfg.overwrite === false && ( if (cfgCfg.overwrite === false && (
@@ -410,11 +410,11 @@ export default class ConfigObj {
} else { } else {
this.pref(key, val); this.pref(key, val);
} }
} else if (['extensions', 'userExtensions', 'allowedOrigins'].includes(key)) { } else if ([ 'extensions', 'userExtensions', 'allowedOrigins' ].includes(key)) {
if (cfgCfg.overwrite === false && if (cfgCfg.overwrite === false &&
( (
this.curConfig.preventAllURLConfig || this.curConfig.preventAllURLConfig ||
['allowedOrigins'].includes(key) || [ 'allowedOrigins' ].includes(key) ||
(key === 'extensions' && this.curConfig.lockExtensions) (key === 'extensions' && this.curConfig.lockExtensions)
) )
) { ) {

View File

@@ -52,7 +52,7 @@ class Editor extends EditorStartup {
* @type {"ignore"|"waiting"|"closed"} * @type {"ignore"|"waiting"|"closed"}
*/ */
this.storagePromptState = 'ignore'; this.storagePromptState = 'ignore';
this.svgCanvas = null; this.svgCanvas = null;
this.isReady = false; this.isReady = false;
this.customExportImage = false; this.customExportImage = false;
@@ -67,7 +67,7 @@ class Editor extends EditorStartup {
this.configObj.preferences = false; this.configObj.preferences = false;
this.canvMenu = null; this.canvMenu = null;
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
this.goodLangs = ['ar', 'cs', 'de', 'en', 'es', 'fa', 'fr', 'fy', 'hi', 'it', 'ja', 'nl', 'pl', 'pt-BR', 'ro', 'ru', 'sk', 'sl', 'zh-CN', 'zh-TW']; this.goodLangs = [ 'ar', 'cs', 'de', 'en', 'es', 'fa', 'fr', 'fy', 'hi', 'it', 'ja', 'nl', 'pl', 'pt-BR', 'ro', 'ru', 'sk', 'sl', 'zh-CN', 'zh-TW' ];
const modKey = (isMac() ? 'meta+' : 'ctrl+'); const modKey = (isMac() ? 'meta+' : 'ctrl+');
this.shortcuts = [ this.shortcuts = [
// Shortcuts not associated with buttons // Shortcuts not associated with buttons
@@ -79,26 +79,26 @@ class Editor extends EditorStartup {
{ key: 'shift+p', fn: () => { this.svgCanvas.cycleElement(1); } }, { key: 'shift+p', fn: () => { this.svgCanvas.cycleElement(1); } },
{ key: 'tab', fn: () => { this.svgCanvas.cycleElement(0); } }, { key: 'tab', fn: () => { this.svgCanvas.cycleElement(0); } },
{ key: 'shift+tab', fn: () => { this.svgCanvas.cycleElement(1); } }, { key: 'shift+tab', fn: () => { this.svgCanvas.cycleElement(1); } },
{ key: [modKey + 'arrowup', true], fn: () => { this.zoomImage(2); } }, { key: [ modKey + 'arrowup', true ], fn: () => { this.zoomImage(2); } },
{ key: [modKey + 'arrowdown', true], fn: () => { this.zoomImage(0.5); } }, { key: [ modKey + 'arrowdown', true ], fn: () => { this.zoomImage(0.5); } },
{ key: [modKey + ']', true], fn: () => { this.moveUpDownSelected('Up'); } }, { key: [ modKey + ']', true ], fn: () => { this.moveUpDownSelected('Up'); } },
{ key: [modKey + '[', true], fn: () => { this.moveUpDownSelected('Down'); } }, { key: [ modKey + '[', true ], fn: () => { this.moveUpDownSelected('Down'); } },
{ key: ['arrowup', true], fn: () => { this.moveSelected(0, -1); } }, { key: [ 'arrowup', true ], fn: () => { this.moveSelected(0, -1); } },
{ key: ['arrowdown', true], fn: () => { this.moveSelected(0, 1); } }, { key: [ 'arrowdown', true ], fn: () => { this.moveSelected(0, 1); } },
{ key: ['arrowleft', true], fn: () => { this.moveSelected(-1, 0); } }, { key: [ 'arrowleft', true ], fn: () => { this.moveSelected(-1, 0); } },
{ key: ['arrowright', true], fn: () => { this.moveSelected(1, 0); } }, { key: [ 'arrowright', true ], fn: () => { this.moveSelected(1, 0); } },
{ key: 'shift+arrowup', fn: () => { this.moveSelected(0, -10); } }, { key: 'shift+arrowup', fn: () => { this.moveSelected(0, -10); } },
{ key: 'shift+arrowdown', fn: () => { this.moveSelected(0, 10); } }, { key: 'shift+arrowdown', fn: () => { this.moveSelected(0, 10); } },
{ key: 'shift+arrowleft', fn: () => { this.moveSelected(-10, 0); } }, { key: 'shift+arrowleft', fn: () => { this.moveSelected(-10, 0); } },
{ key: 'shift+arrowright', 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+arrowup', true ], fn: () => { this.svgCanvas.cloneSelectedElements(0, -1); } },
{ key: ['alt+arrowdown', 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+arrowleft', true ], fn: () => { this.svgCanvas.cloneSelectedElements(-1, 0); } },
{ key: ['alt+arrowright', 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+arrowup', true ], fn: () => { this.svgCanvas.cloneSelectedElements(0, -10); } },
{ key: ['alt+shift+arrowdown', 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+arrowleft', true ], fn: () => { this.svgCanvas.cloneSelectedElements(-10, 0); } },
{ key: ['alt+shift+arrowright', 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: 'a', fn: () => { this.svgCanvas.selectAllInCurrentLayer(); } },
{ key: modKey + 'a', fn: () => { this.svgCanvas.selectAllInCurrentLayer(); } }, { key: modKey + 'a', fn: () => { this.svgCanvas.selectAllInCurrentLayer(); } },
{ key: modKey + 'x', fn: () => { this.cutSelected(); } }, { key: modKey + 'x', fn: () => { this.cutSelected(); } },
@@ -294,8 +294,8 @@ class Editor extends EditorStartup {
'4/Shift+4': 'tools_rect', '4/Shift+4': 'tools_rect',
'5/Shift+5': 'tools_ellipse' '5/Shift+5': 'tools_ellipse'
}; };
Object.entries(keyAssocs).forEach(([keyval, sel]) => { Object.entries(keyAssocs).forEach(([ keyval, sel ]) => {
const parentsElements = this.getParents($id(sel), $id('main_menu')) const parentsElements = this.getParents($id(sel), $id('main_menu'));
const menu = (parentsElements.length); const menu = (parentsElements.length);
$qa(sel).forEach((element) => { $qa(sel).forEach((element) => {
@@ -350,9 +350,9 @@ class Editor extends EditorStartup {
const elements = document.getElementsByClassName("tool_button_current"); const elements = document.getElementsByClassName("tool_button_current");
Array.from(elements).forEach(function (element) { Array.from(elements).forEach(function (element) {
element.classList.add('tool_button_current'); 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'); $id('tool_select').classList.remove('tool_button');
this.multiselected = false; this.multiselected = false;
if (elems.length) { if (elems.length) {
@@ -384,7 +384,7 @@ class Editor extends EditorStartup {
this.exportWindow.location.href = data.bloburl || data.datauri; this.exportWindow.location.href = data.bloburl || data.datauri;
const done = this.configObj.pref('export_notice_done'); const done = this.configObj.pref('export_notice_done');
if (done !== 'all') { 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 // Check if there are issues
if (issues.length) { if (issues.length) {
@@ -775,7 +775,7 @@ class Editor extends EditorStartup {
const icon = (typeof iconId === 'string') ? img : iconId.cloneNode(true); const icon = (typeof iconId === 'string') ? img : iconId.cloneNode(true);
if (!icon) { if (!icon) {
// Todo: Investigate why this still occurs in some cases // Todo: Investigate why this still occurs in some cases
console.log('NOTE: Icon image missing: ' + iconId); console.warn('NOTE: Icon image missing: ' + iconId);
return; return;
} }
// empty() // empty()
@@ -1083,7 +1083,7 @@ class Editor extends EditorStartup {
resolve(cb()); resolve(cb());
return; return;
} }
this.callbacks.push([cb, resolve, reject]); this.callbacks.push([ cb, resolve, reject ]);
}); });
} }
@@ -1094,16 +1094,16 @@ class Editor extends EditorStartup {
*/ */
async runCallbacks() { async runCallbacks() {
try { try {
await Promise.all(this.callbacks.map(([cb]) => { await Promise.all(this.callbacks.map(([ cb ]) => {
return cb(); return cb();
})); }));
} catch (err) { } catch (err) {
this.callbacks.forEach(([, , reject]) => { this.callbacks.forEach(([ , , reject ]) => {
reject(); reject();
}); });
throw err; throw err;
} }
this.callbacks.forEach(([, resolve]) => { this.callbacks.forEach(([ , resolve ]) => {
resolve(); resolve();
}); });
this.isReady = true; this.isReady = true;

View File

@@ -1,6 +1,6 @@
/* globals $ seConfirm seAlert */ /* globals $ seConfirm seAlert */
import './touch.js'; import './touch.js';
import {convertUnit} from '../common/units.js'; import { convertUnit } from '../common/units.js';
import { import {
putLocale putLocale
} from './locale.js'; } from './locale.js';
@@ -41,7 +41,7 @@ const readySignal = () => {
} }
}; };
const {$id} = SvgCanvas; const { $id } = SvgCanvas;
/** /**
* *
@@ -53,7 +53,7 @@ class EditorStartup {
constructor () { constructor () {
this.extensionsAdded = false; this.extensionsAdded = false;
this.messageQueue = []; this.messageQueue = [];
this.$svgEditor = $id('svg_editor') this.$svgEditor = $id('svg_editor');
} }
/** /**
* Auto-run after a Promise microtask. * Auto-run after a Promise microtask.
@@ -61,6 +61,10 @@ class EditorStartup {
* @returns {void} * @returns {void}
*/ */
async init () { async init () {
if ('localStorage' in window) { // && onWeb removed so Webkit works locally
this.storage = window.localStorage;
}
this.configObj.load();
const self = this; const self = this;
const { i18next } = await putLocale(this.configObj.pref('lang'), this.goodLangs); const { i18next } = await putLocale(this.configObj.pref('lang'), this.goodLangs);
this.i18next = i18next; this.i18next = i18next;
@@ -97,12 +101,6 @@ class EditorStartup {
console.error(err); console.error(err);
} }
if ('localStorage' in window) { // && onWeb removed so Webkit works locally
this.storage = window.localStorage;
}
this.configObj.load();
/** /**
* @name module:SVGthis.canvas * @name module:SVGthis.canvas
* @type {module:svgcanvas.SvgCanvas} * @type {module:svgcanvas.SvgCanvas}
@@ -118,7 +116,7 @@ class EditorStartup {
this.layersPanel.init(); this.layersPanel.init();
this.mainMenu.init(); this.mainMenu.init();
const {undoMgr} = this.svgCanvas; const { undoMgr } = this.svgCanvas;
this.workarea = document.getElementById('workarea'); this.workarea = document.getElementById('workarea');
this.canvMenu = document.getElementById('se-cmenu_canvas'); this.canvMenu = document.getElementById('se-cmenu_canvas');
this.exportWindow = null; this.exportWindow = null;
@@ -136,7 +134,7 @@ class EditorStartup {
this.selectedElement = null; this.selectedElement = null;
this.multiselected = false; this.multiselected = false;
const aLinks = $id('cur_context_panel').querySelectorAll('a') const aLinks = $id('cur_context_panel').querySelectorAll('a');
for (const aLink of aLinks) { for (const aLink of aLinks) {
aLink.addEventListener('click', (evt) => { aLink.addEventListener('click', (evt) => {
@@ -160,7 +158,7 @@ class EditorStartup {
if (!data.output) { // Ignore Chrome if (!data.output) { // Ignore Chrome
return; return;
} }
const {exportWindowName} = data; const { exportWindowName } = data;
if (exportWindowName) { if (exportWindowName) {
this.exportWindow = window.open('', this.exportWindowName); // A hack to get the window via JSON-able name without opening a new one 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 * @listens module:svgcanvas.SvgCanvas#event:updateCanvas
* @returns {void} * @returns {void}
*/ */
function (win, {center, newCtr}) { function (win, { center, newCtr }) {
this.updateCanvas(center, newCtr); this.updateCanvas(center, newCtr);
}.bind(this) }.bind(this)
); );
@@ -279,7 +277,7 @@ class EditorStartup {
let lastX = null, lastY = null, let lastX = null, lastY = null,
panning = false, keypan = false; panning = false, keypan = false;
$id('svgcanvas').addEventListener('mouseup', function(evt) { $id('svgcanvas').addEventListener('mouseup', function(evt) {
if (panning === false) { return true; } if (panning === false) { return true; }
wArea.scrollLeft -= (evt.clientX - lastX); wArea.scrollLeft -= (evt.clientX - lastX);
@@ -290,9 +288,9 @@ class EditorStartup {
if (evt.type === 'mouseup') { panning = false; } if (evt.type === 'mouseup') { panning = false; }
return false; return false;
}); });
// eslint-disable-next-line sonarjs/no-identical-functions // 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; } if (panning === false) { return true; }
wArea.scrollLeft -= (evt.clientX - lastX); wArea.scrollLeft -= (evt.clientX - lastX);
@@ -322,10 +320,10 @@ class EditorStartup {
if (e.target.nodeName !== 'BODY') return; if (e.target.nodeName !== 'BODY') return;
if(e.code.toLowerCase() === 'space'){ if(e.code.toLowerCase() === 'space'){
this.svgCanvas.spaceKey = keypan = true; this.svgCanvas.spaceKey = keypan = true;
e.preventDefault(); e.preventDefault();
} else if((e.key.toLowerCase() === 'shift') && (this.svgCanvas.getMode() === 'zoom')){ } else if((e.key.toLowerCase() === 'shift') && (this.svgCanvas.getMode() === 'zoom')){
this.workarea.style.cursor = zoomOutIcon; this.workarea.style.cursor = zoomOutIcon;
e.preventDefault(); e.preventDefault();
} else { } else {
return; return;
} }
@@ -335,10 +333,10 @@ class EditorStartup {
if (e.target.nodeName !== 'BODY') return; if (e.target.nodeName !== 'BODY') return;
if(e.code.toLowerCase() === 'space'){ if(e.code.toLowerCase() === 'space'){
this.svgCanvas.spaceKey = keypan = false; this.svgCanvas.spaceKey = keypan = false;
e.preventDefault(); e.preventDefault();
} else if((e.key.toLowerCase() === 'shift') && (this.svgCanvas.getMode() === 'zoom')){ } else if((e.key.toLowerCase() === 'shift') && (this.svgCanvas.getMode() === 'zoom')){
this.workarea.style.cursor = zoomInIcon; this.workarea.style.cursor = zoomInIcon;
e.preventDefault(); e.preventDefault();
} else { } else {
return; return;
} }
@@ -367,7 +365,7 @@ class EditorStartup {
el.addEventListener("focus", (e) => { el.addEventListener("focus", (e) => {
inp = e.currentTarget; inp = e.currentTarget;
this.uiContext = 'toolbars'; this.uiContext = 'toolbars';
this.workarea.addEventListener('mousedown', unfocus); this.workarea.addEventListener('mousedown', unfocus);
}); });
el.addEventListener("blur", () => { el.addEventListener("blur", () => {
this.uiContext = 'canvas'; this.uiContext = 'canvas';
@@ -399,12 +397,12 @@ class EditorStartup {
); );
} }
const winWh = { const winWh = {
width: getWidth(), width: getWidth(),
height: getHeight() height: getHeight()
}; };
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
Object.entries(winWh).forEach(([type, val]) => { Object.entries(winWh).forEach(([ type, val ]) => {
const curval = (type === 'width') ? window.innerWidth - 15 : window.innerHeight; const curval = (type === 'width') ? window.innerWidth - 15 : window.innerHeight;
this.workarea['scroll' + (type === 'width' ? 'Left' : 'Top')] -= (curval - val) / 2; this.workarea['scroll' + (type === 'width' ? 'Left' : 'Top')] -= (curval - val) / 2;
winWh[type] = curval; winWh[type] = curval;
@@ -426,16 +424,16 @@ class EditorStartup {
Array.from(elements).forEach(function(element) { Array.from(elements).forEach(function(element) {
element.addEventListener('mousedown', function(event) { element.addEventListener('mousedown', function(event) {
if (!event.currentTarget.classList.contains('disabled')) { 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'); event.currentTarget.classList.remove('push_button');
} }
}); });
element.addEventListener('mouseout', function(event) { element.addEventListener('mouseout', function(event) {
event.currentTarget.classList.add('push_button') event.currentTarget.classList.add('push_button');
event.currentTarget.classList.remove('push_button_pressed'); event.currentTarget.classList.remove('push_button_pressed');
}); });
element.addEventListener('mouseup', function(event) { element.addEventListener('mouseup', function(event) {
event.currentTarget.classList.add('push_button') event.currentTarget.classList.add('push_button');
event.currentTarget.classList.remove('push_button_pressed'); event.currentTarget.classList.remove('push_button_pressed');
}); });
}); });
@@ -619,14 +617,14 @@ class EditorStartup {
editorObj.svgCanvas.alignSelectedElements('m', 'page'); editorObj.svgCanvas.alignSelectedElements('m', 'page');
editorObj.svgCanvas.alignSelectedElements('c', 'page'); editorObj.svgCanvas.alignSelectedElements('c', 'page');
// highlight imported element, otherwise we get strange empty selectbox // 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); document.getElementById('se-prompt-dialog').setAttribute('close', true);
}; };
reader.readAsText(file); reader.readAsText(file);
} else { } else {
// bitmap handling // bitmap handling
reader = new FileReader(); reader = new FileReader();
reader.onloadend = function ({target: {result}}) { reader.onloadend = function ({ target: { result } }) {
/** /**
* Insert the new image until we know its dimensions. * Insert the new image until we know its dimensions.
* @param {Float} imageWidth * @param {Float} imageWidth
@@ -646,7 +644,7 @@ class EditorStartup {
} }
}); });
editorObj.svgCanvas.setHref(newImage, result); editorObj.svgCanvas.setHref(newImage, result);
editorObj.svgCanvas.selectOnly([newImage]); editorObj.svgCanvas.selectOnly([ newImage ]);
editorObj.svgCanvas.alignSelectedElements('m', 'page'); editorObj.svgCanvas.alignSelectedElements('m', 'page');
editorObj.svgCanvas.alignSelectedElements('c', 'page'); editorObj.svgCanvas.alignSelectedElements('c', 'page');
editorObj.topPanelHandlers.updateContextPanel(); editorObj.topPanelHandlers.updateContextPanel();
@@ -715,8 +713,8 @@ class EditorStartup {
*/ */
// eslint-disable-next-line no-unsanitized/method // eslint-disable-next-line no-unsanitized/method
const imported = await import(`./extensions/${encodeURIComponent(extname)}/${encodeURIComponent(extname)}.js`); const imported = await import(`./extensions/${encodeURIComponent(extname)}/${encodeURIComponent(extname)}.js`);
const {name = extname, init: initfn} = imported.default; const { name = extname, init: initfn } = imported.default;
return this.addExtension(name, (initfn && initfn.bind(this)), {$, langParam: 'en'}); /** @todo change to current lng */ return this.addExtension(name, (initfn && initfn.bind(this)), { $, langParam: 'en' }); /** @todo change to current lng */
} catch (err) { } catch (err) {
// Todo: Add config to alert any errors // Todo: Add config to alert any errors
console.error('Extension failed to load: ' + extname + '; ', err); console.error('Extension failed to load: ' + extname + '; ', err);
@@ -739,8 +737,8 @@ class EditorStartup {
*/ */
// eslint-disable-next-line no-unsanitized/method // eslint-disable-next-line no-unsanitized/method
const imported = await import(encodeURI(extPathName)); const imported = await import(encodeURI(extPathName));
const {name, init: initfn} = imported.default; const { name, init: initfn } = imported.default;
return this.addExtension(name, (initfn && initfn.bind(this)), {$}); return this.addExtension(name, (initfn && initfn.bind(this)), { $ });
} catch (err) { } catch (err) {
// Todo: Add config to alert any errors // Todo: Add config to alert any errors
console.error('Extension failed to load: ' + extPathName + '; ', err); console.error('Extension failed to load: ' + extPathName + '; ', err);
@@ -790,9 +788,8 @@ class EditorStartup {
* @fires module:svgcanvas.SvgCanvas#event:message * @fires module:svgcanvas.SvgCanvas#event:message
* @returns {void} * @returns {void}
*/ */
messageListener ({data, origin}) { messageListener ({ data, origin }) {
// console.log('data, origin, extensionsAdded', data, origin, extensionsAdded); const messageObj = { data, origin };
const messageObj = {data, origin};
if (!this.extensionsAdded) { if (!this.extensionsAdded) {
this.messageQueue.push(messageObj); this.messageQueue.push(messageObj);
} else { } else {

View File

@@ -1,7 +1,7 @@
/* globals seConfirm, seAlert */ /* globals seConfirm, seAlert */
import SvgCanvas from "../svgcanvas/svgcanvas.js"; import SvgCanvas from "../svgcanvas/svgcanvas.js";
import {convertUnit, isValidUnit} from '../common/units.js'; import { convertUnit, isValidUnit } from '../common/units.js';
import {isChrome} from '../common/browser.js'; import { isChrome } from '../common/browser.js';
const { $id } = SvgCanvas; const { $id } = SvgCanvas;
const homePage = 'https://github.com/SVG-Edit/svgedit'; const homePage = 'https://github.com/SVG-Edit/svgedit';
@@ -26,7 +26,7 @@ class MainMenu {
* @returns {void} * @returns {void}
*/ */
async clickClear() { 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')); const ok = await seConfirm(this.editor.i18next.t('notification.QwantToClear'));
if (ok === "Cancel") { if (ok === "Cancel") {
return; return;
@@ -111,11 +111,8 @@ class MainMenu {
// set language // set language
if (lang && lang !== this.editor.configObj.pref("lang")) { if (lang && lang !== this.editor.configObj.pref("lang")) {
const { langParam, langData } = await this.editor.putLocale( this.editor.configObj.pref("lang", lang);
lang, seAlert('Changing the language needs reload');
this.editor.goodLangs
);
await this.editor.svgCanvassetLang(langParam, langData);
} }
// set grid setting // set grid setting
@@ -130,7 +127,7 @@ class MainMenu {
this.editor.configObj.curConfig.baseUnit = baseunit; this.editor.configObj.curConfig.baseUnit = baseunit;
this.editor.svgCanvas.setConfig(this.editor.configObj.curConfig); this.editor.svgCanvas.setConfig(this.editor.configObj.curConfig);
this.editor.updateCanvas(); this.editor.updateCanvas();
this.editor.hidePreferences(); this.hidePreferences();
} }
/** /**
@@ -183,7 +180,7 @@ class MainMenu {
<body><h1>${loadingImage}</h1></body> <body><h1>${loadingImage}</h1></body>
<html>`; <html>`;
if (typeof URL !== "undefined" && URL.createObjectURL) { 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); popURL = URL.createObjectURL(blob);
} else { } else {
popURL = "data:text/html;base64;charset=utf-8," + popHTML; popURL = "data:text/html;base64;charset=utf-8," + popHTML;
@@ -305,7 +302,7 @@ class MainMenu {
init() { init() {
// add Top panel // add Top panel
const template = document.createElement("template"); const template = document.createElement("template");
const {i18next} = this.editor const { i18next } = this.editor;
// eslint-disable-next-line no-unsanitized/property // eslint-disable-next-line no-unsanitized/property
template.innerHTML = ` template.innerHTML = `
<se-menu id="main_button" label="SVG-Edit" src="./images/logo.svg" alt="logo"> <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_clear").addEventListener("click", this.clickClear.bind(this));
$id("tool_open").addEventListener("click", e => { $id("tool_open").addEventListener("click", (e) => {
e.preventDefault(); e.preventDefault();
this.clickOpen(); this.clickOpen();
window.dispatchEvent(new CustomEvent("openImage")); 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'; import rulersTemplate from './templates/rulersTemplate.js';
/** /**
* *
@@ -52,7 +52,7 @@ class Rulers {
const dim = isX ? 'x' : 'y'; const dim = isX ? 'x' : 'y';
const lentype = isX ? 'width' : 'height'; const lentype = isX ? 'width' : 'height';
const contentDim = Number(contentElem.getAttribute(dim)); const contentDim = Number(contentElem.getAttribute(dim));
const {$id} = this.svgCanvas; const { $id } = this.svgCanvas;
const $hcanvOrig = $id('ruler_' + dim).querySelector('canvas'); const $hcanvOrig = $id('ruler_' + dim).querySelector('canvas');
// Bit of a hack to fully clear the canvas in Safari & IE9 // 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) { static getPaint (svgCanvas, color, opac, type) {
// update the editor's fill paint // update the editor's fill paint
const opts = {alpha: opac}; const opts = { alpha: opac };
if (color.startsWith('url(#')) { if (color.startsWith('url(#')) {
let refElem = svgCanvas.getRefElem(color); let refElem = svgCanvas.getRefElem(color);
refElem = (refElem) ? refElem.cloneNode(true) : document.querySelectorAll('#' + type + '_color defs *')[0]; refElem = (refElem) ? refElem.cloneNode(true) : document.querySelectorAll('#' + type + '_color defs *')[0];
@@ -88,7 +88,7 @@ class PaintBox {
update (svgcanvas, selectedElement) { update (svgcanvas, selectedElement) {
if (!selectedElement) { return null; } if (!selectedElement) { return null; }
const {type} = this; const { type } = this;
switch (selectedElement.tagName) { switch (selectedElement.tagName) {
case 'use': case 'use':
case 'image': case 'image':

View File

@@ -232,7 +232,7 @@ export default class ColorValuePicker {
break; break;
case ahex: case ahex:
color.value = 'ahex'; color.value = 'ahex';
ahex.value = color.value.substring(6); ahex.value = color.value.substring(6);
break; break;
} }
} }
@@ -349,7 +349,7 @@ export default class ColorValuePicker {
value = inputs[2], value = inputs[2],
hex = inputs[(inputs.length > 7) ? 7 : 6], hex = inputs[(inputs.length > 7) ? 7 : 6],
ahex = inputs.length > 7 ? inputs[8] : null; ahex = inputs.length > 7 ? inputs[8] : null;
Object.assign(that, {destroy}); Object.assign(that, { destroy });
red.addEventListener('keyup', keyUp); red.addEventListener('keyup', keyUp);
green.addEventListener('keyup', keyUp); green.addEventListener('keyup', keyUp);
blue.addEventListener('keyup', keyUp); blue.addEventListener('keyup', keyUp);

View File

@@ -1,5 +1,5 @@
/* eslint-disable no-bitwise */ /* eslint-disable no-bitwise */
import {findPos} from './Util.js'; import { findPos } from './Util.js';
/** /**
* Whether a value is `null` or `undefined`. * Whether a value is `null` or `undefined`.
* @param {any} val * @param {any} val
@@ -38,7 +38,7 @@ export default class Slider {
*/ */
function mouseDown (e) { function mouseDown (e) {
const off = findPos(bar); const off = findPos(bar);
offset = {l: off.left | 0, t: off.top | 0}; offset = { l: off.left | 0, t: off.top | 0 };
clearTimeout(timeout); clearTimeout(timeout);
// using setTimeout for visual updates - once the style is updated the browser will re-render internally allowing the next Javascript to run // 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 () { timeout = setTimeout(function () {
@@ -146,7 +146,7 @@ export default class Slider {
case 'x': return x; case 'x': return x;
case 'y': return y; case 'y': return y;
case 'xy': case 'xy':
default: return {x, y}; default: return { x, y };
} }
} }
if (!isNullish(context) && context === that) return undefined; if (!isNullish(context) && context === that) return undefined;
@@ -216,12 +216,12 @@ export default class Slider {
switch (name.toLowerCase()) { switch (name.toLowerCase()) {
case 'minx': return minX; case 'minx': return minX;
case 'maxx': return maxX; case 'maxx': return maxX;
case 'rangex': return {minX, maxX, rangeX}; case 'rangex': return { minX, maxX, rangeX };
case 'miny': return minY; case 'miny': return minY;
case 'maxy': return maxY; case 'maxy': return maxY;
case 'rangey': return {minY, maxY, rangeY}; case 'rangey': return { minY, maxY, rangeY };
case 'all': case 'all':
default: return {minX, maxX, rangeX, minY, maxY, rangeY}; default: return { minX, maxX, rangeX, minY, maxY, rangeY };
} }
} }
let // changed = false, let // changed = false,

View File

@@ -23,7 +23,7 @@ export function isObject(item) {
export function mergeDeep(target, source) { export function mergeDeep(target, source) {
let output = Object.assign({}, target); let output = Object.assign({}, target);
if (isObject(target) && isObject(source)) { if (isObject(target) && isObject(source)) {
Object.keys(source).forEach(key => { Object.keys(source).forEach((key) => {
if (isObject(source[key])) { if (isObject(source[key])) {
if (!(key in target)) if (!(key in target))
Object.assign(output, { [key]: source[key] }); Object.assign(output, { [key]: source[key] });

View File

@@ -20,8 +20,8 @@
* @example $.jGraduate.Paint({hex: '#rrggbb', linearGradient: o}); // throws an exception? * @example $.jGraduate.Paint({hex: '#rrggbb', linearGradient: o}); // throws an exception?
*/ */
import Paint from './paint.js'; import Paint from './paint.js';
import {jPickerDefaults, jPickerMethod} from './jQuery.jPicker.js'; import { jPickerDefaults, jPickerMethod } from './jQuery.jPicker.js';
import {findPos} from './Util.js'; import { findPos } from './Util.js';
/** /**
* @todo JFH: This jQuery plugin was adapted to work within a Web Component. * @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) { function setAttrs (elem, attrs) {
if (isGecko) { if (isGecko) {
Object.entries(attrs).forEach(([aname, val]) => { Object.entries(attrs).forEach(([ aname, val ]) => {
elem.setAttribute(aname, val); elem.setAttribute(aname, val);
}); });
} else { } else {
Object.entries(attrs).forEach(([aname, val]) => { Object.entries(attrs).forEach(([ aname, val ]) => {
const prop = elem[aname]; const prop = elem[aname];
if (prop && prop.constructor === 'SVGLength') { if (prop && prop.constructor === 'SVGLength') {
prop.baseVal.value = val; prop.baseVal.value = val;
@@ -221,7 +221,7 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
}; };
Object.assign($this, { Object.assign($this, {
// make a copy of the incoming paint // 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, okCallback: typeof okCallback === 'function' ? okCallback : null,
cancelCallback: typeof cancelCallback === 'function' ? cancelCallback : null cancelCallback: typeof cancelCallback === 'function' ? cancelCallback : null
}); });
@@ -231,7 +231,7 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
const $win = window; const $win = window;
if ($this.paint.type === 'none') { if ($this.paint.type === 'none') {
$this.paint = new jGraduate.Paint({solidColor: 'ffffff'}); $this.paint = new jGraduate.Paint({ solidColor: 'ffffff' });
} }
$this.classList.add('jGraduate_Picker'); $this.classList.add('jGraduate_Picker');
/* eslint-disable max-len */ /* eslint-disable max-len */
@@ -531,7 +531,7 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
$elem.style.top = e.target.value * MAX; $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]); const isRadial = isNaN(attr[1]);
let attrval = curGradient.getAttribute(attr); let attrval = curGradient.getAttribute(attr);
@@ -620,9 +620,9 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
jqPickerElem.style.left = '100px'; jqPickerElem.style.left = '100px';
jqPickerElem.style.bottom = '15px'; jqPickerElem.style.bottom = '15px';
jPickerMethod(jqPickerElem, { jPickerMethod(jqPickerElem, {
window: {title: 'Pick the start color and opacity for the gradient'}, window: { title: 'Pick the start color and opacity for the gradient' },
images: {clientPath: $settings.images.clientPath}, images: { clientPath: $settings.images.clientPath },
color: {active: colr, alphaSupport: true} color: { active: colr, alphaSupport: true }
}, function (clr) { }, function (clr) {
stopColor = clr.val('hex') ? ('#' + clr.val('hex')) : 'none'; stopColor = clr.val('hex') ? ('#' + clr.val('hex')) : 'none';
stopOpacity = clr.val('a') !== null ? clr.val('a') / 256 : 1; 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); drag.setAttribute('transform', xfStr);
const jqpgpath = $this.querySelector('#'+drag.dataset.bg); const jqpgpath = $this.querySelector('#'+drag.dataset.bg);
jqpgpath.setAttribute('transform', xfStr); jqpgpath.setAttribute('transform', xfStr);
const stop = $this.querySelector('#'+drag.dataset.stop); const stop = $this.querySelector('#'+drag.dataset.stop);
const sX = (x - 10) / MAX; const sX = (x - 10) / MAX;
stop.setAttribute('offset', sX); stop.setAttribute('offset', sX);
@@ -795,7 +795,7 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
stopMakerSVG.addEventListener('click', function (evt) { stopMakerSVG.addEventListener('click', function (evt) {
stopOffset = findPos(stopMakerDiv); stopOffset = findPos(stopMakerDiv);
const {target} = evt; const { target } = evt;
if (target.tagName === 'path') return; if (target.tagName === 'path') return;
let x = evt.pageX - stopOffset.left - 8; let x = evt.pageX - stopOffset.left - 8;
x = x < 10 ? 10 : x > MAX + 10 ? MAX + 10 : x; x = x < 10 ? 10 : x > MAX + 10 ? MAX + 10 : x;
@@ -983,7 +983,7 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
let slider; let slider;
const setSlider = function (e) { const setSlider = function (e) {
const {offset: {left}} = slider; const { offset: { left } } = slider;
const divi = slider.parent; const divi = slider.parent;
let x = (e.pageX - left - Number.parseInt(getComputedStyle(divi, null).getPropertyValue('border-left-width'))); let x = (e.pageX - left - Number.parseInt(getComputedStyle(divi, null).getPropertyValue('border-left-width')));
if (x > SLIDERW) x = SLIDERW; if (x > SLIDERW) x = SLIDERW;
@@ -1088,7 +1088,7 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
val: angleVal 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 handle = $this.querySelector(data.handle);
const sInput = $this.querySelector(data.input); const sInput = $this.querySelector(data.input);
handle.addEventListener('mousedown', function (evt) { handle.addEventListener('mousedown', function (evt) {
@@ -1177,15 +1177,15 @@ export function jGraduateMethod (elem, options, okCallback, cancelCallback) {
} }
// This should be done somewhere else, probably // This should be done somewhere else, probably
Object.assign(jPickerDefaults.window, { Object.assign(jPickerDefaults.window, {
alphaSupport: true, effects: {type: 'show', speed: 0} alphaSupport: true, effects: { type: 'show', speed: 0 }
}); });
jPickerMethod( jPickerMethod(
colPicker, colPicker,
{ {
window: {title: $settings.window.pickerTitle}, window: { title: $settings.window.pickerTitle },
images: {clientPath: $settings.images.clientPath}, images: { clientPath: $settings.images.clientPath },
color: {active: color, alphaSupport: true} color: { active: color, alphaSupport: true }
}, },
function (clr) { function (clr) {
$this.paint.type = 'solidColor'; $this.paint.type = 'solidColor';

View File

@@ -19,7 +19,7 @@
/* eslint-disable max-len */ /* eslint-disable max-len */
import ColorValuePicker from './ColorValuePicker.js'; import ColorValuePicker from './ColorValuePicker.js';
import Slider from './Slider.js'; import Slider from './Slider.js';
import {findPos,mergeDeep} from './Util.js'; import { findPos, mergeDeep } from './Util.js';
/** /**
* @external Math * @external Math
@@ -121,7 +121,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
if (isNullish(name) || name === '') name = 'all'; if (isNullish(name) || name === '') name = 'all';
if (isNullish(r)) return null; if (isNullish(r)) return null;
switch (name.toLowerCase()) { 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 'hex': return val('ahex').substring(0, 6);
case 'all': return { case 'all': return {
r, g, b, a, h, s, v, r, g, b, a, h, s, v,
@@ -131,7 +131,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
default: { default: {
ret = {}; ret = {};
const nameLength = name.length; const nameLength = name.length;
[...name].forEach((ch) => { [ ...name ].forEach((ch) => {
switch (ch) { switch (ch) {
case 'r': case 'r':
if (nameLength === 1) ret = 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.h !== undefined && !name.includes('h')) name += 'h';
if (value.s !== undefined && !name.includes('s')) name += 's'; if (value.s !== undefined && !name.includes('s')) name += 's';
if (value.v !== undefined && !name.includes('v')) name += 'v'; if (value.v !== undefined && !name.includes('v')) name += 'v';
[...name].forEach((ch) => { [ ...name ].forEach((ch) => {
switch (ch) { switch (ch) {
case 'r': case 'r':
if (hsv) return; if (hsv) return;
@@ -243,7 +243,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
if (newV.r < 0) newV.r = 0; if (newV.r < 0) newV.r = 0;
else if (newV.r > 255) newV.r = 255; else if (newV.r > 255) newV.r = 255;
if (r !== newV.r) { if (r !== newV.r) {
({r} = newV); ({ r } = newV);
changed = true; changed = true;
} }
break; break;
@@ -254,7 +254,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
if (newV.g < 0) newV.g = 0; if (newV.g < 0) newV.g = 0;
else if (newV.g > 255) newV.g = 255; else if (newV.g > 255) newV.g = 255;
if (g !== newV.g) { if (g !== newV.g) {
({g} = newV); ({ g } = newV);
changed = true; changed = true;
} }
break; break;
@@ -265,7 +265,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
if (newV.b < 0) newV.b = 0; if (newV.b < 0) newV.b = 0;
else if (newV.b > 255) newV.b = 255; else if (newV.b > 255) newV.b = 255;
if (b !== newV.b) { if (b !== newV.b) {
({b} = newV); ({ b } = newV);
changed = true; changed = true;
} }
break; break;
@@ -274,7 +274,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
if (newV.a < 0) newV.a = 0; if (newV.a < 0) newV.a = 0;
else if (newV.a > 255) newV.a = 255; else if (newV.a > 255) newV.a = 255;
if (a !== newV.a) { if (a !== newV.a) {
({a} = newV); ({ a } = newV);
changed = true; changed = true;
} }
break; break;
@@ -285,7 +285,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
if (newV.h < 0) newV.h = 0; if (newV.h < 0) newV.h = 0;
else if (newV.h > 360) newV.h = 360; else if (newV.h > 360) newV.h = 360;
if (h !== newV.h) { if (h !== newV.h) {
({h} = newV); ({ h } = newV);
changed = true; changed = true;
} }
break; break;
@@ -296,7 +296,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
if (newV.s < 0) newV.s = 0; if (newV.s < 0) newV.s = 0;
else if (newV.s > 100) newV.s = 100; else if (newV.s > 100) newV.s = 100;
if (s !== newV.s) { if (s !== newV.s) {
({s} = newV); ({ s } = newV);
changed = true; changed = true;
} }
break; break;
@@ -307,7 +307,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
if (newV.v < 0) newV.v = 0; if (newV.v < 0) newV.v = 0;
else if (newV.v > 100) newV.v = 100; else if (newV.v > 100) newV.v = 100;
if (v !== newV.v) { if (v !== newV.v) {
({v} = newV); ({ v } = newV);
changed = true; changed = true;
} }
break; break;
@@ -318,14 +318,14 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
r = r || 0; r = r || 0;
g = g || 0; g = g || 0;
b = b || 0; b = b || 0;
const ret = ColorMethods.rgbToHsv({r, g, b}); const ret = ColorMethods.rgbToHsv({ r, g, b });
({h, s, v} = ret); ({ h, s, v } = ret);
} else if (hsv) { } else if (hsv) {
h = h || 0; h = h || 0;
s = !isNullish(s) ? s : 100; s = !isNullish(s) ? s : 100;
v = !isNullish(v) ? v : 100; v = !isNullish(v) ? v : 100;
const ret = ColorMethods.hsvToRgb({h, s, v}); const ret = ColorMethods.hsvToRgb({ h, s, v });
({r, g, b} = ret); ({ r, g, b } = ret);
} }
a = !isNullish(a) ? a : 255; a = !isNullish(a) ? a : 255;
fireChangeEvents.call(that, context || that); fireChangeEvents.call(that, context || that);
@@ -375,7 +375,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
val( val(
(!isNullish(init.a) ? 'a' : '') + 'hex', (!isNullish(init.a) ? 'a' : '') + 'hex',
!isNullish(init.a) !isNullish(init.a)
? {ahex: init.hex + ColorMethods.intToHex(init.a)} ? { ahex: init.hex + ColorMethods.intToHex(init.a) }
: init : init
); );
} else if (!isNullish(init.r) && !isNullish(init.g) && !isNullish(init.b)) { } 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} * @returns {module:jPicker.RGBA}
*/ */
hexToRgba (hex) { 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); hex = this.validateHex(hex);
let r = '00', g = '00', b = '00', a = '255'; let r = '00', g = '00', b = '00', a = '255';
if (hex.length === 6) hex += 'ff'; if (hex.length === 6) hex += 'ff';
@@ -476,7 +476,7 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
* @returns {module:jPicker.HSV} * @returns {module:jPicker.HSV}
*/ */
rgbToHsv (rgb) { 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; let min = 0, max = 0;
if (r >= g && r >= b) { if (r >= g && r >= b) {
max = r; max = r;
@@ -509,8 +509,8 @@ export const jPicker = /** @lends external:jQuery.jPicker */ {
* @returns {module:jPicker.RGB} * @returns {module:jPicker.RGB}
*/ */
hsvToRgb (hsv) { hsvToRgb (hsv) {
const rgb = {r: 0, g: 0, b: 0, a: 100}; const rgb = { r: 0, g: 0, b: 0, a: 100 };
let {h, s, v} = hsv; let { h, s, v } = hsv;
if (s === 0) { if (s === 0) {
if (v === 0) rgb.r = rgb.g = rgb.b = 0; if (v === 0) rgb.r = rgb.g = rgb.b = 0;
else rgb.r = rgb.g = rgb.b = (v * 255 / 100) | 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 * @function external:jQuery.fn.jPicker
* @see {@link external:jQuery.fn.$.fn.jPicker} * @see {@link external:jQuery.fn.$.fn.jPicker}
@@ -617,11 +617,11 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
} }
}); });
if (that.value === '') { if (that.value === '') {
settings.color.active = new Color({hex: null}); settings.color.active = new Color({ hex: null });
settings.color.current = new Color({hex: null}); settings.color.current = new Color({ hex: null });
} else if (ColorMethods.validateHex(that.value)) { } else if (ColorMethods.validateHex(that.value)) {
settings.color.active = 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')}); settings.color.current = new Color({ hex: that.value, a: settings.color.active.val('a') });
} }
} }
if (settings.window.expandable) { if (settings.window.expandable) {
@@ -646,7 +646,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
* @returns {void} * @returns {void}
*/ */
function setColorMode (colorMode) { function setColorMode (colorMode) {
const {active} = color, // local copies for YUI compressor const { active } = color, // local copies for YUI compressor
// {clientPath} = images, // {clientPath} = images,
hex = active.val('hex'); hex = active.val('hex');
let rgbMap, rgbBar; let rgbMap, rgbBar;
@@ -671,10 +671,10 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
setImgLoc.call(that, colorBarL6, 260); setImgLoc.call(that, colorBarL6, 260);
setAlpha.call(that, colorBarL6, 100); setAlpha.call(that, colorBarL6, 100);
}, 0); }, 0);
colorMap.range('all', {minX: 0, maxX: 100, minY: 0, maxY: 100}); colorMap.range('all', { minX: 0, maxX: 100, minY: 0, maxY: 100 });
colorBar.range('rangeY', {minY: 0, maxY: 360}); colorBar.range('rangeY', { minY: 0, maxY: 360 });
if (isNullish(active.val('ahex'))) break; 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); colorBar.val('y', 360 - active.val('h'), colorBar);
break; break;
case 's': case 's':
@@ -687,10 +687,10 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
setImgLoc.call(that, colorBarL6, 260); setImgLoc.call(that, colorBarL6, 260);
setAlpha.call(that, colorBarL6, 100); setAlpha.call(that, colorBarL6, 100);
}, 0); }, 0);
colorMap.range('all', {minX: 0, maxX: 360, minY: 0, maxY: 100}); colorMap.range('all', { minX: 0, maxX: 360, minY: 0, maxY: 100 });
colorBar.range('rangeY', {minY: 0, maxY: 100}); colorBar.range('rangeY', { minY: 0, maxY: 100 });
if (isNullish(active.val('ahex'))) break; 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); colorBar.val('y', 100 - active.val('s'), colorBar);
break; break;
case 'v': case 'v':
@@ -705,37 +705,37 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
setImgLoc.call(that, colorBarL6, 260); setImgLoc.call(that, colorBarL6, 260);
setAlpha.call(that, colorBarL6, 100); setAlpha.call(that, colorBarL6, 100);
}, 0); }, 0);
colorMap.range('all', {minX: 0, maxX: 360, minY: 0, maxY: 100}); colorMap.range('all', { minX: 0, maxX: 360, minY: 0, maxY: 100 });
colorBar.range('rangeY', {minY: 0, maxY: 100}); colorBar.range('rangeY', { minY: 0, maxY: 100 });
if (isNullish(active.val('ahex'))) break; 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); colorBar.val('y', 100 - active.val('v'), colorBar);
break; break;
case 'r': case 'r':
rgbMap = -1040; rgbMap = -1040;
rgbBar = -780; rgbBar = -780;
colorMap.range('all', {minX: 0, maxX: 255, minY: 0, maxY: 255}); colorMap.range('all', { minX: 0, maxX: 255, minY: 0, maxY: 255 });
colorBar.range('rangeY', {minY: 0, maxY: 255}); colorBar.range('rangeY', { minY: 0, maxY: 255 });
if (isNullish(active.val('ahex'))) break; 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); colorBar.val('y', 255 - active.val('r'), colorBar);
break; break;
case 'g': case 'g':
rgbMap = -1560; rgbMap = -1560;
rgbBar = -1820; rgbBar = -1820;
colorMap.range('all', {minX: 0, maxX: 255, minY: 0, maxY: 255}); colorMap.range('all', { minX: 0, maxX: 255, minY: 0, maxY: 255 });
colorBar.range('rangeY', {minY: 0, maxY: 255}); colorBar.range('rangeY', { minY: 0, maxY: 255 });
if (isNullish(active.val('ahex'))) break; 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); colorBar.val('y', 255 - active.val('g'), colorBar);
break; break;
case 'b': case 'b':
rgbMap = -2080; rgbMap = -2080;
rgbBar = -2860; rgbBar = -2860;
colorMap.range('all', {minX: 0, maxX: 255, minY: 0, maxY: 255}); colorMap.range('all', { minX: 0, maxX: 255, minY: 0, maxY: 255 });
colorBar.range('rangeY', {minY: 0, maxY: 255}); colorBar.range('rangeY', { minY: 0, maxY: 255 });
if (isNullish(active.val('ahex'))) break; 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); colorBar.val('y', 255 - active.val('b'), colorBar);
break; break;
case 'a': case 'a':
@@ -749,10 +749,10 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
setImgLoc.call(that, colorBarL6, 0); setImgLoc.call(that, colorBarL6, 0);
setAlpha.call(that, colorBarL6, 100); setAlpha.call(that, colorBarL6, 100);
}, 0); }, 0);
colorMap.range('all', {minX: 0, maxX: 360, minY: 0, maxY: 100}); colorMap.range('all', { minX: 0, maxX: 360, minY: 0, maxY: 100 });
colorBar.range('rangeY', {minY: 0, maxY: 255}); colorBar.range('rangeY', { minY: 0, maxY: 255 });
if (isNullish(active.val('ahex'))) break; 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); colorBar.val('y', 255 - active.val('a'), colorBar);
break; break;
default: default:
@@ -817,28 +817,28 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
* @returns {void} * @returns {void}
*/ */
function mapValueChanged (ui, context) { function mapValueChanged (ui, context) {
const {active} = color; const { active } = color;
if (context !== colorMap && isNullish(active.val())) return; if (context !== colorMap && isNullish(active.val())) return;
const xy = ui.val('all'); const xy = ui.val('all');
switch (settings.color.mode) { switch (settings.color.mode) {
case 'h': 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; break;
case 's': case 's':
case 'a': 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; break;
case 'v': 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; break;
case 'r': 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; break;
case 'g': 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; break;
case 'b': 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; break;
} }
} }
@@ -850,26 +850,26 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
* @returns {void} * @returns {void}
*/ */
function colorBarValueChanged (ui, context) { function colorBarValueChanged (ui, context) {
const {active} = color; const { active } = color;
if (context !== colorBar && isNullish(active.val())) return; if (context !== colorBar && isNullish(active.val())) return;
switch (settings.color.mode) { switch (settings.color.mode) {
case 'h': case 'h':
active.val('h', {h: 360 - ui.val('y')}, context); active.val('h', { h: 360 - ui.val('y') }, context);
break; break;
case 's': case 's':
active.val('s', {s: 100 - ui.val('y')}, context); active.val('s', { s: 100 - ui.val('y') }, context);
break; break;
case 'v': case 'v':
active.val('v', {v: 100 - ui.val('y')}, context); active.val('v', { v: 100 - ui.val('y') }, context);
break; break;
case 'r': case 'r':
active.val('r', {r: 255 - ui.val('y')}, context); active.val('r', { r: 255 - ui.val('y') }, context);
break; break;
case 'g': case 'g':
active.val('g', {g: 255 - ui.val('y')}, context); active.val('g', { g: 255 - ui.val('y') }, context);
break; break;
case 'b': case 'b':
active.val('b', {b: 255 - ui.val('y')}, context); active.val('b', { b: 255 - ui.val('y') }, context);
break; break;
case 'a': case 'a':
active.val('a', 255 - ui.val('y'), context); active.val('a', 255 - ui.val('y'), context);
@@ -888,29 +888,29 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
switch (settings.color.mode) { switch (settings.color.mode) {
case 'h': { case 'h': {
const sv = ui.val('sv'); 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; break;
} case 's': } case 's':
// Fall through // Fall through
case 'a': { case 'a': {
const hv = ui.val('hv'); 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; break;
} case 'v': { } case 'v': {
const hs = ui.val('hs'); 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; break;
} case 'r': { } case 'r': {
const bg = ui.val('bg'); 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; break;
} case 'g': { } case 'g': {
const br = ui.val('br'); 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; break;
} case 'b': { } case 'b': {
const rg = ui.val('rg'); 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; break;
} }
} }
@@ -963,7 +963,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
function updateMapVisuals (ui) { function updateMapVisuals (ui) {
switch (settings.color.mode) { switch (settings.color.mode) {
case 'h': 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; break;
case 's': case 's':
case 'a': { case 'a': {
@@ -999,14 +999,14 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
break; break;
} case 's': { } case 's': {
const hva = ui.val('hva'), 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')); setBG.call(that, colorBarDiv, saturatedColor.val('hex'));
setAlpha.call(that, colorBarL2, 100 - (!isNullish(hva) ? hva.v : 100)); setAlpha.call(that, colorBarL2, 100 - (!isNullish(hva) ? hva.v : 100));
setAlpha.call(that, colorBarL5, toFixedNumeric(((255 - ((hva && hva.a) || 0)) * 100) / 255, 4)); setAlpha.call(that, colorBarL5, toFixedNumeric(((255 - ((hva && hva.a) || 0)) * 100) / 255, 4));
break; break;
} case 'v': { } case 'v': {
const hsa = ui.val('hsa'), 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')); setBG.call(that, colorBarDiv, valueColor.val('hex'));
setAlpha.call(that, colorBarL5, toFixedNumeric(((255 - ((hsa && hsa.a) || 0)) * 100) / 255, 4)); setAlpha.call(that, colorBarL5, toFixedNumeric(((255 - ((hsa && hsa.a) || 0)) * 100) / 255, 4));
break; break;
@@ -1368,7 +1368,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
if (!that.querySelectorAll('div.jPicker.Container').length) { if (!that.querySelectorAll('div.jPicker.Container').length) {
document.body.insertBefore(container, document.body.firstChild); document.body.insertBefore(container, document.body.firstChild);
} else { } else {
that.querySelector('div.jPicker.Container:last').insertAdjacentElement('afterend', container) that.querySelector('div.jPicker.Container:last').insertAdjacentElement('afterend', container);
} }
container.addEventListener('mousedown', function () { container.addEventListener('mousedown', function () {
container.style.zIndex = 20; 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++) { for (let i = 0; i < color.quickList.length; i++) {
/* if default colors are hex strings, change them to color objects */ /* if default colors are hex strings, change them to color objects */
if ((typeof (color.quickList[i])).toString().toLowerCase() === 'string') { 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'); const alpha = color.quickList[i].val('a');
let ahex = color.quickList[i].val('ahex'); let ahex = color.quickList[i].val('ahex');
@@ -1520,7 +1520,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
iconAlpha = that.icon.querySelector('.Alpha'); iconAlpha = that.icon.querySelector('.Alpha');
setImg.call(that, iconAlpha, images.clientPath + 'bar-opacity.png'); setImg.call(that, iconAlpha, images.clientPath + 'bar-opacity.png');
setAlpha.call(that, iconAlpha, toFixedNumeric(((255 - (!isNullish(all) ? all.a : 0)) * 100) / 255, 4)); 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.style.backgroundImage = 'url(\'' + images.clientPath + images.picker.file + '\')';
iconImage.addEventListener('click', iconImageClicked); iconImage.addEventListener('click', iconImageClicked);
if (win.bindToInput && win.updateInputColor) { 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 = { const color = {
active: (typeof settings.color.active).toString().toLowerCase() === 'string' 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.substring(0, 6) + 'ff'
: settings.color.active : 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')
? settings.color.active.val('ahex').substring(0, 6) + 'ff' ? settings.color.active.val('ahex').substring(0, 6) + 'ff'
: settings.color.active.val('ahex') : settings.color.active.val('ahex')
}), }),
current: (typeof settings.color.active).toString().toLowerCase() === 'string' 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.substring(0, 6) + 'ff'
: settings.color.active}) : 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')
? settings.color.active.val('ahex').substring(0, 6) + 'ff' ? settings.color.active.val('ahex').substring(0, 6) + 'ff'
: settings.color.active.val('ahex') : settings.color.active.val('ahex')
@@ -1770,79 +1770,79 @@ export const jPickerDefaults = {
}, },
color: { color: {
mode: 'h', mode: 'h',
active: new Color({ahex: '#ffcc00ff'}), active: new Color({ ahex: '#ffcc00ff' }),
quickList: [ quickList: [
new Color({h: 360, s: 33, v: 100}), new Color({ h: 360, s: 33, v: 100 }),
new Color({h: 360, s: 66, 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: 100 }),
new Color({h: 360, s: 100, v: 75}), new Color({ h: 360, s: 100, v: 75 }),
new Color({h: 360, s: 100, v: 50}), new Color({ h: 360, s: 100, v: 50 }),
new Color({h: 180, s: 0, v: 100}), new Color({ h: 180, s: 0, v: 100 }),
new Color({h: 30, s: 33, v: 100}), new Color({ h: 30, s: 33, v: 100 }),
new Color({h: 30, s: 66, 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: 100 }),
new Color({h: 30, s: 100, v: 75}), new Color({ h: 30, s: 100, v: 75 }),
new Color({h: 30, s: 100, v: 50}), new Color({ h: 30, s: 100, v: 50 }),
new Color({h: 180, s: 0, v: 90}), new Color({ h: 180, s: 0, v: 90 }),
new Color({h: 60, s: 33, v: 100}), new Color({ h: 60, s: 33, v: 100 }),
new Color({h: 60, s: 66, 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: 100 }),
new Color({h: 60, s: 100, v: 75}), new Color({ h: 60, s: 100, v: 75 }),
new Color({h: 60, s: 100, v: 50}), new Color({ h: 60, s: 100, v: 50 }),
new Color({h: 180, s: 0, v: 80}), new Color({ h: 180, s: 0, v: 80 }),
new Color({h: 90, s: 33, v: 100}), new Color({ h: 90, s: 33, v: 100 }),
new Color({h: 90, s: 66, 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: 100 }),
new Color({h: 90, s: 100, v: 75}), new Color({ h: 90, s: 100, v: 75 }),
new Color({h: 90, s: 100, v: 50}), new Color({ h: 90, s: 100, v: 50 }),
new Color({h: 180, s: 0, v: 70}), new Color({ h: 180, s: 0, v: 70 }),
new Color({h: 120, s: 33, v: 100}), new Color({ h: 120, s: 33, v: 100 }),
new Color({h: 120, s: 66, 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: 100 }),
new Color({h: 120, s: 100, v: 75}), new Color({ h: 120, s: 100, v: 75 }),
new Color({h: 120, s: 100, v: 50}), new Color({ h: 120, s: 100, v: 50 }),
new Color({h: 180, s: 0, v: 60}), new Color({ h: 180, s: 0, v: 60 }),
new Color({h: 150, s: 33, v: 100}), new Color({ h: 150, s: 33, v: 100 }),
new Color({h: 150, s: 66, 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: 100 }),
new Color({h: 150, s: 100, v: 75}), new Color({ h: 150, s: 100, v: 75 }),
new Color({h: 150, s: 100, v: 50}), new Color({ h: 150, s: 100, v: 50 }),
new Color({h: 180, s: 0, v: 50}), new Color({ h: 180, s: 0, v: 50 }),
new Color({h: 180, s: 33, v: 100}), new Color({ h: 180, s: 33, v: 100 }),
new Color({h: 180, s: 66, 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: 100 }),
new Color({h: 180, s: 100, v: 75}), new Color({ h: 180, s: 100, v: 75 }),
new Color({h: 180, s: 100, v: 50}), new Color({ h: 180, s: 100, v: 50 }),
new Color({h: 180, s: 0, v: 40}), new Color({ h: 180, s: 0, v: 40 }),
new Color({h: 210, s: 33, v: 100}), new Color({ h: 210, s: 33, v: 100 }),
new Color({h: 210, s: 66, 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: 100 }),
new Color({h: 210, s: 100, v: 75}), new Color({ h: 210, s: 100, v: 75 }),
new Color({h: 210, s: 100, v: 50}), new Color({ h: 210, s: 100, v: 50 }),
new Color({h: 180, s: 0, v: 30}), new Color({ h: 180, s: 0, v: 30 }),
new Color({h: 240, s: 33, v: 100}), new Color({ h: 240, s: 33, v: 100 }),
new Color({h: 240, s: 66, 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: 100 }),
new Color({h: 240, s: 100, v: 75}), new Color({ h: 240, s: 100, v: 75 }),
new Color({h: 240, s: 100, v: 50}), new Color({ h: 240, s: 100, v: 50 }),
new Color({h: 180, s: 0, v: 20}), new Color({ h: 180, s: 0, v: 20 }),
new Color({h: 270, s: 33, v: 100}), new Color({ h: 270, s: 33, v: 100 }),
new Color({h: 270, s: 66, 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: 100 }),
new Color({h: 270, s: 100, v: 75}), new Color({ h: 270, s: 100, v: 75 }),
new Color({h: 270, s: 100, v: 50}), new Color({ h: 270, s: 100, v: 50 }),
new Color({h: 180, s: 0, v: 10}), new Color({ h: 180, s: 0, v: 10 }),
new Color({h: 300, s: 33, v: 100}), new Color({ h: 300, s: 33, v: 100 }),
new Color({h: 300, s: 66, 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: 100 }),
new Color({h: 300, s: 100, v: 75}), new Color({ h: 300, s: 100, v: 75 }),
new Color({h: 300, s: 100, v: 50}), new Color({ h: 300, s: 100, v: 50 }),
new Color({h: 180, s: 0, v: 0}), new Color({ h: 180, s: 0, v: 0 }),
new Color({h: 330, s: 33, v: 100}), new Color({ h: 330, s: 33, v: 100 }),
new Color({h: 330, s: 66, 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: 100 }),
new Color({h: 330, s: 100, v: 75}), new Color({ h: 330, s: 100, v: 75 }),
new Color({h: 330, s: 100, v: 50}), new Color({ h: 330, s: 100, v: 50 }),
new Color() new Color()
] ]
}, },

View File

@@ -51,7 +51,7 @@ export class ToolButton extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
// locate the component // locate the component
this.$div = this._shadowRoot.querySelector('div'); this.$div = this._shadowRoot.querySelector('div');
@@ -62,7 +62,7 @@ export class ToolButton extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['title', 'src', 'pressed', 'disabled', 'size', 'style']; return [ 'title', 'src', 'pressed', 'disabled', 'size', 'style' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback

View File

@@ -1,5 +1,5 @@
/* eslint-disable max-len */ /* 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'; import PaintBox from './PaintBox.js';
const template = document.createElement('template'); const template = document.createElement('template');
@@ -344,7 +344,7 @@ div.jGraduate_Swatch {
} }
div.jGraduate_GradContainer { div.jGraduate_GradContainer {
border: 2px inset #EEE; border: 2px inset #EEE;
background-image: url(../images/map-opacity.png); background-image: url(./components/jgraduate/images/map-opacity.png);
background-position: 0px 0px; background-position: 0px 0px;
height: 256px; height: 256px;
width: 256px; width: 256px;
@@ -658,7 +658,7 @@ export class SeColorPicker extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
this.$logo = this._shadowRoot.getElementById('logo'); this.$logo = this._shadowRoot.getElementById('logo');
this.$label = this._shadowRoot.getElementById('label'); this.$label = this._shadowRoot.getElementById('label');
@@ -672,7 +672,7 @@ export class SeColorPicker extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['label', 'src', 'type']; return [ 'label', 'src', 'type' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback
@@ -754,9 +754,9 @@ export class SeColorPicker extends HTMLElement {
update (svgCanvas, selectedElement, apply) { update (svgCanvas, selectedElement, apply) {
const paint = this.paintBox.update(svgCanvas, selectedElement); const paint = this.paintBox.update(svgCanvas, selectedElement);
if (paint && apply) { if (paint && apply) {
const changeEvent = new CustomEvent('change', {detail: { const changeEvent = new CustomEvent('change', { detail: {
paint paint
}}); } });
this.dispatchEvent(changeEvent); this.dispatchEvent(changeEvent);
} }
} }
@@ -775,21 +775,21 @@ export class SeColorPicker extends HTMLElement {
connectedCallback () { connectedCallback () {
this.paintBox = new PaintBox(this.$block, this.type); this.paintBox = new PaintBox(this.$block, this.type);
this.$picker.addEventListener('click', () => { this.$picker.addEventListener('click', () => {
let {paint} = this.paintBox; let { paint } = this.paintBox;
jGraduateMethod( jGraduateMethod(
this.$color_picker, this.$color_picker,
{ {
images: {clientPath: './components/jgraduate/images/'}, images: { clientPath: './components/jgraduate/images/' },
paint, paint,
window: {pickerTitle: this.label}, window: { pickerTitle: this.label },
newstop: 'inverse' newstop: 'inverse'
}, },
(p) => { (p) => {
paint = new jGraduate.Paint(p); paint = new jGraduate.Paint(p);
this.setPaint(paint); this.setPaint(paint);
const changeEvent = new CustomEvent('change', {detail: { const changeEvent = new CustomEvent('change', { detail: {
paint paint
}}); } });
this.dispatchEvent(changeEvent); this.dispatchEvent(changeEvent);
this.$color_picker.style.display = 'none'; this.$color_picker.style.display = 'none';
}, },

View File

@@ -1,7 +1,7 @@
import ListComboBox from 'elix/define/ListComboBox.js'; import ListComboBox from 'elix/define/ListComboBox.js';
import {defaultState} from 'elix/src/base/internal.js'; import { defaultState } 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 {internal} from 'elix'; import { internal } from 'elix';
import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js'; import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js';
/** /**
@@ -40,7 +40,7 @@ class Dropdown extends ListComboBox {
::slotted(*) { ::slotted(*) {
padding: 4px; padding: 4px;
background: #E8E8E8; background: #E8E8E8;
border: 1px solid #B0B0B0; border: 1px solid #5a6162;
width: 100%; width: 100%;
} }
[part~="popup"] { [part~="popup"] {
@@ -56,7 +56,7 @@ class Dropdown extends ListComboBox {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['title', 'src', 'inputsize', 'value']; return [ 'title', 'src', 'inputsize', 'value' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback
@@ -105,7 +105,7 @@ class Dropdown extends ListComboBox {
e.preventDefault(); e.preventDefault();
const value = e.detail?.closeResult?.getAttribute('value'); const value = e.detail?.closeResult?.getAttribute('value');
if (value) { if (value) {
const closeEvent = new CustomEvent('change', {detail: {value}}); const closeEvent = new CustomEvent('change', { detail: { value } });
this.dispatchEvent(closeEvent); this.dispatchEvent(closeEvent);
} }
}); });
@@ -123,7 +123,7 @@ class Dropdown extends ListComboBox {
* @returns {void} * @returns {void}
*/ */
set src (src) { set src (src) {
this[internal.setState]({src}); this[internal.setState]({ src });
} }
/** /**
* @function inputsize * @function inputsize
@@ -137,7 +137,7 @@ class Dropdown extends ListComboBox {
* @returns {void} * @returns {void}
*/ */
set inputsize (inputsize) { set inputsize (inputsize) {
this[internal.setState]({inputsize}); this[internal.setState]({ inputsize });
} }
/** /**
* @function value * @function value
@@ -151,7 +151,7 @@ class Dropdown extends ListComboBox {
* @returns {void} * @returns {void}
*/ */
set value (value) { set value (value) {
this[internal.setState]({value}); this[internal.setState]({ value });
} }
} }

View File

@@ -67,7 +67,7 @@ template.innerHTML = `
.menu-item { .menu-item {
line-height: 1em; line-height: 1em;
padding: 0.5em; padding: 0.5em;
border: 1px solid #B0B0B0; border: 1px solid #5a6162;
background: #E8E8E8; background: #E8E8E8;
margin-bottom: -1px; margin-bottom: -1px;
white-space: nowrap; white-space: nowrap;
@@ -107,7 +107,7 @@ export class ExplorerButton extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
// locate the component // locate the component
this.$button = this._shadowRoot.querySelector('.menu-button'); this.$button = this._shadowRoot.querySelector('.menu-button');
@@ -124,7 +124,7 @@ export class ExplorerButton extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['title', 'pressed', 'disabled', 'lib', 'src']; return [ 'title', 'pressed', 'disabled', 'lib', 'src' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback
@@ -160,7 +160,7 @@ export class ExplorerButton extends HTMLElement {
try { try {
const response = await fetch(`${newValue}index.json`); const response = await fetch(`${newValue}index.json`);
const json = await response.json(); const json = await response.json();
const {lib} = json; const { lib } = json;
this.$menu.innerHTML = lib.map((menu, i) => ( this.$menu.innerHTML = lib.map((menu, i) => (
`<div data-menu="${menu}" class="menu-item ${(i === 0) ? 'pressed' : ''} ">${menu}</div>` `<div data-menu="${menu}" class="menu-item ${(i === 0) ? 'pressed' : ''} ">${menu}</div>`
)).join(''); )).join('');
@@ -295,9 +295,9 @@ export class ExplorerButton extends HTMLElement {
const size = json.size ?? 300; const size = json.size ?? 300;
const fill = json.fill ? '#333' : 'none'; const fill = json.fill ? '#333' : 'none';
const off = size * 0.05; 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); 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(` const encoded = btoa(`
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"> <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> <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 () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
// locate the component // locate the component
this.$button = this._shadowRoot.querySelector('.menu-button'); this.$button = this._shadowRoot.querySelector('.menu-button');
@@ -105,7 +105,7 @@ export class FlyingButton extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['title', 'pressed', 'disabled', 'opened']; return [ 'title', 'pressed', 'disabled', 'opened' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback

View File

@@ -35,7 +35,7 @@ export class SEInput extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
// locate the component // locate the component
this.$img = this._shadowRoot.querySelector('img'); this.$img = this._shadowRoot.querySelector('img');
@@ -48,7 +48,7 @@ export class SEInput extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['value', 'label', 'src', 'size']; return [ 'value', 'label', 'src', 'size' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback

View File

@@ -35,7 +35,7 @@ export class SeList extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
this.$dropdown = this._shadowRoot.querySelector('elix-dropdown-list'); this.$dropdown = this._shadowRoot.querySelector('elix-dropdown-list');
this.$label = this._shadowRoot.querySelector('label'); this.$label = this._shadowRoot.querySelector('label');
@@ -45,7 +45,7 @@ export class SeList extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['label', 'width', 'height']; return [ 'label', 'width', 'height' ];
} }
/** /**
@@ -128,7 +128,7 @@ export class SeList extends HTMLElement {
e.preventDefault(); e.preventDefault();
if (e?.detail?.selectedIndex !== undefined) { if (e?.detail?.selectedIndex !== undefined) {
const value = this.$dropdown.selectedItem.getAttribute('value'); 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.dispatchEvent(closeEvent);
currentObj.value = value; currentObj.value = value;
} }

View File

@@ -25,7 +25,7 @@ export class SeListItem extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
this.$menuitem = this._shadowRoot.querySelector('elix-option'); this.$menuitem = this._shadowRoot.querySelector('elix-option');
this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark'); this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark');
@@ -36,7 +36,7 @@ export class SeListItem extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['option']; return [ 'option' ];
} }
/** /**

View File

@@ -39,7 +39,7 @@ export class SeMenu extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
this.$menu = this._shadowRoot.querySelector('elix-menu-button'); this.$menu = this._shadowRoot.querySelector('elix-menu-button');
this.$label = this.$menu.shadowRoot.querySelector('#popupToggle').shadowRoot; this.$label = this.$menu.shadowRoot.querySelector('#popupToggle').shadowRoot;
@@ -49,7 +49,7 @@ export class SeMenu extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['label', 'src']; return [ 'label', 'src' ];
} }
/** /**

View File

@@ -22,7 +22,7 @@ export class SeMenuItem extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
this.$img = this._shadowRoot.querySelector('img'); this.$img = this._shadowRoot.querySelector('img');
this.$label = this._shadowRoot.querySelector('span'); this.$label = this._shadowRoot.querySelector('span');
@@ -35,7 +35,7 @@ export class SeMenuItem extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['label', 'src']; return [ 'label', 'src' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback

View File

@@ -92,21 +92,21 @@ export class SEPalette extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
this.$strip = this._shadowRoot.querySelector('#js-se-palette'); this.$strip = this._shadowRoot.querySelector('#js-se-palette');
palette.forEach((rgb) => { palette.forEach((rgb) => {
const newDiv = document.createElement('div'); const newDiv = document.createElement('div');
newDiv.classList.add('square'); newDiv.classList.add('square');
if(rgb === 'none') { 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.src = `data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgY2xhc3M9InN2Z19pY29uIj48c3ZnIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgICA8bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiNkNDAwMDAiIGlkPSJzdmdfOTAiIHkyPSIyNCIgeDI9IjI0IiB5MT0iMCIgeDE9IjAiLz4KICAgIDxsaW5lIGlkPSJzdmdfOTIiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2Q0MDAwMCIgeTI9IjI0IiB4Mj0iMCIgeTE9IjAiIHgxPSIyNCIvPgogIDwvc3ZnPjwvc3ZnPg==`;
img.style.width = "15px"; img.style.width = "15px";
img.style.height = "15px"; img.style.height = "15px";
newDiv.append(img); newDiv.append(img);
} else { } else {
newDiv.style.backgroundColor = rgb; newDiv.style.backgroundColor = rgb;
} }
newDiv.dataset.rgb = rgb; newDiv.dataset.rgb = rgb;
newDiv.addEventListener('click', (evt) => { newDiv.addEventListener('click', (evt) => {
evt.preventDefault(); evt.preventDefault();
@@ -117,7 +117,7 @@ export class SEPalette extends HTMLElement {
if (color === 'none' || color === 'transparent' || color === 'initial') { if (color === 'none' || color === 'transparent' || color === 'initial') {
color = 'none'; 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.dispatchEvent(paletteEvent);
}); });
this.$strip.append(newDiv); this.$strip.append(newDiv);

View File

@@ -1,5 +1,5 @@
import {template} from 'elix/src/base/internal.js'; import { template } from 'elix/src/base/internal.js';
import {fragmentFrom} from 'elix/src/core/htmlLiterals.js'; import { fragmentFrom } from 'elix/src/core/htmlLiterals.js';
import PlainButton from 'elix/src/plain/PlainButton.js'; import PlainButton from 'elix/src/plain/PlainButton.js';
/** /**

View File

@@ -1,5 +1,5 @@
import PlainMenuButton from 'elix/src/plain/PlainMenuButton.js'; 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'; import sePlainBorderButton from './sePlainBorderButton.js';
/** /**

View File

@@ -19,7 +19,7 @@ template.innerHTML = `
elix-number-spin-box { elix-number-spin-box {
background-color: var(--input-color); background-color: var(--input-color);
border-radius: 3px; border-radius: 3px;
height: 20px !important; height: 20px;
margin-top: 1px; margin-top: 1px;
vertical-align: top; vertical-align: top;
} }
@@ -49,7 +49,7 @@ export class SESpinInput extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
// locate the component // locate the component
this.$img = this._shadowRoot.querySelector('img'); this.$img = this._shadowRoot.querySelector('img');
@@ -62,7 +62,7 @@ export class SESpinInput extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['value', 'label', 'src', 'size', 'min', 'max', 'step']; return [ 'value', 'label', 'src', 'size', 'min', 'max', 'step' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback

View File

@@ -1,6 +1,6 @@
import ListComboBox from 'elix/define/ListComboBox.js'; import ListComboBox from 'elix/define/ListComboBox.js';
import * as internal from 'elix/src/base/internal.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'; import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js';
/** /**
@@ -66,7 +66,7 @@ class Zoom extends ListComboBox {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['title', 'src', 'inputsize', 'value']; return [ 'title', 'src', 'inputsize', 'value' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback
@@ -115,7 +115,7 @@ class Zoom extends ListComboBox {
e.preventDefault(); e.preventDefault();
const value = e.detail?.closeResult?.getAttribute('value'); const value = e.detail?.closeResult?.getAttribute('value');
if (value) { if (value) {
const closeEvent = new CustomEvent('change', {detail: {value}}); const closeEvent = new CustomEvent('change', { detail: { value } });
this.dispatchEvent(closeEvent); this.dispatchEvent(closeEvent);
} }
}); });
@@ -133,7 +133,7 @@ class Zoom extends ListComboBox {
* @returns {void} * @returns {void}
*/ */
set src (src) { set src (src) {
this[internal.setState]({src}); this[internal.setState]({ src });
} }
/** /**
* @function inputsize * @function inputsize
@@ -147,7 +147,7 @@ class Zoom extends ListComboBox {
* @returns {void} * @returns {void}
*/ */
set inputsize (inputsize) { set inputsize (inputsize) {
this[internal.setState]({inputsize}); this[internal.setState]({ inputsize });
} }
/** /**
* @function value * @function value
@@ -161,7 +161,7 @@ class Zoom extends ListComboBox {
* @returns {void} * @returns {void}
*/ */
set value (value) { 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"'); 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 // 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; contextMenuExtensions[menuItem.id] = menuItem;
// TODO: Need to consider how to handle custom enable/disable behavior // 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 PlainAlertDialog from 'elix/src/plain/PlainAlertDialog.js';
import {template} from 'elix/src/base/internal.js'; import { template } from 'elix/src/base/internal.js';
import {fragmentFrom} from 'elix/src/core/htmlLiterals.js'; import { fragmentFrom } from 'elix/src/core/htmlLiterals.js';
/** /**
* @class SePlainAlertDialog * @class SePlainAlertDialog
@@ -52,7 +52,7 @@ export default class SePlainAlertDialog extends PlainAlertDialog {
background: #DDD; background: #DDD;
overflow: auto; overflow: auto;
text-align: left; text-align: left;
border: 1px solid #B0B0B0; border: 1px solid #5a6162;
padding: 1em; padding: 1em;
border-radius: 5px; border-radius: 5px;
-moz-border-radius: 5px; -moz-border-radius: 5px;

View File

@@ -127,7 +127,7 @@ export class SeCMenuDialog extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
this._workarea = document.getElementById('workarea'); this._workarea = document.getElementById('workarea');
this.$dialog = this._shadowRoot.querySelector('#cmenu_canvas'); this.$dialog = this._shadowRoot.querySelector('#cmenu_canvas');
@@ -148,7 +148,7 @@ export class SeCMenuDialog extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['disableallmenu', 'enablemenuitems', 'disablemenuitems']; return [ 'disableallmenu', 'enablemenuitems', 'disablemenuitems' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback
@@ -251,9 +251,9 @@ export class SeCMenuDialog extends HTMLElement {
} }
}; };
const onMenuClickHandler = (e, action) => { const onMenuClickHandler = (e, action) => {
const triggerEvent = new CustomEvent('change', {detail: { const triggerEvent = new CustomEvent('change', { detail: {
trigger: action trigger: action
}}); } });
this.dispatchEvent(triggerEvent); this.dispatchEvent(triggerEvent);
}; };
this._workarea.addEventListener('contextmenu', onMenuOpenHandler); this._workarea.addEventListener('contextmenu', onMenuOpenHandler);

View File

@@ -80,7 +80,7 @@ export class SeCMenuLayerDialog extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
this.source = ''; this.source = '';
this._workarea = undefined; this._workarea = undefined;
@@ -96,7 +96,7 @@ export class SeCMenuLayerDialog extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['value', 'leftclick']; return [ 'value', 'leftclick' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback
@@ -168,10 +168,10 @@ export class SeCMenuLayerDialog extends HTMLElement {
} }
}; };
const onMenuClickHandler = (e, action, id) => { const onMenuClickHandler = (e, action, id) => {
const triggerEvent = new CustomEvent('change', {detail: { const triggerEvent = new CustomEvent('change', { detail: {
trigger: action, trigger: action,
source: id source: id
}}); } });
this.dispatchEvent(triggerEvent); this.dispatchEvent(triggerEvent);
current.$dialog.style.display = 'none'; current.$dialog.style.display = 'none';
}; };

View File

@@ -71,7 +71,8 @@ template.innerHTML = `
} }
#svg_prefs #svg_prefs_container { #svg_prefs #svg_prefs_container {
padding: 10px; padding: 10px;
background-color: #B0B0B0; background-color: #5a6162;
color: #c5c5c5;
border: 1px outset #777; border: 1px outset #777;
opacity: 1.0; opacity: 1.0;
font-family: Verdana, Helvetica, sans-serif; font-family: Verdana, Helvetica, sans-serif;
@@ -83,6 +84,17 @@ template.innerHTML = `
margin-left: 1em; margin-left: 1em;
overflow: auto; 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 { #svg_prefs #svg_docprops_prefs {
float: left; float: left;
@@ -138,11 +150,9 @@ template.innerHTML = `
<div id="svg_prefs_container"> <div id="svg_prefs_container">
<div id="tool_prefs_back" class="toolbar_button"> <div id="tool_prefs_back" class="toolbar_button">
<button id="tool_prefs_save"> <button id="tool_prefs_save">
<img class="svg_icon" src="./images/ok.svg" alt="icon" width="16" height="16" />
OK OK
</button> </button>
<button id="tool_prefs_cancel"> <button id="tool_prefs_cancel">
<img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />
Cancel Cancel
</button> </button>
</div> </div>
@@ -241,8 +251,8 @@ export class SeEditPrefsDialog extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // create the shadowDom and insert the template
this.colorBlocks = ['#FFF', '#888', '#000', 'chessboard']; this.colorBlocks = [ '#FFF', '#888', '#000', 'chessboard' ];
this._shadowRoot = this.attachShadow({mode: 'open'}); this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true)); this._shadowRoot.append(template.content.cloneNode(true));
this.$dialog = this._shadowRoot.querySelector('#svg_prefs'); this.$dialog = this._shadowRoot.querySelector('#svg_prefs');
this.$saveBtn = this._shadowRoot.querySelector('#tool_prefs_save'); this.$saveBtn = this._shadowRoot.querySelector('#tool_prefs_save');
@@ -263,7 +273,7 @@ export class SeEditPrefsDialog extends HTMLElement {
*/ */
static get observedAttributes () { static get observedAttributes () {
// eslint-disable-next-line max-len // 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 * @function attributeChangedCallback
@@ -484,14 +494,14 @@ export class SeEditPrefsDialog extends HTMLElement {
*/ */
connectedCallback () { connectedCallback () {
const onCancelHandler = () => { const onCancelHandler = () => {
const closeEvent = new CustomEvent('change', {detail: { const closeEvent = new CustomEvent('change', { detail: {
dialog: 'closed' dialog: 'closed'
}}); } });
this.dispatchEvent(closeEvent); this.dispatchEvent(closeEvent);
}; };
const onSaveHandler = () => { const onSaveHandler = () => {
const color = this.$bgBlocks.querySelector('.cur_background').dataset.bgColor || '#FFF'; 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, lang: this.$langSelect.value,
dialog: 'close', dialog: 'close',
iconsize: this.$iconSize.value, iconsize: this.$iconSize.value,
@@ -501,7 +511,7 @@ export class SeEditPrefsDialog extends HTMLElement {
gridsnappingstep: this.$gridSnappingStep.value, gridsnappingstep: this.$gridSnappingStep.value,
showrulers: this.$showRulers.checked, showrulers: this.$showRulers.checked,
baseunit: this.$baseUnit.value baseunit: this.$baseUnit.value
}}); } });
this.dispatchEvent(closeEvent); this.dispatchEvent(closeEvent);
}; };
// Set up editor background functionality // Set up editor background functionality

View File

@@ -6,10 +6,10 @@ template.innerHTML = `
#dialog_content { #dialog_content {
margin: 10px 10px 5px 10px; margin: 10px 10px 5px 10px;
background: #DDD; background: #5a6162;
overflow: auto; overflow: auto;
text-align: left; text-align: left;
border: 1px solid #B0B0B0; border: 1px solid #c8c8c8;
} }
#dialog_content p, #dialog_content select, #dialog_content label { #dialog_content p, #dialog_content select, #dialog_content label {
@@ -24,7 +24,7 @@ template.innerHTML = `
top: 50%; top: 50%;
max-width: 400px; max-width: 400px;
z-index: 50001; z-index: 50001;
background: #CCC; background: #5a6162;
border: 1px outset #777; border: 1px outset #777;
font-family:Verdana,Helvetica,sans-serif; font-family:Verdana,Helvetica,sans-serif;
font-size:0.8em; font-size:0.8em;
@@ -72,11 +72,9 @@ template.innerHTML = `
</div> </div>
<div id="dialog_buttons"> <div id="dialog_buttons">
<button id="export_ok"> <button id="export_ok">
<img class="svg_icon" src="./images/ok.svg" alt="icon" width="16" height="16" />
Ok Ok
</button> </button>
<button id="export_cancel"> <button id="export_cancel">
<img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />
Cancel Cancel
</button> </button>
</div> </div>
@@ -93,7 +91,7 @@ export class SeExportDialog extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
this.$dialog = this._shadowRoot.querySelector('#export_box'); this.$dialog = this._shadowRoot.querySelector('#export_box');
this.$okBtn = this._shadowRoot.querySelector('#export_ok'); this.$okBtn = this._shadowRoot.querySelector('#export_ok');
@@ -108,7 +106,7 @@ export class SeExportDialog extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['dialog']; return [ 'dialog' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback
@@ -163,11 +161,11 @@ export class SeExportDialog extends HTMLElement {
if (action === 'cancel') { if (action === 'cancel') {
document.getElementById('se-export-dialog').setAttribute('dialog', 'close'); document.getElementById('se-export-dialog').setAttribute('dialog', 'close');
} else { } else {
const triggerEvent = new CustomEvent('change', {detail: { const triggerEvent = new CustomEvent('change', { detail: {
trigger: action, trigger: action,
imgType: this.$exportOption.value, imgType: this.$exportOption.value,
quality: this.value quality: this.value
}}); } });
this.dispatchEvent(triggerEvent); 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'); const template = document.createElement('template');
template.innerHTML = ` template.innerHTML = `
@@ -16,7 +16,8 @@ template.innerHTML = `
} }
#svg_docprops #svg_docprops_container { #svg_docprops #svg_docprops_container {
padding: 10px; padding: 10px;
background-color: #B0B0B0; background-color: #5a6162;
color: #c5c5c5;
border: 1px outset #777; border: 1px outset #777;
opacity: 1.0; opacity: 1.0;
font-family: Verdana, Helvetica, sans-serif; font-family: Verdana, Helvetica, sans-serif;
@@ -126,7 +127,7 @@ export class SeImgPropDialog extends HTMLElement {
super(); super();
// create the shadowDom and insert the template // create the shadowDom and insert the template
this.eventlisten = false; this.eventlisten = false;
this._shadowRoot = this.attachShadow({mode: 'open'}); this._shadowRoot = this.attachShadow({ mode: 'open' });
this._shadowRoot.append(template.content.cloneNode(true)); this._shadowRoot.append(template.content.cloneNode(true));
this.$saveBtn = this._shadowRoot.querySelector('#tool_docprops_save'); this.$saveBtn = this._shadowRoot.querySelector('#tool_docprops_save');
this.$cancelBtn = this._shadowRoot.querySelector('#tool_docprops_cancel'); this.$cancelBtn = this._shadowRoot.querySelector('#tool_docprops_cancel');
@@ -143,7 +144,7 @@ export class SeImgPropDialog extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['title', 'width', 'height', 'save', 'dialog', 'embed']; return [ 'title', 'width', 'height', 'save', 'dialog', 'embed' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback
@@ -342,22 +343,22 @@ export class SeImgPropDialog extends HTMLElement {
if (this.$imageOptRef.getAttribute('checked') === 'true') { if (this.$imageOptRef.getAttribute('checked') === 'true') {
saveOpt = 'ref'; saveOpt = 'ref';
} }
const closeEvent = new CustomEvent('change', {detail: { const closeEvent = new CustomEvent('change', { detail: {
title: this.$canvasTitle.value, title: this.$canvasTitle.value,
w: this.$canvasWidth.value, w: this.$canvasWidth.value,
h: this.$canvasHeight.value, h: this.$canvasHeight.value,
save: saveOpt, save: saveOpt,
dialog: 'close' dialog: 'close'
}}); } });
this.$canvasWidth.removeAttribute('disabled'); this.$canvasWidth.removeAttribute('disabled');
this.$canvasHeight.removeAttribute('disabled'); this.$canvasHeight.removeAttribute('disabled');
this.$resolution.selectedIndex = 0; this.$resolution.selectedIndex = 0;
this.dispatchEvent(closeEvent); this.dispatchEvent(closeEvent);
}; };
const onCancelHandler = () => { const onCancelHandler = () => {
const closeEvent = new CustomEvent('change', {detail: { const closeEvent = new CustomEvent('change', { detail: {
dialog: 'closed' dialog: 'closed'
}}); } });
this.$canvasWidth.removeAttribute('disabled'); this.$canvasWidth.removeAttribute('disabled');
this.$canvasHeight.removeAttribute('disabled'); this.$canvasHeight.removeAttribute('disabled');
this.$resolution.selectedIndex = 0; this.$resolution.selectedIndex = 0;

View File

@@ -3,7 +3,7 @@ import SePlainAlertDialog from './SePlainAlertDialog.js';
const seAlert = (text) => { const seAlert = (text) => {
const dialog = new SePlainAlertDialog(); const dialog = new SePlainAlertDialog();
dialog.textContent = text; dialog.textContent = text;
dialog.choices = ['Ok']; dialog.choices = [ 'Ok' ];
dialog.open(); dialog.open();
}; };

View File

@@ -3,7 +3,7 @@ import SePlainAlertDialog from './SePlainAlertDialog.js';
const seConfirm = async (text, choices) => { const seConfirm = async (text, choices) => {
const dialog = new SePlainAlertDialog(); const dialog = new SePlainAlertDialog();
dialog.textContent = text; dialog.textContent = text;
dialog.choices = (choices === undefined) ? ['Ok', 'Cancel'] : choices; dialog.choices = (choices === undefined) ? [ 'Ok', 'Cancel' ] : choices;
dialog.open(); dialog.open();
const response = await dialog.whenClosed(); const response = await dialog.whenClosed();
return response.choice; return response.choice;

View File

@@ -9,7 +9,7 @@ export class SePromptDialog extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({mode: 'open'}); this._shadowRoot = this.attachShadow({ mode: 'open' });
this.dialog = new SePlainAlertDialog(); this.dialog = new SePlainAlertDialog();
} }
/** /**
@@ -17,7 +17,7 @@ export class SePromptDialog extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['title', 'close']; return [ 'title', 'close' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback
@@ -33,7 +33,7 @@ export class SePromptDialog extends HTMLElement {
this.dialog.close(); this.dialog.close();
} }
this.dialog.textContent = newValue; this.dialog.textContent = newValue;
this.dialog.choices = ['Cancel']; this.dialog.choices = [ 'Cancel' ];
this.dialog.open(); this.dialog.open();
break; break;
case 'close': case 'close':

View File

@@ -14,7 +14,8 @@ template.innerHTML = `
} }
#svg_source_editor #svg_source_container { #svg_source_editor #svg_source_container {
background-color: #B0B0B0; background-color: #5a6162;
color: #c5c5c5;
opacity: 1.0; opacity: 1.0;
text-align: center; text-align: center;
border: 1px outset #777; border: 1px outset #777;
@@ -42,18 +43,27 @@ template.innerHTML = `
#svg_source_editor #tool_source_back { #svg_source_editor #tool_source_back {
text-align: left; 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> </style>
<elix-dialog id="svg_source_editor" aria-label="SVG Source Editor" closed> <elix-dialog id="svg_source_editor" aria-label="SVG Source Editor" closed>
<div id="svg_source_container"> <div id="svg_source_container">
<div id="tool_source_back" class="toolbar_button"> <div id="tool_source_back" class="toolbar_button">
<button id="tool_source_save"> <button id="tool_source_save">
<img class="svg_icon" src="./images/ok.svg" alt="icon" width="16" height="16" />
Apply Changes Apply Changes
</button> </button>
<button id="tool_source_cancel"> <button id="tool_source_cancel">
<img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />
Cancel Cancel
</button> </button>
</div> </div>
@@ -79,7 +89,7 @@ export class SeSvgSourceEditorDialog extends HTMLElement {
constructor () { constructor () {
super(); super();
// create the shadowDom and insert the template // 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._shadowRoot.append(template.content.cloneNode(true));
this.$dialog = this._shadowRoot.querySelector('#svg_source_editor'); this.$dialog = this._shadowRoot.querySelector('#svg_source_editor');
this.$copyBtn = this._shadowRoot.querySelector('#copy_save_done'); this.$copyBtn = this._shadowRoot.querySelector('#copy_save_done');
@@ -94,7 +104,7 @@ export class SeSvgSourceEditorDialog extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['dialog', 'value', 'applysec', 'copysec']; return [ 'dialog', 'value', 'applysec', 'copysec' ];
} }
/** /**
* @function attributeChangedCallback * @function attributeChangedCallback
@@ -203,9 +213,9 @@ export class SeSvgSourceEditorDialog extends HTMLElement {
*/ */
connectedCallback () { connectedCallback () {
const onCancelHandler = () => { const onCancelHandler = () => {
const closeEvent = new CustomEvent('change', {detail: { const closeEvent = new CustomEvent('change', { detail: {
dialog: 'closed' dialog: 'closed'
}}); } });
this.dispatchEvent(closeEvent); this.dispatchEvent(closeEvent);
}; };
const onCopyHandler = () => { const onCopyHandler = () => {
@@ -218,10 +228,10 @@ export class SeSvgSourceEditorDialog extends HTMLElement {
this.dispatchEvent(closeEvent); this.dispatchEvent(closeEvent);
}; };
const onSaveHandler = () => { const onSaveHandler = () => {
const closeEvent = new CustomEvent('change', {detail: { const closeEvent = new CustomEvent('change', { detail: {
value: this.$sourceTxt.value, value: this.$sourceTxt.value,
dialog: 'close' dialog: 'close'
}}); } });
this.dispatchEvent(closeEvent); this.dispatchEvent(closeEvent);
}; };
this.$copyBtn.addEventListener('click', onCopyHandler); this.$copyBtn.addEventListener('click', onCopyHandler);

View File

@@ -3,7 +3,7 @@
* @module EmbeddedSVGEditDOM * @module EmbeddedSVGEditDOM
*/ */
import EmbeddedSVGEdit from './embedapi.js'; import EmbeddedSVGEdit from './embedapi.js';
import {isChrome} from '../common/browser.js'; import { isChrome } from '../common/browser.js';
let svgCanvas = null; let svgCanvas = null;
@@ -106,8 +106,8 @@ iframe.src = frameBase + framePath +
: ''); // Append arguments to this file onto the iframe : ''); // Append arguments to this file onto the iframe
iframe.addEventListener('load', function () { iframe.addEventListener('load', function () {
svgCanvas = new EmbeddedSVGEdit(frame, [new URL(frameBase).origin]); svgCanvas = new EmbeddedSVGEdit(frame, [ new URL(frameBase).origin ]);
const {$id} = svgCanvas; const { $id } = svgCanvas;
// Hide main button, as we will be controlling new, load, save, etc. from the host document // Hide main button, as we will be controlling new, load, save, etc. from the host document
let doc; let doc;
try { try {

View File

@@ -43,7 +43,7 @@ function getCallbackSetter (funcName) {
* @param {Integer} data.id * @param {Integer} data.id
* @returns {void} * @returns {void}
*/ */
function addCallback (t, {result, error, id: callbackID}) { function addCallback (t, { result, error, id: callbackID }) {
if (typeof callbackID === 'number' && t.callbacks[callbackID]) { if (typeof callbackID === 'number' && t.callbacks[callbackID]) {
// These should be safe both because we check `cbid` is numeric and // These should be safe both because we check `cbid` is numeric and
// because the calls are from trusted origins // because the calls are from trusted origins
@@ -62,10 +62,10 @@ function addCallback (t, {result, error, id: callbackID}) {
function messageListener (e) { function messageListener (e) {
// We accept and post strings as opposed to objects for the sake of IE9 support; this // We accept and post strings as opposed to objects for the sake of IE9 support; this
// will most likely be changed in the future // 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; return;
} }
const {allowedOrigins} = this, const { allowedOrigins } = this,
data = typeof e.data === 'object' ? e.data : JSON.parse(e.data); data = typeof e.data === 'object' ? e.data : JSON.parse(e.data);
if (!data || typeof data !== 'object' || data.namespace !== 'svg-edit' || if (!data || typeof data !== 'object' || data.namespace !== 'svg-edit' ||
e.source !== this.frame.contentWindow || 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 // Older IE may need a polyfill for addEventListener, but so it would for SVG
window.addEventListener('message', getMessageListener(this)); window.addEventListener('message', getMessageListener(this));
window.addEventListener('keydown', (e) => { window.addEventListener('keydown', (e) => {
const {type, key} = e; const { type, key } = e;
if (key === 'Backspace') { if (key === 'Backspace') {
e.preventDefault(); e.preventDefault();
const keyboardEvent = new KeyboardEvent(type, {key}); const keyboardEvent = new KeyboardEvent(type, { key });
that.frame.contentDocument.dispatchEvent(keyboardEvent); that.frame.contentDocument.dispatchEvent(keyboardEvent);
} }
}); });
@@ -372,8 +372,8 @@ class EmbeddedSVGEdit {
// of the current JSON-based communication API (e.g., not passing // of the current JSON-based communication API (e.g., not passing
// callbacks). We might be able to address these shortcomings; see // callbacks). We might be able to address these shortcomings; see
// the todo elsewhere in this file. // the todo elsewhere in this file.
const message = {id: callbackID}, const message = { id: callbackID },
{svgEditor: {canvas: svgCanvas}} = that.frame.contentWindow; { svgEditor: { canvas: svgCanvas } } = that.frame.contentWindow;
try { try {
message.result = svgCanvas[name](...args); message.result = svgCanvas[name](...args);
} catch (err) { } catch (err) {

View File

@@ -9,7 +9,7 @@
const loadExtensionTranslation = async function (svgEditor) { const loadExtensionTranslation = async function (svgEditor) {
let translationModule; let translationModule;
const lang = svgEditor.configObj.pref('lang') const lang = svgEditor.configObj.pref('lang');
try { try {
// eslint-disable-next-line no-unsanitized/method // eslint-disable-next-line no-unsanitized/method
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`); translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
@@ -26,11 +26,11 @@ export default {
async init (S) { async init (S) {
const svgEditor = this; const svgEditor = this;
const strings = await loadExtensionTranslation(svgEditor); const strings = await loadExtensionTranslation(svgEditor);
const {svgCanvas} = svgEditor; const { svgCanvas } = svgEditor;
const {$id} = svgCanvas; const { $id } = svgCanvas;
const const
addElem = svgCanvas.addSVGElementFromJson, addElem = svgCanvas.addSVGElementFromJson,
{nonce} = S, { nonce } = S,
prefix = 'se_arrow_'; prefix = 'se_arrow_';
let selElems, arrowprefix, randomizeIds = S.randomize_ids; let selElems, arrowprefix, randomizeIds = S.randomize_ids;
@@ -64,8 +64,8 @@ export default {
arrowprefix = (randomizeIds) ? `${prefix}${nonce}_` : prefix; arrowprefix = (randomizeIds) ? `${prefix}${nonce}_` : prefix;
const pathdata = { const pathdata = {
fw: {d: 'm0,0l10,5l-10,5l5,-5l-5,-5z', refx: 8, id: arrowprefix + 'fw'}, 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'} bk: { d: 'm10,0l-10,5l10,5l-5,-5l5,-5z', refx: 2, id: arrowprefix + 'bk' }
}; };
/** /**
@@ -214,14 +214,14 @@ export default {
*/ */
function colorChanged (elem) { function colorChanged (elem) {
const color = elem.getAttribute('stroke'); const color = elem.getAttribute('stroke');
const mtypes = ['start', 'mid', 'end']; const mtypes = [ 'start', 'mid', 'end' ];
const defs = svgCanvas.findDefs(); const defs = svgCanvas.findDefs();
mtypes.forEach(function(type){ mtypes.forEach(function(type){
const marker = getLinked(elem, 'marker-' + type); const marker = getLinked(elem, 'marker-' + type);
if (!marker) { return; } if (!marker) { return; }
const curColor = marker.children.getAttribute('fill'); const curColor = marker.children.getAttribute('fill');
const curD = marker.children.getAttribute('d'); const curD = marker.children.getAttribute('d');
if (curColor === color) { return; } if (curColor === color) { return; }
@@ -236,7 +236,7 @@ export default {
newMarker = marker; newMarker = marker;
} }
}); });
if (!newMarker) { if (!newMarker) {
// Create a new marker with this color // Create a new marker with this color
const lastId = marker.id; const lastId = marker.id;
@@ -290,12 +290,12 @@ export default {
}), }),
callback () { callback () {
$id("arrow_panel").style.display = 'none'; $id("arrow_panel").style.display = 'none';
// Set ID so it can be translated in locale file // Set ID so it can be translated in locale file
$id('arrow_list option').setAttribute('id', 'connector_no_arrow'); $id('arrow_list option').setAttribute('id', 'connector_no_arrow');
}, },
async addLangData ({_lang, importLocale}) { async addLangData ({ _lang, importLocale }) {
const {langList} = await importLocale(); const { langList } = await importLocale();
return { return {
data: langList data: langList
}; };
@@ -304,7 +304,7 @@ export default {
// Use this to update the current selected elements // Use this to update the current selected elements
selElems = opts.elems; selElems = opts.elems;
const markerElems = ['line', 'path', 'polyline', 'polygon']; const markerElems = [ 'line', 'path', 'polyline', 'polygon' ];
let i = selElems.length; let i = selElems.length;
while (i--) { while (i--) {
const elem = selElems[i]; const elem = selElems[i];

View File

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

View File

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

View File

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

View File

@@ -24,10 +24,10 @@ const loadExtensionTranslation = async function (lang) {
// The button toggles whether the path is open or closed // The button toggles whether the path is open or closed
export default { export default {
name: 'closepath', name: 'closepath',
async init ({_importLocale}) { async init ({ _importLocale }) {
const svgEditor = this; const svgEditor = this;
const {svgCanvas} = svgEditor; const { svgCanvas } = svgEditor;
const {$id} = svgCanvas; const { $id } = svgCanvas;
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang')); const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
let selElems; let selElems;
const updateButton = function (path) { const updateButton = function (path) {

View File

@@ -79,7 +79,7 @@ export default {
x: midX + lenX * ratio, x: midX + lenX * ratio,
y: midY + lenY * ratio y: midY + lenY * ratio
}; };
} };
/** /**
* @param {"start"|"end"} side * @param {"start"|"end"} side
@@ -92,7 +92,7 @@ export default {
// TODO: Make this number (5) be based on marker width/height // TODO: Make this number (5) be based on marker width/height
const size = line.getAttribute('stroke-width') * 5; const size = line.getAttribute('stroke-width') * 5;
return giveOffset ? size : 0; return giveOffset ? size : 0;
} };
/** /**
* @param {boolean} on * @param {boolean} on
@@ -108,7 +108,7 @@ export default {
connRules.textContent = (!on ? '' : '#tool_clone, #tool_topath, #tool_angle, #xy_panel { display: none !important; }'); connRules.textContent = (!on ? '' : '#tool_clone, #tool_topath, #tool_angle, #xy_panel { display: none !important; }');
if ($id('connector_panel')) if ($id('connector_panel'))
$id('connector_panel').style.display = (on) ? 'block' : 'none'; $id('connector_panel').style.display = (on) ? 'block' : 'none';
} };
/** /**
* @param {Element} elem * @param {Element} elem
@@ -144,7 +144,7 @@ export default {
const ptEnd = pts.getItem(pts.numberOfItems - 1); const ptEnd = pts.getItem(pts.numberOfItems - 1);
setPoint(elem, 1, (ptEnd.x + ptStart.x) / 2, (ptEnd.y + ptStart.y) / 2); setPoint(elem, 1, (ptEnd.x + ptStart.x) / 2, (ptEnd.y + ptStart.y) / 2);
} }
} };
/** /**
* @param {Float} diffX * @param {Float} diffX
@@ -184,7 +184,7 @@ export default {
const pt2 = getBBintersect(pt.x, pt.y, dataStorage.get(line, altPre + '_bb'), getOffset(altPre, line)); 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); setPoint(line, conn.is_start ? 'end' : 0, pt2.x, pt2.y, true);
} }
} };
/** /**
* *
@@ -202,7 +202,7 @@ export default {
let addThis; let addThis;
// Grab the ends // Grab the ends
const parts = []; const parts = [];
['start', 'end'].forEach(function (pos, i) { [ 'start', 'end' ].forEach(function (pos, i) {
const key = 'c_' + pos; const key = 'c_' + pos;
let part = dataStorage.get(ethis, key); let part = dataStorage.get(ethis, key);
if (part === null || part === undefined) { // Does this ever return nullish values? if (part === null || part === undefined) { // Does this ever return nullish values?
@@ -210,7 +210,7 @@ export default {
ethis.attributes['se:connector'].value.split(' ')[i] ethis.attributes['se:connector'].value.split(' ')[i]
); );
dataStorage.put(ethis, 'c_' + pos, part.id); 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); } else part = document.getElementById(part);
parts.push(part); parts.push(part);
}, ethis); }, ethis);
@@ -233,7 +233,7 @@ export default {
continue; continue;
} }
if (elems.includes(cElem) || addThis) { if (elems.includes(cElem) || addThis) {
const bb = svgCanvas.getStrokedBBox([cElem]); const bb = svgCanvas.getStrokedBBox([ cElem ]);
connections.push({ connections.push({
elem: cElem, elem: cElem,
connector: ethis, connector: ethis,
@@ -244,7 +244,7 @@ export default {
} }
} }
}); });
} };
/** /**
* @param {Element[]} [elems=selElems] * @param {Element[]} [elems=selElems]
@@ -268,7 +268,7 @@ export default {
const pre = conn.is_start ? 'start' : 'end'; const pre = conn.is_start ? 'start' : 'end';
// Update bbox for this element // Update bbox for this element
const bb = svgCanvas.getStrokedBBox([elem]); const bb = svgCanvas.getStrokedBBox([ elem ]);
bb.x = conn.start_x; bb.x = conn.start_x;
bb.y = conn.start_y; bb.y = conn.start_y;
dataStorage.put(line, pre + '_bb', bb); dataStorage.put(line, pre + '_bb', bb);
@@ -302,7 +302,7 @@ export default {
} }
} }
} }
} };
// Do once // Do once
(function () { (function () {
@@ -338,8 +338,8 @@ export default {
if (conn) { if (conn) {
curthis.setAttribute('class', 'se_connector'); curthis.setAttribute('class', 'se_connector');
const connData = conn.split(' '); const connData = conn.split(' ');
const sbb = svgCanvas.getStrokedBBox([getElem(connData[0])]); const sbb = svgCanvas.getStrokedBBox([ getElem(connData[0]) ]);
const ebb = svgCanvas.getStrokedBBox([getElem(connData[1])]); const ebb = svgCanvas.getStrokedBBox([ getElem(connData[1]) ]);
dataStorage.put(curthis, 'c_start', connData[0]); dataStorage.put(curthis, 'c_start', connData[0]);
dataStorage.put(curthis, 'c_end', connData[1]); dataStorage.put(curthis, 'c_end', connData[1]);
dataStorage.put(curthis, 'start_bb', sbb); dataStorage.put(curthis, 'start_bb', sbb);
@@ -347,7 +347,7 @@ export default {
svgCanvas.getEditorNS(true); svgCanvas.getEditorNS(true);
} }
}); });
} };
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang')); const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
return { return {
@@ -359,7 +359,7 @@ export default {
const buttonTemplate = document.createElement("template"); const buttonTemplate = document.createElement("template");
buttonTemplate.innerHTML = ` buttonTemplate.innerHTML = `
<se-button id="mode_connect" title="Connect two objects" src="./images/conn.svg"></se-button> <se-button id="mode_connect" title="Connect two objects" src="./images/conn.svg"></se-button>
` `;
$id('tools_left').append(buttonTemplate.content.cloneNode(true)); $id('tools_left').append(buttonTemplate.content.cloneNode(true));
$id('mode_connect').addEventListener("click", () => { $id('mode_connect').addEventListener("click", () => {
svgCanvas.setMode('connector'); svgCanvas.setMode('connector');
@@ -393,7 +393,7 @@ export default {
startElem = fo ? fo : mouseTarget; startElem = fo ? fo : mouseTarget;
// Get center of source element // Get center of source element
const bb = svgCanvas.getStrokedBBox([startElem]); const bb = svgCanvas.getStrokedBBox([ startElem ]);
const x = bb.x + bb.width / 2; const x = bb.x + bb.width / 2;
const y = bb.y + bb.height / 2; const y = bb.y + bb.height / 2;
@@ -453,7 +453,7 @@ export default {
// Look for selected connector elements // Look for selected connector elements
if (elem && dataStorage.has(elem, 'c_start')) { if (elem && dataStorage.has(elem, 'c_start')) {
// Remove the "translate" transform given to move // Remove the "translate" transform given to move
svgCanvas.removeFromSelection([elem]); svgCanvas.removeFromSelection([ elem ]);
svgCanvas.getTransformList(elem).clear(); 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)); const pt = getBBintersect(startX, startY, bb, getOffset('start', curLine));
setPoint(curLine, 'end', pt.x, pt.y, true); setPoint(curLine, 'end', pt.x, pt.y, true);
@@ -531,7 +531,7 @@ export default {
curLine.setAttributeNS(seNs, 'se:connector', connStr); curLine.setAttributeNS(seNs, 'se:connector', connStr);
curLine.setAttribute('class', 'se_connector'); curLine.setAttribute('class', 'se_connector');
curLine.setAttribute('opacity', 1); curLine.setAttribute('opacity', 1);
svgCanvas.addToSelection([curLine]); svgCanvas.addToSelection([ curLine ]);
svgCanvas.moveToBottomSelectedElement(); svgCanvas.moveToBottomSelectedElement();
selManager.requestSelector(curLine).showGrips(false); selManager.requestSelector(curLine).showGrips(false);
started = false; started = false;
@@ -618,14 +618,14 @@ export default {
elem.remove(); elem.remove();
svgCanvas.clearSelection(); svgCanvas.clearSelection();
pline.id = id; pline.id = id;
svgCanvas.addToSelection([pline]); svgCanvas.addToSelection([ pline ]);
elem = pline; elem = pline;
} }
} }
// Update line if it's a connector // Update line if it's a connector
if (elem.getAttribute('class') === 'se_connector') { if (elem.getAttribute('class') === 'se_connector') {
const start = getElem(dataStorage.get(elem, 'c_start')); const start = getElem(dataStorage.get(elem, 'c_start'));
updateConnectors([start]); updateConnectors([ start ]);
} else { } else {
updateConnectors(); updateConnectors();
} }

View File

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

View File

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

View File

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

View File

@@ -4,27 +4,19 @@
* @license MIT * @license MIT
* *
* @copyright 2010 Jeff Schiller * @copyright 2010 Jeff Schiller
* @copyright 2021 OptimistikSAS
* *
*/ */
const loadExtensionTranslation = async function (lang) { import { loadExtensionTranslation } from '../../locale.js';
let translationModule;
try { const name = "eyedropper";
// eslint-disable-next-line no-unsanitized/method
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
} catch (_error) {
// eslint-disable-next-line no-console
console.error(`Missing translation (${lang}) - using 'en'`);
translationModule = await import(`./locale/en.js`);
}
return translationModule.default;
};
export default { export default {
name: 'eyedropper', name,
async init(S) { async init(S) {
const svgEditor = this; const svgEditor = this;
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang')); await loadExtensionTranslation(svgEditor, name);
const { ChangeElementCommand } = S, // , svgcontent, const { ChangeElementCommand } = S, // , svgcontent,
// svgdoc = S.svgroot.parentNode.ownerDocument, // svgdoc = S.svgroot.parentNode.ownerDocument,
{ svgCanvas } = svgEditor, { svgCanvas } = svgEditor,
@@ -53,7 +45,7 @@ export default {
// enable-eye-dropper if one element is selected // enable-eye-dropper if one element is selected
let elem = null; let elem = null;
if (!opts.multiselected && opts.elems[0] && 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]; elem = opts.elems[0];
tool.classList.remove('disabled'); tool.classList.remove('disabled');
@@ -71,16 +63,19 @@ export default {
} else { } else {
tool.classList.add('disabled'); tool.classList.add('disabled');
} }
} };
return { return {
name: strings.name, name: svgEditor.i18next.t(`${name}:name`),
callback() { callback() {
// Add the button and its handler(s) // Add the button and its handler(s)
const buttonTemplate = document.createElement("template"); 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 = ` 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('tools_left').append(buttonTemplate.content.cloneNode(true));
$id('tool_eyedropper').addEventListener("click", () => { $id('tool_eyedropper').addEventListener("click", () => {
svgCanvas.setMode('eyedropper'); svgCanvas.setMode('eyedropper');
@@ -94,7 +89,7 @@ export default {
if (mode === 'eyedropper') { if (mode === 'eyedropper') {
const e = opts.event; const e = opts.event;
const { target } = e; const { target } = e;
if (!['svg', 'g', 'use'].includes(target.nodeName)) { if (![ 'svg', 'g', 'use' ].includes(target.nodeName)) {
const changes = {}; const changes = {};
const change = function (elem, attrname, newvalue) { 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', name: 'foreignobject',
async init (S) { async init (S) {
const svgEditor = this; const svgEditor = this;
const {text2xml, NS} = S; const { text2xml, NS } = S;
const {svgCanvas} = svgEditor; const { svgCanvas } = svgEditor;
const {$id} = svgCanvas; const { $id } = svgCanvas;
const const
// {svgcontent} = S, // {svgcontent} = S,
// addElem = svgCanvas.addSVGElementFromJson, // addElem = svgCanvas.addSVGElementFromJson,
@@ -49,7 +49,7 @@ export default {
if (!fcRules) { if (!fcRules) {
fcRules = document.createElement('style'); fcRules = document.createElement('style');
fcRules.setAttribute('id', 'fc_rules'); 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; }'; fcRules.textContent = !on ? '' : ' #tool_topath { display: none !important; }';
$id('foreignObject_panel').style.display = (on) ? 'block' : 'none'; $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 // run it through our sanitizer to remove anything we do not support
svgCanvas.sanitizeSvg(newDoc.documentElement); svgCanvas.sanitizeSvg(newDoc.documentElement);
elt.replaceWith(svgdoc.importNode(newDoc.documentElement.firstChild, true)); elt.replaceWith(svgdoc.importNode(newDoc.documentElement.firstChild, true));
svgCanvas.call('changed', [elt]); svgCanvas.call('changed', [ elt ]);
svgCanvas.clearSelection(); svgCanvas.clearSelection();
} catch (e) { } catch (e) {
// Todo: Surface error to user // Todo: Surface error to user
console.log(e); console.log(e);
return false; return false;
} }
@@ -124,7 +124,7 @@ export default {
svgCanvas.call('changed', selElems); svgCanvas.call('changed', selElems);
} }
const buttons = [{ const buttons = [ {
id: 'tool_foreign', id: 'tool_foreign',
icon: 'foreignobject-tool.png', icon: 'foreignobject-tool.png',
type: 'mode', type: 'mode',
@@ -143,7 +143,7 @@ export default {
showForeignEditor(); showForeignEditor();
} }
} }
}]; } ];
const contextTools = [ const contextTools = [
{ {
@@ -277,9 +277,9 @@ export default {
const attrs = { const attrs = {
width: newFO.getAttribute('width'), width: newFO.getAttribute('width'),
height: newFO.getAttribute('height'), height: newFO.getAttribute('height'),
} };
const keep = (attrs.width !== '0' || attrs.height !== '0'); const keep = (attrs.width !== '0' || attrs.height !== '0');
svgCanvas.addToSelection([newFO], true); svgCanvas.addToSelection([ newFO ], true);
return { return {
keep, keep,

View File

@@ -7,32 +7,23 @@
* *
*/ */
const loadExtensionTranslation = async function (lang) { import { loadExtensionTranslation } from '../../locale.js';
let translationModule;
try { const name = "grid";
// eslint-disable-next-line no-unsanitized/method
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
} catch (_error) {
// eslint-disable-next-line no-console
console.error(`Missing translation (${lang}) - using 'en'`);
translationModule = await import(`./locale/en.js`);
}
return translationModule.default;
};
export default { export default {
name: 'grid', name,
async init ({NS, getTypeMap}) { async init ({ NS, getTypeMap }) {
const svgEditor = this; const svgEditor = this;
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang')); await loadExtensionTranslation(svgEditor, name);
const {svgCanvas} = svgEditor; const { svgCanvas } = svgEditor;
const {$id} = svgCanvas; const { $id } = svgCanvas;
const svgdoc = document.getElementById('svgcanvas').ownerDocument; const svgdoc = document.getElementById('svgcanvas').ownerDocument;
const {assignAttributes} = svgCanvas; const { assignAttributes } = svgCanvas;
const hcanvas = document.createElement('canvas'); const hcanvas = document.createElement('canvas');
const canvBG = $id('canvasBackground'); const canvBG = $id('canvasBackground');
const units = getTypeMap(); // Assumes prior `init()` call on `units.js` module 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; let showGrid = svgEditor.configObj.curConfig.showGrid || false;
hcanvas.style.display = 'none'; hcanvas.style.display = 'none';
@@ -138,7 +129,7 @@ export default {
gridimg.parentNode.setAttribute('width', bigInt); gridimg.parentNode.setAttribute('width', bigInt);
gridimg.parentNode.setAttribute('height', bigInt); gridimg.parentNode.setAttribute('height', bigInt);
svgCanvas.setHref(gridimg, datauri); svgCanvas.setHref(gridimg, datauri);
} };
/** /**
* *
@@ -150,23 +141,26 @@ export default {
} }
$id('canvasGrid').style.display = (showGrid) ? 'block' : 'none'; $id('canvasGrid').style.display = (showGrid) ? 'block' : 'none';
document.getElementById('view_grid').pressed = showGrid; document.getElementById('view_grid').pressed = showGrid;
} };
return { return {
name: strings.name, name: svgEditor.i18next.t(`${name}:name`),
zoomChanged (zoom) { zoomChanged (zoom) {
if (showGrid) { updateGrid(zoom); } if (showGrid) { updateGrid(zoom); }
}, },
callback () { callback () {
// Add the button and its handler(s) // Add the button and its handler(s)
const buttonTemplate = document.createElement("template"); const buttonTemplate = document.createElement("template");
const title = svgEditor.i18next.t(`${name}:buttons.0.title`);
// eslint-disable-next-line no-unsanitized/property
buttonTemplate.innerHTML = ` 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('editor_panel').append(buttonTemplate.content.cloneNode(true));
$id('view_grid').addEventListener("click", () => { $id('view_grid').addEventListener("click", () => {
svgEditor.configObj.curConfig.showGrid = showGrid = !showGrid; svgEditor.configObj.curConfig.showGrid = showGrid = !showGrid;
gridUpdate(); gridUpdate();
}); });
if (showGrid) { if (showGrid) {
gridUpdate(); 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. * will show the user the point on the canvas that was clicked on.
*/ */
const loadExtensionTranslation = async function (lang) { import { loadExtensionTranslation } from '../../locale.js';
let translationModule;
try { const name = "helloworld";
// eslint-disable-next-line no-unsanitized/method
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
} catch (_error) {
// eslint-disable-next-line no-console
console.error(`Missing translation (${lang}) - using 'en'`);
translationModule = await import(`./locale/en.js`);
}
return translationModule.default;
};
export default { export default {
name: 'helloworld', name,
async init ({_importLocale}) { async init ({ _importLocale }) {
const svgEditor = this; const svgEditor = this;
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang')); await loadExtensionTranslation(svgEditor, name);
const {svgCanvas} = svgEditor; const { svgCanvas } = svgEditor;
const { $id } = svgCanvas;
return { return {
name: strings.name, name: svgEditor.i18next.t(`${name}:name`),
events: [{ callback() {
// Must match the icon ID in helloworld-icon.xml // Add the button and its handler(s)
id: 'hello_world', const buttonTemplate = document.createElement("template");
// Tooltip text const title = svgEditor.i18next.t(`${name}:buttons.0.title`);
title: strings.buttons[0].title, // eslint-disable-next-line no-unsanitized/property
click () { buttonTemplate.innerHTML = `
// The action taken when the button is clicked on. <se-button id="hello_world" title="${title}" src="./images/hello_world.svg"></se-button>
// For "mode" buttons, any other button will `;
// automatically be de-pressed. $id('tools_left').append(buttonTemplate.content.cloneNode(true));
$id('hello_world').addEventListener("click", () => {
svgCanvas.setMode('hello_world'); svgCanvas.setMode('hello_world');
} });
}], },
// This is triggered when the main mouse button is pressed down // This is triggered when the main mouse button is pressed down
// on the editor canvas (not the tool panels) // on the editor canvas (not the tool panels)
mouseDown () { mouseDown () {
@@ -53,7 +46,7 @@ export default {
if (svgCanvas.getMode() === 'hello_world') { if (svgCanvas.getMode() === 'hello_world') {
// The returned object must include "started" with // The returned object must include "started" with
// a value of true in order for mouseUp to be triggered // a value of true in order for mouseUp to be triggered
return {started: true}; return { started: true };
} }
return undefined; return undefined;
}, },
@@ -70,16 +63,9 @@ export default {
const y = opts.mouse_y / zoom; const y = opts.mouse_y / zoom;
// We do our own formatting // We do our own formatting
let {text} = strings; let text = svgEditor.i18next.t(`${name}:text`, { x, y });
[
['x', x],
['y', y]
].forEach(([prop, val]) => {
text = text.replace('{' + prop + '}', val);
});
// Show the text using the custom alert function // Show the text using the custom alert function
alert(text); alert(text);
} }
} }
}; };

View File

@@ -1,6 +1,6 @@
export default { export default {
name: 'Hello World', name: 'Hello World',
text: 'Hello World!\n\nYou clicked here: {x}, {y}', text: 'Hello World!\n\nYou clicked here: {{x}}, {{y}}',
buttons: [ buttons: [
{ {
title: "Say 'Hello World'" title: "Say 'Hello World'"

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