move to standard linter for simpler configuration
parent
258e2bd6a1
commit
fdcfc8a253
|
@ -1,30 +0,0 @@
|
|||
node_modules
|
||||
ignore
|
||||
|
||||
coverage
|
||||
instrumented
|
||||
dist
|
||||
docs/jsdoc
|
||||
archive
|
||||
|
||||
jsconfig.json
|
||||
releases
|
||||
!.eslintrc.js
|
||||
!.ncurc.js
|
||||
|
||||
es-dev-server.config.js
|
||||
nyc.config.js
|
||||
|
||||
svgedit-custom.css
|
||||
|
||||
# Vendor/minified files
|
||||
src/editor/jquery.min.js
|
||||
|
||||
# Previously minified though exporting
|
||||
src/editor/js-hotkeys
|
||||
|
||||
src/editor/extensions/ext-mathjax/mathjax
|
||||
|
||||
# jquery files
|
||||
src/editor/jgraduate/jQuery.jPicker.js
|
||||
|
96
.eslintrc.js
96
.eslintrc.js
|
@ -1,96 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
extends: [
|
||||
"plugin:compat/recommended",
|
||||
"plugin:node/recommended",
|
||||
"plugin:no-unsanitized/DOM",
|
||||
"plugin:promise/recommended",
|
||||
"plugin:import/errors",
|
||||
"plugin:markdown/recommended",
|
||||
"eslint:recommended"
|
||||
],
|
||||
plugins: [ "jsdoc", "promise", "html", "import" ],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
sourceType: "module"
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true
|
||||
},
|
||||
rules: {
|
||||
/** @todo len should probably more 120-150 */
|
||||
"max-len": [ "warn", { "code": 250 } ],
|
||||
"indent": [ "error", 2 ],
|
||||
"no-var": "error",
|
||||
/** @todo this rule should be actived. needs some courage as this rule is broken in many places... */
|
||||
"one-var": [ "error", "never" ],
|
||||
/** @todo jsdoc should be made warn or error */
|
||||
"valid-jsdoc": "off",
|
||||
/** @todo no param reassign creates too many warnings but should be a warning */
|
||||
"no-param-reassign": "off",
|
||||
/** @todo no use before define creates too many warnings but should be a warning */
|
||||
"no-use-before-define": "off",
|
||||
/** @todo camel case creates too many warnings but should be a warning */
|
||||
"camelcase": "off",
|
||||
"comma-dangle": [ "error" ],
|
||||
"node/no-unsupported-features/es-syntax": 0,
|
||||
"no-unused-vars": [ "error", { "argsIgnorePattern": "^_" } ],
|
||||
"semi" : "error",
|
||||
"prefer-const": "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" ] }
|
||||
],
|
||||
"arrow-parens": [ "error", "always" ]
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: [ 'cypress/**/*' ],
|
||||
extends: [
|
||||
"plugin:cypress/recommended"
|
||||
],
|
||||
env: {
|
||||
mocha: true,
|
||||
node: true
|
||||
},
|
||||
globals: { "assert": true },
|
||||
rules: {
|
||||
// with ci, instrumented is not created before linter
|
||||
"import/no-unresolved": [ 2, { ignore: [ 'instrumented' ] } ],
|
||||
"node/no-missing-import": 0,
|
||||
"node/no-unpublished-import": 0,
|
||||
"node/no-unpublished-require": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
files: [ 'docs/**/*' ],
|
||||
rules: { // md files have example that don't need a strict checking
|
||||
"no-undef": 0,
|
||||
"import/no-unresolved": 0,
|
||||
"node/no-missing-import": 0,
|
||||
"jsdoc/check-examples": [
|
||||
"warn",
|
||||
{
|
||||
rejectExampleCodeRegex: "^`",
|
||||
checkDefaults: true,
|
||||
checkParams: true,
|
||||
checkProperties: true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
files: [ 'src/editor/locale/*.js' ],
|
||||
rules: { // lang files may have long length
|
||||
"max-len": "off",
|
||||
"camelcase": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
|
@ -9,7 +9,6 @@ coverage
|
|||
instrumented
|
||||
.nyc_output
|
||||
.vscode
|
||||
.eslintcache
|
||||
.DS_Store
|
||||
.idea
|
||||
dist
|
||||
|
|
|
@ -2,5 +2,4 @@ lgtm.yml
|
|||
coverage/**
|
||||
.nyc_output
|
||||
instrumented/**
|
||||
.eslintcache
|
||||
node_modules/**
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
describe('UI - Clipboard', function () {
|
||||
beforeEach(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('Editor - Copy and paste', () => {
|
||||
cy.get('#tool_source').click();
|
||||
cy.get('#tool_source').click()
|
||||
|
||||
cy.get('#svg_source_textarea')
|
||||
.type('{selectall}', { force: true })
|
||||
|
@ -17,47 +17,47 @@ describe('UI - Clipboard', function () {
|
|||
<title>Layer 1</title>
|
||||
<circle cx="100" cy="100" r="50" fill="#FF0000" id="testCircle" stroke="#000000" stroke-width="5"/>
|
||||
</g>
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false });
|
||||
cy.get('#tool_source_save').click();
|
||||
cy.get('#testCircle').should('exist');
|
||||
cy.get('#svg_1').should('not.exist');
|
||||
cy.get('#svg_2').should('not.exist');
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false })
|
||||
cy.get('#tool_source_save').click()
|
||||
cy.get('#testCircle').should('exist')
|
||||
cy.get('#svg_1').should('not.exist')
|
||||
cy.get('#svg_2').should('not.exist')
|
||||
|
||||
// Copy.
|
||||
cy.get('#testCircle').click().rightclick();
|
||||
cy.get('#cmenu_canvas a[href="#copy"]').click({ force: true });
|
||||
cy.get('#testCircle').click().rightclick()
|
||||
cy.get('#cmenu_canvas a[href="#copy"]').click({ force: true })
|
||||
|
||||
// Paste.
|
||||
// Scrollbars fail to recenter in Cypress test. Works fine in reality.
|
||||
// Thus forcing click is needed since workspace is mostly offscreen.
|
||||
cy.get('#svgroot').rightclick({ force: true });
|
||||
cy.get('#cmenu_canvas a[href="#paste"]').click({ force: true });
|
||||
cy.get('#testCircle').should('exist');
|
||||
cy.get('#svg_1').should('exist');
|
||||
cy.get('#svg_2').should('not.exist');
|
||||
cy.get('#svgroot').rightclick({ force: true })
|
||||
cy.get('#cmenu_canvas a[href="#paste"]').click({ force: true })
|
||||
cy.get('#testCircle').should('exist')
|
||||
cy.get('#svg_1').should('exist')
|
||||
cy.get('#svg_2').should('not.exist')
|
||||
|
||||
// Cut.
|
||||
cy.get('#testCircle').click().rightclick();
|
||||
cy.get('#cmenu_canvas a[href="#cut"]').click({ force: true });
|
||||
cy.get('#testCircle').should('not.exist');
|
||||
cy.get('#svg_1').should('exist');
|
||||
cy.get('#svg_2').should('not.exist');
|
||||
cy.get('#testCircle').click().rightclick()
|
||||
cy.get('#cmenu_canvas a[href="#cut"]').click({ force: true })
|
||||
cy.get('#testCircle').should('not.exist')
|
||||
cy.get('#svg_1').should('exist')
|
||||
cy.get('#svg_2').should('not.exist')
|
||||
|
||||
// Paste.
|
||||
// Scrollbars fail to recenter in Cypress test. Works fine in reality.
|
||||
// Thus forcing click is needed since workspace is mostly offscreen.
|
||||
cy.get('#svgroot').rightclick({ force: true });
|
||||
cy.get('#cmenu_canvas a[href="#paste"]').click({ force: true });
|
||||
cy.get('#testCircle').should('not.exist');
|
||||
cy.get('#svg_1').should('exist');
|
||||
cy.get('#svg_2').should('exist');
|
||||
cy.get('#svgroot').rightclick({ force: true })
|
||||
cy.get('#cmenu_canvas a[href="#paste"]').click({ force: true })
|
||||
cy.get('#testCircle').should('not.exist')
|
||||
cy.get('#svg_1').should('exist')
|
||||
cy.get('#svg_2').should('exist')
|
||||
|
||||
// Delete.
|
||||
cy.get('#svg_2').click().rightclick();
|
||||
cy.get('#cmenu_canvas a[href="#delete"]').click({ force: true });
|
||||
cy.get('#svg_1').click().rightclick();
|
||||
cy.get('#cmenu_canvas a[href="#delete"]').click({ force: true });
|
||||
cy.get('#svg_1').should('not.exist');
|
||||
cy.get('#svg_2').should('not.exist');
|
||||
});
|
||||
});
|
||||
cy.get('#svg_2').click().rightclick()
|
||||
cy.get('#cmenu_canvas a[href="#delete"]').click({ force: true })
|
||||
cy.get('#svg_1').click().rightclick()
|
||||
cy.get('#cmenu_canvas a[href="#delete"]').click({ force: true })
|
||||
cy.get('#svg_1').should('not.exist')
|
||||
cy.get('#svg_2').should('not.exist')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
describe('UI - Control Points', function () {
|
||||
beforeEach(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('Editor - No parameters: Drag control point of arc path', () => {
|
||||
const randomOffset = () => 2 + Math.round(10 + Math.random() * 40);
|
||||
cy.get('#tool_source').click();
|
||||
const randomOffset = () => 2 + Math.round(10 + Math.random() * 40)
|
||||
cy.get('#tool_source').click()
|
||||
cy.get('#svg_source_textarea')
|
||||
.type('{selectall}', { force: true })
|
||||
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
|
@ -17,18 +17,18 @@ describe('UI - Control Points', function () {
|
|||
<title>Layer 1</title>
|
||||
<path d="m187,194a114,62 0 1 0 219,2" id="svg_1" fill="#FF0000" stroke="#000000" stroke-width="5"/>
|
||||
</g>
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false });
|
||||
cy.get('#tool_source_save').click({ force: true });
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false })
|
||||
cy.get('#tool_source_save').click({ force: true })
|
||||
|
||||
cy.get('#svg_1').click({ force: true }).click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true }).click({ force: true })
|
||||
|
||||
cy.get('#pathpointgrip_0').trigger('mousedown', { which: 1, force: true })
|
||||
.trigger('mousemove', randomOffset(), randomOffset(), { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
.trigger('mouseup', { force: true })
|
||||
cy.get('#pathpointgrip_1').trigger('mousedown', { which: 1, 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')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
import {
|
||||
visitAndApproveStorage, openMainMenu
|
||||
} from '../../support/ui-test-helper.js';
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
describe('UI - Export tests', function () {
|
||||
beforeEach(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('Editor - No parameters: Has export button', () => {
|
||||
openMainMenu();
|
||||
cy.get('#tool_export');
|
||||
});
|
||||
openMainMenu()
|
||||
cy.get('#tool_export')
|
||||
})
|
||||
|
||||
it('Editor - No parameters: Export button clicking; dialog opens', () => {
|
||||
openMainMenu();
|
||||
cy.get('#tool_export').click({ force: true });
|
||||
cy.get('#dialog_content select');
|
||||
});
|
||||
});
|
||||
openMainMenu()
|
||||
cy.get('#tool_export').click({ force: true })
|
||||
cy.get('#dialog_content select')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../../support/ui-test-helper.js';
|
||||
} from '../../../support/ui-test-helper.js'
|
||||
|
||||
// See https://github.com/SVG-Edit/svgedit/issues/359
|
||||
describe('Fix issue 359', function () {
|
||||
beforeEach(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('can undo without throwing', function () {
|
||||
cy.get('#tool_source').click();
|
||||
cy.get('#tool_source').click()
|
||||
cy.get('#svg_source_textarea')
|
||||
.type('{selectall}', { force: true })
|
||||
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
|
@ -17,10 +17,10 @@ describe('Fix issue 359', function () {
|
|||
<title>Layer 1</title>
|
||||
<rect fill="#ffff00" height="70" width="165" x="179.5" y="146.5"/>
|
||||
</g>
|
||||
</svg>`, { parseSpecialCharSequences: false, force: true });
|
||||
cy.get('#tool_source_save').click();
|
||||
cy.get('#tool_undo').click();
|
||||
cy.get('#tool_redo').click(); // test also redo to make the test more comprehensive
|
||||
</svg>`, { parseSpecialCharSequences: false, force: true })
|
||||
cy.get('#tool_source_save').click()
|
||||
cy.get('#tool_undo').click()
|
||||
cy.get('#tool_redo').click() // test also redo to make the test more comprehensive
|
||||
// if the undo throws an error to the console, the test will fail
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../../support/ui-test-helper.js';
|
||||
} from '../../../support/ui-test-helper.js'
|
||||
|
||||
// See https://github.com/SVG-Edit/svgedit/issues/407
|
||||
describe('Fix issue 407', function () {
|
||||
beforeEach(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('can enter edit on text child', function () {
|
||||
cy.get('#tool_source').click();
|
||||
cy.get('#tool_source').click()
|
||||
cy.get('#svg_source_textarea')
|
||||
.type('{selectall}', { force: true })
|
||||
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
|
@ -20,16 +20,16 @@ describe('Fix issue 407', function () {
|
|||
<text fill="#000000" id="a_text" text-anchor="middle" x="260.5" xml:space="preserve" y="192.5">hello</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false });
|
||||
cy.get('#tool_source_save').click();
|
||||
cy.get('#svg_1').click().dblclick();
|
||||
cy.get('#a_text').should('exist');
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false })
|
||||
cy.get('#tool_source_save').click()
|
||||
cy.get('#svg_1').click().dblclick()
|
||||
cy.get('#a_text').should('exist')
|
||||
cy.get('#a_text')
|
||||
.trigger('mousedown', { which: 1, force: true })
|
||||
.trigger('mouseup', { force: true })
|
||||
.dblclick({ force: true });
|
||||
.dblclick({ force: true })
|
||||
// svgedit use the #text text field to capture the text
|
||||
cy.get('#text').type('1234', { force: true });
|
||||
cy.get('#a_text').should('have.text', 'he1234llo');
|
||||
});
|
||||
});
|
||||
cy.get('#text').type('1234', { force: true })
|
||||
cy.get('#a_text').should('have.text', 'he1234llo')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../../support/ui-test-helper.js';
|
||||
} from '../../../support/ui-test-helper.js'
|
||||
|
||||
// See https://github.com/SVG-Edit/svgedit/issues/408
|
||||
describe('Fix issue 408', function () {
|
||||
beforeEach(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
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')
|
||||
.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">
|
||||
|
@ -20,10 +20,10 @@ describe('Fix issue 408', function () {
|
|||
<circle cx="117.5" cy="87.5" fill="#ffff00" r="19.84943" stroke="#000000" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false });
|
||||
cy.get('#tool_source_save').click();
|
||||
cy.get('#svg_6').click().dblclick(); // change context
|
||||
cy.get('#tool_source').click(); // reopen tool_source
|
||||
cy.get('#tool_source_save').should('exist'); // The save button should be here if it does not throw
|
||||
});
|
||||
});
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false })
|
||||
cy.get('#tool_source_save').click()
|
||||
cy.get('#svg_6').click().dblclick() // change context
|
||||
cy.get('#tool_source').click() // reopen tool_source
|
||||
cy.get('#tool_source_save').should('exist') // The save button should be here if it does not throw
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../../support/ui-test-helper.js';
|
||||
} from '../../../support/ui-test-helper.js'
|
||||
|
||||
// See https://github.com/SVG-Edit/svgedit/issues/423
|
||||
describe('Fix issue 423', function () {
|
||||
beforeEach(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('should not throw when undoing the move', function () {
|
||||
cy.get('#tool_source').click();
|
||||
cy.get('#tool_source').click()
|
||||
cy.get('#svg_source_textarea')
|
||||
.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">
|
||||
|
@ -22,12 +22,12 @@ describe('Fix issue 423', function () {
|
|||
<rect clip-path="url(#svg_2)" fill="#0033b5" height="174.9" id="TANK1" width="78" x="77.5" y="29"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>`, { parseSpecialCharSequences: false, force: true });
|
||||
cy.get('#tool_source_save').click({ force: true });
|
||||
</svg>`, { parseSpecialCharSequences: false, force: true })
|
||||
cy.get('#tool_source_save').click({ force: true })
|
||||
cy.get('#TANK1')
|
||||
.trigger('mousedown', { force: true })
|
||||
.trigger('mousemove', 50, 0, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
cy.get('#tool_undo').click({ force: true });
|
||||
});
|
||||
});
|
||||
.trigger('mouseup', { force: true })
|
||||
cy.get('#tool_undo').click({ force: true })
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../../support/ui-test-helper.js';
|
||||
} from '../../../support/ui-test-helper.js'
|
||||
|
||||
// See https://github.com/SVG-Edit/svgedit/issues/660
|
||||
describe('Fix issue 660', function () {
|
||||
beforeEach(() => {
|
||||
visitAndApproveStorage();
|
||||
cy.viewport(512, 512);
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
cy.viewport(512, 512)
|
||||
})
|
||||
/** @todo: reenable this test when we understand why it is passing locally but not on ci */
|
||||
it.skip('can resize text', function () {
|
||||
cy.get('#tool_source').click();
|
||||
cy.get('#tool_source').click()
|
||||
cy.get('#svg_source_textarea')
|
||||
.type('{selectall}', { force: true })
|
||||
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
|
@ -18,18 +18,18 @@ describe('Fix issue 660', function () {
|
|||
<title>Layer 1</title>
|
||||
<text fill="#000000" id="a_text" text-anchor="middle" x="260.5" xml:space="preserve" y="192.5" font-size="40">hello</text>
|
||||
</g>
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false });
|
||||
cy.get('#tool_source_save').click({ force: true });
|
||||
cy.get('#a_text').should('exist');
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false })
|
||||
cy.get('#tool_source_save').click({ force: true })
|
||||
cy.get('#a_text').should('exist')
|
||||
cy.get('#a_text')
|
||||
.trigger('mousedown', { which: 1, force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
.trigger('mouseup', { force: true })
|
||||
cy.get('#selectorGrip_resize_s')
|
||||
.trigger('mousedown', { which: 1, force: true })
|
||||
.trigger('mousemove', { clientX: 0, clientY: 600 })
|
||||
.trigger('mouseup', { force: true });
|
||||
.trigger('mouseup', { force: true })
|
||||
// svgedit use the #text text field to capture the text
|
||||
cy.get('#a_text').should('have.attr', 'transform')
|
||||
.and('equal', 'matrix(1 0 0 4.54639 0 -540.825)'); // Chrome 96 is matrix(1 0 0 4.17431 0 -325.367)
|
||||
});
|
||||
});
|
||||
.and('equal', 'matrix(1 0 0 4.54639 0 -540.825)') // Chrome 96 is matrix(1 0 0 4.17431 0 -325.367)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
// See https://github.com/SVG-Edit/svgedit/issues/364
|
||||
describe('Key commands', function () {
|
||||
beforeEach(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it.skip('cmd-A on empty canvas should not cause an error', function () {
|
||||
cy.get('body').type('{cmd}a');
|
||||
});
|
||||
});
|
||||
cy.get('body').type('{cmd}a')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,190 +1,188 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
cy.get('#svgcontent').cleanSnapshot()
|
||||
}
|
||||
|
||||
describe('use various parts of svg-edit', function () {
|
||||
before(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('check tool_source', function () {
|
||||
cy.get('#tool_source').click({ force: true });
|
||||
cy.get('#tool_source').click({ force: true })
|
||||
cy.get('#svg_source_textarea')
|
||||
.type('{selectall}', { force: true })
|
||||
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
</g>
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false });
|
||||
cy.get('#tool_source_save').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false })
|
||||
cy.get('#tool_source_save').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_fhpath', function () {
|
||||
cy.get('#tool_fhpath')
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousemove', 200, 200, { force: true })
|
||||
.trigger('mousedown', 200, 200, { force: true })
|
||||
.trigger('mousemove', 20, 20, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text', function () {
|
||||
cy.get('#tool_text')
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousedown', 46, 35, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
.trigger('mousedown', 46, 35, { force: true })
|
||||
.trigger('mouseup', { force: true })
|
||||
// svgedit use the #text text field to capture the text
|
||||
cy.get('#text').type('AB', { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#text').type('AB', { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
|
||||
it('check tool_clone', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_clone')
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_italic', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_italic')
|
||||
.click({ force: true });
|
||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||
cy.wait(500);
|
||||
testSnapshot();
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_bold', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_bold')
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_change_x_y_coordinate', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
for(let n = 0; n < 25; n ++){
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#selected_x').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
for(let n = 0; n < 25; n ++){
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#selected_y').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_change_font_size', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#font_size').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_change_stroke_width', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#stroke_width').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_change_stoke_fill_color', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#stroke_color').shadow().find('#picker').eq(0).click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#stroke_color').shadow().find('#picker').eq(0).click({ force: true })
|
||||
cy.get('#stroke_color').shadow().find('#color_picker').eq(0)
|
||||
.find('#jGraduate_colPick').eq(0).find('#jPicker-table').eq(0)
|
||||
.find('.QuickColor').eq(51).click({ force: true });
|
||||
.find('.QuickColor').eq(51).click({ force: true })
|
||||
cy.get('#stroke_color').shadow().find('#color_picker').eq(0)
|
||||
.find('#jGraduate_colPick').eq(0).find('#jPicker-table').eq(0)
|
||||
.find('#Ok').eq(0).click({ force: true });
|
||||
cy.get('#fill_color').shadow().find('#picker').eq(0).click({ force: true });
|
||||
.find('#Ok').eq(0).click({ force: true })
|
||||
cy.get('#fill_color').shadow().find('#picker').eq(0).click({ force: true })
|
||||
cy.get('#fill_color').shadow().find('#color_picker').eq(0)
|
||||
.find('#jGraduate_colPick').eq(0).find('#jPicker-table').eq(0)
|
||||
.find('.QuickColor').eq(3).click({ force: true });
|
||||
.find('.QuickColor').eq(3).click({ force: true })
|
||||
cy.get('#fill_color').shadow().find('#color_picker').eq(0)
|
||||
.find('#jGraduate_colPick').eq(0).find('#jPicker-table').eq(0)
|
||||
.find('#Ok').eq(0).click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.find('#Ok').eq(0).click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_anchor_start', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_text_anchor_start')
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_anchor_middle', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_text_anchor_middle')
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_anchor_end', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_text_anchor_end')
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_change_rotation', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
for(let n = 0; n < 5; n ++){
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
for (let n = 0; n < 5; n++) {
|
||||
cy.get('#angle').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_change_blur', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#blur').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_change_opacity', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#opacity').shadow().find('elix-number-spin-box').eq(0).shadow().find('#downButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_align_to_page', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#tool_position').shadow().find('elix-dropdown-list').eq(0).invoke('attr', 'opened', 'opened');
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
cy.get('#tool_position').shadow().find('elix-dropdown-list').eq(0).invoke('attr', 'opened', 'opened')
|
||||
cy.get('#tool_position').find('se-list-item').eq(2).shadow().find('elix-option').eq(0)
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_change_class', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
cy.get('#elem_class').shadow().find('elix-input').eq(0).shadow().find('#inner').eq(0)
|
||||
.type('svg_2_class{enter}', { force: true });
|
||||
.type('svg_2_class{enter}', { force: true })
|
||||
cy.get('#svg_2')
|
||||
.should('satisfy', ($el) => {
|
||||
const classList = Array.from($el[0].classList);
|
||||
return classList.includes('svg_2_class');
|
||||
});
|
||||
});
|
||||
const classList = Array.from($el[0].classList)
|
||||
return classList.includes('svg_2_class')
|
||||
})
|
||||
})
|
||||
it('check tool_text_change_id', function () {
|
||||
cy.get('#svg_2').click({ force: true }).click({ force: true });
|
||||
cy.get('#svg_2').click({ force: true }).click({ force: true })
|
||||
cy.get('#elem_id').shadow().find('elix-input').eq(0).shadow().find('#inner').eq(0)
|
||||
.type('_id{enter}', { force: true });
|
||||
.type('_id{enter}', { force: true })
|
||||
cy.get('#svg_2_id')
|
||||
.should('satisfy', ($el) => {
|
||||
const classList = Array.from($el[0].classList);
|
||||
return classList.includes('svg_2_class');
|
||||
});
|
||||
});
|
||||
const classList = Array.from($el[0].classList)
|
||||
return classList.includes('svg_2_class')
|
||||
})
|
||||
})
|
||||
it('check tool_text_delete', function () {
|
||||
cy.get('#svg_2_id').click({ force: true });
|
||||
cy.get('#tool_delete').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_2_id').click({ force: true })
|
||||
cy.get('#tool_delete').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_change_font_family', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#tool_font_family').shadow().find('select').select("Serif");
|
||||
testSnapshot();
|
||||
});
|
||||
});
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_font_family').shadow().find('select').select('Serif')
|
||||
testSnapshot()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,55 +1,55 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
cy.get('#svgcontent').cleanSnapshot()
|
||||
}
|
||||
|
||||
describe('use all parts of svg-edit', function () {
|
||||
before(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('check tool_source_set', function () {
|
||||
cy.get('#tool_source').click({ force: true });
|
||||
cy.get('#tool_source').click({ force: true })
|
||||
cy.get('#svg_source_textarea')
|
||||
.type('{selectall}', { force: true })
|
||||
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
</g>
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false });
|
||||
cy.get('#tool_source_save').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false })
|
||||
cy.get('#tool_source_save').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_shape', function () {
|
||||
cy.get('#tool_shapelib').shadow().find('.overall').eq(0).click({ force: true });
|
||||
cy.get('[data-shape="heart"]').click({ force: true });
|
||||
cy.get('#tool_shapelib').shadow().find('.overall').eq(0).click({ force: true })
|
||||
cy.get('[data-shape="heart"]').click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousemove', 200, 200, { force: true })
|
||||
.trigger('mousedown', 200, 200, { force: true })
|
||||
.trigger('mousemove', 20, 20, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
.trigger('mouseup', { force: true })
|
||||
cy.get('#selectorGrip_rotate')
|
||||
.trigger('mousedown')
|
||||
.trigger('mousemove', 20, 20, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_image', function () {
|
||||
cy.get('#tool_image').click({ force: true });
|
||||
cy.get('#tool_image').click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousedown', 100, 100, { force: true })
|
||||
.trigger('mousemove', 120, 120, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
.trigger('mouseup', { force: true })
|
||||
// eslint-disable-next-line promise/catch-or-return
|
||||
cy.window()
|
||||
// eslint-disable-next-line promise/always-return
|
||||
.then(($win) => {
|
||||
cy.stub($win, 'prompt').returns('./images/logo.svg');
|
||||
cy.contains('OK');
|
||||
});
|
||||
testSnapshot();
|
||||
});
|
||||
});
|
||||
cy.stub($win, 'prompt').returns('./images/logo.svg')
|
||||
cy.contains('OK')
|
||||
})
|
||||
testSnapshot()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,124 +1,124 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
cy.get('#svgcontent').cleanSnapshot()
|
||||
}
|
||||
|
||||
describe('use all parts of svg-edit', function () {
|
||||
before(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('check tool_source_set', function () {
|
||||
cy.get('#tool_source').click({ force: true });
|
||||
cy.get('#tool_source').click({ force: true })
|
||||
cy.get('#svg_source_textarea')
|
||||
.type('{selectall}', { force: true })
|
||||
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
</g>
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false });
|
||||
cy.get('#tool_source_save').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false })
|
||||
cy.get('#tool_source_save').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_circle', function () {
|
||||
cy.get('#tool_circle')
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousedown', 150, 150, { force: true })
|
||||
.trigger('mousemove', 250, 200, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_fhellipse', function () {
|
||||
cy.get('#tool_fhellipse')
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousedown', 200, 80, { force: true })
|
||||
.trigger('mousemove', 320, 80, { force: true })
|
||||
.trigger('mousemove', 320, 180, { force: true })
|
||||
.trigger('mousemove', 200, 180, { force: true })
|
||||
.trigger('mousemove', 200, 80, { force: true })
|
||||
.trigger('mouseup', 200, 80, { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', 200, 80, { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_ellipse', function () {
|
||||
cy.get('#tool_ellipse').click({ force: true });
|
||||
cy.get('#tool_ellipse').click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousedown', 75, 150, { force: true })
|
||||
.trigger('mousemove', 130, 175, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_circle_change_fill_color', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
cy.get('#js-se-palette').find('.square').eq(8)
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_circle_change_opacity', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#opacity').shadow().find('elix-number-spin-box').eq(0).shadow().find('#downButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_ellipse_change_rotation', function () {
|
||||
cy.get('#svg_3').click({ force: true });
|
||||
for(let n = 0; n < 5; n ++){
|
||||
cy.get('#svg_3').click({ force: true })
|
||||
for (let n = 0; n < 5; n++) {
|
||||
cy.get('#angle').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_ellipse_change_blur', function () {
|
||||
cy.get('#svg_3').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_3').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#blur').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_ellipse_change_cx_cy_coordinate', function () {
|
||||
cy.get('#svg_3').click({ force: true });
|
||||
for(let n = 0; n < 25; n ++){
|
||||
cy.get('#svg_3').click({ force: true })
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#ellipse_cx').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
for(let n = 0; n < 25; n ++){
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#ellipse_cy').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_ellipse_change_rx_ry_radius', function () {
|
||||
cy.get('#svg_3').click({ force: true });
|
||||
for(let n = 0; n < 25; n ++){
|
||||
cy.get('#svg_3').click({ force: true })
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#ellipse_rx').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
for(let n = 0; n < 25; n ++){
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#ellipse_ry').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_ellipse_bring_to_back', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#tool_move_bottom').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
cy.get('#tool_move_bottom').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_ellipse_bring_to_front', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#tool_move_top').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
cy.get('#tool_move_top').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_ellipse_clone', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#tool_clone').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
});
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
cy.get('#tool_clone').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
cy.get('#svgcontent').cleanSnapshot()
|
||||
}
|
||||
|
||||
describe('use all parts of svg-edit', function () {
|
||||
before(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('check tool_source_set', function () {
|
||||
cy.get('#tool_source').click({ force: true });
|
||||
cy.get('#tool_source').click({ force: true })
|
||||
cy.get('#svg_source_textarea')
|
||||
.type('{selectall}', { force: true })
|
||||
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
</g>
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false });
|
||||
cy.get('#tool_source_save').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false })
|
||||
cy.get('#tool_source_save').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_path', function () {
|
||||
cy.get('#tool_path')
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousedown', 50, 50, { force: true })
|
||||
.trigger('mouseup', { force: true })
|
||||
|
@ -37,49 +37,49 @@ describe('use all parts of svg-edit', function () {
|
|||
.trigger('mouseup', { force: true })
|
||||
.trigger('mousemove', 0, 0, { force: true })
|
||||
.trigger('mousedown', 0, 0, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_path_change_node_xy', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').dblclick({ force: true });
|
||||
for(let n = 0; n < 25; n ++){
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#svg_1').dblclick({ force: true })
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#path_node_x').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
for(let n = 0; n < 25; n ++){
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#path_node_y').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_path_change_seg_type', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').dblclick({ force: true });
|
||||
cy.get('#seg_type').shadow().find('select').select('6').should('have.value', '6');
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#svg_1').dblclick({ force: true })
|
||||
cy.get('#seg_type').shadow().find('select').select('6').should('have.value', '6')
|
||||
cy.get('#ctrlpointgrip_3c1')
|
||||
.trigger('mousedown', { force: true })
|
||||
.trigger('mousemove', 130, 175, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_path_change_clone_node', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').dblclick({ force: true });
|
||||
cy.get('#tool_node_clone').click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#svg_1').dblclick({ force: true })
|
||||
cy.get('#tool_node_clone').click({ force: true })
|
||||
cy.get('#pathpointgrip_4')
|
||||
.trigger('mousedown', { force: true })
|
||||
.trigger('mousemove', 130, 175, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_path_openclose', function () {
|
||||
cy.get('#tool_select').click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').dblclick({ force: true });
|
||||
cy.get('#tool_openclose_path').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#tool_select').click({ force: true })
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#svg_1').dblclick({ force: true })
|
||||
cy.get('#tool_openclose_path').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
/* it('check tool_path_add_subpath', function () {
|
||||
cy.get('#tool_add_subpath').click({ force: true });
|
||||
cy.get('#svgcontent')
|
||||
|
@ -97,4 +97,4 @@ describe('use all parts of svg-edit', function () {
|
|||
cy.get('#tool_select').click({ force: true });
|
||||
testSnapshot();
|
||||
}); */
|
||||
});
|
||||
})
|
||||
|
|
|
@ -1,164 +1,164 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
cy.get('#svgcontent').cleanSnapshot()
|
||||
}
|
||||
|
||||
describe('use all parts of svg-edit', function () {
|
||||
before(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('check tool_source_set', function () {
|
||||
cy.get('#tool_source').click({ force: true });
|
||||
cy.get('#tool_source').click({ force: true })
|
||||
cy.get('#svg_source_textarea')
|
||||
.type('{selectall}', { force: true })
|
||||
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
</g>
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false });
|
||||
cy.get('#tool_source_save').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false })
|
||||
cy.get('#tool_source_save').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_rect', function () {
|
||||
cy.get('#tool_rect')
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousedown', 150, 150, { force: true })
|
||||
.trigger('mousemove', 250, 200, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_fhrect', function () {
|
||||
cy.get('#tool_fhrect')
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousedown', 200, 80, { force: true })
|
||||
.trigger('mousemove', 320, 80, { force: true })
|
||||
.trigger('mousemove', 320, 180, { force: true })
|
||||
.trigger('mousemove', 200, 180, { force: true })
|
||||
.trigger('mousemove', 200, 80, { force: true })
|
||||
.trigger('mouseup', 200, 80, { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', 200, 80, { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_square', function () {
|
||||
cy.get('#tool_square').click({ force: true });
|
||||
cy.get('#tool_square').click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousedown', 75, 150, { force: true })
|
||||
.trigger('mousemove', 125, 200, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_rect_change_fill_color', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#js-se-palette').find('.square').eq(8)
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_rect_change_rotation', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
for(let n = 0; n < 5; n ++){
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
for (let n = 0; n < 5; n++) {
|
||||
cy.get('#angle').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_rect_change_blur', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#blur').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_rect_change_opacity', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#opacity').shadow().find('elix-number-spin-box').eq(0).shadow().find('#downButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_fhrect_change_x_y_coordinate', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
for(let n = 0; n < 25; n ++){
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#selected_x').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
for(let n = 0; n < 25; n ++){
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#selected_y').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_fhrect_change_width_height', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
for(let n = 0; n < 25; n ++){
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#rect_width').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
for(let n = 0; n < 25; n ++){
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#rect_height').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_square_clone', function () {
|
||||
cy.get('#svg_3').click({ force: true });
|
||||
cy.get('#tool_clone').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_3').click({ force: true })
|
||||
cy.get('#tool_clone').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_square_bring_to_back', function () {
|
||||
cy.get('#svg_3').click({ force: true });
|
||||
cy.get('#tool_move_bottom').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_3').click({ force: true })
|
||||
cy.get('#tool_move_bottom').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_square_bring_to_front', function () {
|
||||
cy.get('#svg_3').click({ force: true });
|
||||
cy.get('#tool_move_top').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_3').click({ force: true })
|
||||
cy.get('#tool_move_top').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_square_change_corner_radius', function () {
|
||||
cy.get('#svg_4').click({ force: true });
|
||||
for(let n = 0; n < 25; n ++){
|
||||
cy.get('#svg_4').click({ force: true })
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#rect_rx').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_rect_change_to_path', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#tool_topath').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
cy.get('#tool_topath').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_rect_delete', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#tool_delete').click({ force: true });
|
||||
cy.get('#svg_3').click({ force: true });
|
||||
cy.get('#tool_delete').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_delete').click({ force: true })
|
||||
cy.get('#svg_3').click({ force: true })
|
||||
cy.get('#tool_delete').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_rect_change_class', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
cy.get('#elem_class').shadow().find('elix-input').eq(0).shadow().find('#inner').eq(0)
|
||||
.type('svg_2_class{enter}', { force: true });
|
||||
.type('svg_2_class{enter}', { force: true })
|
||||
cy.get('#svg_2')
|
||||
.should('satisfy', ($el) => {
|
||||
const classList = Array.from($el[0].classList);
|
||||
return classList.includes('svg_2_class');
|
||||
});
|
||||
});
|
||||
const classList = Array.from($el[0].classList)
|
||||
return classList.includes('svg_2_class')
|
||||
})
|
||||
})
|
||||
it('check tool_rect_change_id', function () {
|
||||
cy.get('#svg_2').click({ force: true }).click({ force: true });
|
||||
cy.get('#svg_2').click({ force: true }).click({ force: true })
|
||||
cy.get('#elem_id').shadow().find('elix-input').eq(0).shadow().find('#inner').eq(0)
|
||||
.type('_id{enter}', { force: true });
|
||||
.type('_id{enter}', { force: true })
|
||||
cy.get('#svg_2_id')
|
||||
.should('satisfy', ($el) => {
|
||||
const classList = Array.from($el[0].classList);
|
||||
return classList.includes('svg_2_class');
|
||||
});
|
||||
});
|
||||
});
|
||||
const classList = Array.from($el[0].classList)
|
||||
return classList.includes('svg_2_class')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,153 +1,153 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
cy.get('#svgcontent').cleanSnapshot()
|
||||
}
|
||||
|
||||
describe('use all parts of svg-edit', function () {
|
||||
before(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('check tool_source_set', function () {
|
||||
cy.get('#tool_source').click({ force: true });
|
||||
cy.get('#tool_source').click({ force: true })
|
||||
cy.get('#svg_source_textarea')
|
||||
.type('{selectall}', { force: true })
|
||||
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
</g>
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false });
|
||||
cy.get('#tool_source_save').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false })
|
||||
cy.get('#tool_source_save').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_line', function () {
|
||||
cy.get('#tool_line')
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousemove', 200, 200, { force: true })
|
||||
.trigger('mousedown', 200, 200, { force: true })
|
||||
.trigger('mousemove', 250, 250, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_line_change_class', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#elem_class').shadow().find('elix-input').eq(0).shadow().find('#inner').eq(0)
|
||||
.type('svg_1_class{enter}', { force: true });
|
||||
.type('svg_1_class{enter}', { force: true })
|
||||
cy.get('#svg_1')
|
||||
.should('satisfy', ($el) => {
|
||||
const classList = Array.from($el[0].classList);
|
||||
return classList.includes('svg_1_class');
|
||||
});
|
||||
});
|
||||
const classList = Array.from($el[0].classList)
|
||||
return classList.includes('svg_1_class')
|
||||
})
|
||||
})
|
||||
it('check tool_line_change_id', function () {
|
||||
cy.get('#svg_1').click({ force: true }).click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true }).click({ force: true })
|
||||
cy.get('#elem_id').shadow().find('elix-input').eq(0).shadow().find('#inner').eq(0)
|
||||
.type('_id{enter}', { force: true });
|
||||
.type('_id{enter}', { force: true })
|
||||
cy.get('#svg_1_id')
|
||||
.should('satisfy', ($el) => {
|
||||
const classList = Array.from($el[0].classList);
|
||||
return classList.includes('svg_1_class');
|
||||
});
|
||||
});
|
||||
const classList = Array.from($el[0].classList)
|
||||
return classList.includes('svg_1_class')
|
||||
})
|
||||
})
|
||||
it('check tool_line_change_rotation', function () {
|
||||
cy.get('#svg_1_id').click({ force: true });
|
||||
for(let n = 0; n < 5; n ++){
|
||||
cy.get('#svg_1_id').click({ force: true })
|
||||
for (let n = 0; n < 5; n++) {
|
||||
cy.get('#angle').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_line_change_blur', function () {
|
||||
cy.get('#svg_1_id').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_1_id').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#blur').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_line_change_opacity', function () {
|
||||
cy.get('#svg_1_id').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_1_id').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#opacity').shadow().find('elix-number-spin-box').eq(0).shadow().find('#downButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_line_delete', function () {
|
||||
cy.get('#svg_1_id').click({ force: true });
|
||||
cy.get('#tool_delete').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_1_id').click({ force: true })
|
||||
cy.get('#tool_delete').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_line_clone', function () {
|
||||
cy.get('#tool_line')
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousemove', 200, 200, { force: true })
|
||||
.trigger('mousedown', 200, 200, { force: true })
|
||||
.trigger('mousemove', 250, 250, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#tool_clone').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', { force: true })
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
cy.get('#tool_clone').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_line_bring_to_back', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#tool_move_bottom').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
cy.get('#tool_move_bottom').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_line_bring_to_front', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#tool_move_top').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
cy.get('#tool_move_top').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_line_change_x_y_coordinate', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
for(let n = 0; n < 25; n ++){
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#line_x1').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
for(let n = 0; n < 25; n ++){
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#line_y1').shadow().find('elix-number-spin-box').eq(0).shadow().find('#downButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
for(let n = 0; n < 25; n ++){
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#line_x2').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
for(let n = 0; n < 25; n ++){
|
||||
for (let n = 0; n < 25; n++) {
|
||||
cy.get('#line_y2').shadow().find('elix-number-spin-box').eq(0).shadow().find('#downButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_line_change_stroke_width', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#stroke_width').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_line_change_stoke_color', function () {
|
||||
cy.get('#svg_3').click({ force: true });
|
||||
cy.get('#stroke_color').shadow().find('#picker').eq(0).click({ force: true });
|
||||
cy.get('#svg_3').click({ force: true })
|
||||
cy.get('#stroke_color').shadow().find('#picker').eq(0).click({ force: true })
|
||||
cy.get('#stroke_color').shadow().find('#color_picker').eq(0)
|
||||
.find('#jGraduate_colPick').eq(0).find('#jPicker-table').eq(0)
|
||||
.find('.QuickColor').eq(9).click({ force: true });
|
||||
.find('.QuickColor').eq(9).click({ force: true })
|
||||
cy.get('#stroke_color').shadow().find('#color_picker').eq(0)
|
||||
.find('#jGraduate_colPick').eq(0).find('#jPicker-table').eq(0)
|
||||
.find('#Ok').eq(0).click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.find('#Ok').eq(0).click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_line_align_to_page', function () {
|
||||
cy.get('#svg_3').click({ force: true });
|
||||
cy.get('#tool_position').shadow().find('elix-dropdown-list').eq(0).invoke('attr', 'opened', 'opened');
|
||||
cy.get('#svg_3').click({ force: true })
|
||||
cy.get('#tool_position').shadow().find('elix-dropdown-list').eq(0).invoke('attr', 'opened', 'opened')
|
||||
cy.get('#tool_position').find('se-list-item').eq(2).shadow().find('elix-option').eq(0)
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,108 +1,108 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
cy.get('#svgcontent').cleanSnapshot()
|
||||
}
|
||||
|
||||
describe('use all parts of svg-edit', function () {
|
||||
before(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('check tool_source_set', function () {
|
||||
cy.get('#tool_source').click({ force: true });
|
||||
cy.get('#tool_source').click({ force: true })
|
||||
cy.get('#svg_source_textarea')
|
||||
.type('{selectall}', { force: true })
|
||||
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
</g>
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false });
|
||||
cy.get('#tool_source_save').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false })
|
||||
cy.get('#tool_source_save').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_polygon', function () {
|
||||
cy.get('#tool_polygon')
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousedown', 325, 250, { force: true })
|
||||
.trigger('mousemove', 325, 345, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_polygon_clone', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#tool_clone').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_clone').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_polygon_change_class', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
cy.get('#elem_class').shadow().find('elix-input').eq(0).shadow().find('#inner').eq(0)
|
||||
.type('svg_2_class{enter}', { force: true });
|
||||
.type('svg_2_class{enter}', { force: true })
|
||||
cy.get('#svg_2')
|
||||
.should('satisfy', ($el) => {
|
||||
const classList = Array.from($el[0].classList);
|
||||
return classList.includes('svg_2_class');
|
||||
});
|
||||
});
|
||||
const classList = Array.from($el[0].classList)
|
||||
return classList.includes('svg_2_class')
|
||||
})
|
||||
})
|
||||
it('check tool_polygon_change_id', function () {
|
||||
cy.get('#svg_2').click({ force: true }).click({ force: true });
|
||||
cy.get('#svg_2').click({ force: true }).click({ force: true })
|
||||
cy.get('#elem_id').shadow().find('elix-input').eq(0).shadow().find('#inner').eq(0)
|
||||
.type('_id{enter}', { force: true });
|
||||
.type('_id{enter}', { force: true })
|
||||
cy.get('#svg_2_id')
|
||||
.should('satisfy', ($el) => {
|
||||
const classList = Array.from($el[0].classList);
|
||||
return classList.includes('svg_2_class');
|
||||
});
|
||||
});
|
||||
const classList = Array.from($el[0].classList)
|
||||
return classList.includes('svg_2_class')
|
||||
})
|
||||
})
|
||||
it('check tool_polygon_change_rotation', function () {
|
||||
cy.get('#svg_2_id').click({ force: true });
|
||||
for(let n = 0; n < 5; n ++){
|
||||
cy.get('#svg_2_id').click({ force: true })
|
||||
for (let n = 0; n < 5; n++) {
|
||||
cy.get('#angle').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_polygon_change_blur', function () {
|
||||
cy.get('#svg_2_id').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_2_id').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#blur').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_polygon_change_opacity', function () {
|
||||
cy.get('#svg_2_id').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_2_id').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#opacity').shadow().find('elix-number-spin-box').eq(0).shadow().find('#downButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_polygon_bring_to_back', function () {
|
||||
cy.get('#svg_2_id').click({ force: true });
|
||||
cy.get('#tool_move_bottom').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_2_id').click({ force: true })
|
||||
cy.get('#tool_move_bottom').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_polygon_bring_to_front', function () {
|
||||
cy.get('#svg_2_id').click({ force: true });
|
||||
cy.get('#tool_move_top').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_2_id').click({ force: true })
|
||||
cy.get('#tool_move_top').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_polygon_delete', function () {
|
||||
cy.get('#svg_2_id').click({ force: true });
|
||||
cy.get('#tool_delete').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_2_id').click({ force: true })
|
||||
cy.get('#tool_delete').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_polygon_align_to_page', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#tool_position').shadow().find('elix-dropdown-list').eq(0).invoke('attr', 'opened', 'opened');
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_position').shadow().find('elix-dropdown-list').eq(0).invoke('attr', 'opened', 'opened')
|
||||
cy.get('#tool_position').find('se-list-item').eq(0).shadow().find('elix-option').eq(0)
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
/* it('check tool_polygon_change_x_y_coordinate', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
for(let n = 0; n < 25; n ++){
|
||||
|
@ -116,35 +116,35 @@ describe('use all parts of svg-edit', function () {
|
|||
testSnapshot();
|
||||
}); */
|
||||
it('check tool_polygon_change_stroke_width', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#stroke_width').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_polygon_change_stoke_fill_color', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#stroke_color').shadow().find('#picker').eq(0).click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#stroke_color').shadow().find('#picker').eq(0).click({ force: true })
|
||||
cy.get('#stroke_color').shadow().find('#color_picker').eq(0)
|
||||
.find('#jGraduate_colPick').eq(0).find('#jPicker-table').eq(0)
|
||||
.find('.QuickColor').eq(51).click({ force: true });
|
||||
.find('.QuickColor').eq(51).click({ force: true })
|
||||
cy.get('#stroke_color').shadow().find('#color_picker').eq(0)
|
||||
.find('#jGraduate_colPick').eq(0).find('#jPicker-table').eq(0)
|
||||
.find('#Ok').eq(0).click({ force: true });
|
||||
cy.get('#fill_color').shadow().find('#picker').eq(0).click({ force: true });
|
||||
.find('#Ok').eq(0).click({ force: true })
|
||||
cy.get('#fill_color').shadow().find('#picker').eq(0).click({ force: true })
|
||||
cy.get('#fill_color').shadow().find('#color_picker').eq(0)
|
||||
.find('#jGraduate_colPick').eq(0).find('#jPicker-table').eq(0)
|
||||
.find('.QuickColor').eq(3).click({ force: true });
|
||||
.find('.QuickColor').eq(3).click({ force: true })
|
||||
cy.get('#fill_color').shadow().find('#color_picker').eq(0)
|
||||
.find('#jGraduate_colPick').eq(0).find('#jPicker-table').eq(0)
|
||||
.find('#Ok').eq(0).click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.find('#Ok').eq(0).click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_polygon_change_sides', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#polySides').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,138 +1,138 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
cy.get('#svgcontent').cleanSnapshot()
|
||||
}
|
||||
|
||||
describe('use all parts of svg-edit', function () {
|
||||
before(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('check tool_source_set', function () {
|
||||
cy.get('#tool_source').click({ force: true });
|
||||
cy.get('#tool_source').click({ force: true })
|
||||
cy.get('#svg_source_textarea')
|
||||
.type('{selectall}', { force: true })
|
||||
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
</g>
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false });
|
||||
cy.get('#tool_source_save').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
</svg>`, { force: true, parseSpecialCharSequences: false })
|
||||
cy.get('#tool_source_save').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_star', function () {
|
||||
cy.get('#tool_star')
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
cy.get('#svgcontent')
|
||||
.trigger('mousedown', 300, 150, { force: true })
|
||||
.trigger('mousemove', 300, 250, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.trigger('mouseup', { force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_star_clone', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#tool_clone').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_clone').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_star_change_class', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
cy.get('#elem_class').shadow().find('elix-input').eq(0).shadow().find('#inner').eq(0)
|
||||
.type('svg_2_class{enter}', { force: true });
|
||||
.type('svg_2_class{enter}', { force: true })
|
||||
cy.get('#svg_2')
|
||||
.should('satisfy', ($el) => {
|
||||
const classList = Array.from($el[0].classList);
|
||||
return classList.includes('svg_2_class');
|
||||
});
|
||||
});
|
||||
const classList = Array.from($el[0].classList)
|
||||
return classList.includes('svg_2_class')
|
||||
})
|
||||
})
|
||||
it('check tool_star_change_id', function () {
|
||||
cy.get('#svg_2').click({ force: true }).click({ force: true });
|
||||
cy.get('#svg_2').click({ force: true }).click({ force: true })
|
||||
cy.get('#elem_id').shadow().find('elix-input').eq(0).shadow().find('#inner').eq(0)
|
||||
.type('_id{enter}', { force: true });
|
||||
.type('_id{enter}', { force: true })
|
||||
cy.get('#svg_2_id')
|
||||
.should('satisfy', ($el) => {
|
||||
const classList = Array.from($el[0].classList);
|
||||
return classList.includes('svg_2_class');
|
||||
});
|
||||
});
|
||||
const classList = Array.from($el[0].classList)
|
||||
return classList.includes('svg_2_class')
|
||||
})
|
||||
})
|
||||
it('check tool_star_change_rotation', function () {
|
||||
cy.get('#svg_2_id').click({ force: true });
|
||||
for(let n = 0; n < 5; n ++){
|
||||
cy.get('#svg_2_id').click({ force: true })
|
||||
for (let n = 0; n < 5; n++) {
|
||||
cy.get('#angle').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_star_change_blur', function () {
|
||||
cy.get('#svg_2_id').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_2_id').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#blur').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_star_change_opacity', function () {
|
||||
cy.get('#svg_2_id').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_2_id').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#opacity').shadow().find('elix-number-spin-box').eq(0).shadow().find('#downButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_star_bring_to_back', function () {
|
||||
cy.get('#svg_2_id').click({ force: true });
|
||||
cy.get('#tool_move_bottom').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_2_id').click({ force: true })
|
||||
cy.get('#tool_move_bottom').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_star_bring_to_front', function () {
|
||||
cy.get('#svg_2_id').click({ force: true });
|
||||
cy.get('#tool_move_top').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_2_id').click({ force: true })
|
||||
cy.get('#tool_move_top').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_star_delete', function () {
|
||||
cy.get('#svg_2_id').click({ force: true });
|
||||
cy.get('#tool_delete').click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
cy.get('#svg_2_id').click({ force: true })
|
||||
cy.get('#tool_delete').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_star_align_to_page', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#tool_position').shadow().find('elix-dropdown-list').eq(0).invoke('attr', 'opened', 'opened');
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_position').shadow().find('elix-dropdown-list').eq(0).invoke('attr', 'opened', 'opened')
|
||||
cy.get('#tool_position').find('se-list-item').eq(0).shadow().find('elix-option').eq(0)
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_star_change_stroke_width', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
for(let n = 0; n < 10; n ++){
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
for (let n = 0; n < 10; n++) {
|
||||
cy.get('#stroke_width').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
.click({ force: true })
|
||||
}
|
||||
testSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_star_change_stoke_fill_color', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#stroke_color').shadow().find('#picker').eq(0).click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#stroke_color').shadow().find('#picker').eq(0).click({ force: true })
|
||||
cy.get('#stroke_color').shadow().find('#color_picker').eq(0)
|
||||
.find('#jGraduate_colPick').eq(0).find('#jPicker-table').eq(0)
|
||||
.find('.QuickColor').eq(51).click({ force: true });
|
||||
.find('.QuickColor').eq(51).click({ force: true })
|
||||
cy.get('#stroke_color').shadow().find('#color_picker').eq(0)
|
||||
.find('#jGraduate_colPick').eq(0).find('#jPicker-table').eq(0)
|
||||
.find('#Ok').eq(0).click({ force: true });
|
||||
cy.get('#fill_color').shadow().find('#picker').eq(0).click({ force: true });
|
||||
.find('#Ok').eq(0).click({ force: true })
|
||||
cy.get('#fill_color').shadow().find('#picker').eq(0).click({ force: true })
|
||||
cy.get('#fill_color').shadow().find('#color_picker').eq(0)
|
||||
.find('#jGraduate_colPick').eq(0).find('#jPicker-table').eq(0)
|
||||
.find('.QuickColor').eq(3).click({ force: true });
|
||||
.find('.QuickColor').eq(3).click({ force: true })
|
||||
cy.get('#fill_color').shadow().find('#color_picker').eq(0)
|
||||
.find('#jGraduate_colPick').eq(0).find('#jPicker-table').eq(0)
|
||||
.find('#Ok').eq(0).click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.find('#Ok').eq(0).click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_star_change_sides', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#starNumPoints').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
describe('UI - Tool selection', function () {
|
||||
beforeEach(() => {
|
||||
visitAndApproveStorage();
|
||||
});
|
||||
visitAndApproveStorage()
|
||||
})
|
||||
|
||||
it('should set rectangle selection by click', function () {
|
||||
cy.get('#tools_rect')
|
||||
.should('not.have.attr', 'pressed');
|
||||
.should('not.have.attr', 'pressed')
|
||||
cy.get('#tools_rect')
|
||||
.trigger('click', { force: true })
|
||||
.should('have.attr', 'pressed');
|
||||
});
|
||||
});
|
||||
.should('have.attr', 'pressed')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
describe('Browser bugs', function () {
|
||||
it('removeItem and setAttribute test (Chromium 843901; now fixed)', function () {
|
||||
// See https://bugs.chromium.org/p/chromium/issues/detail?id=843901
|
||||
const elem = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
||||
elem.setAttribute('transform', 'matrix(1,0,0,1,0,0)');
|
||||
elem.transform.baseVal.removeItem(0);
|
||||
elem.removeAttribute('transform');
|
||||
assert.equal(elem.hasAttribute('transform'), false);
|
||||
});
|
||||
});
|
||||
const elem = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
|
||||
elem.setAttribute('transform', 'matrix(1,0,0,1,0,0)')
|
||||
elem.transform.baseVal.removeItem(0)
|
||||
elem.removeAttribute('transform')
|
||||
assert.equal(elem.hasAttribute('transform'), false)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as contextmenu from '../../../instrumented/editor/contextmenu.js';
|
||||
import * as contextmenu from '../../../instrumented/editor/contextmenu.js'
|
||||
|
||||
describe('contextmenu', function () {
|
||||
/**
|
||||
|
@ -6,53 +6,53 @@ describe('contextmenu', function () {
|
|||
* @returns {void}
|
||||
*/
|
||||
afterEach(() => {
|
||||
contextmenu.resetCustomMenus();
|
||||
});
|
||||
contextmenu.resetCustomMenus()
|
||||
})
|
||||
|
||||
it('Test svgedit.contextmenu package', function () {
|
||||
assert.ok(contextmenu, 'contextmenu registered correctly');
|
||||
assert.ok(contextmenu.add, 'add registered correctly');
|
||||
assert.ok(contextmenu.hasCustomHandler, 'contextmenu hasCustomHandler registered correctly');
|
||||
assert.ok(contextmenu.getCustomHandler, 'contextmenu getCustomHandler registered correctly');
|
||||
});
|
||||
assert.ok(contextmenu, 'contextmenu registered correctly')
|
||||
assert.ok(contextmenu.add, 'add registered correctly')
|
||||
assert.ok(contextmenu.hasCustomHandler, 'contextmenu hasCustomHandler registered correctly')
|
||||
assert.ok(contextmenu.getCustomHandler, 'contextmenu getCustomHandler registered correctly')
|
||||
})
|
||||
|
||||
it('Test svgedit.contextmenu does not add invalid menu item', function () {
|
||||
assert.throws(
|
||||
() => contextmenu.add({ id: 'justanid' }),
|
||||
null, null,
|
||||
'menu item with just an id is invalid'
|
||||
);
|
||||
)
|
||||
|
||||
assert.throws(
|
||||
() => contextmenu.add({ id: 'idandlabel', label: 'anicelabel' }),
|
||||
null, null,
|
||||
'menu item with just an id and label is invalid'
|
||||
);
|
||||
)
|
||||
|
||||
assert.throws(
|
||||
() => contextmenu.add({ id: 'idandlabel', label: 'anicelabel', action: 'notafunction' }),
|
||||
null, null,
|
||||
'menu item with action that is not a function is invalid'
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
it('Test svgedit.contextmenu adds valid menu item', function () {
|
||||
const validItem = { id: 'valid', label: 'anicelabel', action () { /* empty fn */ } };
|
||||
contextmenu.add(validItem);
|
||||
const validItem = { id: 'valid', label: 'anicelabel', action () { /* empty fn */ } }
|
||||
contextmenu.add(validItem)
|
||||
|
||||
assert.ok(contextmenu.hasCustomHandler('valid'), 'Valid menu item is added.');
|
||||
assert.equal(contextmenu.getCustomHandler('valid'), validItem.action, 'Valid menu action is added.');
|
||||
});
|
||||
assert.ok(contextmenu.hasCustomHandler('valid'), 'Valid menu item is added.')
|
||||
assert.equal(contextmenu.getCustomHandler('valid'), validItem.action, 'Valid menu action is added.')
|
||||
})
|
||||
|
||||
it('Test svgedit.contextmenu rejects valid duplicate menu item id', function () {
|
||||
const validItem1 = { id: 'valid', label: 'anicelabel', action () { /* empty fn */ } };
|
||||
const validItem2 = { id: 'valid', label: 'anicelabel', action () { /* empty fn */ } };
|
||||
contextmenu.add(validItem1);
|
||||
const validItem1 = { id: 'valid', label: 'anicelabel', action () { /* empty fn */ } }
|
||||
const validItem2 = { id: 'valid', label: 'anicelabel', action () { /* empty fn */ } }
|
||||
contextmenu.add(validItem1)
|
||||
|
||||
assert.throws(
|
||||
() => contextmenu.add(validItem2),
|
||||
null, null,
|
||||
'duplicate menu item is rejected.'
|
||||
);
|
||||
});
|
||||
});
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js';
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
|
||||
import * as coords from '../../../instrumented/svgcanvas/coords.js';
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js'
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js'
|
||||
import * as coords from '../../../instrumented/svgcanvas/coords.js'
|
||||
|
||||
describe('coords', function () {
|
||||
let elemId = 1;
|
||||
let elemId = 1
|
||||
|
||||
const root = document.createElement('div');
|
||||
root.id = 'root';
|
||||
root.style.visibility = 'hidden';
|
||||
document.body.append(root);
|
||||
const root = document.createElement('div')
|
||||
root.id = 'root'
|
||||
root.style.visibility = 'hidden'
|
||||
document.body.append(root)
|
||||
|
||||
/**
|
||||
* Set up tests with mock data.
|
||||
* @returns {void}
|
||||
*/
|
||||
beforeEach(function () {
|
||||
const svgroot = document.createElementNS(NS.SVG, 'svg');
|
||||
svgroot.id = 'svgroot';
|
||||
root.append(svgroot);
|
||||
this.svg = document.createElementNS(NS.SVG, 'svg');
|
||||
svgroot.append(this.svg);
|
||||
const svgroot = document.createElementNS(NS.SVG, 'svg')
|
||||
svgroot.id = 'svgroot'
|
||||
root.append(svgroot)
|
||||
this.svg = document.createElementNS(NS.SVG, 'svg')
|
||||
svgroot.append(this.svg)
|
||||
|
||||
// Mock out editor context.
|
||||
utilities.init(
|
||||
|
@ -27,25 +27,25 @@ describe('coords', function () {
|
|||
* @implements {module:utilities.EditorContext}
|
||||
*/
|
||||
{
|
||||
getSvgRoot: () => { return this.svg; },
|
||||
getDOMDocument () { return null; },
|
||||
getDOMContainer () { return null; }
|
||||
getSvgRoot: () => { return this.svg },
|
||||
getDOMDocument () { return null },
|
||||
getDOMContainer () { return null }
|
||||
}
|
||||
);
|
||||
)
|
||||
coords.init(
|
||||
/**
|
||||
* @implements {module:coords.EditorContext}
|
||||
*/
|
||||
{
|
||||
getGridSnapping () { return false; },
|
||||
getGridSnapping () { return false },
|
||||
getDrawing () {
|
||||
return {
|
||||
getNextId () { return String(elemId++); }
|
||||
};
|
||||
getNextId () { return String(elemId++) }
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
/**
|
||||
* Tear down tests, removing elements.
|
||||
|
@ -53,255 +53,255 @@ describe('coords', function () {
|
|||
*/
|
||||
afterEach(function () {
|
||||
while (this.svg.hasChildNodes()) {
|
||||
this.svg.firstChild.remove();
|
||||
this.svg.firstChild.remove()
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
it('Test remapElement(translate) for rect', function () {
|
||||
const rect = document.createElementNS(NS.SVG, 'rect');
|
||||
rect.setAttribute('x', '200');
|
||||
rect.setAttribute('y', '150');
|
||||
rect.setAttribute('width', '250');
|
||||
rect.setAttribute('height', '120');
|
||||
this.svg.append(rect);
|
||||
const rect = document.createElementNS(NS.SVG, 'rect')
|
||||
rect.setAttribute('x', '200')
|
||||
rect.setAttribute('y', '150')
|
||||
rect.setAttribute('width', '250')
|
||||
rect.setAttribute('height', '120')
|
||||
this.svg.append(rect)
|
||||
|
||||
const attrs = {
|
||||
x: '200',
|
||||
y: '150',
|
||||
width: '125',
|
||||
height: '75'
|
||||
};
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
const m = this.svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
const m = this.svg.createSVGMatrix()
|
||||
m.a = 1; m.b = 0
|
||||
m.c = 0; m.d = 1
|
||||
m.e = 100; m.f = -50
|
||||
|
||||
coords.remapElement(rect, attrs, m);
|
||||
coords.remapElement(rect, attrs, m)
|
||||
|
||||
assert.equal(rect.getAttribute('x'), '300');
|
||||
assert.equal(rect.getAttribute('y'), '100');
|
||||
assert.equal(rect.getAttribute('width'), '125');
|
||||
assert.equal(rect.getAttribute('height'), '75');
|
||||
});
|
||||
assert.equal(rect.getAttribute('x'), '300')
|
||||
assert.equal(rect.getAttribute('y'), '100')
|
||||
assert.equal(rect.getAttribute('width'), '125')
|
||||
assert.equal(rect.getAttribute('height'), '75')
|
||||
})
|
||||
|
||||
it('Test remapElement(scale) for rect', function () {
|
||||
const rect = document.createElementNS(NS.SVG, 'rect');
|
||||
rect.setAttribute('width', '250');
|
||||
rect.setAttribute('height', '120');
|
||||
this.svg.append(rect);
|
||||
const rect = document.createElementNS(NS.SVG, 'rect')
|
||||
rect.setAttribute('width', '250')
|
||||
rect.setAttribute('height', '120')
|
||||
this.svg.append(rect)
|
||||
|
||||
const attrs = {
|
||||
x: '0',
|
||||
y: '0',
|
||||
width: '250',
|
||||
height: '120'
|
||||
};
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
const m = this.svg.createSVGMatrix();
|
||||
m.a = 2; m.b = 0;
|
||||
m.c = 0; m.d = 0.5;
|
||||
m.e = 0; m.f = 0;
|
||||
const m = this.svg.createSVGMatrix()
|
||||
m.a = 2; m.b = 0
|
||||
m.c = 0; m.d = 0.5
|
||||
m.e = 0; m.f = 0
|
||||
|
||||
coords.remapElement(rect, attrs, m);
|
||||
coords.remapElement(rect, attrs, m)
|
||||
|
||||
assert.equal(rect.getAttribute('x'), '0');
|
||||
assert.equal(rect.getAttribute('y'), '0');
|
||||
assert.equal(rect.getAttribute('width'), '500');
|
||||
assert.equal(rect.getAttribute('height'), '60');
|
||||
});
|
||||
assert.equal(rect.getAttribute('x'), '0')
|
||||
assert.equal(rect.getAttribute('y'), '0')
|
||||
assert.equal(rect.getAttribute('width'), '500')
|
||||
assert.equal(rect.getAttribute('height'), '60')
|
||||
})
|
||||
|
||||
it('Test remapElement(translate) for circle', function () {
|
||||
const circle = document.createElementNS(NS.SVG, 'circle');
|
||||
circle.setAttribute('cx', '200');
|
||||
circle.setAttribute('cy', '150');
|
||||
circle.setAttribute('r', '125');
|
||||
this.svg.append(circle);
|
||||
const circle = document.createElementNS(NS.SVG, 'circle')
|
||||
circle.setAttribute('cx', '200')
|
||||
circle.setAttribute('cy', '150')
|
||||
circle.setAttribute('r', '125')
|
||||
this.svg.append(circle)
|
||||
|
||||
const attrs = {
|
||||
cx: '200',
|
||||
cy: '150',
|
||||
r: '125'
|
||||
};
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
const m = this.svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
const m = this.svg.createSVGMatrix()
|
||||
m.a = 1; m.b = 0
|
||||
m.c = 0; m.d = 1
|
||||
m.e = 100; m.f = -50
|
||||
|
||||
coords.remapElement(circle, attrs, m);
|
||||
coords.remapElement(circle, attrs, m)
|
||||
|
||||
assert.equal(circle.getAttribute('cx'), '300');
|
||||
assert.equal(circle.getAttribute('cy'), '100');
|
||||
assert.equal(circle.getAttribute('r'), '125');
|
||||
});
|
||||
assert.equal(circle.getAttribute('cx'), '300')
|
||||
assert.equal(circle.getAttribute('cy'), '100')
|
||||
assert.equal(circle.getAttribute('r'), '125')
|
||||
})
|
||||
|
||||
it('Test remapElement(scale) for circle', function () {
|
||||
const circle = document.createElementNS(NS.SVG, 'circle');
|
||||
circle.setAttribute('cx', '200');
|
||||
circle.setAttribute('cy', '150');
|
||||
circle.setAttribute('r', '250');
|
||||
this.svg.append(circle);
|
||||
const circle = document.createElementNS(NS.SVG, 'circle')
|
||||
circle.setAttribute('cx', '200')
|
||||
circle.setAttribute('cy', '150')
|
||||
circle.setAttribute('r', '250')
|
||||
this.svg.append(circle)
|
||||
|
||||
const attrs = {
|
||||
cx: '200',
|
||||
cy: '150',
|
||||
r: '250'
|
||||
};
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
const m = this.svg.createSVGMatrix();
|
||||
m.a = 2; m.b = 0;
|
||||
m.c = 0; m.d = 0.5;
|
||||
m.e = 0; m.f = 0;
|
||||
const m = this.svg.createSVGMatrix()
|
||||
m.a = 2; m.b = 0
|
||||
m.c = 0; m.d = 0.5
|
||||
m.e = 0; m.f = 0
|
||||
|
||||
coords.remapElement(circle, attrs, m);
|
||||
coords.remapElement(circle, attrs, m)
|
||||
|
||||
assert.equal(circle.getAttribute('cx'), '400');
|
||||
assert.equal(circle.getAttribute('cy'), '75');
|
||||
assert.equal(circle.getAttribute('cx'), '400')
|
||||
assert.equal(circle.getAttribute('cy'), '75')
|
||||
// Radius is the minimum that fits in the new bounding box.
|
||||
assert.equal(circle.getAttribute('r'), '125');
|
||||
});
|
||||
assert.equal(circle.getAttribute('r'), '125')
|
||||
})
|
||||
|
||||
it('Test remapElement(translate) for ellipse', function () {
|
||||
const ellipse = document.createElementNS(NS.SVG, 'ellipse');
|
||||
ellipse.setAttribute('cx', '200');
|
||||
ellipse.setAttribute('cy', '150');
|
||||
ellipse.setAttribute('rx', '125');
|
||||
ellipse.setAttribute('ry', '75');
|
||||
this.svg.append(ellipse);
|
||||
const ellipse = document.createElementNS(NS.SVG, 'ellipse')
|
||||
ellipse.setAttribute('cx', '200')
|
||||
ellipse.setAttribute('cy', '150')
|
||||
ellipse.setAttribute('rx', '125')
|
||||
ellipse.setAttribute('ry', '75')
|
||||
this.svg.append(ellipse)
|
||||
|
||||
const attrs = {
|
||||
cx: '200',
|
||||
cy: '150',
|
||||
rx: '125',
|
||||
ry: '75'
|
||||
};
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
const m = this.svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
const m = this.svg.createSVGMatrix()
|
||||
m.a = 1; m.b = 0
|
||||
m.c = 0; m.d = 1
|
||||
m.e = 100; m.f = -50
|
||||
|
||||
coords.remapElement(ellipse, attrs, m);
|
||||
coords.remapElement(ellipse, attrs, m)
|
||||
|
||||
assert.equal(ellipse.getAttribute('cx'), '300');
|
||||
assert.equal(ellipse.getAttribute('cy'), '100');
|
||||
assert.equal(ellipse.getAttribute('rx'), '125');
|
||||
assert.equal(ellipse.getAttribute('ry'), '75');
|
||||
});
|
||||
assert.equal(ellipse.getAttribute('cx'), '300')
|
||||
assert.equal(ellipse.getAttribute('cy'), '100')
|
||||
assert.equal(ellipse.getAttribute('rx'), '125')
|
||||
assert.equal(ellipse.getAttribute('ry'), '75')
|
||||
})
|
||||
|
||||
it('Test remapElement(scale) for ellipse', function () {
|
||||
const ellipse = document.createElementNS(NS.SVG, 'ellipse');
|
||||
ellipse.setAttribute('cx', '200');
|
||||
ellipse.setAttribute('cy', '150');
|
||||
ellipse.setAttribute('rx', '250');
|
||||
ellipse.setAttribute('ry', '120');
|
||||
this.svg.append(ellipse);
|
||||
const ellipse = document.createElementNS(NS.SVG, 'ellipse')
|
||||
ellipse.setAttribute('cx', '200')
|
||||
ellipse.setAttribute('cy', '150')
|
||||
ellipse.setAttribute('rx', '250')
|
||||
ellipse.setAttribute('ry', '120')
|
||||
this.svg.append(ellipse)
|
||||
|
||||
const attrs = {
|
||||
cx: '200',
|
||||
cy: '150',
|
||||
rx: '250',
|
||||
ry: '120'
|
||||
};
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
const m = this.svg.createSVGMatrix();
|
||||
m.a = 2; m.b = 0;
|
||||
m.c = 0; m.d = 0.5;
|
||||
m.e = 0; m.f = 0;
|
||||
const m = this.svg.createSVGMatrix()
|
||||
m.a = 2; m.b = 0
|
||||
m.c = 0; m.d = 0.5
|
||||
m.e = 0; m.f = 0
|
||||
|
||||
coords.remapElement(ellipse, attrs, m);
|
||||
coords.remapElement(ellipse, attrs, m)
|
||||
|
||||
assert.equal(ellipse.getAttribute('cx'), '400');
|
||||
assert.equal(ellipse.getAttribute('cy'), '75');
|
||||
assert.equal(ellipse.getAttribute('rx'), '500');
|
||||
assert.equal(ellipse.getAttribute('ry'), '60');
|
||||
});
|
||||
assert.equal(ellipse.getAttribute('cx'), '400')
|
||||
assert.equal(ellipse.getAttribute('cy'), '75')
|
||||
assert.equal(ellipse.getAttribute('rx'), '500')
|
||||
assert.equal(ellipse.getAttribute('ry'), '60')
|
||||
})
|
||||
|
||||
it('Test remapElement(translate) for line', function () {
|
||||
const line = document.createElementNS(NS.SVG, 'line');
|
||||
line.setAttribute('x1', '50');
|
||||
line.setAttribute('y1', '100');
|
||||
line.setAttribute('x2', '120');
|
||||
line.setAttribute('y2', '200');
|
||||
this.svg.append(line);
|
||||
const line = document.createElementNS(NS.SVG, 'line')
|
||||
line.setAttribute('x1', '50')
|
||||
line.setAttribute('y1', '100')
|
||||
line.setAttribute('x2', '120')
|
||||
line.setAttribute('y2', '200')
|
||||
this.svg.append(line)
|
||||
|
||||
const attrs = {
|
||||
x1: '50',
|
||||
y1: '100',
|
||||
x2: '120',
|
||||
y2: '200'
|
||||
};
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
const m = this.svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
const m = this.svg.createSVGMatrix()
|
||||
m.a = 1; m.b = 0
|
||||
m.c = 0; m.d = 1
|
||||
m.e = 100; m.f = -50
|
||||
|
||||
coords.remapElement(line, attrs, m);
|
||||
coords.remapElement(line, attrs, m)
|
||||
|
||||
assert.equal(line.getAttribute('x1'), '150');
|
||||
assert.equal(line.getAttribute('y1'), '50');
|
||||
assert.equal(line.getAttribute('x2'), '220');
|
||||
assert.equal(line.getAttribute('y2'), '150');
|
||||
});
|
||||
assert.equal(line.getAttribute('x1'), '150')
|
||||
assert.equal(line.getAttribute('y1'), '50')
|
||||
assert.equal(line.getAttribute('x2'), '220')
|
||||
assert.equal(line.getAttribute('y2'), '150')
|
||||
})
|
||||
|
||||
it('Test remapElement(scale) for line', function () {
|
||||
const line = document.createElementNS(NS.SVG, 'line');
|
||||
line.setAttribute('x1', '50');
|
||||
line.setAttribute('y1', '100');
|
||||
line.setAttribute('x2', '120');
|
||||
line.setAttribute('y2', '200');
|
||||
this.svg.append(line);
|
||||
const line = document.createElementNS(NS.SVG, 'line')
|
||||
line.setAttribute('x1', '50')
|
||||
line.setAttribute('y1', '100')
|
||||
line.setAttribute('x2', '120')
|
||||
line.setAttribute('y2', '200')
|
||||
this.svg.append(line)
|
||||
|
||||
const attrs = {
|
||||
x1: '50',
|
||||
y1: '100',
|
||||
x2: '120',
|
||||
y2: '200'
|
||||
};
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
const m = this.svg.createSVGMatrix();
|
||||
m.a = 2; m.b = 0;
|
||||
m.c = 0; m.d = 0.5;
|
||||
m.e = 0; m.f = 0;
|
||||
const m = this.svg.createSVGMatrix()
|
||||
m.a = 2; m.b = 0
|
||||
m.c = 0; m.d = 0.5
|
||||
m.e = 0; m.f = 0
|
||||
|
||||
coords.remapElement(line, attrs, m);
|
||||
coords.remapElement(line, attrs, m)
|
||||
|
||||
assert.equal(line.getAttribute('x1'), '100');
|
||||
assert.equal(line.getAttribute('y1'), '50');
|
||||
assert.equal(line.getAttribute('x2'), '240');
|
||||
assert.equal(line.getAttribute('y2'), '100');
|
||||
});
|
||||
assert.equal(line.getAttribute('x1'), '100')
|
||||
assert.equal(line.getAttribute('y1'), '50')
|
||||
assert.equal(line.getAttribute('x2'), '240')
|
||||
assert.equal(line.getAttribute('y2'), '100')
|
||||
})
|
||||
|
||||
it('Test remapElement(translate) for text', function () {
|
||||
const text = document.createElementNS(NS.SVG, 'text');
|
||||
text.setAttribute('x', '50');
|
||||
text.setAttribute('y', '100');
|
||||
this.svg.append(text);
|
||||
const text = document.createElementNS(NS.SVG, 'text')
|
||||
text.setAttribute('x', '50')
|
||||
text.setAttribute('y', '100')
|
||||
this.svg.append(text)
|
||||
|
||||
const attrs = {
|
||||
x: '50',
|
||||
y: '100'
|
||||
};
|
||||
}
|
||||
|
||||
// Create a translate.
|
||||
const m = this.svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 100; m.f = -50;
|
||||
const m = this.svg.createSVGMatrix()
|
||||
m.a = 1; m.b = 0
|
||||
m.c = 0; m.d = 1
|
||||
m.e = 100; m.f = -50
|
||||
|
||||
coords.remapElement(text, attrs, m);
|
||||
coords.remapElement(text, attrs, m)
|
||||
|
||||
assert.equal(text.getAttribute('x'), '150');
|
||||
assert.equal(text.getAttribute('y'), '50');
|
||||
});
|
||||
});
|
||||
assert.equal(text.getAttribute('x'), '150')
|
||||
assert.equal(text.getAttribute('y'), '50')
|
||||
})
|
||||
})
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,31 +1,34 @@
|
|||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js';
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
|
||||
import * as history from '../../../instrumented/svgcanvas/history.js';
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js'
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js'
|
||||
import * as history from '../../../instrumented/svgcanvas/history.js'
|
||||
|
||||
describe('history', function () {
|
||||
// TODO(codedread): Write tests for handling history events.
|
||||
|
||||
utilities.mock({
|
||||
getHref () { return '#foo'; },
|
||||
getHref () { return '#foo' },
|
||||
setHref () { /* empty fn */ },
|
||||
getRotationAngle () { return 0; }
|
||||
});
|
||||
getRotationAngle () { return 0 }
|
||||
})
|
||||
|
||||
// const svg = document.createElementNS(NS.SVG, 'svg');
|
||||
let undoMgr = null;
|
||||
let undoMgr = null
|
||||
|
||||
class MockCommand extends history.Command {
|
||||
constructor (optText) {
|
||||
super();
|
||||
this.text = optText;
|
||||
super()
|
||||
this.text = optText
|
||||
}
|
||||
|
||||
apply (handler) {
|
||||
super.apply(handler, () => { /* empty fn */ });
|
||||
super.apply(handler, () => { /* empty fn */ })
|
||||
}
|
||||
|
||||
unapply (handler) {
|
||||
super.unapply(handler, () => { /* empty fn */ });
|
||||
super.unapply(handler, () => { /* empty fn */ })
|
||||
}
|
||||
elements () { return []; }
|
||||
|
||||
elements () { return [] }
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -39,479 +42,479 @@ describe('history', function () {
|
|||
* @returns {void}
|
||||
*/
|
||||
beforeEach(function () {
|
||||
undoMgr = new history.UndoManager();
|
||||
undoMgr = new history.UndoManager()
|
||||
|
||||
document.body.textContent = '';
|
||||
this.divparent = document.createElement('div');
|
||||
this.divparent.id = 'divparent';
|
||||
this.divparent.style.visibility = 'hidden';
|
||||
document.body.textContent = ''
|
||||
this.divparent = document.createElement('div')
|
||||
this.divparent.id = 'divparent'
|
||||
this.divparent.style.visibility = 'hidden'
|
||||
|
||||
for (let i = 1; i <= 5; i++) {
|
||||
const div = document.createElement('div');
|
||||
const id = `div${i}`;
|
||||
div.id = id;
|
||||
this[id] = div;
|
||||
const div = document.createElement('div')
|
||||
const id = `div${i}`
|
||||
div.id = id
|
||||
this[id] = div
|
||||
}
|
||||
|
||||
this.divparent.append(this.div1, this.div2, this.div3);
|
||||
this.divparent.append(this.div1, this.div2, this.div3)
|
||||
|
||||
this.div4.style.visibility = 'hidden';
|
||||
this.div4.append(this.div5);
|
||||
this.div4.style.visibility = 'hidden'
|
||||
this.div4.append(this.div5)
|
||||
|
||||
document.body.append(this.divparent, this.div);
|
||||
});
|
||||
document.body.append(this.divparent, this.div)
|
||||
})
|
||||
/**
|
||||
* Tear down tests, destroying undo manager.
|
||||
* @returns {void}
|
||||
*/
|
||||
afterEach(() => {
|
||||
undoMgr = null;
|
||||
});
|
||||
undoMgr = null
|
||||
})
|
||||
|
||||
it('Test svgedit.history package', function () {
|
||||
assert.ok(history);
|
||||
assert.ok(history.MoveElementCommand);
|
||||
assert.ok(history.InsertElementCommand);
|
||||
assert.ok(history.ChangeElementCommand);
|
||||
assert.ok(history.RemoveElementCommand);
|
||||
assert.ok(history.BatchCommand);
|
||||
assert.ok(history.UndoManager);
|
||||
assert.equal(typeof history.MoveElementCommand, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof history.InsertElementCommand, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof history.ChangeElementCommand, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof history.RemoveElementCommand, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof history.BatchCommand, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof history.UndoManager, typeof function () { /* empty fn */ });
|
||||
});
|
||||
assert.ok(history)
|
||||
assert.ok(history.MoveElementCommand)
|
||||
assert.ok(history.InsertElementCommand)
|
||||
assert.ok(history.ChangeElementCommand)
|
||||
assert.ok(history.RemoveElementCommand)
|
||||
assert.ok(history.BatchCommand)
|
||||
assert.ok(history.UndoManager)
|
||||
assert.equal(typeof history.MoveElementCommand, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof history.InsertElementCommand, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof history.ChangeElementCommand, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof history.RemoveElementCommand, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof history.BatchCommand, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof history.UndoManager, typeof function () { /* empty fn */ })
|
||||
})
|
||||
|
||||
it('Test UndoManager methods', function () {
|
||||
assert.ok(undoMgr);
|
||||
assert.ok(undoMgr.addCommandToHistory);
|
||||
assert.ok(undoMgr.getUndoStackSize);
|
||||
assert.ok(undoMgr.getRedoStackSize);
|
||||
assert.ok(undoMgr.resetUndoStack);
|
||||
assert.ok(undoMgr.getNextUndoCommandText);
|
||||
assert.ok(undoMgr.getNextRedoCommandText);
|
||||
assert.ok(undoMgr)
|
||||
assert.ok(undoMgr.addCommandToHistory)
|
||||
assert.ok(undoMgr.getUndoStackSize)
|
||||
assert.ok(undoMgr.getRedoStackSize)
|
||||
assert.ok(undoMgr.resetUndoStack)
|
||||
assert.ok(undoMgr.getNextUndoCommandText)
|
||||
assert.ok(undoMgr.getNextRedoCommandText)
|
||||
|
||||
assert.equal(typeof undoMgr, typeof {});
|
||||
assert.equal(typeof undoMgr.addCommandToHistory, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof undoMgr.getUndoStackSize, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof undoMgr.getRedoStackSize, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof undoMgr.resetUndoStack, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof undoMgr.getNextUndoCommandText, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof undoMgr.getNextRedoCommandText, typeof function () { /* empty fn */ });
|
||||
});
|
||||
assert.equal(typeof undoMgr, typeof {})
|
||||
assert.equal(typeof undoMgr.addCommandToHistory, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof undoMgr.getUndoStackSize, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof undoMgr.getRedoStackSize, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof undoMgr.resetUndoStack, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof undoMgr.getNextUndoCommandText, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof undoMgr.getNextRedoCommandText, typeof function () { /* empty fn */ })
|
||||
})
|
||||
|
||||
it('Test UndoManager.addCommandToHistory() function', function () {
|
||||
assert.equal(undoMgr.getUndoStackSize(), 0);
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
assert.equal(undoMgr.getUndoStackSize(), 1);
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
assert.equal(undoMgr.getUndoStackSize(), 2);
|
||||
});
|
||||
assert.equal(undoMgr.getUndoStackSize(), 0)
|
||||
undoMgr.addCommandToHistory(new MockCommand())
|
||||
assert.equal(undoMgr.getUndoStackSize(), 1)
|
||||
undoMgr.addCommandToHistory(new MockCommand())
|
||||
assert.equal(undoMgr.getUndoStackSize(), 2)
|
||||
})
|
||||
|
||||
it('Test UndoManager.getUndoStackSize() and getRedoStackSize() functions', function () {
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.addCommandToHistory(new MockCommand())
|
||||
undoMgr.addCommandToHistory(new MockCommand())
|
||||
undoMgr.addCommandToHistory(new MockCommand())
|
||||
|
||||
assert.equal(undoMgr.getUndoStackSize(), 3);
|
||||
assert.equal(undoMgr.getRedoStackSize(), 0);
|
||||
assert.equal(undoMgr.getUndoStackSize(), 3)
|
||||
assert.equal(undoMgr.getRedoStackSize(), 0)
|
||||
|
||||
undoMgr.undo();
|
||||
assert.equal(undoMgr.getUndoStackSize(), 2);
|
||||
assert.equal(undoMgr.getRedoStackSize(), 1);
|
||||
undoMgr.undo()
|
||||
assert.equal(undoMgr.getUndoStackSize(), 2)
|
||||
assert.equal(undoMgr.getRedoStackSize(), 1)
|
||||
|
||||
undoMgr.undo();
|
||||
assert.equal(undoMgr.getUndoStackSize(), 1);
|
||||
assert.equal(undoMgr.getRedoStackSize(), 2);
|
||||
undoMgr.undo()
|
||||
assert.equal(undoMgr.getUndoStackSize(), 1)
|
||||
assert.equal(undoMgr.getRedoStackSize(), 2)
|
||||
|
||||
undoMgr.undo();
|
||||
assert.equal(undoMgr.getUndoStackSize(), 0);
|
||||
assert.equal(undoMgr.getRedoStackSize(), 3);
|
||||
undoMgr.undo()
|
||||
assert.equal(undoMgr.getUndoStackSize(), 0)
|
||||
assert.equal(undoMgr.getRedoStackSize(), 3)
|
||||
|
||||
undoMgr.undo();
|
||||
assert.equal(undoMgr.getUndoStackSize(), 0);
|
||||
assert.equal(undoMgr.getRedoStackSize(), 3);
|
||||
undoMgr.undo()
|
||||
assert.equal(undoMgr.getUndoStackSize(), 0)
|
||||
assert.equal(undoMgr.getRedoStackSize(), 3)
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(undoMgr.getUndoStackSize(), 1);
|
||||
assert.equal(undoMgr.getRedoStackSize(), 2);
|
||||
undoMgr.redo()
|
||||
assert.equal(undoMgr.getUndoStackSize(), 1)
|
||||
assert.equal(undoMgr.getRedoStackSize(), 2)
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(undoMgr.getUndoStackSize(), 2);
|
||||
assert.equal(undoMgr.getRedoStackSize(), 1);
|
||||
undoMgr.redo()
|
||||
assert.equal(undoMgr.getUndoStackSize(), 2)
|
||||
assert.equal(undoMgr.getRedoStackSize(), 1)
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(undoMgr.getUndoStackSize(), 3);
|
||||
assert.equal(undoMgr.getRedoStackSize(), 0);
|
||||
undoMgr.redo()
|
||||
assert.equal(undoMgr.getUndoStackSize(), 3)
|
||||
assert.equal(undoMgr.getRedoStackSize(), 0)
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(undoMgr.getUndoStackSize(), 3);
|
||||
assert.equal(undoMgr.getRedoStackSize(), 0);
|
||||
});
|
||||
undoMgr.redo()
|
||||
assert.equal(undoMgr.getUndoStackSize(), 3)
|
||||
assert.equal(undoMgr.getRedoStackSize(), 0)
|
||||
})
|
||||
|
||||
it('Test UndoManager.resetUndoStackSize() function', function () {
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.addCommandToHistory(new MockCommand());
|
||||
undoMgr.undo();
|
||||
undoMgr.addCommandToHistory(new MockCommand())
|
||||
undoMgr.addCommandToHistory(new MockCommand())
|
||||
undoMgr.addCommandToHistory(new MockCommand())
|
||||
undoMgr.undo()
|
||||
|
||||
assert.equal(undoMgr.getUndoStackSize(), 2);
|
||||
assert.equal(undoMgr.getRedoStackSize(), 1);
|
||||
assert.equal(undoMgr.getUndoStackSize(), 2)
|
||||
assert.equal(undoMgr.getRedoStackSize(), 1)
|
||||
|
||||
undoMgr.resetUndoStack();
|
||||
undoMgr.resetUndoStack()
|
||||
|
||||
assert.equal(undoMgr.getUndoStackSize(), 0);
|
||||
assert.equal(undoMgr.getRedoStackSize(), 0);
|
||||
});
|
||||
assert.equal(undoMgr.getUndoStackSize(), 0)
|
||||
assert.equal(undoMgr.getRedoStackSize(), 0)
|
||||
})
|
||||
|
||||
it('Test UndoManager.getNextUndoCommandText() function', function () {
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), '');
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), '')
|
||||
|
||||
undoMgr.addCommandToHistory(new MockCommand('First'));
|
||||
undoMgr.addCommandToHistory(new MockCommand('Second'));
|
||||
undoMgr.addCommandToHistory(new MockCommand('Third'));
|
||||
undoMgr.addCommandToHistory(new MockCommand('First'))
|
||||
undoMgr.addCommandToHistory(new MockCommand('Second'))
|
||||
undoMgr.addCommandToHistory(new MockCommand('Third'))
|
||||
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), 'Third');
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), 'Third')
|
||||
|
||||
undoMgr.undo();
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), 'Second');
|
||||
undoMgr.undo()
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), 'Second')
|
||||
|
||||
undoMgr.undo();
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), 'First');
|
||||
undoMgr.undo()
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), 'First')
|
||||
|
||||
undoMgr.undo();
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), '');
|
||||
undoMgr.undo()
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), '')
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), 'First');
|
||||
undoMgr.redo()
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), 'First')
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), 'Second');
|
||||
undoMgr.redo()
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), 'Second')
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), 'Third');
|
||||
undoMgr.redo()
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), 'Third')
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), 'Third');
|
||||
});
|
||||
undoMgr.redo()
|
||||
assert.equal(undoMgr.getNextUndoCommandText(), 'Third')
|
||||
})
|
||||
|
||||
it('Test UndoManager.getNextRedoCommandText() function', function () {
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), '');
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), '')
|
||||
|
||||
undoMgr.addCommandToHistory(new MockCommand('First'));
|
||||
undoMgr.addCommandToHistory(new MockCommand('Second'));
|
||||
undoMgr.addCommandToHistory(new MockCommand('Third'));
|
||||
undoMgr.addCommandToHistory(new MockCommand('First'))
|
||||
undoMgr.addCommandToHistory(new MockCommand('Second'))
|
||||
undoMgr.addCommandToHistory(new MockCommand('Third'))
|
||||
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), '');
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), '')
|
||||
|
||||
undoMgr.undo();
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), 'Third');
|
||||
undoMgr.undo()
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), 'Third')
|
||||
|
||||
undoMgr.undo();
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), 'Second');
|
||||
undoMgr.undo()
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), 'Second')
|
||||
|
||||
undoMgr.undo();
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), 'First');
|
||||
undoMgr.undo()
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), 'First')
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), 'Second');
|
||||
undoMgr.redo()
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), 'Second')
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), 'Third');
|
||||
undoMgr.redo()
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), 'Third')
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), '');
|
||||
});
|
||||
undoMgr.redo()
|
||||
assert.equal(undoMgr.getNextRedoCommandText(), '')
|
||||
})
|
||||
|
||||
it('Test UndoManager.undo() and redo() functions', function () {
|
||||
let lastCalled = null;
|
||||
const cmd1 = new MockCommand();
|
||||
const cmd2 = new MockCommand();
|
||||
const cmd3 = new MockCommand();
|
||||
cmd1.apply = function () { lastCalled = 'cmd1.apply'; };
|
||||
cmd2.apply = function () { lastCalled = 'cmd2.apply'; };
|
||||
cmd3.apply = function () { lastCalled = 'cmd3.apply'; };
|
||||
cmd1.unapply = function () { lastCalled = 'cmd1.unapply'; };
|
||||
cmd2.unapply = function () { lastCalled = 'cmd2.unapply'; };
|
||||
cmd3.unapply = function () { lastCalled = 'cmd3.unapply'; };
|
||||
let lastCalled = null
|
||||
const cmd1 = new MockCommand()
|
||||
const cmd2 = new MockCommand()
|
||||
const cmd3 = new MockCommand()
|
||||
cmd1.apply = function () { lastCalled = 'cmd1.apply' }
|
||||
cmd2.apply = function () { lastCalled = 'cmd2.apply' }
|
||||
cmd3.apply = function () { lastCalled = 'cmd3.apply' }
|
||||
cmd1.unapply = function () { lastCalled = 'cmd1.unapply' }
|
||||
cmd2.unapply = function () { lastCalled = 'cmd2.unapply' }
|
||||
cmd3.unapply = function () { lastCalled = 'cmd3.unapply' }
|
||||
|
||||
undoMgr.addCommandToHistory(cmd1);
|
||||
undoMgr.addCommandToHistory(cmd2);
|
||||
undoMgr.addCommandToHistory(cmd3);
|
||||
undoMgr.addCommandToHistory(cmd1)
|
||||
undoMgr.addCommandToHistory(cmd2)
|
||||
undoMgr.addCommandToHistory(cmd3)
|
||||
|
||||
assert.ok(!lastCalled);
|
||||
assert.ok(!lastCalled)
|
||||
|
||||
undoMgr.undo();
|
||||
assert.equal(lastCalled, 'cmd3.unapply');
|
||||
undoMgr.undo()
|
||||
assert.equal(lastCalled, 'cmd3.unapply')
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(lastCalled, 'cmd3.apply');
|
||||
undoMgr.redo()
|
||||
assert.equal(lastCalled, 'cmd3.apply')
|
||||
|
||||
undoMgr.undo();
|
||||
undoMgr.undo();
|
||||
assert.equal(lastCalled, 'cmd2.unapply');
|
||||
undoMgr.undo()
|
||||
undoMgr.undo()
|
||||
assert.equal(lastCalled, 'cmd2.unapply')
|
||||
|
||||
undoMgr.undo();
|
||||
assert.equal(lastCalled, 'cmd1.unapply');
|
||||
lastCalled = null;
|
||||
undoMgr.undo()
|
||||
assert.equal(lastCalled, 'cmd1.unapply')
|
||||
lastCalled = null
|
||||
|
||||
undoMgr.undo();
|
||||
assert.ok(!lastCalled);
|
||||
undoMgr.undo()
|
||||
assert.ok(!lastCalled)
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(lastCalled, 'cmd1.apply');
|
||||
undoMgr.redo()
|
||||
assert.equal(lastCalled, 'cmd1.apply')
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(lastCalled, 'cmd2.apply');
|
||||
undoMgr.redo()
|
||||
assert.equal(lastCalled, 'cmd2.apply')
|
||||
|
||||
undoMgr.redo();
|
||||
assert.equal(lastCalled, 'cmd3.apply');
|
||||
lastCalled = null;
|
||||
undoMgr.redo()
|
||||
assert.equal(lastCalled, 'cmd3.apply')
|
||||
lastCalled = null
|
||||
|
||||
undoMgr.redo();
|
||||
assert.ok(!lastCalled);
|
||||
});
|
||||
undoMgr.redo()
|
||||
assert.ok(!lastCalled)
|
||||
})
|
||||
|
||||
it('Test MoveElementCommand', function () {
|
||||
let move = new history.MoveElementCommand(this.div3, this.div1, this.divparent);
|
||||
assert.ok(move.unapply);
|
||||
assert.ok(move.apply);
|
||||
assert.equal(typeof move.unapply, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof move.apply, typeof function () { /* empty fn */ });
|
||||
let move = new history.MoveElementCommand(this.div3, this.div1, this.divparent)
|
||||
assert.ok(move.unapply)
|
||||
assert.ok(move.apply)
|
||||
assert.equal(typeof move.unapply, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof move.apply, typeof function () { /* empty fn */ })
|
||||
|
||||
move.unapply();
|
||||
assert.equal(this.divparent.firstElementChild, this.div3);
|
||||
assert.equal(this.divparent.firstElementChild.nextElementSibling, this.div1);
|
||||
assert.equal(this.divparent.lastElementChild, this.div2);
|
||||
move.unapply()
|
||||
assert.equal(this.divparent.firstElementChild, this.div3)
|
||||
assert.equal(this.divparent.firstElementChild.nextElementSibling, this.div1)
|
||||
assert.equal(this.divparent.lastElementChild, this.div2)
|
||||
|
||||
move.apply();
|
||||
assert.equal(this.divparent.firstElementChild, this.div1);
|
||||
assert.equal(this.divparent.firstElementChild.nextElementSibling, this.div2);
|
||||
assert.equal(this.divparent.lastElementChild, this.div3);
|
||||
move.apply()
|
||||
assert.equal(this.divparent.firstElementChild, this.div1)
|
||||
assert.equal(this.divparent.firstElementChild.nextElementSibling, this.div2)
|
||||
assert.equal(this.divparent.lastElementChild, this.div3)
|
||||
|
||||
move = new history.MoveElementCommand(this.div1, null, this.divparent);
|
||||
move = new history.MoveElementCommand(this.div1, null, this.divparent)
|
||||
|
||||
move.unapply();
|
||||
assert.equal(this.divparent.firstElementChild, this.div2);
|
||||
assert.equal(this.divparent.firstElementChild.nextElementSibling, this.div3);
|
||||
assert.equal(this.divparent.lastElementChild, this.div1);
|
||||
move.unapply()
|
||||
assert.equal(this.divparent.firstElementChild, this.div2)
|
||||
assert.equal(this.divparent.firstElementChild.nextElementSibling, this.div3)
|
||||
assert.equal(this.divparent.lastElementChild, this.div1)
|
||||
|
||||
move.apply();
|
||||
assert.equal(this.divparent.firstElementChild, this.div1);
|
||||
assert.equal(this.divparent.firstElementChild.nextElementSibling, this.div2);
|
||||
assert.equal(this.divparent.lastElementChild, this.div3);
|
||||
move.apply()
|
||||
assert.equal(this.divparent.firstElementChild, this.div1)
|
||||
assert.equal(this.divparent.firstElementChild.nextElementSibling, this.div2)
|
||||
assert.equal(this.divparent.lastElementChild, this.div3)
|
||||
|
||||
move = new history.MoveElementCommand(this.div2, this.div5, this.div4);
|
||||
move = new history.MoveElementCommand(this.div2, this.div5, this.div4)
|
||||
|
||||
move.unapply();
|
||||
assert.equal(this.divparent.firstElementChild, this.div1);
|
||||
assert.equal(this.divparent.firstElementChild.nextElementSibling, this.div3);
|
||||
assert.equal(this.divparent.lastElementChild, this.div3);
|
||||
assert.equal(this.div4.firstElementChild, this.div2);
|
||||
assert.equal(this.div4.firstElementChild.nextElementSibling, this.div5);
|
||||
move.unapply()
|
||||
assert.equal(this.divparent.firstElementChild, this.div1)
|
||||
assert.equal(this.divparent.firstElementChild.nextElementSibling, this.div3)
|
||||
assert.equal(this.divparent.lastElementChild, this.div3)
|
||||
assert.equal(this.div4.firstElementChild, this.div2)
|
||||
assert.equal(this.div4.firstElementChild.nextElementSibling, this.div5)
|
||||
|
||||
move.apply();
|
||||
assert.equal(this.divparent.firstElementChild, this.div1);
|
||||
assert.equal(this.divparent.firstElementChild.nextElementSibling, this.div2);
|
||||
assert.equal(this.divparent.lastElementChild, this.div3);
|
||||
assert.equal(this.div4.firstElementChild, this.div5);
|
||||
assert.equal(this.div4.lastElementChild, this.div5);
|
||||
});
|
||||
move.apply()
|
||||
assert.equal(this.divparent.firstElementChild, this.div1)
|
||||
assert.equal(this.divparent.firstElementChild.nextElementSibling, this.div2)
|
||||
assert.equal(this.divparent.lastElementChild, this.div3)
|
||||
assert.equal(this.div4.firstElementChild, this.div5)
|
||||
assert.equal(this.div4.lastElementChild, this.div5)
|
||||
})
|
||||
|
||||
it('Test InsertElementCommand', function () {
|
||||
let insert = new history.InsertElementCommand(this.div3);
|
||||
assert.ok(insert.unapply);
|
||||
assert.ok(insert.apply);
|
||||
assert.equal(typeof insert.unapply, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof insert.apply, typeof function () { /* empty fn */ });
|
||||
let insert = new history.InsertElementCommand(this.div3)
|
||||
assert.ok(insert.unapply)
|
||||
assert.ok(insert.apply)
|
||||
assert.equal(typeof insert.unapply, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof insert.apply, typeof function () { /* empty fn */ })
|
||||
|
||||
insert.unapply();
|
||||
assert.equal(this.divparent.childElementCount, 2);
|
||||
assert.equal(this.divparent.firstElementChild, this.div1);
|
||||
assert.equal(this.div1.nextElementSibling, this.div2);
|
||||
assert.equal(this.divparent.lastElementChild, this.div2);
|
||||
insert.unapply()
|
||||
assert.equal(this.divparent.childElementCount, 2)
|
||||
assert.equal(this.divparent.firstElementChild, this.div1)
|
||||
assert.equal(this.div1.nextElementSibling, this.div2)
|
||||
assert.equal(this.divparent.lastElementChild, this.div2)
|
||||
|
||||
insert.apply();
|
||||
assert.equal(this.divparent.childElementCount, 3);
|
||||
assert.equal(this.divparent.firstElementChild, this.div1);
|
||||
assert.equal(this.div1.nextElementSibling, this.div2);
|
||||
assert.equal(this.div2.nextElementSibling, this.div3);
|
||||
insert.apply()
|
||||
assert.equal(this.divparent.childElementCount, 3)
|
||||
assert.equal(this.divparent.firstElementChild, this.div1)
|
||||
assert.equal(this.div1.nextElementSibling, this.div2)
|
||||
assert.equal(this.div2.nextElementSibling, this.div3)
|
||||
|
||||
insert = new history.InsertElementCommand(this.div2);
|
||||
insert = new history.InsertElementCommand(this.div2)
|
||||
|
||||
insert.unapply();
|
||||
assert.equal(this.divparent.childElementCount, 2);
|
||||
assert.equal(this.divparent.firstElementChild, this.div1);
|
||||
assert.equal(this.div1.nextElementSibling, this.div3);
|
||||
assert.equal(this.divparent.lastElementChild, this.div3);
|
||||
insert.unapply()
|
||||
assert.equal(this.divparent.childElementCount, 2)
|
||||
assert.equal(this.divparent.firstElementChild, this.div1)
|
||||
assert.equal(this.div1.nextElementSibling, this.div3)
|
||||
assert.equal(this.divparent.lastElementChild, this.div3)
|
||||
|
||||
insert.apply();
|
||||
assert.equal(this.divparent.childElementCount, 3);
|
||||
assert.equal(this.divparent.firstElementChild, this.div1);
|
||||
assert.equal(this.div1.nextElementSibling, this.div2);
|
||||
assert.equal(this.div2.nextElementSibling, this.div3);
|
||||
});
|
||||
insert.apply()
|
||||
assert.equal(this.divparent.childElementCount, 3)
|
||||
assert.equal(this.divparent.firstElementChild, this.div1)
|
||||
assert.equal(this.div1.nextElementSibling, this.div2)
|
||||
assert.equal(this.div2.nextElementSibling, this.div3)
|
||||
})
|
||||
|
||||
it('Test RemoveElementCommand', function () {
|
||||
const div6 = document.createElement('div');
|
||||
div6.id = 'div6';
|
||||
const div6 = document.createElement('div')
|
||||
div6.id = 'div6'
|
||||
|
||||
let remove = new history.RemoveElementCommand(div6, null, this.divparent);
|
||||
assert.ok(remove.unapply);
|
||||
assert.ok(remove.apply);
|
||||
assert.equal(typeof remove.unapply, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof remove.apply, typeof function () { /* empty fn */ });
|
||||
let remove = new history.RemoveElementCommand(div6, null, this.divparent)
|
||||
assert.ok(remove.unapply)
|
||||
assert.ok(remove.apply)
|
||||
assert.equal(typeof remove.unapply, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof remove.apply, typeof function () { /* empty fn */ })
|
||||
|
||||
remove.unapply();
|
||||
assert.equal(this.divparent.childElementCount, 4);
|
||||
assert.equal(this.divparent.firstElementChild, this.div1);
|
||||
assert.equal(this.div1.nextElementSibling, this.div2);
|
||||
assert.equal(this.div2.nextElementSibling, this.div3);
|
||||
assert.equal(this.div3.nextElementSibling, div6);
|
||||
remove.unapply()
|
||||
assert.equal(this.divparent.childElementCount, 4)
|
||||
assert.equal(this.divparent.firstElementChild, this.div1)
|
||||
assert.equal(this.div1.nextElementSibling, this.div2)
|
||||
assert.equal(this.div2.nextElementSibling, this.div3)
|
||||
assert.equal(this.div3.nextElementSibling, div6)
|
||||
|
||||
remove.apply();
|
||||
assert.equal(this.divparent.childElementCount, 3);
|
||||
assert.equal(this.divparent.firstElementChild, this.div1);
|
||||
assert.equal(this.div1.nextElementSibling, this.div2);
|
||||
assert.equal(this.div2.nextElementSibling, this.div3);
|
||||
remove.apply()
|
||||
assert.equal(this.divparent.childElementCount, 3)
|
||||
assert.equal(this.divparent.firstElementChild, this.div1)
|
||||
assert.equal(this.div1.nextElementSibling, this.div2)
|
||||
assert.equal(this.div2.nextElementSibling, this.div3)
|
||||
|
||||
remove = new history.RemoveElementCommand(div6, this.div2, this.divparent);
|
||||
remove = new history.RemoveElementCommand(div6, this.div2, this.divparent)
|
||||
|
||||
remove.unapply();
|
||||
assert.equal(this.divparent.childElementCount, 4);
|
||||
assert.equal(this.divparent.firstElementChild, this.div1);
|
||||
assert.equal(this.div1.nextElementSibling, div6);
|
||||
assert.equal(div6.nextElementSibling, this.div2);
|
||||
assert.equal(this.div2.nextElementSibling, this.div3);
|
||||
remove.unapply()
|
||||
assert.equal(this.divparent.childElementCount, 4)
|
||||
assert.equal(this.divparent.firstElementChild, this.div1)
|
||||
assert.equal(this.div1.nextElementSibling, div6)
|
||||
assert.equal(div6.nextElementSibling, this.div2)
|
||||
assert.equal(this.div2.nextElementSibling, this.div3)
|
||||
|
||||
remove.apply();
|
||||
assert.equal(this.divparent.childElementCount, 3);
|
||||
assert.equal(this.divparent.firstElementChild, this.div1);
|
||||
assert.equal(this.div1.nextElementSibling, this.div2);
|
||||
assert.equal(this.div2.nextElementSibling, this.div3);
|
||||
});
|
||||
remove.apply()
|
||||
assert.equal(this.divparent.childElementCount, 3)
|
||||
assert.equal(this.divparent.firstElementChild, this.div1)
|
||||
assert.equal(this.div1.nextElementSibling, this.div2)
|
||||
assert.equal(this.div2.nextElementSibling, this.div3)
|
||||
})
|
||||
|
||||
it('Test ChangeElementCommand', function () {
|
||||
this.div1.setAttribute('title', 'new title');
|
||||
this.div1.setAttribute('title', 'new title')
|
||||
let change = new history.ChangeElementCommand(this.div1,
|
||||
{ title: 'old title', class: 'foo' });
|
||||
assert.ok(change.unapply);
|
||||
assert.ok(change.apply);
|
||||
assert.equal(typeof change.unapply, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof change.apply, typeof function () { /* empty fn */ });
|
||||
{ title: 'old title', class: 'foo' })
|
||||
assert.ok(change.unapply)
|
||||
assert.ok(change.apply)
|
||||
assert.equal(typeof change.unapply, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof change.apply, typeof function () { /* empty fn */ })
|
||||
|
||||
change.unapply();
|
||||
assert.equal(this.div1.getAttribute('title'), 'old title');
|
||||
assert.equal(this.div1.getAttribute('class'), 'foo');
|
||||
change.unapply()
|
||||
assert.equal(this.div1.getAttribute('title'), 'old title')
|
||||
assert.equal(this.div1.getAttribute('class'), 'foo')
|
||||
|
||||
change.apply();
|
||||
assert.equal(this.div1.getAttribute('title'), 'new title');
|
||||
assert.ok(!this.div1.getAttribute('class'));
|
||||
change.apply()
|
||||
assert.equal(this.div1.getAttribute('title'), 'new title')
|
||||
assert.ok(!this.div1.getAttribute('class'))
|
||||
|
||||
this.div1.textContent = 'inner text';
|
||||
this.div1.textContent = 'inner text'
|
||||
change = new history.ChangeElementCommand(this.div1,
|
||||
{ '#text': null });
|
||||
{ '#text': null })
|
||||
|
||||
change.unapply();
|
||||
assert.ok(!this.div1.textContent);
|
||||
change.unapply()
|
||||
assert.ok(!this.div1.textContent)
|
||||
|
||||
change.apply();
|
||||
assert.equal(this.div1.textContent, 'inner text');
|
||||
change.apply()
|
||||
assert.equal(this.div1.textContent, 'inner text')
|
||||
|
||||
this.div1.textContent = '';
|
||||
this.div1.textContent = ''
|
||||
change = new history.ChangeElementCommand(this.div1,
|
||||
{ '#text': 'old text' });
|
||||
{ '#text': 'old text' })
|
||||
|
||||
change.unapply();
|
||||
assert.equal(this.div1.textContent, 'old text');
|
||||
change.unapply()
|
||||
assert.equal(this.div1.textContent, 'old text')
|
||||
|
||||
change.apply();
|
||||
assert.ok(!this.div1.textContent);
|
||||
change.apply()
|
||||
assert.ok(!this.div1.textContent)
|
||||
|
||||
// TODO(codedread): Refactor this #href stuff in history.js and svgcanvas.js
|
||||
const rect = document.createElementNS(NS.SVG, 'rect');
|
||||
let justCalled = null;
|
||||
let gethrefvalue = null;
|
||||
let sethrefvalue = null;
|
||||
const rect = document.createElementNS(NS.SVG, 'rect')
|
||||
let justCalled = null
|
||||
let gethrefvalue = null
|
||||
let sethrefvalue = null
|
||||
utilities.mock({
|
||||
getHref (elem) {
|
||||
assert.equal(elem, rect);
|
||||
justCalled = 'getHref';
|
||||
return gethrefvalue;
|
||||
assert.equal(elem, rect)
|
||||
justCalled = 'getHref'
|
||||
return gethrefvalue
|
||||
},
|
||||
setHref (elem, val) {
|
||||
assert.equal(elem, rect);
|
||||
assert.equal(val, sethrefvalue);
|
||||
justCalled = 'setHref';
|
||||
assert.equal(elem, rect)
|
||||
assert.equal(val, sethrefvalue)
|
||||
justCalled = 'setHref'
|
||||
},
|
||||
getRotationAngle () { return 0; }
|
||||
});
|
||||
getRotationAngle () { return 0 }
|
||||
})
|
||||
|
||||
gethrefvalue = '#newhref';
|
||||
gethrefvalue = '#newhref'
|
||||
change = new history.ChangeElementCommand(rect,
|
||||
{ '#href': '#oldhref' });
|
||||
assert.equal(justCalled, 'getHref');
|
||||
{ '#href': '#oldhref' })
|
||||
assert.equal(justCalled, 'getHref')
|
||||
|
||||
justCalled = null;
|
||||
sethrefvalue = '#oldhref';
|
||||
change.unapply();
|
||||
assert.equal(justCalled, 'setHref');
|
||||
justCalled = null
|
||||
sethrefvalue = '#oldhref'
|
||||
change.unapply()
|
||||
assert.equal(justCalled, 'setHref')
|
||||
|
||||
justCalled = null;
|
||||
sethrefvalue = '#newhref';
|
||||
change.apply();
|
||||
assert.equal(justCalled, 'setHref');
|
||||
justCalled = null
|
||||
sethrefvalue = '#newhref'
|
||||
change.apply()
|
||||
assert.equal(justCalled, 'setHref')
|
||||
|
||||
const line = document.createElementNS(NS.SVG, 'line');
|
||||
line.setAttribute('class', 'newClass');
|
||||
change = new history.ChangeElementCommand(line, { class: 'oldClass' });
|
||||
const line = document.createElementNS(NS.SVG, 'line')
|
||||
line.setAttribute('class', 'newClass')
|
||||
change = new history.ChangeElementCommand(line, { class: 'oldClass' })
|
||||
|
||||
assert.ok(change.unapply);
|
||||
assert.ok(change.apply);
|
||||
assert.equal(typeof change.unapply, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof change.apply, typeof function () { /* empty fn */ });
|
||||
assert.ok(change.unapply)
|
||||
assert.ok(change.apply)
|
||||
assert.equal(typeof change.unapply, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof change.apply, typeof function () { /* empty fn */ })
|
||||
|
||||
change.unapply();
|
||||
assert.equal(line.getAttribute('class'), 'oldClass');
|
||||
change.unapply()
|
||||
assert.equal(line.getAttribute('class'), 'oldClass')
|
||||
|
||||
change.apply();
|
||||
assert.equal(line.getAttribute('class'), 'newClass');
|
||||
});
|
||||
change.apply()
|
||||
assert.equal(line.getAttribute('class'), 'newClass')
|
||||
})
|
||||
|
||||
it('Test BatchCommand', function () {
|
||||
let concatResult = '';
|
||||
MockCommand.prototype.apply = function () { concatResult += this.text; };
|
||||
let concatResult = ''
|
||||
MockCommand.prototype.apply = function () { concatResult += this.text }
|
||||
|
||||
const batch = new history.BatchCommand();
|
||||
assert.ok(batch.unapply);
|
||||
assert.ok(batch.apply);
|
||||
assert.ok(batch.addSubCommand);
|
||||
assert.ok(batch.isEmpty);
|
||||
assert.equal(typeof batch.unapply, 'function');
|
||||
assert.equal(typeof batch.apply, 'function');
|
||||
assert.equal(typeof batch.addSubCommand, 'function');
|
||||
assert.equal(typeof batch.isEmpty, 'function');
|
||||
const batch = new history.BatchCommand()
|
||||
assert.ok(batch.unapply)
|
||||
assert.ok(batch.apply)
|
||||
assert.ok(batch.addSubCommand)
|
||||
assert.ok(batch.isEmpty)
|
||||
assert.equal(typeof batch.unapply, 'function')
|
||||
assert.equal(typeof batch.apply, 'function')
|
||||
assert.equal(typeof batch.addSubCommand, 'function')
|
||||
assert.equal(typeof batch.isEmpty, 'function')
|
||||
|
||||
assert.ok(batch.isEmpty());
|
||||
assert.ok(batch.isEmpty())
|
||||
|
||||
batch.addSubCommand(new MockCommand('a'));
|
||||
assert.ok(!batch.isEmpty());
|
||||
batch.addSubCommand(new MockCommand('b'));
|
||||
batch.addSubCommand(new MockCommand('c'));
|
||||
batch.addSubCommand(new MockCommand('a'))
|
||||
assert.ok(!batch.isEmpty())
|
||||
batch.addSubCommand(new MockCommand('b'))
|
||||
batch.addSubCommand(new MockCommand('c'))
|
||||
|
||||
assert.ok(!concatResult);
|
||||
batch.apply();
|
||||
assert.equal(concatResult, 'abc');
|
||||
assert.ok(!concatResult)
|
||||
batch.apply()
|
||||
assert.equal(concatResult, 'abc')
|
||||
|
||||
MockCommand.prototype.apply = function () { /* empty fn */ };
|
||||
MockCommand.prototype.unapply = function () { concatResult += this.text; };
|
||||
concatResult = '';
|
||||
assert.ok(!concatResult);
|
||||
batch.unapply();
|
||||
assert.equal(concatResult, 'cba');
|
||||
MockCommand.prototype.apply = function () { /* empty fn */ }
|
||||
MockCommand.prototype.unapply = function () { concatResult += this.text }
|
||||
concatResult = ''
|
||||
assert.ok(!concatResult)
|
||||
batch.unapply()
|
||||
assert.equal(concatResult, 'cba')
|
||||
|
||||
MockCommand.prototype.unapply = function () { /* empty fn */ };
|
||||
});
|
||||
});
|
||||
MockCommand.prototype.unapply = function () { /* empty fn */ }
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,106 +1,106 @@
|
|||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js';
|
||||
import * as math from '../../../instrumented/svgcanvas/math.js';
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js'
|
||||
import * as math from '../../../instrumented/svgcanvas/math.js'
|
||||
|
||||
describe('math', function () {
|
||||
const svg = document.createElementNS(NS.SVG, 'svg');
|
||||
const svg = document.createElementNS(NS.SVG, 'svg')
|
||||
|
||||
it('Test svgedit.math package', function () {
|
||||
assert.ok(math);
|
||||
assert.ok(math.transformPoint);
|
||||
assert.ok(math.isIdentity);
|
||||
assert.ok(math.matrixMultiply);
|
||||
assert.equal(typeof math.transformPoint, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof math.isIdentity, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof math.matrixMultiply, typeof function () { /* empty fn */ });
|
||||
});
|
||||
assert.ok(math)
|
||||
assert.ok(math.transformPoint)
|
||||
assert.ok(math.isIdentity)
|
||||
assert.ok(math.matrixMultiply)
|
||||
assert.equal(typeof math.transformPoint, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof math.isIdentity, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof math.matrixMultiply, typeof function () { /* empty fn */ })
|
||||
})
|
||||
|
||||
it('Test svgedit.math.transformPoint() function', function () {
|
||||
const { transformPoint } = math;
|
||||
const { transformPoint } = math
|
||||
|
||||
const m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 0; m.f = 0;
|
||||
let pt = transformPoint(100, 200, m);
|
||||
assert.equal(pt.x, 100);
|
||||
assert.equal(pt.y, 200);
|
||||
const m = svg.createSVGMatrix()
|
||||
m.a = 1; m.b = 0
|
||||
m.c = 0; m.d = 1
|
||||
m.e = 0; m.f = 0
|
||||
let pt = transformPoint(100, 200, m)
|
||||
assert.equal(pt.x, 100)
|
||||
assert.equal(pt.y, 200)
|
||||
|
||||
m.e = 300; m.f = 400;
|
||||
pt = transformPoint(100, 200, m);
|
||||
assert.equal(pt.x, 400);
|
||||
assert.equal(pt.y, 600);
|
||||
m.e = 300; m.f = 400
|
||||
pt = transformPoint(100, 200, m)
|
||||
assert.equal(pt.x, 400)
|
||||
assert.equal(pt.y, 600)
|
||||
|
||||
m.a = 0.5; m.b = 0.75;
|
||||
m.c = 1.25; m.d = 2;
|
||||
pt = transformPoint(100, 200, m);
|
||||
assert.equal(pt.x, 100 * m.a + 200 * m.c + m.e);
|
||||
assert.equal(pt.y, 100 * m.b + 200 * m.d + m.f);
|
||||
});
|
||||
m.a = 0.5; m.b = 0.75
|
||||
m.c = 1.25; m.d = 2
|
||||
pt = transformPoint(100, 200, m)
|
||||
assert.equal(pt.x, 100 * m.a + 200 * m.c + m.e)
|
||||
assert.equal(pt.y, 100 * m.b + 200 * m.d + m.f)
|
||||
})
|
||||
|
||||
it('Test svgedit.math.isIdentity() function', function () {
|
||||
assert.ok(math.isIdentity(svg.createSVGMatrix()));
|
||||
assert.ok(math.isIdentity(svg.createSVGMatrix()))
|
||||
|
||||
const m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 0; m.f = 0;
|
||||
assert.ok(math.isIdentity(m));
|
||||
});
|
||||
const m = svg.createSVGMatrix()
|
||||
m.a = 1; m.b = 0
|
||||
m.c = 0; m.d = 1
|
||||
m.e = 0; m.f = 0
|
||||
assert.ok(math.isIdentity(m))
|
||||
})
|
||||
|
||||
it('Test svgedit.math.matrixMultiply() function', function () {
|
||||
const mult = math.matrixMultiply;
|
||||
const { isIdentity } = math;
|
||||
const mult = math.matrixMultiply
|
||||
const { isIdentity } = math
|
||||
|
||||
// translate there and back
|
||||
const tr1 = svg.createSVGMatrix().translate(100, 50);
|
||||
const tr2 = svg.createSVGMatrix().translate(-90, 0);
|
||||
const tr3 = svg.createSVGMatrix().translate(-10, -50);
|
||||
let I = mult(tr1, tr2, tr3);
|
||||
assert.ok(isIdentity(I), 'Expected identity matrix when translating there and back');
|
||||
const tr1 = svg.createSVGMatrix().translate(100, 50)
|
||||
const tr2 = svg.createSVGMatrix().translate(-90, 0)
|
||||
const tr3 = svg.createSVGMatrix().translate(-10, -50)
|
||||
let I = mult(tr1, tr2, tr3)
|
||||
assert.ok(isIdentity(I), 'Expected identity matrix when translating there and back')
|
||||
|
||||
// rotate there and back
|
||||
// TODO: currently Mozilla fails this when rotating back at -50 and then -40 degrees
|
||||
// (b and c are *almost* zero, but not zero)
|
||||
const rotThere = svg.createSVGMatrix().rotate(90);
|
||||
const rotBack = svg.createSVGMatrix().rotate(-90); // TODO: set this to -50
|
||||
const rotBackMore = svg.createSVGMatrix().rotate(0); // TODO: set this to -40
|
||||
I = mult(rotThere, rotBack, rotBackMore);
|
||||
assert.ok(isIdentity(I), 'Expected identity matrix when rotating there and back');
|
||||
const rotThere = svg.createSVGMatrix().rotate(90)
|
||||
const rotBack = svg.createSVGMatrix().rotate(-90) // TODO: set this to -50
|
||||
const rotBackMore = svg.createSVGMatrix().rotate(0) // TODO: set this to -40
|
||||
I = mult(rotThere, rotBack, rotBackMore)
|
||||
assert.ok(isIdentity(I), 'Expected identity matrix when rotating there and back')
|
||||
|
||||
// scale up and down
|
||||
const scaleUp = svg.createSVGMatrix().scale(4);
|
||||
const scaleDown = svg.createSVGMatrix().scaleNonUniform(0.25, 1);
|
||||
const scaleDownMore = svg.createSVGMatrix().scaleNonUniform(1, 0.25);
|
||||
I = mult(scaleUp, scaleDown, scaleDownMore);
|
||||
assert.ok(isIdentity(I), 'Expected identity matrix when scaling up and down');
|
||||
const scaleUp = svg.createSVGMatrix().scale(4)
|
||||
const scaleDown = svg.createSVGMatrix().scaleNonUniform(0.25, 1)
|
||||
const scaleDownMore = svg.createSVGMatrix().scaleNonUniform(1, 0.25)
|
||||
I = mult(scaleUp, scaleDown, scaleDownMore)
|
||||
assert.ok(isIdentity(I), 'Expected identity matrix when scaling up and down')
|
||||
|
||||
// test multiplication with its inverse
|
||||
I = mult(rotThere, rotThere.inverse());
|
||||
assert.ok(isIdentity(I), 'Expected identity matrix when multiplying a matrix by its inverse');
|
||||
I = mult(rotThere.inverse(), rotThere);
|
||||
assert.ok(isIdentity(I), 'Expected identity matrix when multiplying a matrix by its inverse');
|
||||
});
|
||||
I = mult(rotThere, rotThere.inverse())
|
||||
assert.ok(isIdentity(I), 'Expected identity matrix when multiplying a matrix by its inverse')
|
||||
I = mult(rotThere.inverse(), rotThere)
|
||||
assert.ok(isIdentity(I), 'Expected identity matrix when multiplying a matrix by its inverse')
|
||||
})
|
||||
|
||||
it('Test svgedit.math.transformBox() function', function () {
|
||||
const { transformBox } = math;
|
||||
const { transformBox } = math
|
||||
|
||||
const m = svg.createSVGMatrix();
|
||||
m.a = 1; m.b = 0;
|
||||
m.c = 0; m.d = 1;
|
||||
m.e = 0; m.f = 0;
|
||||
const m = svg.createSVGMatrix()
|
||||
m.a = 1; m.b = 0
|
||||
m.c = 0; m.d = 1
|
||||
m.e = 0; m.f = 0
|
||||
|
||||
const r = transformBox(10, 10, 200, 300, m);
|
||||
assert.equal(r.tl.x, 10);
|
||||
assert.equal(r.tl.y, 10);
|
||||
assert.equal(r.tr.x, 210);
|
||||
assert.equal(r.tr.y, 10);
|
||||
assert.equal(r.bl.x, 10);
|
||||
assert.equal(r.bl.y, 310);
|
||||
assert.equal(r.br.x, 210);
|
||||
assert.equal(r.br.y, 310);
|
||||
assert.equal(r.aabox.x, 10);
|
||||
assert.equal(r.aabox.y, 10);
|
||||
assert.equal(r.aabox.width, 200);
|
||||
assert.equal(r.aabox.height, 300);
|
||||
});
|
||||
});
|
||||
const r = transformBox(10, 10, 200, 300, m)
|
||||
assert.equal(r.tl.x, 10)
|
||||
assert.equal(r.tl.y, 10)
|
||||
assert.equal(r.tr.x, 210)
|
||||
assert.equal(r.tr.y, 10)
|
||||
assert.equal(r.bl.x, 10)
|
||||
assert.equal(r.bl.y, 310)
|
||||
assert.equal(r.br.x, 210)
|
||||
assert.equal(r.br.y, 310)
|
||||
assert.equal(r.aabox.x, 10)
|
||||
assert.equal(r.aabox.y, 10)
|
||||
assert.equal(r.aabox.width, 200)
|
||||
assert.equal(r.aabox.height, 300)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/* globals SVGPathSeg */
|
||||
import 'pathseg';
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js';
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
|
||||
import * as pathModule from '../../../instrumented/svgcanvas/path.js';
|
||||
import { Path, Segment } from '../../../instrumented/svgcanvas/path-method.js';
|
||||
import { init as unitsInit } from '../../../instrumented/common/units.js';
|
||||
import 'pathseg'
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js'
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js'
|
||||
import * as pathModule from '../../../instrumented/svgcanvas/path.js'
|
||||
import { Path, Segment } from '../../../instrumented/svgcanvas/path-method.js'
|
||||
import { init as unitsInit } from '../../../instrumented/common/units.js'
|
||||
|
||||
describe('path', function () {
|
||||
/**
|
||||
|
@ -18,165 +18,165 @@ describe('path', function () {
|
|||
* @returns {EditorContexts}
|
||||
*/
|
||||
function getMockContexts (svg) {
|
||||
svg = svg || document.createElementNS(NS.SVG, 'svg');
|
||||
const selectorParentGroup = document.createElementNS(NS.SVG, 'g');
|
||||
selectorParentGroup.setAttribute('id', 'selectorParentGroup');
|
||||
svg.append(selectorParentGroup);
|
||||
svg = svg || document.createElementNS(NS.SVG, 'svg')
|
||||
const selectorParentGroup = document.createElementNS(NS.SVG, 'g')
|
||||
selectorParentGroup.setAttribute('id', 'selectorParentGroup')
|
||||
svg.append(selectorParentGroup)
|
||||
return [
|
||||
/**
|
||||
* @implements {module:path.EditorContext}
|
||||
*/
|
||||
{
|
||||
getSvgRoot () { return svg; },
|
||||
getZoom () { return 1; }
|
||||
getSvgRoot () { return svg },
|
||||
getZoom () { return 1 }
|
||||
},
|
||||
/**
|
||||
* @implements {module:utilities.EditorContext}
|
||||
*/
|
||||
{
|
||||
getDOMDocument () { return svg; },
|
||||
getDOMContainer () { return svg; },
|
||||
getSvgRoot () { return svg; }
|
||||
getDOMDocument () { return svg },
|
||||
getDOMContainer () { return svg },
|
||||
getSvgRoot () { return svg }
|
||||
}
|
||||
];
|
||||
]
|
||||
}
|
||||
|
||||
it('Test svgedit.path.replacePathSeg', function () {
|
||||
const path = document.createElementNS(NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 L10,11 L20,21Z');
|
||||
const path = document.createElementNS(NS.SVG, 'path')
|
||||
path.setAttribute('d', 'M0,0 L10,11 L20,21Z')
|
||||
|
||||
const [ mockPathContext, mockUtilitiesContext ] = getMockContexts();
|
||||
pathModule.init(mockPathContext);
|
||||
utilities.init(mockUtilitiesContext);
|
||||
new Path(path);
|
||||
const [mockPathContext, mockUtilitiesContext] = getMockContexts()
|
||||
pathModule.init(mockPathContext)
|
||||
utilities.init(mockUtilitiesContext)
|
||||
Path(path)
|
||||
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L');
|
||||
assert.equal(path.pathSegList.getItem(1).x, 10);
|
||||
assert.equal(path.pathSegList.getItem(1).y, 11);
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L')
|
||||
assert.equal(path.pathSegList.getItem(1).x, 10)
|
||||
assert.equal(path.pathSegList.getItem(1).y, 11)
|
||||
|
||||
pathModule.replacePathSeg(SVGPathSeg.PATHSEG_LINETO_REL, 1, [ 30, 31 ], path);
|
||||
pathModule.replacePathSeg(SVGPathSeg.PATHSEG_LINETO_REL, 1, [30, 31], path)
|
||||
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'l');
|
||||
assert.equal(path.pathSegList.getItem(1).x, 30);
|
||||
assert.equal(path.pathSegList.getItem(1).y, 31);
|
||||
});
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'l')
|
||||
assert.equal(path.pathSegList.getItem(1).x, 30)
|
||||
assert.equal(path.pathSegList.getItem(1).y, 31)
|
||||
})
|
||||
|
||||
it('Test svgedit.path.Segment.setType simple', function () {
|
||||
const path = document.createElementNS(NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 L10,11 L20,21Z');
|
||||
const path = document.createElementNS(NS.SVG, 'path')
|
||||
path.setAttribute('d', 'M0,0 L10,11 L20,21Z')
|
||||
|
||||
const [ mockPathContext, mockUtilitiesContext ] = getMockContexts();
|
||||
pathModule.init(mockPathContext);
|
||||
utilities.init(mockUtilitiesContext);
|
||||
new Path(path);
|
||||
const [mockPathContext, mockUtilitiesContext] = getMockContexts()
|
||||
pathModule.init(mockPathContext)
|
||||
utilities.init(mockUtilitiesContext)
|
||||
Path(path)
|
||||
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L');
|
||||
assert.equal(path.pathSegList.getItem(1).x, 10);
|
||||
assert.equal(path.pathSegList.getItem(1).y, 11);
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L')
|
||||
assert.equal(path.pathSegList.getItem(1).x, 10)
|
||||
assert.equal(path.pathSegList.getItem(1).y, 11)
|
||||
|
||||
const segment = new Segment(1, path.pathSegList.getItem(1));
|
||||
segment.setType(SVGPathSeg.PATHSEG_LINETO_REL, [ 30, 31 ]);
|
||||
assert.equal(segment.item.pathSegTypeAsLetter, 'l');
|
||||
assert.equal(segment.item.x, 30);
|
||||
assert.equal(segment.item.y, 31);
|
||||
const segment = new Segment(1, path.pathSegList.getItem(1))
|
||||
segment.setType(SVGPathSeg.PATHSEG_LINETO_REL, [30, 31])
|
||||
assert.equal(segment.item.pathSegTypeAsLetter, 'l')
|
||||
assert.equal(segment.item.x, 30)
|
||||
assert.equal(segment.item.y, 31)
|
||||
|
||||
// Also verify that the actual path changed.
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'l');
|
||||
assert.equal(path.pathSegList.getItem(1).x, 30);
|
||||
assert.equal(path.pathSegList.getItem(1).y, 31);
|
||||
});
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'l')
|
||||
assert.equal(path.pathSegList.getItem(1).x, 30)
|
||||
assert.equal(path.pathSegList.getItem(1).y, 31)
|
||||
})
|
||||
|
||||
it('Test svgedit.path.Segment.setType with control points', function () {
|
||||
// Setup the dom for a mock control group.
|
||||
const svg = document.createElementNS(NS.SVG, 'svg');
|
||||
const path = document.createElementNS(NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 C11,12 13,14 15,16 Z');
|
||||
svg.append(path);
|
||||
const svg = document.createElementNS(NS.SVG, 'svg')
|
||||
const path = document.createElementNS(NS.SVG, 'path')
|
||||
path.setAttribute('d', 'M0,0 C11,12 13,14 15,16 Z')
|
||||
svg.append(path)
|
||||
|
||||
const [ mockPathContext, mockUtilitiesContext ] = getMockContexts(svg);
|
||||
pathModule.init(mockPathContext);
|
||||
utilities.init(mockUtilitiesContext);
|
||||
const segment = new Segment(1, path.pathSegList.getItem(1));
|
||||
segment.path = new Path(path);
|
||||
const [mockPathContext, mockUtilitiesContext] = getMockContexts(svg)
|
||||
pathModule.init(mockPathContext)
|
||||
utilities.init(mockUtilitiesContext)
|
||||
const segment = new Segment(1, path.pathSegList.getItem(1))
|
||||
segment.path = new Path(path)
|
||||
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'C');
|
||||
assert.equal(path.pathSegList.getItem(1).x1, 11);
|
||||
assert.equal(path.pathSegList.getItem(1).y1, 12);
|
||||
assert.equal(path.pathSegList.getItem(1).x2, 13);
|
||||
assert.equal(path.pathSegList.getItem(1).y2, 14);
|
||||
assert.equal(path.pathSegList.getItem(1).x, 15);
|
||||
assert.equal(path.pathSegList.getItem(1).y, 16);
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'C')
|
||||
assert.equal(path.pathSegList.getItem(1).x1, 11)
|
||||
assert.equal(path.pathSegList.getItem(1).y1, 12)
|
||||
assert.equal(path.pathSegList.getItem(1).x2, 13)
|
||||
assert.equal(path.pathSegList.getItem(1).y2, 14)
|
||||
assert.equal(path.pathSegList.getItem(1).x, 15)
|
||||
assert.equal(path.pathSegList.getItem(1).y, 16)
|
||||
|
||||
segment.setType(SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, [ 30, 31, 32, 33, 34, 35 ]);
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'c');
|
||||
assert.equal(path.pathSegList.getItem(1).x1, 32);
|
||||
assert.equal(path.pathSegList.getItem(1).y1, 33);
|
||||
assert.equal(path.pathSegList.getItem(1).x2, 34);
|
||||
assert.equal(path.pathSegList.getItem(1).y2, 35);
|
||||
assert.equal(path.pathSegList.getItem(1).x, 30);
|
||||
assert.equal(path.pathSegList.getItem(1).y, 31);
|
||||
});
|
||||
segment.setType(SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, [30, 31, 32, 33, 34, 35])
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'c')
|
||||
assert.equal(path.pathSegList.getItem(1).x1, 32)
|
||||
assert.equal(path.pathSegList.getItem(1).y1, 33)
|
||||
assert.equal(path.pathSegList.getItem(1).x2, 34)
|
||||
assert.equal(path.pathSegList.getItem(1).y2, 35)
|
||||
assert.equal(path.pathSegList.getItem(1).x, 30)
|
||||
assert.equal(path.pathSegList.getItem(1).y, 31)
|
||||
})
|
||||
|
||||
it('Test svgedit.path.Segment.move', function () {
|
||||
const path = document.createElementNS(NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 L10,11 L20,21Z');
|
||||
const path = document.createElementNS(NS.SVG, 'path')
|
||||
path.setAttribute('d', 'M0,0 L10,11 L20,21Z')
|
||||
|
||||
const [ mockPathContext, mockUtilitiesContext ] = getMockContexts();
|
||||
pathModule.init(mockPathContext);
|
||||
utilities.init(mockUtilitiesContext);
|
||||
new Path(path);
|
||||
const [mockPathContext, mockUtilitiesContext] = getMockContexts()
|
||||
pathModule.init(mockPathContext)
|
||||
utilities.init(mockUtilitiesContext)
|
||||
Path(path)
|
||||
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L');
|
||||
assert.equal(path.pathSegList.getItem(1).x, 10);
|
||||
assert.equal(path.pathSegList.getItem(1).y, 11);
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L')
|
||||
assert.equal(path.pathSegList.getItem(1).x, 10)
|
||||
assert.equal(path.pathSegList.getItem(1).y, 11)
|
||||
|
||||
const segment = new Segment(1, path.pathSegList.getItem(1));
|
||||
segment.move(-3, 4);
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L');
|
||||
assert.equal(path.pathSegList.getItem(1).x, 7);
|
||||
assert.equal(path.pathSegList.getItem(1).y, 15);
|
||||
});
|
||||
const segment = new Segment(1, path.pathSegList.getItem(1))
|
||||
segment.move(-3, 4)
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'L')
|
||||
assert.equal(path.pathSegList.getItem(1).x, 7)
|
||||
assert.equal(path.pathSegList.getItem(1).y, 15)
|
||||
})
|
||||
|
||||
it('Test svgedit.path.Segment.moveCtrl', function () {
|
||||
const path = document.createElementNS(NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 C11,12 13,14 15,16 Z');
|
||||
const path = document.createElementNS(NS.SVG, 'path')
|
||||
path.setAttribute('d', 'M0,0 C11,12 13,14 15,16 Z')
|
||||
|
||||
const [ mockPathContext, mockUtilitiesContext ] = getMockContexts();
|
||||
pathModule.init(mockPathContext);
|
||||
utilities.init(mockUtilitiesContext);
|
||||
new Path(path);
|
||||
const [mockPathContext, mockUtilitiesContext] = getMockContexts()
|
||||
pathModule.init(mockPathContext)
|
||||
utilities.init(mockUtilitiesContext)
|
||||
Path(path)
|
||||
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'C');
|
||||
assert.equal(path.pathSegList.getItem(1).x1, 11);
|
||||
assert.equal(path.pathSegList.getItem(1).y1, 12);
|
||||
assert.equal(path.pathSegList.getItem(1).x2, 13);
|
||||
assert.equal(path.pathSegList.getItem(1).y2, 14);
|
||||
assert.equal(path.pathSegList.getItem(1).x, 15);
|
||||
assert.equal(path.pathSegList.getItem(1).y, 16);
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'C')
|
||||
assert.equal(path.pathSegList.getItem(1).x1, 11)
|
||||
assert.equal(path.pathSegList.getItem(1).y1, 12)
|
||||
assert.equal(path.pathSegList.getItem(1).x2, 13)
|
||||
assert.equal(path.pathSegList.getItem(1).y2, 14)
|
||||
assert.equal(path.pathSegList.getItem(1).x, 15)
|
||||
assert.equal(path.pathSegList.getItem(1).y, 16)
|
||||
|
||||
const segment = new Segment(1, path.pathSegList.getItem(1));
|
||||
segment.moveCtrl(1, 100, -200);
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'C');
|
||||
assert.equal(path.pathSegList.getItem(1).x1, 111);
|
||||
assert.equal(path.pathSegList.getItem(1).y1, -188);
|
||||
assert.equal(path.pathSegList.getItem(1).x2, 13);
|
||||
assert.equal(path.pathSegList.getItem(1).y2, 14);
|
||||
assert.equal(path.pathSegList.getItem(1).x, 15);
|
||||
assert.equal(path.pathSegList.getItem(1).y, 16);
|
||||
});
|
||||
const segment = new Segment(1, path.pathSegList.getItem(1))
|
||||
segment.moveCtrl(1, 100, -200)
|
||||
assert.equal(path.pathSegList.getItem(1).pathSegTypeAsLetter, 'C')
|
||||
assert.equal(path.pathSegList.getItem(1).x1, 111)
|
||||
assert.equal(path.pathSegList.getItem(1).y1, -188)
|
||||
assert.equal(path.pathSegList.getItem(1).x2, 13)
|
||||
assert.equal(path.pathSegList.getItem(1).y2, 14)
|
||||
assert.equal(path.pathSegList.getItem(1).x, 15)
|
||||
assert.equal(path.pathSegList.getItem(1).y, 16)
|
||||
})
|
||||
|
||||
it('Test svgedit.path.convertPath', function () {
|
||||
unitsInit({
|
||||
getRoundDigits () { return 5; }
|
||||
});
|
||||
getRoundDigits () { return 5 }
|
||||
})
|
||||
|
||||
const path = document.createElementNS(NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M40,55h20v20');
|
||||
const path = document.createElementNS(NS.SVG, 'path')
|
||||
path.setAttribute('d', 'M40,55h20v20')
|
||||
|
||||
const abs = pathModule.convertPath(path);
|
||||
assert.equal(abs, 'M40,55L60,55L60,75');
|
||||
const abs = pathModule.convertPath(path)
|
||||
assert.equal(abs, 'M40,55L60,55L60,75')
|
||||
|
||||
const rel = pathModule.convertPath(path, true);
|
||||
assert.equal(rel, 'm40,55l20,0l0,20');
|
||||
});
|
||||
});
|
||||
const rel = pathModule.convertPath(path, true)
|
||||
assert.equal(rel, 'm40,55l20,0l0,20')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,122 +1,121 @@
|
|||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js';
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
|
||||
import * as coords from '../../../instrumented/svgcanvas/coords.js';
|
||||
import * as recalculate from '../../../instrumented/svgcanvas/recalculate.js';
|
||||
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js'
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js'
|
||||
import * as coords from '../../../instrumented/svgcanvas/coords.js'
|
||||
import * as recalculate from '../../../instrumented/svgcanvas/recalculate.js'
|
||||
|
||||
describe('recalculate', function () {
|
||||
const root = document.createElement('div');
|
||||
root.id = 'root';
|
||||
root.style.visibility = 'hidden';
|
||||
const root = document.createElement('div')
|
||||
root.id = 'root'
|
||||
root.style.visibility = 'hidden'
|
||||
|
||||
const svgroot = document.createElementNS(NS.SVG, 'svg');
|
||||
svgroot.id = 'svgroot';
|
||||
root.append(svgroot);
|
||||
const svg = document.createElementNS(NS.SVG, 'svg');
|
||||
svgroot.append(svg);
|
||||
const svgroot = document.createElementNS(NS.SVG, 'svg')
|
||||
svgroot.id = 'svgroot'
|
||||
root.append(svgroot)
|
||||
const svg = document.createElementNS(NS.SVG, 'svg')
|
||||
svgroot.append(svg)
|
||||
|
||||
const dataStorage = {
|
||||
_storage: new WeakMap(),
|
||||
put: function (element, key, obj) {
|
||||
if (!this._storage.has(element)) {
|
||||
this._storage.set(element, new Map());
|
||||
this._storage.set(element, new Map())
|
||||
}
|
||||
this._storage.get(element).set(key, obj);
|
||||
this._storage.get(element).set(key, obj)
|
||||
},
|
||||
get: function (element, key) {
|
||||
return this._storage.get(element).get(key);
|
||||
return this._storage.get(element).get(key)
|
||||
},
|
||||
has: function (element, key) {
|
||||
return this._storage.has(element) && this._storage.get(element).has(key);
|
||||
return this._storage.has(element) && this._storage.get(element).has(key)
|
||||
},
|
||||
remove: function (element, key) {
|
||||
const ret = this._storage.get(element).delete(key);
|
||||
const ret = this._storage.get(element).delete(key)
|
||||
if (!this._storage.get(element).size === 0) {
|
||||
this._storage.delete(element);
|
||||
this._storage.delete(element)
|
||||
}
|
||||
return ret;
|
||||
return ret
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let elemId = 1;
|
||||
let elemId = 1
|
||||
|
||||
/**
|
||||
* Initilize modules to set up the tests.
|
||||
* @returns {void}
|
||||
*/
|
||||
function setUp() {
|
||||
function setUp () {
|
||||
utilities.init(
|
||||
/**
|
||||
* @implements {module:utilities.EditorContext}
|
||||
*/
|
||||
{
|
||||
getSvgRoot() { return svg; },
|
||||
getDOMDocument() { return null; },
|
||||
getDOMContainer() { return null; },
|
||||
getDataStorage() { return dataStorage; }
|
||||
getSvgRoot () { return svg },
|
||||
getDOMDocument () { return null },
|
||||
getDOMContainer () { return null },
|
||||
getDataStorage () { return dataStorage }
|
||||
}
|
||||
);
|
||||
)
|
||||
coords.init(
|
||||
/**
|
||||
* @implements {module:coords.EditorContext}
|
||||
*/
|
||||
{
|
||||
getGridSnapping() { return false; },
|
||||
getDrawing() {
|
||||
getGridSnapping () { return false },
|
||||
getDrawing () {
|
||||
return {
|
||||
getNextId() { return String(elemId++); }
|
||||
};
|
||||
getNextId () { return String(elemId++) }
|
||||
}
|
||||
},
|
||||
getDataStorage() { return dataStorage; }
|
||||
getDataStorage () { return dataStorage }
|
||||
}
|
||||
);
|
||||
)
|
||||
recalculate.init(
|
||||
/**
|
||||
* @implements {module:recalculate.EditorContext}
|
||||
*/
|
||||
{
|
||||
getSvgRoot() { return svg; },
|
||||
getStartTransform() { return ''; },
|
||||
setStartTransform() { /* empty fn */ },
|
||||
getDataStorage() { return dataStorage; }
|
||||
getSvgRoot () { return svg },
|
||||
getStartTransform () { return '' },
|
||||
setStartTransform () { /* empty fn */ },
|
||||
getDataStorage () { return dataStorage }
|
||||
}
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
let elem;
|
||||
let elem
|
||||
|
||||
/**
|
||||
* Initialize for tests and set up `rect` element.
|
||||
* @returns {void}
|
||||
*/
|
||||
function setUpRect() {
|
||||
setUp();
|
||||
elem = document.createElementNS(NS.SVG, 'rect');
|
||||
elem.setAttribute('x', '200');
|
||||
elem.setAttribute('y', '150');
|
||||
elem.setAttribute('width', '250');
|
||||
elem.setAttribute('height', '120');
|
||||
svg.append(elem);
|
||||
function setUpRect () {
|
||||
setUp()
|
||||
elem = document.createElementNS(NS.SVG, 'rect')
|
||||
elem.setAttribute('x', '200')
|
||||
elem.setAttribute('y', '150')
|
||||
elem.setAttribute('width', '250')
|
||||
elem.setAttribute('height', '120')
|
||||
svg.append(elem)
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize for tests and set up `text` element with `tspan` child.
|
||||
* @returns {void}
|
||||
*/
|
||||
function setUpTextWithTspan() {
|
||||
setUp();
|
||||
elem = document.createElementNS(NS.SVG, 'text');
|
||||
elem.setAttribute('x', '200');
|
||||
elem.setAttribute('y', '150');
|
||||
function setUpTextWithTspan () {
|
||||
setUp()
|
||||
elem = document.createElementNS(NS.SVG, 'text')
|
||||
elem.setAttribute('x', '200')
|
||||
elem.setAttribute('y', '150')
|
||||
|
||||
const tspan = document.createElementNS(NS.SVG, 'tspan');
|
||||
tspan.setAttribute('x', '200');
|
||||
tspan.setAttribute('y', '150');
|
||||
const tspan = document.createElementNS(NS.SVG, 'tspan')
|
||||
tspan.setAttribute('x', '200')
|
||||
tspan.setAttribute('y', '150')
|
||||
|
||||
const theText = 'Foo bar';
|
||||
tspan.append(theText);
|
||||
elem.append(tspan);
|
||||
svg.append(elem);
|
||||
const theText = 'Foo bar'
|
||||
tspan.append(theText)
|
||||
elem.append(tspan)
|
||||
svg.append(elem)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,53 +124,53 @@ describe('recalculate', function () {
|
|||
*/
|
||||
afterEach(() => {
|
||||
while (svg.hasChildNodes()) {
|
||||
svg.firstChild.remove();
|
||||
svg.firstChild.remove()
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
it('Test recalculateDimensions() on rect with identity matrix', function () {
|
||||
setUpRect();
|
||||
elem.setAttribute('transform', 'matrix(1,0,0,1,0,0)');
|
||||
setUpRect()
|
||||
elem.setAttribute('transform', 'matrix(1,0,0,1,0,0)')
|
||||
|
||||
recalculate.recalculateDimensions(elem);
|
||||
recalculate.recalculateDimensions(elem)
|
||||
|
||||
// Ensure that the identity matrix is swallowed and the element has no
|
||||
// transform on it.
|
||||
assert.equal(elem.hasAttribute('transform'), false);
|
||||
});
|
||||
assert.equal(elem.hasAttribute('transform'), false)
|
||||
})
|
||||
|
||||
it('Test recalculateDimensions() on rect with simple translate', function () {
|
||||
setUpRect();
|
||||
elem.setAttribute('transform', 'translate(100,50)');
|
||||
setUpRect()
|
||||
elem.setAttribute('transform', 'translate(100,50)')
|
||||
|
||||
recalculate.recalculateDimensions(elem);
|
||||
recalculate.recalculateDimensions(elem)
|
||||
|
||||
assert.equal(elem.hasAttribute('transform'), false);
|
||||
assert.equal(elem.getAttribute('x'), '300');
|
||||
assert.equal(elem.getAttribute('y'), '200');
|
||||
assert.equal(elem.getAttribute('width'), '250');
|
||||
assert.equal(elem.getAttribute('height'), '120');
|
||||
});
|
||||
assert.equal(elem.hasAttribute('transform'), false)
|
||||
assert.equal(elem.getAttribute('x'), '300')
|
||||
assert.equal(elem.getAttribute('y'), '200')
|
||||
assert.equal(elem.getAttribute('width'), '250')
|
||||
assert.equal(elem.getAttribute('height'), '120')
|
||||
})
|
||||
|
||||
it('Test recalculateDimensions() on text w/tspan with simple translate', function () {
|
||||
setUpTextWithTspan();
|
||||
elem.setAttribute('transform', 'translate(100,50)');
|
||||
setUpTextWithTspan()
|
||||
elem.setAttribute('transform', 'translate(100,50)')
|
||||
|
||||
recalculate.recalculateDimensions(elem);
|
||||
recalculate.recalculateDimensions(elem)
|
||||
|
||||
// Ensure that the identity matrix is swallowed and the element has no
|
||||
// transform on it.
|
||||
assert.equal(elem.hasAttribute('transform'), false);
|
||||
assert.equal(elem.getAttribute('x'), '300');
|
||||
assert.equal(elem.getAttribute('y'), '200');
|
||||
assert.equal(elem.hasAttribute('transform'), false)
|
||||
assert.equal(elem.getAttribute('x'), '300')
|
||||
assert.equal(elem.getAttribute('y'), '200')
|
||||
|
||||
const tspan = elem.firstElementChild;
|
||||
assert.equal(tspan.getAttribute('x'), '300');
|
||||
assert.equal(tspan.getAttribute('y'), '200');
|
||||
});
|
||||
const tspan = elem.firstElementChild
|
||||
assert.equal(tspan.getAttribute('x'), '300')
|
||||
assert.equal(tspan.getAttribute('y'), '200')
|
||||
})
|
||||
|
||||
// TODO: Since recalculateDimensions() and surrounding code is
|
||||
// probably the largest, most complicated and strange piece of
|
||||
// code in SVG-edit, we need to write a whole lot of unit tests
|
||||
// for it here.
|
||||
});
|
||||
})
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js';
|
||||
import * as sanitize from '../../../instrumented/svgcanvas/sanitize.js';
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js'
|
||||
import * as sanitize from '../../../instrumented/svgcanvas/sanitize.js'
|
||||
|
||||
describe('sanitize', function () {
|
||||
const svg = document.createElementNS(NS.SVG, 'svg');
|
||||
const svg = document.createElementNS(NS.SVG, 'svg')
|
||||
|
||||
it('Test sanitizeSvg() strips ws from style attr', function () {
|
||||
const rect = document.createElementNS(NS.SVG, 'rect');
|
||||
rect.setAttribute('style', 'stroke: blue ;\t\tstroke-width :\t\t40;');
|
||||
const rect = document.createElementNS(NS.SVG, 'rect')
|
||||
rect.setAttribute('style', 'stroke: blue ;\t\tstroke-width :\t\t40;')
|
||||
// sanitizeSvg() requires the node to have a parent and a document.
|
||||
svg.append(rect);
|
||||
sanitize.sanitizeSvg(rect);
|
||||
svg.append(rect)
|
||||
sanitize.sanitizeSvg(rect)
|
||||
|
||||
assert.equal(rect.getAttribute('stroke'), 'blue');
|
||||
assert.equal(rect.getAttribute('stroke-width'), '40');
|
||||
});
|
||||
});
|
||||
assert.equal(rect.getAttribute('stroke'), 'blue')
|
||||
assert.equal(rect.getAttribute('stroke-width'), '40')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
import * as select from '../../../instrumented/svgcanvas/select.js';
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js';
|
||||
import * as select from '../../../instrumented/svgcanvas/select.js'
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js'
|
||||
|
||||
describe('select', function () {
|
||||
const sandbox = document.createElement('div');
|
||||
sandbox.id = 'sandbox';
|
||||
const sandbox = document.createElement('div')
|
||||
sandbox.id = 'sandbox'
|
||||
|
||||
let svgroot;
|
||||
let svgContent;
|
||||
let svgroot
|
||||
let svgContent
|
||||
const mockConfig = {
|
||||
dimensions: [ 640, 480 ]
|
||||
};
|
||||
dimensions: [640, 480]
|
||||
}
|
||||
const dataStorage = {
|
||||
_storage: new WeakMap(),
|
||||
put: function (element, key, obj) {
|
||||
if (!this._storage.has(element)) {
|
||||
this._storage.set(element, new Map());
|
||||
this._storage.set(element, new Map())
|
||||
}
|
||||
this._storage.get(element).set(key, obj);
|
||||
this._storage.get(element).set(key, obj)
|
||||
},
|
||||
get: function (element, key) {
|
||||
return this._storage.get(element).get(key);
|
||||
return this._storage.get(element).get(key)
|
||||
},
|
||||
has: function (element, key) {
|
||||
return this._storage.has(element) && this._storage.get(element).has(key);
|
||||
return this._storage.has(element) && this._storage.get(element).has(key)
|
||||
},
|
||||
remove: function (element, key) {
|
||||
const ret = this._storage.get(element).delete(key);
|
||||
const ret = this._storage.get(element).delete(key)
|
||||
if (!this._storage.get(element).size === 0) {
|
||||
this._storage.delete(element);
|
||||
this._storage.delete(element)
|
||||
}
|
||||
return ret;
|
||||
return ret
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @implements {module:select.SVGFactory}
|
||||
|
@ -39,16 +39,16 @@ describe('select', function () {
|
|||
const mockSvgCanvas = {
|
||||
curConfig: mockConfig,
|
||||
createSVGElement (jsonMap) {
|
||||
const elem = document.createElementNS(NS.SVG, jsonMap.element);
|
||||
Object.entries(jsonMap.attr).forEach(([ attr, value ]) => {
|
||||
elem.setAttribute(attr, value);
|
||||
});
|
||||
return elem;
|
||||
const elem = document.createElementNS(NS.SVG, jsonMap.element)
|
||||
Object.entries(jsonMap.attr).forEach(([attr, value]) => {
|
||||
elem.setAttribute(attr, value)
|
||||
})
|
||||
return elem
|
||||
},
|
||||
getSvgRoot () { return svgroot; },
|
||||
getSvgContent () { return svgContent; },
|
||||
getDataStorage () { return dataStorage; }
|
||||
};
|
||||
getSvgRoot () { return svgroot },
|
||||
getSvgContent () { return svgContent },
|
||||
getDataStorage () { return dataStorage }
|
||||
}
|
||||
|
||||
/**
|
||||
* Potentially reusable test set-up.
|
||||
|
@ -58,13 +58,13 @@ describe('select', function () {
|
|||
svgroot = mockSvgCanvas.createSVGElement({
|
||||
element: 'svg',
|
||||
attr: { id: 'svgroot' }
|
||||
});
|
||||
})
|
||||
svgContent = mockSvgCanvas.createSVGElement({
|
||||
element: 'svg',
|
||||
attr: { id: 'svgcontent' }
|
||||
});
|
||||
})
|
||||
|
||||
svgroot.append(svgContent);
|
||||
svgroot.append(svgContent)
|
||||
/* const rect = */ svgContent.append(
|
||||
mockSvgCanvas.createSVGElement({
|
||||
element: 'rect',
|
||||
|
@ -76,9 +76,9 @@ describe('select', function () {
|
|||
height: '100'
|
||||
}
|
||||
})
|
||||
);
|
||||
sandbox.append(svgroot);
|
||||
});
|
||||
)
|
||||
sandbox.append(svgroot)
|
||||
})
|
||||
|
||||
/*
|
||||
function setUpWithInit () {
|
||||
|
@ -92,61 +92,61 @@ describe('select', function () {
|
|||
*/
|
||||
afterEach(() => {
|
||||
while (sandbox.hasChildNodes()) {
|
||||
sandbox.firstChild.remove();
|
||||
sandbox.firstChild.remove()
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
it('Test svgedit.select package', function () {
|
||||
assert.ok(select);
|
||||
assert.ok(select.Selector);
|
||||
assert.ok(select.SelectorManager);
|
||||
assert.ok(select.init);
|
||||
assert.ok(select.getSelectorManager);
|
||||
assert.equal(typeof select, typeof {});
|
||||
assert.equal(typeof select.Selector, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof select.SelectorManager, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof select.init, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof select.getSelectorManager, typeof function () { /* empty fn */ });
|
||||
});
|
||||
assert.ok(select)
|
||||
assert.ok(select.Selector)
|
||||
assert.ok(select.SelectorManager)
|
||||
assert.ok(select.init)
|
||||
assert.ok(select.getSelectorManager)
|
||||
assert.equal(typeof select, typeof {})
|
||||
assert.equal(typeof select.Selector, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof select.SelectorManager, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof select.init, typeof function () { /* empty fn */ })
|
||||
assert.equal(typeof select.getSelectorManager, typeof function () { /* empty fn */ })
|
||||
})
|
||||
|
||||
it('Test Selector DOM structure', function () {
|
||||
assert.ok(svgroot);
|
||||
assert.ok(svgroot.hasChildNodes());
|
||||
assert.ok(svgroot)
|
||||
assert.ok(svgroot.hasChildNodes())
|
||||
|
||||
// Verify non-existence of Selector DOM nodes
|
||||
assert.equal(svgroot.childNodes.length, 1);
|
||||
assert.equal(svgroot.childNodes.item(0), svgContent);
|
||||
assert.ok(!svgroot.querySelector('#selectorParentGroup'));
|
||||
assert.equal(svgroot.childNodes.length, 1)
|
||||
assert.equal(svgroot.childNodes.item(0), svgContent)
|
||||
assert.ok(!svgroot.querySelector('#selectorParentGroup'))
|
||||
|
||||
select.init(mockSvgCanvas);
|
||||
select.init(mockSvgCanvas)
|
||||
|
||||
assert.equal(svgroot.childNodes.length, 3);
|
||||
assert.equal(svgroot.childNodes.length, 3)
|
||||
|
||||
// Verify existence of canvas background.
|
||||
const cb = svgroot.childNodes.item(0);
|
||||
assert.ok(cb);
|
||||
assert.equal(cb.id, 'canvasBackground');
|
||||
const cb = svgroot.childNodes.item(0)
|
||||
assert.ok(cb)
|
||||
assert.equal(cb.id, 'canvasBackground')
|
||||
|
||||
assert.ok(svgroot.childNodes.item(1));
|
||||
assert.equal(svgroot.childNodes.item(1), svgContent);
|
||||
assert.ok(svgroot.childNodes.item(1))
|
||||
assert.equal(svgroot.childNodes.item(1), svgContent)
|
||||
|
||||
// Verify existence of selectorParentGroup.
|
||||
const spg = svgroot.childNodes.item(2);
|
||||
assert.ok(spg);
|
||||
assert.equal(svgroot.querySelector('#selectorParentGroup'), spg);
|
||||
assert.equal(spg.id, 'selectorParentGroup');
|
||||
assert.equal(spg.tagName, 'g');
|
||||
const spg = svgroot.childNodes.item(2)
|
||||
assert.ok(spg)
|
||||
assert.equal(svgroot.querySelector('#selectorParentGroup'), spg)
|
||||
assert.equal(spg.id, 'selectorParentGroup')
|
||||
assert.equal(spg.tagName, 'g')
|
||||
|
||||
// Verify existence of all grip elements.
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_nw'));
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_n'));
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_ne'));
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_e'));
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_se'));
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_s'));
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_sw'));
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_w'));
|
||||
assert.ok(spg.querySelector('#selectorGrip_rotateconnector'));
|
||||
assert.ok(spg.querySelector('#selectorGrip_rotate'));
|
||||
});
|
||||
});
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_nw'))
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_n'))
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_ne'))
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_e'))
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_se'))
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_s'))
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_sw'))
|
||||
assert.ok(spg.querySelector('#selectorGrip_resize_w'))
|
||||
assert.ok(spg.querySelector('#selectorGrip_rotateconnector'))
|
||||
assert.ok(spg.querySelector('#selectorGrip_rotate'))
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable max-len, no-console */
|
||||
import SvgCanvas from '../../../instrumented/svgcanvas/svgcanvas.js';
|
||||
import SvgCanvas from '../../../instrumented/svgcanvas/svgcanvas.js'
|
||||
|
||||
describe('Basic Module', function () {
|
||||
// helper functions
|
||||
|
@ -12,34 +12,34 @@ describe('Basic Module', function () {
|
|||
};
|
||||
*/
|
||||
|
||||
let svgCanvas;
|
||||
let svgCanvas
|
||||
|
||||
const
|
||||
// svgroot = document.getElementById('svgroot'),
|
||||
// svgdoc = svgroot.documentElement,
|
||||
svgns = 'http://www.w3.org/2000/svg';
|
||||
const xlinkns = 'http://www.w3.org/1999/xlink';
|
||||
svgns = 'http://www.w3.org/2000/svg'
|
||||
const xlinkns = 'http://www.w3.org/1999/xlink'
|
||||
|
||||
beforeEach(() => {
|
||||
document.body.textContent = '';
|
||||
const svgEditor = document.createElement('div');
|
||||
svgEditor.id = 'svg_editor';
|
||||
const svgcanvas = document.createElement('div');
|
||||
svgcanvas.style.visibility = 'hidden';
|
||||
svgcanvas.id = 'svgcanvas';
|
||||
const workarea = document.createElement('div');
|
||||
workarea.id = 'workarea';
|
||||
workarea.append(svgcanvas);
|
||||
const toolsLeft = document.createElement('div');
|
||||
toolsLeft.id = 'tools_left';
|
||||
document.body.textContent = ''
|
||||
const svgEditor = document.createElement('div')
|
||||
svgEditor.id = 'svg_editor'
|
||||
const svgcanvas = document.createElement('div')
|
||||
svgcanvas.style.visibility = 'hidden'
|
||||
svgcanvas.id = 'svgcanvas'
|
||||
const workarea = document.createElement('div')
|
||||
workarea.id = 'workarea'
|
||||
workarea.append(svgcanvas)
|
||||
const toolsLeft = document.createElement('div')
|
||||
toolsLeft.id = 'tools_left'
|
||||
|
||||
svgEditor.append(workarea, toolsLeft);
|
||||
document.body.append(svgEditor);
|
||||
svgEditor.append(workarea, toolsLeft)
|
||||
document.body.append(svgEditor)
|
||||
|
||||
svgCanvas = new SvgCanvas(
|
||||
document.getElementById('svgcanvas'), {
|
||||
canvas_expansion: 3,
|
||||
dimensions: [ 640, 480 ],
|
||||
dimensions: [640, 480],
|
||||
initFill: {
|
||||
color: 'FF0000', // solid red
|
||||
opacity: 1
|
||||
|
@ -53,20 +53,20 @@ describe('Basic Module', function () {
|
|||
imgPath: '../editor/images',
|
||||
langPath: 'locale/',
|
||||
extPath: 'extensions/',
|
||||
extensions: [ 'ext-arrows.js', 'ext-eyedropper.js' ],
|
||||
extensions: ['ext-arrows.js', 'ext-eyedropper.js'],
|
||||
initTool: 'select',
|
||||
wireframe: false
|
||||
}
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
it('Test existence of SvgCanvas object', function () {
|
||||
assert.equal(typeof {}, typeof svgCanvas);
|
||||
});
|
||||
assert.equal(typeof {}, typeof svgCanvas)
|
||||
})
|
||||
|
||||
describe('Path Module', function () {
|
||||
it('Test path conversion from absolute to relative', function () {
|
||||
const convert = svgCanvas.pathActions.convertPath;
|
||||
const convert = svgCanvas.pathActions.convertPath
|
||||
|
||||
// TODO: Test these paths:
|
||||
// "m400.00491,625.01379a1.78688,1.78688 0 1 1-3.57373,0a1.78688,1.78688 0 1 13.57373,0z"
|
||||
|
@ -78,36 +78,36 @@ describe('Basic Module', function () {
|
|||
"<path id='p1' d='M100,100 L200,100 L100,100Z'/>" +
|
||||
"<path id='p2' d='m 0,0 l 200,0 l 0,100 L 0,100'/>" +
|
||||
'</svg>'
|
||||
);
|
||||
)
|
||||
|
||||
const p1 = document.getElementById('p1');
|
||||
const p2 = document.getElementById('p2');
|
||||
const dAbs = p1.getAttribute('d');
|
||||
const seglist = p1.pathSegList;
|
||||
const p1 = document.getElementById('p1')
|
||||
const p2 = document.getElementById('p2')
|
||||
const dAbs = p1.getAttribute('d')
|
||||
const seglist = p1.pathSegList
|
||||
|
||||
assert.equal(p1.nodeName, 'path', "Expected 'path', got");
|
||||
assert.equal(p1.nodeName, 'path', "Expected 'path', got")
|
||||
|
||||
assert.equal(seglist.numberOfItems, 4, 'Number of segments before conversion');
|
||||
assert.equal(seglist.numberOfItems, 4, 'Number of segments before conversion')
|
||||
|
||||
// verify segments before conversion
|
||||
let curseg = seglist.getItem(0);
|
||||
assert.equal(curseg.pathSegTypeAsLetter.toUpperCase(), 'M', 'Before conversion, segment #1 type');
|
||||
curseg = seglist.getItem(1);
|
||||
assert.equal(curseg.pathSegTypeAsLetter.toUpperCase(), 'L', 'Before conversion, segment #2 type');
|
||||
curseg = seglist.getItem(3);
|
||||
assert.equal(curseg.pathSegTypeAsLetter.toUpperCase(), 'Z', 'Before conversion, segment #3 type' + dAbs);
|
||||
let curseg = seglist.getItem(0)
|
||||
assert.equal(curseg.pathSegTypeAsLetter.toUpperCase(), 'M', 'Before conversion, segment #1 type')
|
||||
curseg = seglist.getItem(1)
|
||||
assert.equal(curseg.pathSegTypeAsLetter.toUpperCase(), 'L', 'Before conversion, segment #2 type')
|
||||
curseg = seglist.getItem(3)
|
||||
assert.equal(curseg.pathSegTypeAsLetter.toUpperCase(), 'Z', 'Before conversion, segment #3 type' + dAbs)
|
||||
|
||||
// convert and verify segments
|
||||
let d = convert(p1, true);
|
||||
assert.equal(d, 'm100,100l100,0l-100,0z', 'Converted path to relative string');
|
||||
let d = convert(p1, true)
|
||||
assert.equal(d, 'm100,100l100,0l-100,0z', 'Converted path to relative string')
|
||||
|
||||
// TODO: see why this isn't working in SVG-edit
|
||||
d = convert(p2, true);
|
||||
console.log('Convert true', d);
|
||||
d = convert(p2, false);
|
||||
console.log('Convert false', d);
|
||||
});
|
||||
});
|
||||
d = convert(p2, true)
|
||||
console.log('Convert true', d)
|
||||
d = convert(p2, false)
|
||||
console.log('Convert false', d)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Import Module', function () {
|
||||
it('Test import use', function () {
|
||||
|
@ -118,16 +118,16 @@ describe('Basic Module', function () {
|
|||
"<use id='foreign-use' xlink:href='somefile.svg#the-rect'/>" +
|
||||
"<use id='no-use'/>" +
|
||||
'</svg>'
|
||||
);
|
||||
)
|
||||
|
||||
const u = document.getElementById('the-use');
|
||||
const fu = document.getElementById('foreign-use');
|
||||
const nfu = document.getElementById('no-use');
|
||||
const u = document.getElementById('the-use')
|
||||
const fu = document.getElementById('foreign-use')
|
||||
const nfu = document.getElementById('no-use')
|
||||
|
||||
assert.equal((u && u.nodeName), 'use', 'Did not import <use> element');
|
||||
assert.equal(fu, null, 'Removed <use> element that had a foreign href');
|
||||
assert.equal(nfu, null, 'Removed <use> element that had no href');
|
||||
});
|
||||
assert.equal((u && u.nodeName), 'use', 'Did not import <use> element')
|
||||
assert.equal(fu, null, 'Removed <use> element that had a foreign href')
|
||||
assert.equal(nfu, null, 'Removed <use> element that had no href')
|
||||
})
|
||||
|
||||
// This test shows that an element with an invalid attribute is still parsed in properly
|
||||
// and only the attribute is not imported
|
||||
|
@ -136,13 +136,13 @@ describe('Basic Module', function () {
|
|||
'<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">' +
|
||||
'<text x="182.75" y="173.5" id="the-text" fill="#008000" font-size="150" font-family="serif" text-anchor="middle" d="M116,222 L110,108">words</text>' +
|
||||
'</svg>'
|
||||
);
|
||||
)
|
||||
|
||||
const t = document.getElementById('the-text');
|
||||
const t = document.getElementById('the-text')
|
||||
|
||||
assert.equal((t && t.nodeName), 'text', 'Did not import <text> element');
|
||||
assert.equal(t.getAttribute('d'), null, 'Imported a <text> with a d attribute');
|
||||
});
|
||||
assert.equal((t && t.nodeName), 'text', 'Did not import <text> element')
|
||||
assert.equal(t.getAttribute('d'), null, 'Imported a <text> with a d attribute')
|
||||
})
|
||||
|
||||
// This test makes sure import/export properly handles namespaced attributes
|
||||
it('Test importing/exporting namespaced attributes', function () {
|
||||
|
@ -151,22 +151,22 @@ describe('Basic Module', function () {
|
|||
'<image xlink:href="../editor/images/logo.png"/>' +
|
||||
'<polyline id="se_test_elem" se:foo="bar" foo:bar="baz"/>' +
|
||||
'</svg>'
|
||||
);
|
||||
const attrVal = document.getElementById('se_test_elem').getAttributeNS('http://svg-edit.googlecode.com', 'foo');
|
||||
)
|
||||
const attrVal = document.getElementById('se_test_elem').getAttributeNS('http://svg-edit.googlecode.com', 'foo')
|
||||
|
||||
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 hasXlink = output.includes('xmlns:xlink="http://www.w3.org/1999/xlink"');
|
||||
const hasSe = output.includes('xmlns:se=');
|
||||
const hasFoo = output.includes('xmlns:foo=');
|
||||
const hasAttr = output.includes('se:foo="bar"');
|
||||
const output = svgCanvas.getSvgString()
|
||||
const hasXlink = output.includes('xmlns:xlink="http://www.w3.org/1999/xlink"')
|
||||
const hasSe = output.includes('xmlns:se=')
|
||||
const hasFoo = output.includes('xmlns:foo=')
|
||||
const hasAttr = output.includes('se:foo="bar"')
|
||||
|
||||
assert.equal(hasAttr, true, 'Preserved namespaced attribute on export');
|
||||
assert.equal(hasXlink, true, 'Included xlink: xmlns');
|
||||
assert.equal(hasSe, true, 'Included se: xmlns');
|
||||
assert.equal(hasFoo, false, 'Did not include foo: xmlns');
|
||||
});
|
||||
assert.equal(hasAttr, true, 'Preserved namespaced attribute on export')
|
||||
assert.equal(hasXlink, true, 'Included xlink: xmlns')
|
||||
assert.equal(hasSe, true, 'Included se: xmlns')
|
||||
assert.equal(hasFoo, false, 'Did not include foo: xmlns')
|
||||
})
|
||||
|
||||
it('Test import math elements inside a foreignObject', function () {
|
||||
/* const set = */ svgCanvas.setSvgString(
|
||||
|
@ -179,17 +179,17 @@ describe('Basic Module', function () {
|
|||
'</math>' +
|
||||
'</foreignObject>' +
|
||||
'</svg>'
|
||||
);
|
||||
const fo = document.getElementById('fo');
|
||||
)
|
||||
const fo = document.getElementById('fo')
|
||||
// we cannot use getElementById('math') because not all browsers understand MathML and do not know to use the @id attribute
|
||||
// see Bug https://bugs.webkit.org/show_bug.cgi?id=35042
|
||||
const math = fo.firstChild;
|
||||
const math = fo.firstChild
|
||||
|
||||
assert.equal(Boolean(math), true, 'Math element exists');
|
||||
assert.equal(math.nodeName, 'math', 'Math element has the proper nodeName');
|
||||
assert.equal(math.getAttribute('id'), 'm', 'Math element has an id');
|
||||
assert.equal(math.namespaceURI, 'http://www.w3.org/1998/Math/MathML', 'Preserved MathML namespace');
|
||||
});
|
||||
assert.equal(Boolean(math), true, 'Math element exists')
|
||||
assert.equal(math.nodeName, 'math', 'Math element has the proper nodeName')
|
||||
assert.equal(math.getAttribute('id'), 'm', 'Math element has an id')
|
||||
assert.equal(math.namespaceURI, 'http://www.w3.org/1998/Math/MathML', 'Preserved MathML namespace')
|
||||
})
|
||||
|
||||
it('Test importing SVG into existing drawing', function () {
|
||||
/* const doc = */ svgCanvas.setSvgString(
|
||||
|
@ -199,23 +199,23 @@ describe('Basic Module', function () {
|
|||
'<ellipse cx="300" cy="100" rx="40" ry="30" fill="green"/>' +
|
||||
'</g>' +
|
||||
'</svg>'
|
||||
);
|
||||
)
|
||||
|
||||
svgCanvas.importSvgString(
|
||||
'<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">' +
|
||||
'<circle cx="50" cy="50" r="40" fill="yellow"/>' +
|
||||
'<rect width="20" height="20" fill="blue"/>' +
|
||||
'</svg>'
|
||||
);
|
||||
)
|
||||
|
||||
const svgContent = document.getElementById('svgcontent');
|
||||
const circles = svgContent.getElementsByTagNameNS(svgns, 'circle');
|
||||
const rects = svgContent.getElementsByTagNameNS(svgns, 'rect');
|
||||
const ellipses = svgContent.getElementsByTagNameNS(svgns, 'ellipse');
|
||||
assert.equal(circles.length, 2, 'Found two circles upon importing');
|
||||
assert.equal(rects.length, 1, 'Found one rectangle upon importing');
|
||||
assert.equal(ellipses.length, 1, 'Found one ellipse upon importing');
|
||||
});
|
||||
const svgContent = document.getElementById('svgcontent')
|
||||
const circles = svgContent.getElementsByTagNameNS(svgns, 'circle')
|
||||
const rects = svgContent.getElementsByTagNameNS(svgns, 'rect')
|
||||
const ellipses = svgContent.getElementsByTagNameNS(svgns, 'ellipse')
|
||||
assert.equal(circles.length, 2, 'Found two circles upon importing')
|
||||
assert.equal(rects.length, 1, 'Found one rectangle upon importing')
|
||||
assert.equal(ellipses.length, 1, 'Found one ellipse upon importing')
|
||||
})
|
||||
|
||||
it('Test importing SVG remaps IDs', function () {
|
||||
/* const doc = */ svgCanvas.setSvgString(
|
||||
|
@ -226,7 +226,7 @@ describe('Basic Module', function () {
|
|||
'<ellipse id="svg_3" cx="300" cy="100" rx="40" ry="30" fill="green"/>' +
|
||||
'</g>' +
|
||||
'</svg>'
|
||||
);
|
||||
)
|
||||
|
||||
svgCanvas.importSvgString(
|
||||
'<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink">' +
|
||||
|
@ -240,24 +240,24 @@ describe('Basic Module', function () {
|
|||
'<circle id="svg_1" cx="50" cy="50" r="40" fill="url(#svg_2)"/>' +
|
||||
'<use id="svg_4" width="30" height="30" xl:href="#svg_3"/>' +
|
||||
'</svg>'
|
||||
);
|
||||
)
|
||||
|
||||
const svgContent = document.getElementById('svgcontent');
|
||||
const circles = svgContent.getElementsByTagNameNS(svgns, 'circle');
|
||||
const rects = svgContent.getElementsByTagNameNS(svgns, 'rect');
|
||||
const svgContent = document.getElementById('svgcontent')
|
||||
const circles = svgContent.getElementsByTagNameNS(svgns, 'circle')
|
||||
const rects = svgContent.getElementsByTagNameNS(svgns, 'rect')
|
||||
// ellipses = svgContent.getElementsByTagNameNS(svgns, 'ellipse'),
|
||||
const defs = svgContent.getElementsByTagNameNS(svgns, 'defs');
|
||||
const defs = svgContent.getElementsByTagNameNS(svgns, 'defs')
|
||||
// grads = svgContent.getElementsByTagNameNS(svgns, 'linearGradient'),
|
||||
const uses = svgContent.getElementsByTagNameNS(svgns, 'use');
|
||||
assert.notEqual(circles.item(0).id, 'svg_1', 'Circle not re-identified');
|
||||
assert.notEqual(rects.item(0).id, 'svg_3', 'Rectangle not re-identified');
|
||||
const uses = svgContent.getElementsByTagNameNS(svgns, 'use')
|
||||
assert.notEqual(circles.item(0).id, 'svg_1', 'Circle not re-identified')
|
||||
assert.notEqual(rects.item(0).id, 'svg_3', 'Rectangle not re-identified')
|
||||
// TODO: determine why this test fails in WebKit browsers
|
||||
// assert.equal(grads.length, 1, 'Linear gradient imported');
|
||||
const grad = defs.item(0).firstChild;
|
||||
assert.notEqual(grad.id, 'svg_2', 'Linear gradient not re-identified');
|
||||
assert.notEqual(circles.item(0).getAttribute('fill'), 'url(#svg_2)', 'Circle fill value not remapped');
|
||||
assert.notEqual(rects.item(0).getAttribute('stroke'), 'url(#svg_2)', 'Rectangle stroke value not remapped');
|
||||
assert.notEqual(uses.item(0).getAttributeNS(xlinkns, 'href'), '#svg_3');
|
||||
});
|
||||
});
|
||||
});
|
||||
const grad = defs.item(0).firstChild
|
||||
assert.notEqual(grad.id, 'svg_2', 'Linear gradient not re-identified')
|
||||
assert.notEqual(circles.item(0).getAttribute('fill'), 'url(#svg_2)', 'Circle fill value not remapped')
|
||||
assert.notEqual(rects.item(0).getAttribute('stroke'), 'url(#svg_2)', 'Rectangle stroke value not remapped')
|
||||
assert.notEqual(uses.item(0).getAttributeNS(xlinkns, 'href'), '#svg_3')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as units from '../../../instrumented/common/units.js';
|
||||
import * as units from '../../../instrumented/common/units.js'
|
||||
|
||||
describe('units', function () {
|
||||
/**
|
||||
|
@ -6,86 +6,86 @@ describe('units', function () {
|
|||
* @returns {void}
|
||||
*/
|
||||
beforeEach(() => {
|
||||
document.body.textContent = '';
|
||||
const anchor = document.createElement('div');
|
||||
anchor.id = 'anchor';
|
||||
anchor.style.visibility = 'hidden';
|
||||
document.body.textContent = ''
|
||||
const anchor = document.createElement('div')
|
||||
anchor.id = 'anchor'
|
||||
anchor.style.visibility = 'hidden'
|
||||
|
||||
const elementsContainer = document.createElement('div');
|
||||
elementsContainer.id = 'elementsContainer';
|
||||
const elementsContainer = document.createElement('div')
|
||||
elementsContainer.id = 'elementsContainer'
|
||||
|
||||
const uniqueId = document.createElement('div');
|
||||
uniqueId.id = 'uniqueId';
|
||||
uniqueId.style.visibility = 'hidden';
|
||||
const uniqueId = document.createElement('div')
|
||||
uniqueId.id = 'uniqueId'
|
||||
uniqueId.style.visibility = 'hidden'
|
||||
|
||||
const nonUniqueId = document.createElement('div');
|
||||
nonUniqueId.id = 'nonUniqueId';
|
||||
nonUniqueId.style.visibility = 'hidden';
|
||||
const nonUniqueId = document.createElement('div')
|
||||
nonUniqueId.id = 'nonUniqueId'
|
||||
nonUniqueId.style.visibility = 'hidden'
|
||||
|
||||
elementsContainer.append(uniqueId, nonUniqueId);
|
||||
elementsContainer.append(uniqueId, nonUniqueId)
|
||||
|
||||
document.body.append(anchor, elementsContainer);
|
||||
document.body.append(anchor, elementsContainer)
|
||||
|
||||
units.init(
|
||||
/**
|
||||
* @implements {module:units.ElementContainer}
|
||||
*/
|
||||
{
|
||||
getBaseUnit () { return 'cm'; },
|
||||
getHeight () { return 600; },
|
||||
getWidth () { return 800; },
|
||||
getRoundDigits () { return 4; },
|
||||
getElement (elementId) { return document.getElementById(elementId); }
|
||||
getBaseUnit () { return 'cm' },
|
||||
getHeight () { return 600 },
|
||||
getWidth () { return 800 },
|
||||
getRoundDigits () { return 4 },
|
||||
getElement (elementId) { return document.getElementById(elementId) }
|
||||
}
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
it('Test svgedit.units package', function () {
|
||||
assert.ok(units);
|
||||
assert.equal(typeof units, typeof {});
|
||||
});
|
||||
assert.ok(units)
|
||||
assert.equal(typeof units, typeof {})
|
||||
})
|
||||
|
||||
it('Test svgedit.units.shortFloat()', function () {
|
||||
assert.ok(units.shortFloat);
|
||||
assert.equal(typeof units.shortFloat, typeof function () { /* empty fn */ });
|
||||
assert.ok(units.shortFloat)
|
||||
assert.equal(typeof units.shortFloat, typeof function () { /* empty fn */ })
|
||||
|
||||
const { shortFloat } = units;
|
||||
assert.equal(shortFloat(0.00000001), 0);
|
||||
assert.equal(shortFloat(1), 1);
|
||||
assert.equal(shortFloat(3.45678), 3.4568);
|
||||
assert.equal(shortFloat(1.23443), 1.2344);
|
||||
assert.equal(shortFloat(1.23455), 1.2346);
|
||||
});
|
||||
const { shortFloat } = units
|
||||
assert.equal(shortFloat(0.00000001), 0)
|
||||
assert.equal(shortFloat(1), 1)
|
||||
assert.equal(shortFloat(3.45678), 3.4568)
|
||||
assert.equal(shortFloat(1.23443), 1.2344)
|
||||
assert.equal(shortFloat(1.23455), 1.2346)
|
||||
})
|
||||
|
||||
it('Test svgedit.units.isValidUnit()', function () {
|
||||
assert.ok(units.isValidUnit);
|
||||
assert.equal(typeof units.isValidUnit, typeof function () { /* empty fn */ });
|
||||
assert.ok(units.isValidUnit)
|
||||
assert.equal(typeof units.isValidUnit, typeof function () { /* empty fn */ })
|
||||
|
||||
const { isValidUnit } = units;
|
||||
assert.ok(isValidUnit('0'));
|
||||
assert.ok(isValidUnit('1'));
|
||||
assert.ok(isValidUnit('1.1'));
|
||||
assert.ok(isValidUnit('-1.1'));
|
||||
assert.ok(isValidUnit('.6mm'));
|
||||
assert.ok(isValidUnit('-.6cm'));
|
||||
assert.ok(isValidUnit('6000in'));
|
||||
assert.ok(isValidUnit('6px'));
|
||||
assert.ok(isValidUnit('6.3pc'));
|
||||
assert.ok(isValidUnit('-0.4em'));
|
||||
assert.ok(isValidUnit('-0.ex'));
|
||||
assert.ok(isValidUnit('40.123%'));
|
||||
const { isValidUnit } = units
|
||||
assert.ok(isValidUnit('0'))
|
||||
assert.ok(isValidUnit('1'))
|
||||
assert.ok(isValidUnit('1.1'))
|
||||
assert.ok(isValidUnit('-1.1'))
|
||||
assert.ok(isValidUnit('.6mm'))
|
||||
assert.ok(isValidUnit('-.6cm'))
|
||||
assert.ok(isValidUnit('6000in'))
|
||||
assert.ok(isValidUnit('6px'))
|
||||
assert.ok(isValidUnit('6.3pc'))
|
||||
assert.ok(isValidUnit('-0.4em'))
|
||||
assert.ok(isValidUnit('-0.ex'))
|
||||
assert.ok(isValidUnit('40.123%'))
|
||||
|
||||
assert.equal(isValidUnit('id', 'uniqueId', document.getElementById('uniqueId')), true);
|
||||
assert.equal(isValidUnit('id', 'newId', document.getElementById('uniqueId')), true);
|
||||
assert.equal(isValidUnit('id', 'uniqueId'), false);
|
||||
assert.equal(isValidUnit('id', 'uniqueId', document.getElementById('nonUniqueId')), false);
|
||||
});
|
||||
assert.equal(isValidUnit('id', 'uniqueId', document.getElementById('uniqueId')), true)
|
||||
assert.equal(isValidUnit('id', 'newId', document.getElementById('uniqueId')), true)
|
||||
assert.equal(isValidUnit('id', 'uniqueId'), false)
|
||||
assert.equal(isValidUnit('id', 'uniqueId', document.getElementById('nonUniqueId')), false)
|
||||
})
|
||||
|
||||
it('Test svgedit.units.convertUnit()', function () {
|
||||
assert.ok(units.convertUnit);
|
||||
assert.equal(typeof units.convertUnit, typeof function () { /* empty fn */ });
|
||||
assert.ok(units.convertUnit)
|
||||
assert.equal(typeof units.convertUnit, typeof function () { /* empty fn */ })
|
||||
// cm in default setup
|
||||
assert.equal(units.convertUnit(42), 1.1113);
|
||||
assert.equal(units.convertUnit(42, 'px'), 42);
|
||||
});
|
||||
});
|
||||
assert.equal(units.convertUnit(42), 1.1113)
|
||||
assert.equal(units.convertUnit(42, 'px'), 42)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import 'pathseg';
|
||||
import 'pathseg'
|
||||
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js';
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
|
||||
import * as math from '../../../instrumented/svgcanvas/math.js';
|
||||
import * as path from '../../../instrumented/svgcanvas/path.js';
|
||||
import setAssertionMethods from '../../support/assert-close.js';
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js'
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js'
|
||||
import * as math from '../../../instrumented/svgcanvas/math.js'
|
||||
import * as path from '../../../instrumented/svgcanvas/path.js'
|
||||
import setAssertionMethods from '../../support/assert-close.js'
|
||||
|
||||
chai.use(setAssertionMethods);
|
||||
// eslint-disable-next-line
|
||||
chai.use(setAssertionMethods)
|
||||
|
||||
describe('utilities bbox', function () {
|
||||
/**
|
||||
|
@ -15,13 +16,13 @@ describe('utilities bbox', function () {
|
|||
* @returns {SVGElement}
|
||||
*/
|
||||
function mockCreateSVGElement (jsonMap) {
|
||||
const elem = document.createElementNS(NS.SVG, jsonMap.element);
|
||||
Object.entries(jsonMap.attr).forEach(([ attr, value ]) => {
|
||||
elem.setAttribute(attr, value);
|
||||
});
|
||||
return elem;
|
||||
const elem = document.createElementNS(NS.SVG, jsonMap.element)
|
||||
Object.entries(jsonMap.attr).forEach(([attr, value]) => {
|
||||
elem.setAttribute(attr, value)
|
||||
})
|
||||
return elem
|
||||
}
|
||||
let mockaddSVGElemensFromJsonCallCount = 0;
|
||||
let mockaddSVGElemensFromJsonCallCount = 0
|
||||
|
||||
/**
|
||||
* Mock of {@link module:utilities.EditorContext#addSVGElemensFromJson}.
|
||||
|
@ -29,435 +30,435 @@ describe('utilities bbox', function () {
|
|||
* @returns {SVGElement}
|
||||
*/
|
||||
function mockaddSVGElemensFromJson (json) {
|
||||
const elem = mockCreateSVGElement(json);
|
||||
svgroot.append(elem);
|
||||
mockaddSVGElemensFromJsonCallCount++;
|
||||
return elem;
|
||||
const elem = mockCreateSVGElement(json)
|
||||
svgroot.append(elem)
|
||||
mockaddSVGElemensFromJsonCallCount++
|
||||
return elem
|
||||
}
|
||||
const mockPathActions = {
|
||||
resetOrientation (pth) {
|
||||
if (utilities.isNullish(pth) || pth.nodeName !== 'path') { return false; }
|
||||
const tlist = pth.transform.baseVal;
|
||||
const m = math.transformListToTransform(tlist).matrix;
|
||||
tlist.clear();
|
||||
pth.removeAttribute('transform');
|
||||
const segList = pth.pathSegList;
|
||||
if (utilities.isNullish(pth) || pth.nodeName !== 'path') { return false }
|
||||
const tlist = pth.transform.baseVal
|
||||
const m = math.transformListToTransform(tlist).matrix
|
||||
tlist.clear()
|
||||
pth.removeAttribute('transform')
|
||||
const segList = pth.pathSegList
|
||||
|
||||
const len = segList.numberOfItems;
|
||||
const len = segList.numberOfItems
|
||||
// let lastX, lastY;
|
||||
|
||||
for (let i = 0; i < len; ++i) {
|
||||
const seg = segList.getItem(i);
|
||||
const type = seg.pathSegType;
|
||||
if (type === 1) { continue; }
|
||||
const seg = segList.getItem(i)
|
||||
const type = seg.pathSegType
|
||||
if (type === 1) { continue }
|
||||
const pts = [];
|
||||
[ '', 1, 2 ].forEach(function (n) {
|
||||
const x = seg['x' + n]; const y = seg['y' + n];
|
||||
['', 1, 2].forEach(function (n) {
|
||||
const x = seg['x' + n]; const y = seg['y' + n]
|
||||
if (x !== undefined && y !== undefined) {
|
||||
const pt = math.transformPoint(x, y, m);
|
||||
pts.splice(pts.length, 0, pt.x, pt.y);
|
||||
const pt = math.transformPoint(x, y, m)
|
||||
pts.splice(pts.length, 0, pt.x, pt.y)
|
||||
}
|
||||
});
|
||||
path.replacePathSeg(type, i, pts, pth);
|
||||
})
|
||||
path.replacePathSeg(type, i, pts, pth)
|
||||
}
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const EPSILON = 0.001;
|
||||
const EPSILON = 0.001
|
||||
|
||||
let svgroot;
|
||||
let svgroot
|
||||
beforeEach(() => {
|
||||
document.body.textContent = '';
|
||||
document.body.textContent = ''
|
||||
|
||||
// const svg = document.createElementNS(NS.SVG, 'svg');
|
||||
const sandbox = document.createElement('div');
|
||||
sandbox.id = 'sandbox';
|
||||
document.body.append(sandbox);
|
||||
const sandbox = document.createElement('div')
|
||||
sandbox.id = 'sandbox'
|
||||
document.body.append(sandbox)
|
||||
|
||||
svgroot = mockCreateSVGElement({
|
||||
element: 'svg',
|
||||
attr: { id: 'svgroot' }
|
||||
});
|
||||
sandbox.append(svgroot);
|
||||
})
|
||||
sandbox.append(svgroot)
|
||||
|
||||
const mockSvgCanvas = {
|
||||
createSVGElement (jsonMap) {
|
||||
const elem = document.createElementNS(NS.SVG, jsonMap.element);
|
||||
Object.entries(jsonMap.attr).forEach(([ attr, value ]) => {
|
||||
elem.setAttribute(attr, value);
|
||||
});
|
||||
return elem;
|
||||
const elem = document.createElementNS(NS.SVG, jsonMap.element)
|
||||
Object.entries(jsonMap.attr).forEach(([attr, value]) => {
|
||||
elem.setAttribute(attr, value)
|
||||
})
|
||||
return elem
|
||||
},
|
||||
getSvgRoot () { return svgroot; }
|
||||
};
|
||||
getSvgRoot () { return svgroot }
|
||||
}
|
||||
|
||||
path.init(mockSvgCanvas);
|
||||
mockaddSVGElemensFromJsonCallCount = 0;
|
||||
});
|
||||
path.init(mockSvgCanvas)
|
||||
mockaddSVGElemensFromJsonCallCount = 0
|
||||
})
|
||||
|
||||
it('Test svgedit.utilities package', function () {
|
||||
assert.ok(utilities);
|
||||
assert.ok(utilities.getBBoxWithTransform);
|
||||
assert.ok(utilities.getStrokedBBox);
|
||||
assert.ok(utilities.getRotationAngleFromTransformList);
|
||||
assert.ok(utilities.getRotationAngle);
|
||||
});
|
||||
assert.ok(utilities)
|
||||
assert.ok(utilities.getBBoxWithTransform)
|
||||
assert.ok(utilities.getStrokedBBox)
|
||||
assert.ok(utilities.getRotationAngleFromTransformList)
|
||||
assert.ok(utilities.getRotationAngle)
|
||||
})
|
||||
|
||||
it('Test getBBoxWithTransform and no transform', function () {
|
||||
const { getBBoxWithTransform } = utilities;
|
||||
const { getBBoxWithTransform } = utilities
|
||||
|
||||
let elem = mockCreateSVGElement({
|
||||
element: 'path',
|
||||
attr: { id: 'path', d: 'M0,1 L2,3' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
let bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 2, height: 2 });
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 0);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
let bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 2, height: 2 })
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 0)
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 0);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 })
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 0)
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'line',
|
||||
attr: { id: 'line', x1: '0', y1: '1', x2: '5', y2: '6' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 });
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 0);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 })
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 0)
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
|
||||
});
|
||||
})
|
||||
const g = mockCreateSVGElement({
|
||||
element: 'g',
|
||||
attr: {}
|
||||
});
|
||||
g.append(elem);
|
||||
svgroot.append(g);
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 0);
|
||||
g.remove();
|
||||
});
|
||||
})
|
||||
g.append(elem)
|
||||
svgroot.append(g)
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 })
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 0)
|
||||
g.remove()
|
||||
})
|
||||
|
||||
it('Test getBBoxWithTransform and a rotation transform', function () {
|
||||
const { getBBoxWithTransform } = utilities;
|
||||
const { getBBoxWithTransform } = utilities
|
||||
|
||||
let elem = mockCreateSVGElement({
|
||||
element: 'path',
|
||||
attr: { id: 'path', d: 'M10,10 L20,20', transform: 'rotate(45 10,10)' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
let bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.close(bbox.x, 10, EPSILON);
|
||||
assert.close(bbox.y, 10, EPSILON);
|
||||
assert.close(bbox.width, 0, EPSILON);
|
||||
assert.close(bbox.height, Math.sqrt(100 + 100), EPSILON);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
let bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.close(bbox.x, 10, EPSILON)
|
||||
assert.close(bbox.y, 10, EPSILON)
|
||||
assert.close(bbox.width, 0, EPSILON)
|
||||
assert.close(bbox.height, Math.sqrt(100 + 100), EPSILON)
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect', x: '10', y: '10', width: '10', height: '20', transform: 'rotate(90 15,20)' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.close(bbox.x, 5, EPSILON);
|
||||
assert.close(bbox.y, 15, EPSILON);
|
||||
assert.close(bbox.width, 20, EPSILON);
|
||||
assert.close(bbox.height, 10, EPSILON);
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 1);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.close(bbox.x, 5, EPSILON)
|
||||
assert.close(bbox.y, 15, EPSILON)
|
||||
assert.close(bbox.width, 20, EPSILON)
|
||||
assert.close(bbox.height, 10, EPSILON)
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 1)
|
||||
elem.remove()
|
||||
|
||||
const rect = { x: 10, y: 10, width: 10, height: 20 };
|
||||
const angle = 45;
|
||||
const origin = { x: 15, y: 20 };
|
||||
const rect = { x: 10, y: 10, width: 10, height: 20 }
|
||||
const angle = 45
|
||||
const origin = { x: 15, y: 20 }
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect2', x: rect.x, y: rect.y, width: rect.width, height: rect.height, transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ')' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
mockaddSVGElemensFromJsonCallCount = 0;
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
const r2 = rotateRect(rect, angle, origin);
|
||||
assert.close(bbox.x, r2.x, EPSILON, 'rect2 x is ' + r2.x);
|
||||
assert.close(bbox.y, r2.y, EPSILON, 'rect2 y is ' + r2.y);
|
||||
assert.close(bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width);
|
||||
assert.close(bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height);
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 0);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
mockaddSVGElemensFromJsonCallCount = 0
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
const r2 = rotateRect(rect, angle, origin)
|
||||
assert.close(bbox.x, r2.x, EPSILON, 'rect2 x is ' + r2.x)
|
||||
assert.close(bbox.y, r2.y, EPSILON, 'rect2 y is ' + r2.y)
|
||||
assert.close(bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width)
|
||||
assert.close(bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height)
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 0)
|
||||
elem.remove()
|
||||
|
||||
// Same as previous but wrapped with g and the transform is with the g.
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect3', x: rect.x, y: rect.y, width: rect.width, height: rect.height }
|
||||
});
|
||||
})
|
||||
const g = mockCreateSVGElement({
|
||||
element: 'g',
|
||||
attr: { transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ')' }
|
||||
});
|
||||
g.append(elem);
|
||||
svgroot.append(g);
|
||||
mockaddSVGElemensFromJsonCallCount = 0;
|
||||
bbox = getBBoxWithTransform(g, mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.close(bbox.x, r2.x, EPSILON, 'rect2 x is ' + r2.x);
|
||||
assert.close(bbox.y, r2.y, EPSILON, 'rect2 y is ' + r2.y);
|
||||
assert.close(bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width);
|
||||
assert.close(bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height);
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 0);
|
||||
g.remove();
|
||||
})
|
||||
g.append(elem)
|
||||
svgroot.append(g)
|
||||
mockaddSVGElemensFromJsonCallCount = 0
|
||||
bbox = getBBoxWithTransform(g, mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.close(bbox.x, r2.x, EPSILON, 'rect2 x is ' + r2.x)
|
||||
assert.close(bbox.y, r2.y, EPSILON, 'rect2 y is ' + r2.y)
|
||||
assert.close(bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width)
|
||||
assert.close(bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height)
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 0)
|
||||
g.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'ellipse',
|
||||
attr: { id: 'ellipse1', cx: '100', cy: '100', rx: '50', ry: '50', transform: 'rotate(45 100,100)' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
mockaddSVGElemensFromJsonCallCount = 0;
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
})
|
||||
svgroot.append(elem)
|
||||
mockaddSVGElemensFromJsonCallCount = 0
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
/** @todo: Review these test the BBox algorithm is using the bezier control points to calculate the bounding box. Should be 50, 50, 100, 100. */
|
||||
// assert.ok(bbox.x > 45 && bbox.x <= 50);
|
||||
assert.ok(bbox.y > 45 && bbox.y <= 50);
|
||||
assert.ok(bbox.y > 45 && bbox.y <= 50)
|
||||
// assert.ok(bbox.width >= 100 && bbox.width < 110);
|
||||
// assert.ok(bbox.height >= 100 && bbox.height < 110);
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 1);
|
||||
elem.remove();
|
||||
});
|
||||
assert.equal(mockaddSVGElemensFromJsonCallCount, 1)
|
||||
elem.remove()
|
||||
})
|
||||
|
||||
it('Test getBBoxWithTransform with rotation and matrix transforms', function () {
|
||||
const { getBBoxWithTransform } = utilities;
|
||||
const { getBBoxWithTransform } = utilities
|
||||
|
||||
let tx = 10; // tx right
|
||||
let ty = 10; // tx down
|
||||
let txInRotatedSpace = Math.sqrt(tx * tx + ty * ty); // translate in rotated 45 space.
|
||||
let tyInRotatedSpace = 0;
|
||||
let matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')';
|
||||
let tx = 10 // tx right
|
||||
let ty = 10 // tx down
|
||||
let txInRotatedSpace = Math.sqrt(tx * tx + ty * ty) // translate in rotated 45 space.
|
||||
let tyInRotatedSpace = 0
|
||||
let matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')'
|
||||
let elem = mockCreateSVGElement({
|
||||
element: 'path',
|
||||
attr: { id: 'path', d: 'M10,10 L20,20', transform: 'rotate(45 10,10) ' + matrix }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
let bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.close(bbox.x, 10 + tx, EPSILON);
|
||||
assert.close(bbox.y, 10 + ty, EPSILON);
|
||||
assert.close(bbox.width, 0, EPSILON);
|
||||
assert.close(bbox.height, Math.sqrt(100 + 100), EPSILON);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
let bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.close(bbox.x, 10 + tx, EPSILON)
|
||||
assert.close(bbox.y, 10 + ty, EPSILON)
|
||||
assert.close(bbox.width, 0, EPSILON)
|
||||
assert.close(bbox.height, Math.sqrt(100 + 100), EPSILON)
|
||||
elem.remove()
|
||||
|
||||
txInRotatedSpace = tx; // translate in rotated 90 space.
|
||||
tyInRotatedSpace = -ty;
|
||||
matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')';
|
||||
txInRotatedSpace = tx // translate in rotated 90 space.
|
||||
tyInRotatedSpace = -ty
|
||||
matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')'
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect', x: '10', y: '10', width: '10', height: '20', transform: 'rotate(90 15,20) ' + matrix }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.close(bbox.x, 5 + tx, EPSILON);
|
||||
assert.close(bbox.y, 15 + ty, EPSILON);
|
||||
assert.close(bbox.width, 20, EPSILON);
|
||||
assert.close(bbox.height, 10, EPSILON);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.close(bbox.x, 5 + tx, EPSILON)
|
||||
assert.close(bbox.y, 15 + ty, EPSILON)
|
||||
assert.close(bbox.width, 20, EPSILON)
|
||||
assert.close(bbox.height, 10, EPSILON)
|
||||
elem.remove()
|
||||
|
||||
const rect = { x: 10, y: 10, width: 10, height: 20 };
|
||||
const angle = 45;
|
||||
const origin = { x: 15, y: 20 };
|
||||
tx = 10; // tx right
|
||||
ty = 10; // tx down
|
||||
txInRotatedSpace = Math.sqrt(tx * tx + ty * ty); // translate in rotated 45 space.
|
||||
tyInRotatedSpace = 0;
|
||||
matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')';
|
||||
const rect = { x: 10, y: 10, width: 10, height: 20 }
|
||||
const angle = 45
|
||||
const origin = { x: 15, y: 20 }
|
||||
tx = 10 // tx right
|
||||
ty = 10 // tx down
|
||||
txInRotatedSpace = Math.sqrt(tx * tx + ty * ty) // translate in rotated 45 space.
|
||||
tyInRotatedSpace = 0
|
||||
matrix = 'matrix(1,0,0,1,' + txInRotatedSpace + ',' + tyInRotatedSpace + ')'
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect2', x: rect.x, y: rect.y, width: rect.width, height: rect.height, transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ') ' + matrix }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
const r2 = rotateRect(rect, angle, origin);
|
||||
assert.close(bbox.x, r2.x + tx, EPSILON, 'rect2 x is ' + r2.x);
|
||||
assert.close(bbox.y, r2.y + ty, EPSILON, 'rect2 y is ' + r2.y);
|
||||
assert.close(bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width);
|
||||
assert.close(bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
const r2 = rotateRect(rect, angle, origin)
|
||||
assert.close(bbox.x, r2.x + tx, EPSILON, 'rect2 x is ' + r2.x)
|
||||
assert.close(bbox.y, r2.y + ty, EPSILON, 'rect2 y is ' + r2.y)
|
||||
assert.close(bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width)
|
||||
assert.close(bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height)
|
||||
elem.remove()
|
||||
|
||||
// Same as previous but wrapped with g and the transform is with the g.
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect3', x: rect.x, y: rect.y, width: rect.width, height: rect.height }
|
||||
});
|
||||
})
|
||||
const g = mockCreateSVGElement({
|
||||
element: 'g',
|
||||
attr: { transform: 'rotate(' + angle + ' ' + origin.x + ',' + origin.y + ') ' + matrix }
|
||||
});
|
||||
g.append(elem);
|
||||
svgroot.append(g);
|
||||
bbox = getBBoxWithTransform(g, mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.close(bbox.x, r2.x + tx, EPSILON, 'rect2 x is ' + r2.x);
|
||||
assert.close(bbox.y, r2.y + ty, EPSILON, 'rect2 y is ' + r2.y);
|
||||
assert.close(bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width);
|
||||
assert.close(bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height);
|
||||
g.remove();
|
||||
})
|
||||
g.append(elem)
|
||||
svgroot.append(g)
|
||||
bbox = getBBoxWithTransform(g, mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.close(bbox.x, r2.x + tx, EPSILON, 'rect2 x is ' + r2.x)
|
||||
assert.close(bbox.y, r2.y + ty, EPSILON, 'rect2 y is ' + r2.y)
|
||||
assert.close(bbox.width, r2.width, EPSILON, 'rect2 width is' + r2.width)
|
||||
assert.close(bbox.height, r2.height, EPSILON, 'rect2 height is ' + r2.height)
|
||||
g.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'ellipse',
|
||||
attr: { id: 'ellipse1', cx: '100', cy: '100', rx: '50', ry: '50', transform: 'rotate(45 100,100) ' + matrix }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
/** @todo: the BBox algorithm is using the bezier control points to calculate the bounding box. Should be 50, 50, 100, 100. */
|
||||
// assert.ok(bbox.x > 45 + tx && bbox.x <= 50 + tx);
|
||||
assert.ok(bbox.y > 45 + ty && bbox.y <= 50 + ty);
|
||||
assert.ok(bbox.y > 45 + ty && bbox.y <= 50 + ty)
|
||||
// assert.ok(bbox.width >= 100 && bbox.width < 110);
|
||||
// assert.ok(bbox.height >= 100 && bbox.height < 110);
|
||||
elem.remove();
|
||||
});
|
||||
elem.remove()
|
||||
})
|
||||
|
||||
it('Test getStrokedBBox with stroke-width 10', function () {
|
||||
const { getStrokedBBox } = utilities;
|
||||
const { getStrokedBBox } = utilities
|
||||
|
||||
const strokeWidth = 10;
|
||||
const strokeWidth = 10
|
||||
let elem = mockCreateSVGElement({
|
||||
element: 'path',
|
||||
attr: { id: 'path', d: 'M0,1 L2,3', 'stroke-width': strokeWidth }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
let bbox = getStrokedBBox([ elem ], mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 2 + strokeWidth, height: 2 + strokeWidth });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
let bbox = getStrokedBBox([elem], mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 2 + strokeWidth, height: 2 + strokeWidth })
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10', 'stroke-width': strokeWidth }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getStrokedBBox([ elem ], mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 10 + strokeWidth });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 10 + strokeWidth })
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'line',
|
||||
attr: { id: 'line', x1: '0', y1: '1', x2: '5', y2: '6', 'stroke-width': strokeWidth }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getStrokedBBox([ elem ], mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 5 + strokeWidth });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 5 + strokeWidth })
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10', 'stroke-width': strokeWidth }
|
||||
});
|
||||
})
|
||||
const g = mockCreateSVGElement({
|
||||
element: 'g',
|
||||
attr: {}
|
||||
});
|
||||
g.append(elem);
|
||||
svgroot.append(g);
|
||||
bbox = getStrokedBBox([ elem ], mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 10 + strokeWidth });
|
||||
g.remove();
|
||||
});
|
||||
})
|
||||
g.append(elem)
|
||||
svgroot.append(g)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0 - strokeWidth / 2, y: 1 - strokeWidth / 2, width: 5 + strokeWidth, height: 10 + strokeWidth })
|
||||
g.remove()
|
||||
})
|
||||
|
||||
it("Test getStrokedBBox with stroke-width 'none'", function () {
|
||||
const { getStrokedBBox } = utilities;
|
||||
const { getStrokedBBox } = utilities
|
||||
|
||||
let elem = mockCreateSVGElement({
|
||||
element: 'path',
|
||||
attr: { id: 'path', d: 'M0,1 L2,3', 'stroke-width': 'none' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
let bbox = getStrokedBBox([ elem ], mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 2, height: 2 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
let bbox = getStrokedBBox([elem], mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 2, height: 2 })
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10', 'stroke-width': 'none' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getStrokedBBox([ elem ], mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 })
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'line',
|
||||
attr: { id: 'line', x1: '0', y1: '1', x2: '5', y2: '6', 'stroke-width': 'none' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getStrokedBBox([ elem ], mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 })
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10', 'stroke-width': 'none' }
|
||||
});
|
||||
})
|
||||
const g = mockCreateSVGElement({
|
||||
element: 'g',
|
||||
attr: {}
|
||||
});
|
||||
g.append(elem);
|
||||
svgroot.append(g);
|
||||
bbox = getStrokedBBox([ elem ], mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
|
||||
g.remove();
|
||||
});
|
||||
})
|
||||
g.append(elem)
|
||||
svgroot.append(g)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 })
|
||||
g.remove()
|
||||
})
|
||||
|
||||
it('Test getStrokedBBox with no stroke-width attribute', function () {
|
||||
const { getStrokedBBox } = utilities;
|
||||
const { getStrokedBBox } = utilities
|
||||
|
||||
let elem = mockCreateSVGElement({
|
||||
element: 'path',
|
||||
attr: { id: 'path', d: 'M0,1 L2,3' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
let bbox = getStrokedBBox([ elem ], mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 2, height: 2 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
let bbox = getStrokedBBox([elem], mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 2, height: 2 })
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getStrokedBBox([ elem ], mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 })
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'line',
|
||||
attr: { id: 'line', x1: '0', y1: '1', x2: '5', y2: '6' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getStrokedBBox([ elem ], mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 })
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
|
||||
});
|
||||
})
|
||||
const g = mockCreateSVGElement({
|
||||
element: 'g',
|
||||
attr: {}
|
||||
});
|
||||
g.append(elem);
|
||||
svgroot.append(g);
|
||||
bbox = getStrokedBBox([ elem ], mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
|
||||
g.remove();
|
||||
});
|
||||
})
|
||||
g.append(elem)
|
||||
svgroot.append(g)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 })
|
||||
g.remove()
|
||||
})
|
||||
|
||||
/**
|
||||
* Returns radians for degrees.
|
||||
|
@ -465,7 +466,7 @@ describe('utilities bbox', function () {
|
|||
* @returns {Float}
|
||||
*/
|
||||
function radians (degrees) {
|
||||
return degrees * Math.PI / 180;
|
||||
return degrees * Math.PI / 180
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -477,15 +478,15 @@ describe('utilities bbox', function () {
|
|||
*/
|
||||
function rotatePoint (point, angle, origin) {
|
||||
if (!origin) {
|
||||
origin = { x: 0, y: 0 };
|
||||
origin = { x: 0, y: 0 }
|
||||
}
|
||||
const x = point.x - origin.x;
|
||||
const y = point.y - origin.y;
|
||||
const theta = radians(angle);
|
||||
const x = point.x - origin.x
|
||||
const y = point.y - origin.y
|
||||
const theta = radians(angle)
|
||||
return {
|
||||
x: x * Math.cos(theta) + y * Math.sin(theta) + origin.x,
|
||||
y: x * Math.sin(theta) + y * Math.cos(theta) + origin.y
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
|
@ -495,21 +496,21 @@ describe('utilities bbox', function () {
|
|||
* @returns {module:utilities.BBoxObject}
|
||||
*/
|
||||
function rotateRect (rect, angle, origin) {
|
||||
const tl = rotatePoint({ x: rect.x, y: rect.y }, angle, origin);
|
||||
const tr = rotatePoint({ x: rect.x + rect.width, y: rect.y }, angle, origin);
|
||||
const br = rotatePoint({ x: rect.x + rect.width, y: rect.y + rect.height }, angle, origin);
|
||||
const bl = rotatePoint({ x: rect.x, y: rect.y + rect.height }, angle, origin);
|
||||
const tl = rotatePoint({ x: rect.x, y: rect.y }, angle, origin)
|
||||
const tr = rotatePoint({ x: rect.x + rect.width, y: rect.y }, angle, origin)
|
||||
const br = rotatePoint({ x: rect.x + rect.width, y: rect.y + rect.height }, angle, origin)
|
||||
const bl = rotatePoint({ x: rect.x, y: rect.y + rect.height }, angle, origin)
|
||||
|
||||
const minx = Math.min(tl.x, tr.x, bl.x, br.x);
|
||||
const maxx = Math.max(tl.x, tr.x, bl.x, br.x);
|
||||
const miny = Math.min(tl.y, tr.y, bl.y, br.y);
|
||||
const maxy = Math.max(tl.y, tr.y, bl.y, br.y);
|
||||
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 miny = Math.min(tl.y, tr.y, bl.y, br.y)
|
||||
const maxy = Math.max(tl.y, tr.y, bl.y, br.y)
|
||||
|
||||
return {
|
||||
x: minx,
|
||||
y: miny,
|
||||
width: (maxx - minx),
|
||||
height: (maxy - miny)
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/* eslint-disable max-len, no-console */
|
||||
import 'pathseg';
|
||||
import 'pathseg'
|
||||
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js';
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
|
||||
import * as math from '../../../instrumented/svgcanvas/math.js';
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js'
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js'
|
||||
import * as math from '../../../instrumented/svgcanvas/math.js'
|
||||
|
||||
describe('utilities performance', function () {
|
||||
let currentLayer; let groupWithMatrixTransform; let textWithMatrixTransform;
|
||||
let currentLayer; let groupWithMatrixTransform; let textWithMatrixTransform
|
||||
beforeEach(() => {
|
||||
document.body.textContent = '';
|
||||
const style = document.createElement('style');
|
||||
style.id = 'styleoverrides';
|
||||
style.media = 'screen';
|
||||
document.body.textContent = ''
|
||||
const style = document.createElement('style')
|
||||
style.id = 'styleoverrides'
|
||||
style.media = 'screen'
|
||||
style.textContent = `
|
||||
#svgcanvas svg * {
|
||||
cursor: move;
|
||||
|
@ -19,9 +19,9 @@ describe('utilities performance', function () {
|
|||
}
|
||||
#svgcanvas svg {
|
||||
cursor: default
|
||||
}`;
|
||||
}`
|
||||
|
||||
document.head.append(style);
|
||||
document.head.append(style)
|
||||
|
||||
const editor = new DOMParser().parseFromString(`<div id="svg_editor">
|
||||
<div id="workarea" style="cursor: auto; overflow: scroll; line-height: 12px; right: 100px;">
|
||||
|
@ -64,14 +64,14 @@ describe('utilities performance', function () {
|
|||
</svg>
|
||||
</svg>
|
||||
</div>
|
||||
</div></div>`, 'application/xml');
|
||||
const newNode = document.body.ownerDocument.importNode(editor.documentElement, true);
|
||||
document.body.append(newNode);
|
||||
</div></div>`, 'application/xml')
|
||||
const newNode = document.body.ownerDocument.importNode(editor.documentElement, true)
|
||||
document.body.append(newNode)
|
||||
|
||||
currentLayer = document.getElementById('layer1');
|
||||
groupWithMatrixTransform = document.getElementById('svg_group_with_matrix_transform');
|
||||
textWithMatrixTransform = document.getElementById('svg_text_with_matrix_transform');
|
||||
});
|
||||
currentLayer = document.getElementById('layer1')
|
||||
groupWithMatrixTransform = document.getElementById('svg_group_with_matrix_transform')
|
||||
textWithMatrixTransform = document.getElementById('svg_text_with_matrix_transform')
|
||||
})
|
||||
|
||||
/**
|
||||
* Create an SVG element for a mock.
|
||||
|
@ -79,11 +79,11 @@ describe('utilities performance', function () {
|
|||
* @returns {SVGElement}
|
||||
*/
|
||||
function mockCreateSVGElement (jsonMap) {
|
||||
const elem = document.createElementNS(NS.SVG, jsonMap.element);
|
||||
Object.entries(jsonMap.attr).forEach(([ attr, value ]) => {
|
||||
elem.setAttribute(attr, value);
|
||||
});
|
||||
return elem;
|
||||
const elem = document.createElementNS(NS.SVG, jsonMap.element)
|
||||
Object.entries(jsonMap.attr).forEach(([attr, value]) => {
|
||||
elem.setAttribute(attr, value)
|
||||
})
|
||||
return elem
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,9 +92,9 @@ describe('utilities performance', function () {
|
|||
* @returns {SVGElement}
|
||||
*/
|
||||
function mockaddSVGElemensFromJson (json) {
|
||||
const elem = mockCreateSVGElement(json);
|
||||
currentLayer.append(elem);
|
||||
return elem;
|
||||
const elem = mockCreateSVGElement(json)
|
||||
currentLayer.append(elem)
|
||||
return elem
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,49 +104,49 @@ describe('utilities performance', function () {
|
|||
* @returns {void}
|
||||
*/
|
||||
function fillDocumentByCloningElement (elem, count) {
|
||||
const elemId = elem.getAttribute('id') + '-';
|
||||
const elemId = elem.getAttribute('id') + '-'
|
||||
for (let index = 0; index < count; index++) {
|
||||
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.
|
||||
clone.setAttribute('id', elemId + index);
|
||||
const { parentNode } = elem;
|
||||
parentNode.append(clone);
|
||||
clone.setAttribute('id', elemId + index)
|
||||
const { parentNode } = elem
|
||||
parentNode.append(clone)
|
||||
}
|
||||
}
|
||||
|
||||
const mockPathActions = {
|
||||
resetOrientation (path) {
|
||||
if (utilities.isNullish(path) || path.nodeName !== 'path') { return false; }
|
||||
const tlist = path.transform.baseVal;
|
||||
const m = math.transformListToTransform(tlist).matrix;
|
||||
tlist.clear();
|
||||
path.removeAttribute('transform');
|
||||
const segList = path.pathSegList;
|
||||
if (utilities.isNullish(path) || path.nodeName !== 'path') { return false }
|
||||
const tlist = path.transform.baseVal
|
||||
const m = math.transformListToTransform(tlist).matrix
|
||||
tlist.clear()
|
||||
path.removeAttribute('transform')
|
||||
const segList = path.pathSegList
|
||||
|
||||
const len = segList.numberOfItems;
|
||||
const len = segList.numberOfItems
|
||||
// let lastX, lastY;
|
||||
|
||||
for (let i = 0; i < len; ++i) {
|
||||
const seg = segList.getItem(i);
|
||||
const type = seg.pathSegType;
|
||||
const seg = segList.getItem(i)
|
||||
const type = seg.pathSegType
|
||||
if (type === 1) {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
const pts = [];
|
||||
[ '', 1, 2 ].forEach(function (n) {
|
||||
const x = seg['x' + n];
|
||||
const y = seg['y' + n];
|
||||
['', 1, 2].forEach(function (n) {
|
||||
const x = seg['x' + n]
|
||||
const y = seg['y' + n]
|
||||
if (x !== undefined && y !== undefined) {
|
||||
const pt = math.transformPoint(x, y, m);
|
||||
pts.splice(pts.length, 0, pt.x, pt.y);
|
||||
const pt = math.transformPoint(x, y, m)
|
||||
pts.splice(pts.length, 0, pt.x, pt.y)
|
||||
}
|
||||
});
|
||||
})
|
||||
// path.replacePathSeg(type, i, pts, path);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////
|
||||
// Performance times with various browsers on Macbook 2011 8MB RAM OS X El Capitan 10.11.4
|
||||
|
@ -180,57 +180,57 @@ describe('utilities performance', function () {
|
|||
// Pass2 svgCanvas.getStrokedBBox total ms 17, ave ms 0.2, min/max 0 23
|
||||
|
||||
it('Test svgCanvas.getStrokedBBox() performance with matrix transforms', function () {
|
||||
const { getStrokedBBox } = utilities;
|
||||
const { children } = currentLayer;
|
||||
const { getStrokedBBox } = utilities
|
||||
const { children } = currentLayer
|
||||
|
||||
let lastTime; let now;
|
||||
let min = Number.MAX_VALUE;
|
||||
let max = 0;
|
||||
let total = 0;
|
||||
let lastTime; let now
|
||||
let min = Number.MAX_VALUE
|
||||
let max = 0
|
||||
let total = 0
|
||||
|
||||
fillDocumentByCloningElement(groupWithMatrixTransform, 50);
|
||||
fillDocumentByCloningElement(textWithMatrixTransform, 50);
|
||||
fillDocumentByCloningElement(groupWithMatrixTransform, 50)
|
||||
fillDocumentByCloningElement(textWithMatrixTransform, 50)
|
||||
|
||||
// The first pass through all elements is slower.
|
||||
const count = children.length;
|
||||
const start = lastTime = now = Date.now();
|
||||
const count = children.length
|
||||
const start = lastTime = now = Date.now()
|
||||
// Skip the first child which is the title.
|
||||
for (let index = 1; index < count; index++) {
|
||||
const child = children[index];
|
||||
/* const obj = */ getStrokedBBox([ child ], mockaddSVGElemensFromJson, mockPathActions);
|
||||
now = Date.now(); const delta = now - lastTime; lastTime = now;
|
||||
total += delta;
|
||||
min = Math.min(min, delta);
|
||||
max = Math.max(max, delta);
|
||||
const child = children[index]
|
||||
/* const obj = */ getStrokedBBox([child], mockaddSVGElemensFromJson, mockPathActions)
|
||||
now = Date.now(); const delta = now - lastTime; lastTime = now
|
||||
total += delta
|
||||
min = Math.min(min, delta)
|
||||
max = Math.max(max, delta)
|
||||
}
|
||||
total = lastTime - start;
|
||||
const ave = total / count;
|
||||
assert.isBelow(ave, 20, 'svgedit.utilities.getStrokedBBox average execution time is less than 20 ms');
|
||||
console.log('Pass1 svgCanvas.getStrokedBBox total ms ' + total + ', ave ms ' + ave.toFixed(1) + ',\t min/max ' + min + ' ' + max);
|
||||
total = lastTime - start
|
||||
const ave = total / count
|
||||
assert.isBelow(ave, 20, 'svgedit.utilities.getStrokedBBox average execution time is less than 20 ms')
|
||||
console.log('Pass1 svgCanvas.getStrokedBBox total ms ' + total + ', ave ms ' + ave.toFixed(1) + ',\t min/max ' + min + ' ' + max)
|
||||
|
||||
return new Promise((resolve) => {
|
||||
// The second pass is two to ten times faster.
|
||||
setTimeout(function () {
|
||||
const ct = children.length;
|
||||
const ct = children.length
|
||||
|
||||
const strt = lastTime = now = Date.now();
|
||||
const strt = lastTime = now = Date.now()
|
||||
// Skip the first child which is the title.
|
||||
for (let index = 1; index < ct; index++) {
|
||||
const child = children[index];
|
||||
/* const obj = */ getStrokedBBox([ child ], mockaddSVGElemensFromJson, mockPathActions);
|
||||
now = Date.now(); const delta = now - lastTime; lastTime = now;
|
||||
total += delta;
|
||||
min = Math.min(min, delta);
|
||||
max = Math.max(max, delta);
|
||||
const child = children[index]
|
||||
/* const obj = */ getStrokedBBox([child], mockaddSVGElemensFromJson, mockPathActions)
|
||||
now = Date.now(); const delta = now - lastTime; lastTime = now
|
||||
total += delta
|
||||
min = Math.min(min, delta)
|
||||
max = Math.max(max, delta)
|
||||
}
|
||||
|
||||
total = lastTime - strt;
|
||||
const avg = total / ct;
|
||||
assert.isBelow(avg, 2, 'svgedit.utilities.getStrokedBBox average execution time is less than 1 ms');
|
||||
console.log('Pass2 svgCanvas.getStrokedBBox total ms ' + total + ', ave ms ' + avg.toFixed(1) + ',\t min/max ' + min + ' ' + max);
|
||||
total = lastTime - strt
|
||||
const avg = total / ct
|
||||
assert.isBelow(avg, 2, 'svgedit.utilities.getStrokedBBox average execution time is less than 1 ms')
|
||||
console.log('Pass2 svgCanvas.getStrokedBBox total ms ' + total + ', ave ms ' + avg.toFixed(1) + ',\t min/max ' + min + ' ' + max)
|
||||
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js';
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js'
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js'
|
||||
|
||||
describe('utilities', function () {
|
||||
/**
|
||||
|
@ -8,11 +8,11 @@ describe('utilities', function () {
|
|||
* @returns {SVGElement}
|
||||
*/
|
||||
function mockCreateSVGElement (jsonMap) {
|
||||
const elem = document.createElementNS(NS.SVG, jsonMap.element);
|
||||
Object.entries(jsonMap.attr).forEach(([ attr, value ]) => {
|
||||
elem.setAttribute(attr, value);
|
||||
});
|
||||
return elem;
|
||||
const elem = document.createElementNS(NS.SVG, jsonMap.element)
|
||||
Object.entries(jsonMap.attr).forEach(([attr, value]) => {
|
||||
elem.setAttribute(attr, value)
|
||||
})
|
||||
return elem
|
||||
}
|
||||
/**
|
||||
* Adds SVG Element per parameters and appends to root.
|
||||
|
@ -20,225 +20,225 @@ describe('utilities', function () {
|
|||
* @returns {SVGElement}
|
||||
*/
|
||||
function mockaddSVGElemensFromJson (json) {
|
||||
const elem = mockCreateSVGElement(json);
|
||||
svgroot.append(elem);
|
||||
return elem;
|
||||
const elem = mockCreateSVGElement(json)
|
||||
svgroot.append(elem)
|
||||
return elem
|
||||
}
|
||||
const mockPathActions = { resetOrientation () { /* empty fn */ } };
|
||||
let mockHistorySubCommands = [];
|
||||
const mockPathActions = { resetOrientation () { /* empty fn */ } }
|
||||
let mockHistorySubCommands = []
|
||||
const mockHistory = {
|
||||
BatchCommand: class {
|
||||
addSubCommand (cmd) {
|
||||
mockHistorySubCommands.push(cmd);
|
||||
mockHistorySubCommands.push(cmd)
|
||||
}
|
||||
},
|
||||
RemoveElementCommand: class {
|
||||
// Longhand needed since used as a constructor
|
||||
constructor (elem, nextSibling, parent) {
|
||||
this.elem = elem;
|
||||
this.nextSibling = nextSibling;
|
||||
this.parent = parent;
|
||||
this.elem = elem
|
||||
this.nextSibling = nextSibling
|
||||
this.parent = parent
|
||||
}
|
||||
},
|
||||
InsertElementCommand: class {
|
||||
constructor (path) { // Longhand needed since used as a constructor
|
||||
this.path = path;
|
||||
this.path = path
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
const mockCount = {
|
||||
clearSelection: 0,
|
||||
addToSelection: 0,
|
||||
addCommandToHistory: 0
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments clear seleciton count for mock test.
|
||||
* @returns {void}
|
||||
*/
|
||||
function mockClearSelection () {
|
||||
mockCount.clearSelection++;
|
||||
mockCount.clearSelection++
|
||||
}
|
||||
/**
|
||||
* Increments add selection count for mock test.
|
||||
* @returns {void}
|
||||
*/
|
||||
function mockAddToSelection () {
|
||||
mockCount.addToSelection++;
|
||||
mockCount.addToSelection++
|
||||
}
|
||||
/**
|
||||
* Increments add command to history count for mock test.
|
||||
* @returns {void}
|
||||
*/
|
||||
function mockAddCommandToHistory () {
|
||||
mockCount.addCommandToHistory++;
|
||||
mockCount.addCommandToHistory++
|
||||
}
|
||||
|
||||
let svg; let svgroot;
|
||||
let svg; let svgroot
|
||||
beforeEach(() => {
|
||||
document.body.textContent = '';
|
||||
document.body.textContent = ''
|
||||
|
||||
mockHistorySubCommands = [];
|
||||
mockCount.clearSelection = 0;
|
||||
mockCount.addToSelection = 0;
|
||||
mockCount.addCommandToHistory = 0;
|
||||
mockHistorySubCommands = []
|
||||
mockCount.clearSelection = 0
|
||||
mockCount.addToSelection = 0
|
||||
mockCount.addCommandToHistory = 0
|
||||
|
||||
const sandbox = document.createElement('div');
|
||||
svg = document.createElementNS(NS.SVG, 'svg');
|
||||
const sandbox = document.createElement('div')
|
||||
svg = document.createElementNS(NS.SVG, 'svg')
|
||||
svgroot = mockCreateSVGElement({
|
||||
element: 'svg',
|
||||
attr: { id: 'svgroot' }
|
||||
});
|
||||
sandbox.append(svgroot);
|
||||
document.body.append(sandbox);
|
||||
});
|
||||
})
|
||||
sandbox.append(svgroot)
|
||||
document.body.append(sandbox)
|
||||
})
|
||||
|
||||
it('Test svgedit.utilities package', function () {
|
||||
assert.ok(utilities);
|
||||
assert.ok(utilities.toXml);
|
||||
assert.equal(typeof utilities.toXml, typeof function () { /* empty fn */ });
|
||||
});
|
||||
assert.ok(utilities)
|
||||
assert.ok(utilities.toXml)
|
||||
assert.equal(typeof utilities.toXml, typeof function () { /* empty fn */ })
|
||||
})
|
||||
|
||||
it('Test svgedit.utilities.toXml() function', function () {
|
||||
const { toXml } = utilities;
|
||||
const { toXml } = utilities
|
||||
|
||||
assert.equal(toXml('a'), 'a');
|
||||
assert.equal(toXml('ABC_'), 'ABC_');
|
||||
assert.equal(toXml('PB&J'), 'PB&J');
|
||||
assert.equal(toXml('2 < 5'), '2 < 5');
|
||||
assert.equal(toXml('5 > 2'), '5 > 2');
|
||||
assert.equal(toXml('\'<&>"'), ''<&>"');
|
||||
});
|
||||
assert.equal(toXml('a'), 'a')
|
||||
assert.equal(toXml('ABC_'), 'ABC_')
|
||||
assert.equal(toXml('PB&J'), 'PB&J')
|
||||
assert.equal(toXml('2 < 5'), '2 < 5')
|
||||
assert.equal(toXml('5 > 2'), '5 > 2')
|
||||
assert.equal(toXml('\'<&>"'), ''<&>"')
|
||||
})
|
||||
|
||||
it('Test svgedit.utilities.encode64() function', function () {
|
||||
const { encode64 } = utilities;
|
||||
const { encode64 } = utilities
|
||||
|
||||
assert.equal(encode64('abcdef'), 'YWJjZGVm');
|
||||
assert.equal(encode64('12345'), 'MTIzNDU=');
|
||||
assert.equal(encode64(' '), 'IA==');
|
||||
assert.equal(encode64('`~!@#$%^&*()-_=+[{]}\\|;:\'",<.>/?'), 'YH4hQCMkJV4mKigpLV89K1t7XX1cfDs6JyIsPC4+Lz8=');
|
||||
});
|
||||
assert.equal(encode64('abcdef'), 'YWJjZGVm')
|
||||
assert.equal(encode64('12345'), 'MTIzNDU=')
|
||||
assert.equal(encode64(' '), 'IA==')
|
||||
assert.equal(encode64('`~!@#$%^&*()-_=+[{]}\\|;:\'",<.>/?'), 'YH4hQCMkJV4mKigpLV89K1t7XX1cfDs6JyIsPC4+Lz8=')
|
||||
})
|
||||
|
||||
it('Test svgedit.utilities.decode64() function', function () {
|
||||
const { decode64 } = utilities;
|
||||
const { decode64 } = utilities
|
||||
|
||||
assert.equal(decode64('YWJjZGVm'), 'abcdef');
|
||||
assert.equal(decode64('MTIzNDU='), '12345');
|
||||
assert.equal(decode64('IA=='), ' ');
|
||||
assert.equal(decode64('YH4hQCMkJV4mKigpLV89K1t7XX1cfDs6JyIsPC4+Lz8='), '`~!@#$%^&*()-_=+[{]}\\|;:\'",<.>/?');
|
||||
});
|
||||
assert.equal(decode64('YWJjZGVm'), 'abcdef')
|
||||
assert.equal(decode64('MTIzNDU='), '12345')
|
||||
assert.equal(decode64('IA=='), ' ')
|
||||
assert.equal(decode64('YH4hQCMkJV4mKigpLV89K1t7XX1cfDs6JyIsPC4+Lz8='), '`~!@#$%^&*()-_=+[{]}\\|;:\'",<.>/?')
|
||||
})
|
||||
|
||||
it('Test svgedit.utilities.convertToXMLReferences() function', function () {
|
||||
const convert = utilities.convertToXMLReferences;
|
||||
assert.equal(convert('ABC'), 'ABC');
|
||||
const convert = utilities.convertToXMLReferences
|
||||
assert.equal(convert('ABC'), 'ABC')
|
||||
// assert.equal(convert('<27>BC'), 'ÀBC');
|
||||
});
|
||||
})
|
||||
|
||||
it('Test svgedit.utilities.bboxToObj() function', function () {
|
||||
const { bboxToObj } = utilities;
|
||||
const { bboxToObj } = utilities
|
||||
|
||||
const rect = svg.createSVGRect();
|
||||
rect.x = 1;
|
||||
rect.y = 2;
|
||||
rect.width = 3;
|
||||
rect.height = 4;
|
||||
const rect = svg.createSVGRect()
|
||||
rect.x = 1
|
||||
rect.y = 2
|
||||
rect.width = 3
|
||||
rect.height = 4
|
||||
|
||||
const obj = bboxToObj(rect);
|
||||
assert.equal(typeof obj, typeof {});
|
||||
assert.equal(obj.x, 1);
|
||||
assert.equal(obj.y, 2);
|
||||
assert.equal(obj.width, 3);
|
||||
assert.equal(obj.height, 4);
|
||||
});
|
||||
const obj = bboxToObj(rect)
|
||||
assert.equal(typeof obj, typeof {})
|
||||
assert.equal(obj.x, 1)
|
||||
assert.equal(obj.y, 2)
|
||||
assert.equal(obj.width, 3)
|
||||
assert.equal(obj.height, 4)
|
||||
})
|
||||
|
||||
it('Test getUrlFromAttr', function () {
|
||||
assert.equal(utilities.getUrlFromAttr('url(#foo)'), '#foo');
|
||||
assert.equal(utilities.getUrlFromAttr('url(somefile.svg#foo)'), 'somefile.svg#foo');
|
||||
assert.equal(utilities.getUrlFromAttr('url("#foo")'), '#foo');
|
||||
assert.equal(utilities.getUrlFromAttr('url("#foo")'), '#foo');
|
||||
});
|
||||
assert.equal(utilities.getUrlFromAttr('url(#foo)'), '#foo')
|
||||
assert.equal(utilities.getUrlFromAttr('url(somefile.svg#foo)'), 'somefile.svg#foo')
|
||||
assert.equal(utilities.getUrlFromAttr('url("#foo")'), '#foo')
|
||||
assert.equal(utilities.getUrlFromAttr('url("#foo")'), '#foo')
|
||||
})
|
||||
|
||||
it('Test getPathDFromSegments', function () {
|
||||
const { getPathDFromSegments } = utilities;
|
||||
const { getPathDFromSegments } = utilities
|
||||
|
||||
const doc = utilities.text2xml('<svg></svg>');
|
||||
const path = doc.createElementNS(NS.SVG, 'path');
|
||||
path.setAttribute('d', 'm0,0l5,0l0,5l-5,0l0,-5z');
|
||||
const doc = utilities.text2xml('<svg></svg>')
|
||||
const path = doc.createElementNS(NS.SVG, 'path')
|
||||
path.setAttribute('d', 'm0,0l5,0l0,5l-5,0l0,-5z')
|
||||
let d = getPathDFromSegments([
|
||||
[ 'M', [ 1, 2 ] ],
|
||||
[ 'Z', [] ]
|
||||
]);
|
||||
assert.equal(d, 'M1,2 Z');
|
||||
['M', [1, 2]],
|
||||
['Z', []]
|
||||
])
|
||||
assert.equal(d, 'M1,2 Z')
|
||||
|
||||
d = getPathDFromSegments([
|
||||
[ 'M', [ 1, 2 ] ],
|
||||
[ 'M', [ 3, 4 ] ],
|
||||
[ 'Z', [] ]
|
||||
]);
|
||||
assert.equal(d, 'M1,2 M3,4 Z');
|
||||
['M', [1, 2]],
|
||||
['M', [3, 4]],
|
||||
['Z', []]
|
||||
])
|
||||
assert.equal(d, 'M1,2 M3,4 Z')
|
||||
|
||||
d = getPathDFromSegments([
|
||||
[ 'M', [ 1, 2 ] ],
|
||||
[ 'C', [ 3, 4, 5, 6 ] ],
|
||||
[ 'Z', [] ]
|
||||
]);
|
||||
assert.equal(d, 'M1,2 C3,4 5,6 Z');
|
||||
});
|
||||
['M', [1, 2]],
|
||||
['C', [3, 4, 5, 6]],
|
||||
['Z', []]
|
||||
])
|
||||
assert.equal(d, 'M1,2 C3,4 5,6 Z')
|
||||
})
|
||||
|
||||
it('Test getPathDFromElement', function () {
|
||||
const { getPathDFromElement } = utilities;
|
||||
const { getPathDFromElement } = utilities
|
||||
|
||||
let elem = mockCreateSVGElement({
|
||||
element: 'path',
|
||||
attr: { id: 'path', d: 'M0,1 Z' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
assert.equal(getPathDFromElement(elem), 'M0,1 Z');
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
assert.equal(getPathDFromElement(elem), 'M0,1 Z')
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
assert.equal(getPathDFromElement(elem), 'M0,1 L5,1 L5,11 L0,11 L0,1 Z');
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
assert.equal(getPathDFromElement(elem), 'M0,1 L5,1 L5,11 L0,11 L0,1 Z')
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'roundrect', x: '0', y: '1', rx: '2', ry: '3', width: '10', height: '11' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
const closeEnough = /M0,4 C0,2.3\d* 0.9\d*,1 2,1 L8,1 C9.0\d*,1 10,2.3\d* 10,4 L10,9 C10,10.6\d* 9.0\d*,12 8,12 L2,12 C0.9\d*,12 0,10.6\d* 0,9 L0,4 Z/;
|
||||
assert.equal(closeEnough.test(getPathDFromElement(elem)), true);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
const closeEnough = /M0,4 C0,2.3\d* 0.9\d*,1 2,1 L8,1 C9.0\d*,1 10,2.3\d* 10,4 L10,9 C10,10.6\d* 9.0\d*,12 8,12 L2,12 C0.9\d*,12 0,10.6\d* 0,9 L0,4 Z/
|
||||
assert.equal(closeEnough.test(getPathDFromElement(elem)), true)
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'line',
|
||||
attr: { id: 'line', x1: '0', y1: '1', x2: '5', y2: '6' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
assert.equal(getPathDFromElement(elem), 'M0,1L5,6');
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
assert.equal(getPathDFromElement(elem), 'M0,1L5,6')
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'circle',
|
||||
attr: { id: 'circle', cx: '10', cy: '11', rx: '5', ry: '10' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
assert.equal(getPathDFromElement(elem), 'M5,11 C5,5.475138121546961 7.237569060773481,1 10,1 C12.762430939226519,1 15,5.475138121546961 15,11 C15,16.524861878453038 12.762430939226519,21 10,21 C7.237569060773481,21 5,16.524861878453038 5,11 Z');
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
assert.equal(getPathDFromElement(elem), 'M5,11 C5,5.475138121546961 7.237569060773481,1 10,1 C12.762430939226519,1 15,5.475138121546961 15,11 C15,16.524861878453038 12.762430939226519,21 10,21 C7.237569060773481,21 5,16.524861878453038 5,11 Z')
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'polyline',
|
||||
attr: { id: 'polyline', points: '0,1 5,1 5,11 0,11' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
assert.equal(getPathDFromElement(elem), 'M0,1 5,1 5,11 0,11');
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
assert.equal(getPathDFromElement(elem), 'M0,1 5,1 5,11 0,11')
|
||||
elem.remove()
|
||||
|
||||
assert.equal(getPathDFromElement({ tagName: 'something unknown' }), undefined);
|
||||
});
|
||||
assert.equal(getPathDFromElement({ tagName: 'something unknown' }), undefined)
|
||||
})
|
||||
|
||||
it('Test getBBoxOfElementAsPath', function () {
|
||||
/**
|
||||
|
@ -246,88 +246,88 @@ describe('utilities', function () {
|
|||
* @type {module:utilities.getBBoxOfElementAsPath}
|
||||
*/
|
||||
function getBBoxOfElementAsPath (elem, addSVGElemensFromJson, pathActions) {
|
||||
const bbox = utilities.getBBoxOfElementAsPath(elem, addSVGElemensFromJson, pathActions);
|
||||
return utilities.bboxToObj(bbox); // need this for assert.equal() to work.
|
||||
const bbox = utilities.getBBoxOfElementAsPath(elem, addSVGElemensFromJson, pathActions)
|
||||
return utilities.bboxToObj(bbox) // need this for assert.equal() to work.
|
||||
}
|
||||
|
||||
let elem = mockCreateSVGElement({
|
||||
element: 'path',
|
||||
attr: { id: 'path', d: 'M0,1 Z' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
let bbox = getBBoxOfElementAsPath(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 0, height: 0 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
let bbox = getBBoxOfElementAsPath(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 0, height: 0 })
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getBBoxOfElementAsPath(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getBBoxOfElementAsPath(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 })
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'line',
|
||||
attr: { id: 'line', x1: '0', y1: '1', x2: '5', y2: '6' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getBBoxOfElementAsPath(elem, mockaddSVGElemensFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getBBoxOfElementAsPath(elem, mockaddSVGElemensFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 })
|
||||
elem.remove()
|
||||
|
||||
// TODO: test element with transform. Need resetOrientation above to be working or mock it.
|
||||
});
|
||||
})
|
||||
|
||||
it('Test convertToPath rect', function () {
|
||||
const { convertToPath } = utilities;
|
||||
const { convertToPath } = utilities
|
||||
const attrs = {
|
||||
fill: 'red',
|
||||
stroke: 'white',
|
||||
'stroke-width': '1',
|
||||
visibility: 'hidden'
|
||||
};
|
||||
}
|
||||
|
||||
const elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
const path = convertToPath(elem, attrs, mockaddSVGElemensFromJson, mockPathActions, mockClearSelection, mockAddToSelection, mockHistory, mockAddCommandToHistory);
|
||||
assert.equal(path.getAttribute('d'), 'M0,1 L5,1 L5,11 L0,11 L0,1 Z');
|
||||
assert.equal(path.getAttribute('visibilituy'), null);
|
||||
assert.equal(path.id, 'rect');
|
||||
assert.equal(path.parentNode, svgroot);
|
||||
assert.equal(elem.parentNode, null);
|
||||
assert.equal(mockHistorySubCommands.length, 2);
|
||||
assert.equal(mockCount.clearSelection, 1);
|
||||
assert.equal(mockCount.addToSelection, 1);
|
||||
assert.equal(mockCount.addCommandToHistory, 1);
|
||||
path.remove();
|
||||
});
|
||||
})
|
||||
svgroot.append(elem)
|
||||
const path = convertToPath(elem, attrs, mockaddSVGElemensFromJson, mockPathActions, mockClearSelection, mockAddToSelection, mockHistory, mockAddCommandToHistory)
|
||||
assert.equal(path.getAttribute('d'), 'M0,1 L5,1 L5,11 L0,11 L0,1 Z')
|
||||
assert.equal(path.getAttribute('visibilituy'), null)
|
||||
assert.equal(path.id, 'rect')
|
||||
assert.equal(path.parentNode, svgroot)
|
||||
assert.equal(elem.parentNode, null)
|
||||
assert.equal(mockHistorySubCommands.length, 2)
|
||||
assert.equal(mockCount.clearSelection, 1)
|
||||
assert.equal(mockCount.addToSelection, 1)
|
||||
assert.equal(mockCount.addCommandToHistory, 1)
|
||||
path.remove()
|
||||
})
|
||||
|
||||
it('Test convertToPath unknown element', function () {
|
||||
const { convertToPath } = utilities;
|
||||
const { convertToPath } = utilities
|
||||
const attrs = {
|
||||
fill: 'red',
|
||||
stroke: 'white',
|
||||
'stroke-width': '1',
|
||||
visibility: 'hidden'
|
||||
};
|
||||
}
|
||||
|
||||
const elem = {
|
||||
tagName: 'something unknown',
|
||||
id: 'something-unknown',
|
||||
getAttribute () { return ''; },
|
||||
getAttribute () { return '' },
|
||||
parentNode: svgroot
|
||||
};
|
||||
const path = convertToPath(elem, attrs, mockaddSVGElemensFromJson, mockPathActions, mockClearSelection, mockAddToSelection, mockHistory, mockAddCommandToHistory);
|
||||
assert.equal(path, null);
|
||||
assert.equal(elem.parentNode, svgroot);
|
||||
assert.equal(mockHistorySubCommands.length, 0);
|
||||
assert.equal(mockCount.clearSelection, 0);
|
||||
assert.equal(mockCount.addToSelection, 0);
|
||||
assert.equal(mockCount.addCommandToHistory, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
const path = convertToPath(elem, attrs, mockaddSVGElemensFromJson, mockPathActions, mockClearSelection, mockAddToSelection, mockHistory, mockAddCommandToHistory)
|
||||
assert.equal(path, null)
|
||||
assert.equal(elem.parentNode, svgroot)
|
||||
assert.equal(mockHistorySubCommands.length, 0)
|
||||
assert.equal(mockCount.clearSelection, 0)
|
||||
assert.equal(mockCount.addToSelection, 0)
|
||||
assert.equal(mockCount.addCommandToHistory, 0)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
'use strict';
|
||||
'use strict'
|
||||
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
|
@ -11,6 +11,6 @@
|
|||
// ***********************************************************
|
||||
|
||||
require('@babel/register')({
|
||||
plugins: [ '@babel/plugin-transform-modules-commonjs' ]
|
||||
});
|
||||
module.exports = require('./main.js').default;
|
||||
plugins: ['@babel/plugin-transform-modules-commonjs']
|
||||
})
|
||||
module.exports = require('./main.js').default
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
import codeCoverageTask from "@cypress/code-coverage/task.js";
|
||||
import { initPlugin } from "cypress-plugin-snapshots/plugin.js";
|
||||
import codeCoverageTask from '@cypress/code-coverage/task.js'
|
||||
import { initPlugin } from 'cypress-plugin-snapshots/plugin.js'
|
||||
|
||||
export default (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
|
@ -12,35 +12,35 @@ export default (on, config) => {
|
|||
// `config` is the resolved Cypress config
|
||||
|
||||
// https://docs.cypress.io/guides/tooling/code-coverage.html#Install-the-plugin
|
||||
codeCoverageTask(on, config);
|
||||
initPlugin(on, config);
|
||||
on("before:browser:launch", (browser, launchOptions) => {
|
||||
if (browser.name === "chrome" && browser.isHeadless) {
|
||||
codeCoverageTask(on, config)
|
||||
initPlugin(on, config)
|
||||
on('before:browser:launch', (browser, launchOptions) => {
|
||||
if (browser.name === 'chrome' && browser.isHeadless) {
|
||||
// fullPage screenshot size is 1400x1200 on non-retina screens
|
||||
// and 2800x2400 on retina screens
|
||||
launchOptions.args.push("--window-size=1400,1200");
|
||||
launchOptions.args.push('--window-size=1400,1200')
|
||||
|
||||
// force screen to be non-retina (1400x1200 size)
|
||||
launchOptions.args.push("--force-device-scale-factor=1");
|
||||
launchOptions.args.push('--force-device-scale-factor=1')
|
||||
|
||||
// force screen to be retina (2800x2400 size)
|
||||
// launchOptions.args.push('--force-device-scale-factor=2')
|
||||
}
|
||||
|
||||
if (browser.name === "electron" && browser.isHeadless) {
|
||||
if (browser.name === 'electron' && browser.isHeadless) {
|
||||
// fullPage screenshot size is 1400x1200
|
||||
launchOptions.preferences.width = 1400;
|
||||
launchOptions.preferences.height = 1200;
|
||||
launchOptions.preferences.width = 1400
|
||||
launchOptions.preferences.height = 1200
|
||||
}
|
||||
|
||||
if (browser.name === "firefox" && browser.isHeadless) {
|
||||
if (browser.name === 'firefox' && browser.isHeadless) {
|
||||
// menubars take up height on the screen
|
||||
// so fullPage screenshot size is 1400x1126
|
||||
launchOptions.args.push("--width=1400");
|
||||
launchOptions.args.push("--height=1200");
|
||||
launchOptions.args.push('--width=1400')
|
||||
launchOptions.args.push('--height=1200')
|
||||
}
|
||||
|
||||
return launchOptions;
|
||||
});
|
||||
return config;
|
||||
};
|
||||
return launchOptions
|
||||
})
|
||||
return config
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import assertionWrapper from './assertion-wrapper.js';
|
||||
import assertionWrapper from './assertion-wrapper.js'
|
||||
|
||||
const NEAR_ZERO = 5e-6; // 0.000005, Firefox fails at higher levels of precision.
|
||||
const NEAR_ZERO = 5e-6 // 0.000005, Firefox fails at higher levels of precision.
|
||||
|
||||
/**
|
||||
* Checks that the supplied values are equal with a high though not absolute degree of precision.
|
||||
|
@ -10,9 +10,9 @@ const NEAR_ZERO = 5e-6; // 0.000005, Firefox fails at higher levels of precision
|
|||
* @returns {void}
|
||||
*/
|
||||
function almostEquals (actual, expected, message) {
|
||||
message = message || (actual + ' did not equal ' + expected);
|
||||
const result = Math.abs(actual - expected) < NEAR_ZERO;
|
||||
return { result, message, actual, expected };
|
||||
message = message || (actual + ' did not equal ' + expected)
|
||||
const result = Math.abs(actual - expected) < NEAR_ZERO
|
||||
return { result, message, actual, expected }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,9 +21,9 @@ function almostEquals (actual, expected, message) {
|
|||
* @returns {void}
|
||||
*/
|
||||
function setAssertionMethods (_chai, utils) {
|
||||
const wrap = assertionWrapper(_chai, utils);
|
||||
const wrap = assertionWrapper(_chai, utils)
|
||||
|
||||
assert.almostEquals = wrap(almostEquals);
|
||||
assert.almostEquals = wrap(almostEquals)
|
||||
}
|
||||
|
||||
export default setAssertionMethods;
|
||||
export default setAssertionMethods
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import assertionWrapper from './assertion-wrapper.js';
|
||||
import assertionWrapper from './assertion-wrapper.js'
|
||||
|
||||
/**
|
||||
* @typedef {PlainObject} InfoObject
|
||||
|
@ -21,10 +21,10 @@ import assertionWrapper from './assertion-wrapper.js';
|
|||
* @returns {InfoObject}
|
||||
*/
|
||||
function close (actual, expected, maxDifference, message) {
|
||||
const actualDiff = (actual === expected) ? 0 : Math.abs(actual - expected);
|
||||
const result = actualDiff <= maxDifference;
|
||||
message = message || (actual + ' should be within ' + maxDifference + ' (inclusive) of ' + expected + (result ? '' : '. Actual: ' + actualDiff));
|
||||
return { result, message, actual, expected };
|
||||
const actualDiff = (actual === expected) ? 0 : Math.abs(actual - expected)
|
||||
const result = actualDiff <= maxDifference
|
||||
message = message || (actual + ' should be within ' + maxDifference + ' (inclusive) of ' + expected + (result ? '' : '. Actual: ' + actualDiff))
|
||||
return { result, message, actual, expected }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,21 +40,21 @@ function close (actual, expected, maxDifference, message) {
|
|||
* @returns {InfoObject}
|
||||
*/
|
||||
function closePercent (actual, expected, maxPercentDifference, message) {
|
||||
let actualDiff; let result;
|
||||
let actualDiff; let result
|
||||
if (actual === expected) {
|
||||
actualDiff = 0;
|
||||
result = actualDiff <= maxPercentDifference;
|
||||
actualDiff = 0
|
||||
result = actualDiff <= maxPercentDifference
|
||||
} else if (actual !== 0 && expected !== 0 && expected !== Infinity && expected !== -Infinity) {
|
||||
actualDiff = Math.abs(100 * (actual - expected) / expected);
|
||||
result = actualDiff <= maxPercentDifference;
|
||||
actualDiff = Math.abs(100 * (actual - expected) / expected)
|
||||
result = actualDiff <= maxPercentDifference
|
||||
} else {
|
||||
// Dividing by zero (0)! Should return `false` unless the max percentage was `Infinity`
|
||||
actualDiff = Infinity;
|
||||
result = maxPercentDifference === Infinity;
|
||||
actualDiff = Infinity
|
||||
result = maxPercentDifference === Infinity
|
||||
}
|
||||
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 }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,10 +70,10 @@ function closePercent (actual, expected, maxPercentDifference, message) {
|
|||
* @returns {InfoObject}
|
||||
*/
|
||||
function notClose (actual, expected, minDifference, message) {
|
||||
const actualDiff = Math.abs(actual - expected);
|
||||
const result = actualDiff > minDifference;
|
||||
message = message || (actual + ' should not be within ' + minDifference + ' (exclusive) of ' + expected + (result ? '' : '. Actual: ' + actualDiff));
|
||||
return { result, message, actual, expected };
|
||||
const actualDiff = Math.abs(actual - expected)
|
||||
const result = actualDiff > minDifference
|
||||
message = message || (actual + ' should not be within ' + minDifference + ' (exclusive) of ' + expected + (result ? '' : '. Actual: ' + actualDiff))
|
||||
return { result, message, actual, expected }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,21 +89,21 @@ function notClose (actual, expected, minDifference, message) {
|
|||
* @returns {InfoObject}
|
||||
*/
|
||||
function notClosePercent (actual, expected, minPercentDifference, message) {
|
||||
let actualDiff; let result;
|
||||
let actualDiff; let result
|
||||
if (actual === expected) {
|
||||
actualDiff = 0;
|
||||
result = actualDiff > minPercentDifference;
|
||||
actualDiff = 0
|
||||
result = actualDiff > minPercentDifference
|
||||
} else if (actual !== 0 && expected !== 0 && expected !== Infinity && expected !== -Infinity) {
|
||||
actualDiff = Math.abs(100 * (actual - expected) / expected);
|
||||
result = actualDiff > minPercentDifference;
|
||||
actualDiff = Math.abs(100 * (actual - expected) / expected)
|
||||
result = actualDiff > minPercentDifference
|
||||
} else {
|
||||
// Dividing by zero (0)! Should only return `true` if the min percentage was `Infinity`
|
||||
actualDiff = Infinity;
|
||||
result = minPercentDifference !== Infinity;
|
||||
actualDiff = Infinity
|
||||
result = minPercentDifference !== Infinity
|
||||
}
|
||||
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 }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,12 +112,12 @@ function notClosePercent (actual, expected, minPercentDifference, message) {
|
|||
* @returns {void}
|
||||
*/
|
||||
function setAssertionMethods (_chai, utils) {
|
||||
const wrap = assertionWrapper(_chai, utils);
|
||||
const wrap = assertionWrapper(_chai, utils)
|
||||
|
||||
assert.close = wrap(close);
|
||||
assert.closePercent = wrap(closePercent);
|
||||
assert.notClose = wrap(notClose);
|
||||
assert.notClosePercent = wrap(notClosePercent);
|
||||
assert.close = wrap(close)
|
||||
assert.closePercent = wrap(closePercent)
|
||||
assert.notClose = wrap(notClose)
|
||||
assert.notClosePercent = wrap(notClosePercent)
|
||||
}
|
||||
|
||||
export default setAssertionMethods;
|
||||
export default setAssertionMethods
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import assertionWrapper from './assertion-wrapper.js';
|
||||
import assertionWrapper from './assertion-wrapper.js'
|
||||
|
||||
/**
|
||||
* Expects an out of bounds `INDEX_SIZE_ERR` exception.
|
||||
|
@ -8,18 +8,18 @@ import assertionWrapper from './assertion-wrapper.js';
|
|||
* @returns {void}
|
||||
*/
|
||||
function expectOutOfBoundsException (obj, fn, arg1) {
|
||||
const expected = true;
|
||||
const message = 'Caught an INDEX_SIZE_ERR exception';
|
||||
let result = false;
|
||||
const expected = true
|
||||
const message = 'Caught an INDEX_SIZE_ERR exception'
|
||||
let result = false
|
||||
try {
|
||||
obj[fn](arg1);
|
||||
obj[fn](arg1)
|
||||
} catch (e) {
|
||||
if (e.code === 1) {
|
||||
result = true;
|
||||
result = true
|
||||
}
|
||||
}
|
||||
const actual = result;
|
||||
return { result, message, actual, expected };
|
||||
const actual = result
|
||||
return { result, message, actual, expected }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -28,9 +28,9 @@ function expectOutOfBoundsException (obj, fn, arg1) {
|
|||
* @returns {void}
|
||||
*/
|
||||
function setAssertionMethods (_chai, utils) {
|
||||
const wrap = assertionWrapper(_chai, utils);
|
||||
const wrap = assertionWrapper(_chai, utils)
|
||||
|
||||
assert.expectOutOfBoundsException = wrap(expectOutOfBoundsException);
|
||||
assert.expectOutOfBoundsException = wrap(expectOutOfBoundsException)
|
||||
}
|
||||
|
||||
export default setAssertionMethods;
|
||||
export default setAssertionMethods
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
function setAssertionMethods (_chai, _utils) {
|
||||
return (method) => {
|
||||
return (...args) => {
|
||||
const { result, message, actual, expected } = method(...args);
|
||||
const assertion = new _chai.Assertion();
|
||||
assertion.assert(result, `Expected ${actual} to be ${expected}`, message);
|
||||
};
|
||||
};
|
||||
const { result, message, actual, expected } = method(...args)
|
||||
const assertion = new _chai.Assertion()
|
||||
assertion.assert(result, `Expected ${actual} to be ${expected}`, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
export default setAssertionMethods;
|
||||
export default setAssertionMethods
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
|
||||
/* globals Cypress */
|
||||
// remove the style attributes that is causing differences in snapshots
|
||||
const ngAttributes = [ 'style' ];
|
||||
const ngAttributes = ['style']
|
||||
|
||||
Cypress.Commands.add(
|
||||
'cleanSnapshot',
|
||||
|
@ -33,16 +33,16 @@ Cypress.Commands.add(
|
|||
prevSubject: true
|
||||
},
|
||||
(subject, _snapshotOptions) => {
|
||||
let html = subject[0].outerHTML;
|
||||
let html = subject[0].outerHTML
|
||||
|
||||
for (const attribute of ngAttributes) {
|
||||
const expression = new RegExp(`${attribute}[^= ]*="[^"]*"`, 'g');
|
||||
html = html.replace(expression, '');
|
||||
const expression = new RegExp(`${attribute}[^= ]*="[^"]*"`, 'g')
|
||||
html = html.replace(expression, '')
|
||||
}
|
||||
html = html.replace(/<!--[\s\S]*?-->/g, '');
|
||||
html = html.replace(/<!--[\s\S]*?-->/g, '')
|
||||
|
||||
const sanitisedBody = new DOMParser().parseFromString(html, 'text/html').querySelector('body');
|
||||
const sanitisedBody = new DOMParser().parseFromString(html, 'text/html').querySelector('body')
|
||||
|
||||
return cy.wrap(sanitisedBody.firstChild).toMatchSnapshot();
|
||||
return cy.wrap(sanitisedBody.firstChild).toMatchSnapshot()
|
||||
}
|
||||
);
|
||||
)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands.js';
|
||||
import './commands.js'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
|
@ -29,17 +29,17 @@ import './commands.js';
|
|||
* @see https://github.com/cypress-io/cypress-fiddle
|
||||
* @example import {testExamples} from '@cypress/fiddle';
|
||||
*/
|
||||
import '@cypress/fiddle';
|
||||
import '@cypress/fiddle'
|
||||
|
||||
/**
|
||||
* COVERAGE.
|
||||
* @see https://docs.cypress.io/guides/tooling/code-coverage.html#Install-the-plugin
|
||||
*/
|
||||
import '@cypress/code-coverage/support.js';
|
||||
import '@cypress/code-coverage/support.js'
|
||||
|
||||
/*****
|
||||
* SNAPSHOTS
|
||||
* @see https://www.npmjs.com/package/cypress-plugin-snapshots
|
||||
*/
|
||||
|
||||
import 'cypress-plugin-snapshots/commands.js';
|
||||
import 'cypress-plugin-snapshots/commands.js'
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
export const approveStorage = () => {
|
||||
// JFH will need to be chnaged when dialog is changed...
|
||||
cy.get('#storage_ok').click();
|
||||
};
|
||||
cy.get('#storage_ok').click()
|
||||
}
|
||||
|
||||
export const visitAndApproveStorage = () => {
|
||||
cy.visit('/instrumented/editor/index.html');
|
||||
approveStorage();
|
||||
};
|
||||
cy.visit('/instrumented/editor/index.html')
|
||||
approveStorage()
|
||||
}
|
||||
|
||||
export const openMainMenu = () => {
|
||||
return cy.get('#main_button').click({ force: true });
|
||||
};
|
||||
return cy.get('#main_button').click({ force: true })
|
||||
}
|
||||
|
||||
export const openEditorPreferences = () => {
|
||||
openMainMenu();
|
||||
return cy.get('#tool_editor_prefs').click();
|
||||
};
|
||||
openMainMenu()
|
||||
return cy.get('#tool_editor_prefs').click()
|
||||
}
|
||||
|
||||
export const selectEnglish = () => {
|
||||
openEditorPreferences();
|
||||
cy.get('#lang_select').select('en');
|
||||
cy.get('#tool_prefs_save').click();
|
||||
};
|
||||
openEditorPreferences()
|
||||
cy.get('#lang_select').select('en')
|
||||
cy.get('#tool_prefs_save').click()
|
||||
}
|
||||
|
|
|
@ -27,14 +27,14 @@
|
|||
<input id="text" style="width:0;height:0;opacity: 0"/>
|
||||
<script type="module">
|
||||
/* globals canvas */
|
||||
import SvgCanvas from '../src/svgcanvas/svgcanvas.js';
|
||||
import SvgCanvas from '../src/svgcanvas/svgcanvas.js'
|
||||
|
||||
const container = document.querySelector('#editorContainer');
|
||||
const { width, height } = { width: 500, height: 300 };
|
||||
window.width = width;
|
||||
window.height = height;
|
||||
const container = document.querySelector('#editorContainer')
|
||||
const { width, height } = { width: 500, height: 300 }
|
||||
window.width = width
|
||||
window.height = height
|
||||
|
||||
const hiddenTextTagId = "text";
|
||||
const hiddenTextTagId = 'text'
|
||||
|
||||
const config = {
|
||||
initFill: { color: 'FFFFFF', opacity: 1 },
|
||||
|
@ -44,28 +44,27 @@ const config = {
|
|||
imgPath: '../src/editor/images',
|
||||
dimensions: [ width, height ],
|
||||
baseUnit: 'px'
|
||||
};
|
||||
}
|
||||
|
||||
window.canvas = new SvgCanvas(container, config);
|
||||
canvas.updateCanvas(width, height);
|
||||
window.canvas = new SvgCanvas(container, config)
|
||||
canvas.updateCanvas(width, height)
|
||||
|
||||
window.fill = function (colour) {
|
||||
canvas.getSelectedElements().forEach((el) => {
|
||||
el.setAttribute('fill', colour);
|
||||
});
|
||||
};
|
||||
el.setAttribute('fill', colour)
|
||||
})
|
||||
}
|
||||
|
||||
const hiddenTextTag = window.canvas.$id(hiddenTextTagId);
|
||||
window.canvas.textActions.setInputElem(hiddenTextTag);
|
||||
const hiddenTextTag = window.canvas.$id(hiddenTextTagId)
|
||||
window.canvas.textActions.setInputElem(hiddenTextTag)
|
||||
|
||||
const addListenerMulti = (element, eventNames, listener)=> {
|
||||
eventNames.split(' ').forEach((eventName)=> element.addEventListener(eventName, listener, false));
|
||||
};
|
||||
const addListenerMulti = (element, eventNames, listener) => {
|
||||
eventNames.split(' ').forEach((eventName) => element.addEventListener(eventName, listener, false))
|
||||
}
|
||||
|
||||
addListenerMulti(hiddenTextTag, 'keyup input', (evt) => {
|
||||
window.canvas.setTextContent(evt.currentTarget.value);
|
||||
});
|
||||
|
||||
window.canvas.setTextContent(evt.currentTarget.value)
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* eslint-env node */
|
||||
'use strict';
|
||||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
plugins: [ 'plugins/markdown' ],
|
||||
plugins: ['plugins/markdown'],
|
||||
markdown: {},
|
||||
recurseDepth: 10,
|
||||
source: {
|
||||
|
@ -33,4 +33,4 @@ module.exports = {
|
|||
destination: 'docs/jsdoc',
|
||||
tutorials: 'docs/tutorials'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ svgEditor.setConfig({
|
|||
initFill: {
|
||||
color: '0000FF'
|
||||
}
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
This will set the default width/height of the image, the size of the outside
|
||||
|
@ -121,13 +121,13 @@ set if storage is found.
|
|||
|
||||
```js
|
||||
// Serialized string:
|
||||
svgEditor.loadFromString('<svg xmlns="...">...</svg>');
|
||||
svgEditor.loadFromString('<svg xmlns="...">...</svg>')
|
||||
|
||||
// Data URI:
|
||||
svgEditor.loadFromDataURI('data:image/svg+xml;base64,...');
|
||||
svgEditor.loadFromDataURI('data:image/svg+xml;base64,...')
|
||||
|
||||
// Local URL:
|
||||
svgEditor.loadFromURL('images/logo.svg');
|
||||
svgEditor.loadFromURL('images/logo.svg')
|
||||
```
|
||||
|
||||
### Preload a file (by URL)
|
||||
|
@ -136,13 +136,13 @@ As a URL parameter, one can pre-load an SVG file in the following manner:
|
|||
|
||||
```js
|
||||
// Data URI
|
||||
location.href += '?source=' + encodeURIComponent('data:image/svg+xml;utf8,' + svgText);
|
||||
location.href += '?source=' + encodeURIComponent('data:image/svg+xml;utf8,' + svgText)
|
||||
|
||||
// Data URI (base 64):
|
||||
location.href += '?source=' + encodeURIComponent('data:image/svg+xml;base64,' + svgTextAsBase64); // data%3Aimage%2Fsvg%2Bxml%3Bbase64%2C ...
|
||||
location.href += '?source=' + encodeURIComponent('data:image/svg+xml;base64,' + svgTextAsBase64) // data%3Aimage%2Fsvg%2Bxml%3Bbase64%2C ...
|
||||
|
||||
// Local URL:
|
||||
location.href += '?url=' + encodeURIComponent('images/logo.svg'); // images%2Flogo.svg
|
||||
location.href += '?url=' + encodeURIComponent('images/logo.svg') // images%2Flogo.svg
|
||||
```
|
||||
|
||||
**Note:** There is currently a bug that prevents data URIs ending with
|
||||
|
@ -160,7 +160,7 @@ To add your own stylesheets along with the default stylesheets, ensure
|
|||
`"@default"` is present in the array along with your own. For example:
|
||||
|
||||
```js
|
||||
svgEditor.setConfig({ stylesheets: [ '@default', 'myStylesheet.css' ] });
|
||||
svgEditor.setConfig({ stylesheets: [ '@default', 'myStylesheet.css' ] })
|
||||
```
|
||||
|
||||
(In version 2.8, the CSS file `editor/custom.css` was included by default,
|
||||
|
|
|
@ -11,7 +11,7 @@ svgEditor.setCustomHandlers({
|
|||
save (_win, _data) {
|
||||
// Save svg
|
||||
}
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
Other methods corresponding to UI events that may be supplied are `open`
|
||||
|
@ -40,9 +40,9 @@ $(document).bind('svgEditorReady', function () {
|
|||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="50">
|
||||
<ellipse cx="50" cy="25" rx="50" ry="25" style="fill:blue;"/>
|
||||
</svg>`;
|
||||
$('iframe.svgedit')[0].contentWindow.svgCanvas.setSvgString(svg);
|
||||
});
|
||||
</svg>`
|
||||
$('iframe.svgedit')[0].contentWindow.svgCanvas.setSvgString(svg)
|
||||
})
|
||||
```
|
||||
|
||||
If you are acting within the frame, you may use `svgEditor.ready`
|
||||
|
@ -86,7 +86,7 @@ Canvas events are listened to with the bind method
|
|||
([JSDocs API]{@link module:svgcanvas.SvgCanvas#bind}):
|
||||
|
||||
```js
|
||||
canvas.bind(eventName, callback);
|
||||
canvas.bind(eventName, callback)
|
||||
```
|
||||
|
||||
Canvas events are passed between the editor and canvas and should mostly
|
||||
|
|
|
@ -28,9 +28,9 @@ This is the general format for an extension:
|
|||
export default {
|
||||
name: 'extensionname',
|
||||
init (_methods) {
|
||||
return extensionData;
|
||||
return extensionData
|
||||
}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Extensions must export an object. (For the API docs of this object, see
|
||||
|
@ -86,9 +86,9 @@ export default {
|
|||
mouseUp (_opts) {
|
||||
// ...
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Note how the returned properties may include information on the buttons,
|
||||
|
@ -145,15 +145,15 @@ import { importSetGlobalDefault } from '../external/dynamic-import-polyfill/impo
|
|||
|
||||
(async () => {
|
||||
|
||||
const url = `${svgEditor.curConfig.extPath}ext-locale/<extNameWithoutExtPrefix>/<lang>.js`;
|
||||
const url = `${svgEditor.curConfig.extPath}ext-locale/<extNameWithoutExtPrefix>/<lang>.js`
|
||||
const localeStrings = await importSetGlobalDefault(url, {
|
||||
global: 'svgEditorExtensionLocale_imagelib_' + lang
|
||||
});
|
||||
})
|
||||
|
||||
// Use `localeStrings`
|
||||
console.info(localeStrings);
|
||||
console.info(localeStrings)
|
||||
|
||||
})();
|
||||
})()
|
||||
```
|
||||
|
||||
In addition to your own extension's locale strings,
|
||||
|
|
|
@ -120,7 +120,7 @@ these files). The default behavior is equivalent to this:
|
|||
```js
|
||||
svgEditor.setConfig({
|
||||
stylesheets: [ '@default', '../svgedit-custom.css' ]
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
...which indicates that all default stylesheets will be loaded and then
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
|
||||
module.exports = {
|
||||
"statements": 45,
|
||||
"branches": 34,
|
||||
"lines": 46,
|
||||
"functions": 45,
|
||||
statements: 45,
|
||||
branches: 34,
|
||||
lines: 46,
|
||||
functions: 45,
|
||||
exclude: [
|
||||
'editor/jquery.min.js',
|
||||
'editor/jgraduate/**'
|
||||
],
|
||||
"reporter": [
|
||||
"json-summary",
|
||||
"text",
|
||||
"html"
|
||||
reporter: [
|
||||
'json-summary',
|
||||
'text',
|
||||
'html'
|
||||
]
|
||||
};
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
58
package.json
58
package.json
|
@ -13,7 +13,7 @@
|
|||
"node": ">=10"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint --ext js,html,md .",
|
||||
"lint": "standard .",
|
||||
"test": "run-s cypress:instrument cypress:test",
|
||||
"build": "rollup -c",
|
||||
"build:watch": "rollup -c --watch",
|
||||
|
@ -67,62 +67,55 @@
|
|||
"not IE 11",
|
||||
"not OperaMini all"
|
||||
],
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"archive/"
|
||||
],
|
||||
"globals": [
|
||||
"cy",
|
||||
"assert"
|
||||
],
|
||||
"env": [
|
||||
"mocha",
|
||||
"browser"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "7.12.1",
|
||||
"browser-fs-access": "0.23.0",
|
||||
"canvg": "3.0.9",
|
||||
"core-js": "3.19.3",
|
||||
"core-js": "3.20.1",
|
||||
"elix": "15.0.1",
|
||||
"html2canvas": "1.3.3",
|
||||
"i18next": "21.6.0",
|
||||
"jspdf": "2.4.0",
|
||||
"i18next": "21.6.4",
|
||||
"jspdf": "2.5.0",
|
||||
"pathseg": "1.2.1",
|
||||
"regenerator-runtime": "0.13.9",
|
||||
"rollup-plugin-polyfill-node": "0.8.0",
|
||||
"svg2pdf.js": "2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.16.0",
|
||||
"@babel/preset-env": "7.16.4",
|
||||
"@babel/register": "7.16.0",
|
||||
"@babel/runtime-corejs3": "7.16.3",
|
||||
"@babel/core": "7.16.5",
|
||||
"@babel/preset-env": "7.16.5",
|
||||
"@babel/register": "7.16.5",
|
||||
"@babel/runtime-corejs3": "7.16.5",
|
||||
"@cypress/code-coverage": "3.9.12",
|
||||
"@cypress/fiddle": "1.19.3",
|
||||
"@fintechstudios/eslint-plugin-chai-as-promised": "3.1.0",
|
||||
"@rollup/plugin-babel": "5.3.0",
|
||||
"@rollup/plugin-commonjs": "^18",
|
||||
"@rollup/plugin-dynamic-import-vars": "1.4.1",
|
||||
"@rollup/plugin-node-resolve": "13.0.6",
|
||||
"@rollup/plugin-node-resolve": "13.1.1",
|
||||
"@rollup/plugin-replace": "3.0.0",
|
||||
"@rollup/plugin-url": "6.1.0",
|
||||
"@web/dev-server": "0.1.28",
|
||||
"@web/dev-server-esbuild": "^0.2.16",
|
||||
"@web/dev-server-rollup": "0.3.13",
|
||||
"babel-plugin-transform-object-rest-spread": "7.0.0-beta.3",
|
||||
"copyfiles": "2.4.1",
|
||||
"core-js-bundle": "3.19.3",
|
||||
"core-js-bundle": "3.20.1",
|
||||
"cp-cli": "2.0.0",
|
||||
"cypress": "9.1.1",
|
||||
"cypress": "9.2.0",
|
||||
"cypress-multi-reporters": "1.5.0",
|
||||
"cypress-plugin-snapshots": "1.4.4",
|
||||
"eslint": "^7",
|
||||
"eslint-config-standard": "16.0.3",
|
||||
"eslint-plugin-array-func": "3.1.7",
|
||||
"eslint-plugin-chai-expect": "3.0.0",
|
||||
"eslint-plugin-chai-expect-keywords": "2.1.0",
|
||||
"eslint-plugin-chai-friendly": "0.7.2",
|
||||
"eslint-plugin-compat": "4.0.0",
|
||||
"eslint-plugin-cypress": "2.12.1",
|
||||
"eslint-plugin-eslint-comments": "3.2.0",
|
||||
"eslint-plugin-html": "6.2.0",
|
||||
"eslint-plugin-import": "2.25.3",
|
||||
"eslint-plugin-jsdoc": "37.2.0",
|
||||
"eslint-plugin-markdown": "2.2.1",
|
||||
"eslint-plugin-no-unsanitized": "4.0.1",
|
||||
"eslint-plugin-no-use-extend-native": "0.5.0",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-promise": "5.2.0",
|
||||
"eslint-plugin-standard": "4.1.0",
|
||||
"jamilih": "0.54.0",
|
||||
"jsdoc": "3.6.7",
|
||||
"node-static": "0.7.11",
|
||||
|
@ -135,7 +128,7 @@
|
|||
"remark-cli": "10.0.1",
|
||||
"remark-lint-ordered-list-marker-value": "3.1.1",
|
||||
"rimraf": "3.0.2",
|
||||
"rollup": "2.61.0",
|
||||
"rollup": "2.62.0",
|
||||
"rollup-plugin-copy": "3.4.0",
|
||||
"rollup-plugin-filesize": "9.1.1",
|
||||
"rollup-plugin-html": "^0.2.1",
|
||||
|
@ -143,6 +136,7 @@
|
|||
"rollup-plugin-progress": "1.1.2",
|
||||
"rollup-plugin-re": "1.0.7",
|
||||
"rollup-plugin-terser": "7.0.2",
|
||||
"standard": "16.0.4",
|
||||
"start-server-and-test": "1.14.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,42 +3,42 @@
|
|||
// This rollup script is run by the command:
|
||||
// 'npm run build'
|
||||
|
||||
import path from 'path';
|
||||
import { lstatSync, readdirSync } from 'fs';
|
||||
import rimraf from 'rimraf';
|
||||
import babel from '@rollup/plugin-babel';
|
||||
import copy from 'rollup-plugin-copy';
|
||||
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import nodePolyfills from 'rollup-plugin-node-polyfills';
|
||||
import url from '@rollup/plugin-url'; // for XML/SVG files
|
||||
import path from 'path'
|
||||
import { lstatSync, readdirSync } from 'fs'
|
||||
import rimraf from 'rimraf'
|
||||
import babel from '@rollup/plugin-babel'
|
||||
import copy from 'rollup-plugin-copy'
|
||||
import { nodeResolve } from '@rollup/plugin-node-resolve'
|
||||
import commonjs from '@rollup/plugin-commonjs'
|
||||
import nodePolyfills from 'rollup-plugin-node-polyfills'
|
||||
import url from '@rollup/plugin-url' // for XML/SVG files
|
||||
// eslint-disable-next-line node/no-extraneous-import
|
||||
import html from 'rollup-plugin-html';
|
||||
import html from 'rollup-plugin-html'
|
||||
|
||||
import dynamicImportVars from '@rollup/plugin-dynamic-import-vars';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
import dynamicImportVars from '@rollup/plugin-dynamic-import-vars'
|
||||
import { terser } from 'rollup-plugin-terser'
|
||||
// import progress from 'rollup-plugin-progress';
|
||||
import filesize from 'rollup-plugin-filesize';
|
||||
import filesize from 'rollup-plugin-filesize'
|
||||
|
||||
// utility function
|
||||
const getDirectories = (source) => {
|
||||
const isDirectory = (dir) => {
|
||||
return lstatSync(dir).isDirectory();
|
||||
};
|
||||
return readdirSync(source).map((name) => path.join(source, name)).filter((i) => isDirectory(i));
|
||||
};
|
||||
return lstatSync(dir).isDirectory()
|
||||
}
|
||||
return readdirSync(source).map((name) => path.join(source, name)).filter((i) => isDirectory(i))
|
||||
}
|
||||
|
||||
// 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' ];
|
||||
const dest = ['dist/editor']
|
||||
|
||||
// remove existing distribution
|
||||
rimraf('./dist', () => console.info('recreating dist'));
|
||||
rimraf('./dist', () => console.info('recreating dist'))
|
||||
|
||||
// config for svgedit core module
|
||||
const config = [ {
|
||||
input: [ 'src/editor/Editor.js' ],
|
||||
const config = [{
|
||||
input: ['src/editor/Editor.js'],
|
||||
output: [
|
||||
{
|
||||
format: 'es',
|
||||
|
@ -80,8 +80,8 @@ const config = [ {
|
|||
dest: 'dist/editor',
|
||||
rename: 'iife-index.html',
|
||||
transform: (contents) => {
|
||||
const replace1 = contents.toString().replace("import Editor from './Editor.js'", "/* import Editor from './xdomain-Editor.js' */");
|
||||
return replace1.replace('<script type="module">', '<script src="./iife-Editor.js"></script><script>');
|
||||
const replace1 = contents.toString().replace("import Editor from './Editor.js'", "/* import Editor from './xdomain-Editor.js' */")
|
||||
return replace1.replace('<script type="module">', '<script src="./iife-Editor.js"></script><script>')
|
||||
}
|
||||
},
|
||||
{ src: 'src/editor/images', dest },
|
||||
|
@ -94,27 +94,29 @@ const config = [ {
|
|||
{ src: 'src/editor/svgedit.css', dest }
|
||||
]
|
||||
}),
|
||||
html({ include: [
|
||||
'src/editor/panels/*.html',
|
||||
'src/editor/templates/*.html',
|
||||
'src/editor/dialogs/*.html'
|
||||
] }),
|
||||
html({
|
||||
include: [
|
||||
'src/editor/panels/*.html',
|
||||
'src/editor/templates/*.html',
|
||||
'src/editor/dialogs/*.html'
|
||||
]
|
||||
}),
|
||||
nodeResolve({
|
||||
browser: true,
|
||||
preferBuiltins: false
|
||||
}),
|
||||
commonjs(),
|
||||
dynamicImportVars({ include: `src/editor/locale.js` }),
|
||||
babel({ babelHelpers: 'bundled', exclude: [ /\/core-js\// ] }), // exclude core-js to avoid circular dependencies.
|
||||
dynamicImportVars({ include: 'src/editor/locale.js' }),
|
||||
babel({ babelHelpers: 'bundled', exclude: [/\/core-js\//] }), // exclude core-js to avoid circular dependencies.
|
||||
nodePolyfills(),
|
||||
terser({ keep_fnames: true }), // keep_fnames is needed to avoid an error when calling extensions.
|
||||
filesize()
|
||||
]
|
||||
} ];
|
||||
}]
|
||||
|
||||
// config for dynamic extensions
|
||||
extensionDirs.forEach((extensionDir) => {
|
||||
const extensionName = path.basename(extensionDir);
|
||||
const extensionName = path.basename(extensionDir)
|
||||
extensionName && config.push(
|
||||
{
|
||||
input: `./src/editor/extensions/${extensionName}/${extensionName}.js`,
|
||||
|
@ -128,25 +130,27 @@ extensionDirs.forEach((extensionDir) => {
|
|||
],
|
||||
plugins: [
|
||||
url({
|
||||
include: [ '**/*.svg', '**/*.xml' ],
|
||||
include: ['**/*.svg', '**/*.xml'],
|
||||
limit: 0,
|
||||
fileName: '[name][extname]'
|
||||
}),
|
||||
html({ include: [
|
||||
'src/editor/extensions/*/*.html'
|
||||
] }),
|
||||
html({
|
||||
include: [
|
||||
'src/editor/extensions/*/*.html'
|
||||
]
|
||||
}),
|
||||
nodeResolve({
|
||||
browser: true,
|
||||
preferBuiltins: true
|
||||
}),
|
||||
commonjs({ exclude: `src/editor/extensions/${extensionName}/${extensionName}.js` }),
|
||||
dynamicImportVars({ include: `src/editor/extensions/${extensionName}/${extensionName}.js` }),
|
||||
babel({ babelHelpers: 'bundled', exclude: [ /\/core-js\// ] }),
|
||||
babel({ babelHelpers: 'bundled', exclude: [/\/core-js\//] }),
|
||||
nodePolyfills(),
|
||||
terser({ keep_fnames: true })
|
||||
]
|
||||
}
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
export default config;
|
||||
export default config
|
||||
|
|
|
@ -6,36 +6,36 @@
|
|||
* @copyright 2010 Jeff Schiller, 2010 Alexis Deveria
|
||||
*/
|
||||
|
||||
const NSSVG = 'http://www.w3.org/2000/svg';
|
||||
const NSSVG = 'http://www.w3.org/2000/svg'
|
||||
|
||||
const { userAgent } = navigator;
|
||||
const { userAgent } = navigator
|
||||
|
||||
// Note: Browser sniffing should only be used if no other detection method is possible
|
||||
const isWebkit_ = userAgent.includes('AppleWebKit');
|
||||
const isGecko_ = userAgent.includes('Gecko/');
|
||||
const isChrome_ = userAgent.includes('Chrome/');
|
||||
const isMac_ = userAgent.includes('Macintosh');
|
||||
const isTouch_ = 'ontouchstart' in window;
|
||||
const isWebkit_ = userAgent.includes('AppleWebKit')
|
||||
const isGecko_ = userAgent.includes('Gecko/')
|
||||
const isChrome_ = userAgent.includes('Chrome/')
|
||||
const isMac_ = userAgent.includes('Macintosh')
|
||||
const isTouch_ = 'ontouchstart' in window
|
||||
|
||||
// text character positioning (for IE9 and now Chrome)
|
||||
const supportsGoodTextCharPos_ = (function () {
|
||||
const svgroot = document.createElementNS(NSSVG, 'svg');
|
||||
const svgContent = document.createElementNS(NSSVG, 'svg');
|
||||
document.documentElement.append(svgroot);
|
||||
svgContent.setAttribute('x', 5);
|
||||
svgroot.append(svgContent);
|
||||
const text = document.createElementNS(NSSVG, 'text');
|
||||
text.textContent = 'a';
|
||||
svgContent.append(text);
|
||||
const svgroot = document.createElementNS(NSSVG, 'svg')
|
||||
const svgContent = document.createElementNS(NSSVG, 'svg')
|
||||
document.documentElement.append(svgroot)
|
||||
svgContent.setAttribute('x', 5)
|
||||
svgroot.append(svgContent)
|
||||
const text = document.createElementNS(NSSVG, 'text')
|
||||
text.textContent = 'a'
|
||||
svgContent.append(text)
|
||||
try { // Chrome now fails here
|
||||
const pos = text.getStartPositionOfChar(0).x;
|
||||
return (pos === 0);
|
||||
const pos = text.getStartPositionOfChar(0).x
|
||||
return (pos === 0)
|
||||
} catch (err) {
|
||||
return false;
|
||||
return false
|
||||
} finally {
|
||||
svgroot.remove();
|
||||
svgroot.remove()
|
||||
}
|
||||
}());
|
||||
}())
|
||||
|
||||
// Public API
|
||||
|
||||
|
@ -43,31 +43,31 @@ const supportsGoodTextCharPos_ = (function () {
|
|||
* @function module:browser.isWebkit
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isWebkit = () => isWebkit_;
|
||||
export const isWebkit = () => isWebkit_
|
||||
/**
|
||||
* @function module:browser.isGecko
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isGecko = () => isGecko_;
|
||||
export const isGecko = () => isGecko_
|
||||
/**
|
||||
* @function module:browser.isChrome
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isChrome = () => isChrome_;
|
||||
export const isChrome = () => isChrome_
|
||||
|
||||
/**
|
||||
* @function module:browser.isMac
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isMac = () => isMac_;
|
||||
export const isMac = () => isMac_
|
||||
/**
|
||||
* @function module:browser.isTouch
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isTouch = () => isTouch_;
|
||||
export const isTouch = () => isTouch_
|
||||
|
||||
/**
|
||||
* @function module:browser.supportsGoodTextCharPos
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const supportsGoodTextCharPos = () => supportsGoodTextCharPos_;
|
||||
export const supportsGoodTextCharPos = () => supportsGoodTextCharPos_
|
||||
|
|
|
@ -6,17 +6,17 @@
|
|||
* @copyright 2010 Alexis Deveria, 2010 Jeff Schiller
|
||||
*/
|
||||
|
||||
const NSSVG = 'http://www.w3.org/2000/svg';
|
||||
const NSSVG = 'http://www.w3.org/2000/svg'
|
||||
|
||||
const wAttrs = [ 'x', 'x1', 'cx', 'rx', 'width' ];
|
||||
const hAttrs = [ 'y', 'y1', 'cy', 'ry', 'height' ];
|
||||
const unitAttrs = [ 'r', 'radius', ...wAttrs, ...hAttrs ];
|
||||
const wAttrs = ['x', 'x1', 'cx', 'rx', 'width']
|
||||
const hAttrs = ['y', 'y1', 'cy', 'ry', 'height']
|
||||
const unitAttrs = ['r', 'radius', ...wAttrs, ...hAttrs]
|
||||
|
||||
// Container of elements.
|
||||
let elementContainer_;
|
||||
let elementContainer_
|
||||
|
||||
// Stores mapping of unit type to user coordinates.
|
||||
let typeMap_ = {};
|
||||
let typeMap_ = {}
|
||||
|
||||
/**
|
||||
* @interface module:units.ElementContainer
|
||||
|
@ -63,20 +63,20 @@ let typeMap_ = {};
|
|||
* @returns {void}
|
||||
*/
|
||||
export const init = function (elementContainer) {
|
||||
elementContainer_ = elementContainer;
|
||||
elementContainer_ = elementContainer
|
||||
|
||||
// Get correct em/ex values by creating a temporary SVG.
|
||||
const svg = document.createElementNS(NSSVG, 'svg');
|
||||
document.body.append(svg);
|
||||
const rect = document.createElementNS(NSSVG, 'rect');
|
||||
rect.setAttribute('width', '1em');
|
||||
rect.setAttribute('height', '1ex');
|
||||
rect.setAttribute('x', '1in');
|
||||
svg.append(rect);
|
||||
const bb = rect.getBBox();
|
||||
svg.remove();
|
||||
const svg = document.createElementNS(NSSVG, 'svg')
|
||||
document.body.append(svg)
|
||||
const rect = document.createElementNS(NSSVG, 'rect')
|
||||
rect.setAttribute('width', '1em')
|
||||
rect.setAttribute('height', '1ex')
|
||||
rect.setAttribute('x', '1in')
|
||||
svg.append(rect)
|
||||
const bb = rect.getBBox()
|
||||
svg.remove()
|
||||
|
||||
const inch = bb.x;
|
||||
const inch = bb.x
|
||||
typeMap_ = {
|
||||
em: bb.width,
|
||||
ex: bb.height,
|
||||
|
@ -87,8 +87,8 @@ export const init = function (elementContainer) {
|
|||
pc: inch / 6,
|
||||
px: 1,
|
||||
'%': 0
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Group: Unit conversion functions.
|
||||
|
@ -99,8 +99,8 @@ export const init = function (elementContainer) {
|
|||
* @returns {module:units.TypeMap} The unit object with values for each unit
|
||||
*/
|
||||
export const getTypeMap = function () {
|
||||
return typeMap_;
|
||||
};
|
||||
return typeMap_
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {GenericArray} module:units.CompareNumbers
|
||||
|
@ -119,15 +119,15 @@ export const getTypeMap = function () {
|
|||
* with comma-separated floats
|
||||
*/
|
||||
export const shortFloat = function (val) {
|
||||
const digits = elementContainer_.getRoundDigits();
|
||||
const digits = elementContainer_.getRoundDigits()
|
||||
if (!isNaN(val)) {
|
||||
return Number(Number(val).toFixed(digits));
|
||||
return Number(Number(val).toFixed(digits))
|
||||
}
|
||||
if (Array.isArray(val)) {
|
||||
return shortFloat(val[0]) + ',' + shortFloat(val[1]);
|
||||
return shortFloat(val[0]) + ',' + shortFloat(val[1])
|
||||
}
|
||||
return Number.parseFloat(val).toFixed(digits) - 0;
|
||||
};
|
||||
return Number.parseFloat(val).toFixed(digits) - 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the number to given unit or baseUnit.
|
||||
|
@ -137,12 +137,12 @@ export const shortFloat = function (val) {
|
|||
* @returns {Float}
|
||||
*/
|
||||
export const convertUnit = function (val, unit) {
|
||||
unit = unit || elementContainer_.getBaseUnit();
|
||||
unit = unit || elementContainer_.getBaseUnit()
|
||||
// baseVal.convertToSpecifiedUnits(unitNumMap[unit]);
|
||||
// const val = baseVal.valueInSpecifiedUnits;
|
||||
// baseVal.convertToSpecifiedUnits(1);
|
||||
return shortFloat(val / typeMap_[unit]);
|
||||
};
|
||||
return shortFloat(val / typeMap_[unit])
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element's attribute based on the unit in its current value.
|
||||
|
@ -185,19 +185,19 @@ export const setUnitAttr = function (elem, attr, val) {
|
|||
// val += unit;
|
||||
// }
|
||||
// }
|
||||
elem.setAttribute(attr, val);
|
||||
};
|
||||
elem.setAttribute(attr, val)
|
||||
}
|
||||
|
||||
const attrsToConvert = {
|
||||
line: [ 'x1', 'x2', 'y1', 'y2' ],
|
||||
circle: [ 'cx', 'cy', 'r' ],
|
||||
ellipse: [ 'cx', 'cy', 'rx', 'ry' ],
|
||||
foreignObject: [ 'x', 'y', 'width', 'height' ],
|
||||
rect: [ 'x', 'y', 'width', 'height' ],
|
||||
image: [ 'x', 'y', 'width', 'height' ],
|
||||
use: [ 'x', 'y', 'width', 'height' ],
|
||||
text: [ 'x', 'y' ]
|
||||
};
|
||||
line: ['x1', 'x2', 'y1', 'y2'],
|
||||
circle: ['cx', 'cy', 'r'],
|
||||
ellipse: ['cx', 'cy', 'rx', 'ry'],
|
||||
foreignObject: ['x', 'y', 'width', 'height'],
|
||||
rect: ['x', 'y', 'width', 'height'],
|
||||
image: ['x', 'y', 'width', 'height'],
|
||||
use: ['x', 'y', 'width', 'height'],
|
||||
text: ['x', 'y']
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts all applicable attributes to the configured baseUnit.
|
||||
|
@ -206,18 +206,18 @@ const attrsToConvert = {
|
|||
* @returns {void}
|
||||
*/
|
||||
export const convertAttrs = function (element) {
|
||||
const elName = element.tagName;
|
||||
const unit = elementContainer_.getBaseUnit();
|
||||
const attrs = attrsToConvert[elName];
|
||||
if (!attrs) { return; }
|
||||
const elName = element.tagName
|
||||
const unit = elementContainer_.getBaseUnit()
|
||||
const attrs = attrsToConvert[elName]
|
||||
if (!attrs) { return }
|
||||
|
||||
attrs.forEach( (attr) => {
|
||||
const cur = element.getAttribute(attr);
|
||||
attrs.forEach((attr) => {
|
||||
const cur = element.getAttribute(attr)
|
||||
if (cur && !isNaN(cur)) {
|
||||
element.setAttribute(attr, (cur / typeMap_[unit]) + unit);
|
||||
element.setAttribute(attr, (cur / typeMap_[unit]) + unit)
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts given values to numbers. Attributes must be supplied in
|
||||
|
@ -230,26 +230,26 @@ export const convertAttrs = function (element) {
|
|||
*/
|
||||
export const convertToNum = function (attr, val) {
|
||||
// Return a number if that's what it already is
|
||||
if (!isNaN(val)) { return val - 0; }
|
||||
if (!isNaN(val)) { return val - 0 }
|
||||
if (val.substr(-1) === '%') {
|
||||
// Deal with percentage, depends on attribute
|
||||
const num = val.substr(0, val.length - 1) / 100;
|
||||
const width = elementContainer_.getWidth();
|
||||
const height = elementContainer_.getHeight();
|
||||
const num = val.substr(0, val.length - 1) / 100
|
||||
const width = elementContainer_.getWidth()
|
||||
const height = elementContainer_.getHeight()
|
||||
|
||||
if (wAttrs.includes(attr)) {
|
||||
return num * width;
|
||||
return num * width
|
||||
}
|
||||
if (hAttrs.includes(attr)) {
|
||||
return num * height;
|
||||
return num * height
|
||||
}
|
||||
return num * Math.sqrt((width * width) + (height * height)) / Math.sqrt(2);
|
||||
return num * Math.sqrt((width * width) + (height * height)) / Math.sqrt(2)
|
||||
}
|
||||
const unit = val.substr(-2);
|
||||
const num = val.substr(0, val.length - 2);
|
||||
const unit = val.substr(-2)
|
||||
const num = val.substr(0, val.length - 2)
|
||||
// Note that this multiplication turns the string into a number
|
||||
return num * typeMap_[unit];
|
||||
};
|
||||
return num * typeMap_[unit]
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an attribute's value is in a valid format.
|
||||
|
@ -263,29 +263,29 @@ export const isValidUnit = function (attr, val, selectedElement) {
|
|||
if (unitAttrs.includes(attr)) {
|
||||
// True if it's just a number
|
||||
if (!isNaN(val)) {
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
// Not a number, check if it has a valid unit
|
||||
val = val.toLowerCase();
|
||||
val = val.toLowerCase()
|
||||
return Object.keys(typeMap_).some((unit) => {
|
||||
const re = new RegExp('^-?[\\d\\.]+' + unit + '$');
|
||||
return re.test(val);
|
||||
});
|
||||
const re = new RegExp('^-?[\\d\\.]+' + unit + '$')
|
||||
return re.test(val)
|
||||
})
|
||||
}
|
||||
if (attr === 'id') {
|
||||
// if we're trying to change the id, make sure it's not already present in the doc
|
||||
// and the id value is valid.
|
||||
|
||||
let result = false;
|
||||
let result = false
|
||||
// because getElem() can throw an exception in the case of an invalid id
|
||||
// (according to https://www.w3.org/TR/xml-id/ IDs must be a NCName)
|
||||
// we wrap it in an exception and only return true if the ID was valid and
|
||||
// not already present
|
||||
try {
|
||||
const elem = elementContainer_.getElement(val);
|
||||
result = (!elem || elem === selectedElement);
|
||||
} catch (e) {/* empty fn */}
|
||||
return result;
|
||||
const elem = elementContainer_.getElement(val)
|
||||
result = (!elem || elem === selectedElement)
|
||||
} catch (e) { /* empty fn */ }
|
||||
return result
|
||||
}
|
||||
return true;
|
||||
};
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { mergeDeep } from './components/jgraduate/Util.js';
|
||||
import { mergeDeep } from './components/jgraduate/Util.js'
|
||||
|
||||
/**
|
||||
* Escapes special characters in a regular expression.
|
||||
|
@ -8,8 +8,8 @@ import { mergeDeep } from './components/jgraduate/Util.js';
|
|||
*/
|
||||
export const regexEscape = function (str) {
|
||||
// Originally from: http://phpjs.org/functions
|
||||
return String(str).replace(/[.\\+*?[^\]$(){}=!<>|:-]/g, '\\$&');
|
||||
};
|
||||
return String(str).replace(/[.\\+*?[^\]$(){}=!<>|:-]/g, '\\$&')
|
||||
}
|
||||
/**
|
||||
* @class configObj
|
||||
*/
|
||||
|
@ -47,7 +47,7 @@ export default class ConfigObj {
|
|||
// Only shows in UI as far as alert notices, but useful to remember, so keeping as pref
|
||||
save_notice_done: false,
|
||||
export_notice_done: false
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @tutorial ConfigOptions
|
||||
* @interface module:SVGEditor.Config
|
||||
|
@ -134,7 +134,7 @@ export default class ConfigObj {
|
|||
imgPath: './images',
|
||||
// DOCUMENT PROPERTIES
|
||||
// Change the following to a preference (already in the Document Properties dialog)?
|
||||
dimensions: [ 640, 480 ],
|
||||
dimensions: [640, 480],
|
||||
// EDITOR OPTIONS
|
||||
// Change the following to preferences (already in the Editor Options dialog)?
|
||||
gridSnapping: false,
|
||||
|
@ -158,13 +158,13 @@ export default class ConfigObj {
|
|||
avoidClientSide: false, // Deprecated in favor of `avoidClientSideDownload`
|
||||
avoidClientSideDownload: false,
|
||||
avoidClientSideOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
this.curPrefs = {};
|
||||
this.curPrefs = {}
|
||||
// Note: The difference between Prefs and Config is that Prefs
|
||||
// can be changed in the UI and are stored in the browser,
|
||||
// while config cannot
|
||||
this.urldata = {};
|
||||
this.urldata = {}
|
||||
/**
|
||||
* @name module:SVGEditor~defaultExtensions
|
||||
* @type {string[]}
|
||||
|
@ -182,7 +182,7 @@ export default class ConfigObj {
|
|||
'ext-polystar',
|
||||
'ext-storage',
|
||||
'ext-opensave'
|
||||
];
|
||||
]
|
||||
this.curConfig = {
|
||||
// We do not put on defaultConfig to simplify object copying
|
||||
// procedures (we obtain instead from defaultExtensions)
|
||||
|
@ -203,61 +203,64 @@ export default class ConfigObj {
|
|||
* @todo We might instead make as a user-facing preference.
|
||||
*/
|
||||
allowedOrigins: []
|
||||
};
|
||||
this.editor = editor;
|
||||
}
|
||||
this.editor = editor
|
||||
}
|
||||
|
||||
/**
|
||||
* @function setupCurPrefs
|
||||
* @returns {void}
|
||||
*/
|
||||
setupCurPrefs () {
|
||||
const curPrefs = { ...this.defaultPrefs, ...this.curPrefs }; // Now safe to merge with priority for curPrefs in the event any are already set
|
||||
const curPrefs = { ...this.defaultPrefs, ...this.curPrefs } // Now safe to merge with priority for curPrefs in the event any are already set
|
||||
// Export updated prefs
|
||||
this.curPrefs = curPrefs;
|
||||
this.curPrefs = curPrefs
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up current config based on defaults.
|
||||
* @returns {void}
|
||||
*/
|
||||
setupCurConfig () {
|
||||
const curConfig = { ...this.defaultConfig, ...this.curConfig }; // Now safe to merge with priority for curConfig in the event any are already set
|
||||
const curConfig = { ...this.defaultConfig, ...this.curConfig } // Now safe to merge with priority for curConfig in the event any are already set
|
||||
|
||||
// Now deal with extensions and other array config
|
||||
if (!curConfig.noDefaultExtensions) {
|
||||
curConfig.extensions = [ ...this.defaultExtensions ];
|
||||
curConfig.extensions = [...this.defaultExtensions]
|
||||
}
|
||||
// Export updated config
|
||||
this.curConfig = curConfig;
|
||||
this.curConfig = curConfig
|
||||
}
|
||||
|
||||
/**
|
||||
* @function loadFromURL Load config/data from URL if given
|
||||
* @returns {void}
|
||||
*/
|
||||
loadFromURL () {
|
||||
const self = this;
|
||||
const { search, searchParams } = new URL(location);
|
||||
const self = this
|
||||
const { search, searchParams } = new URL(location)
|
||||
if (search) {
|
||||
this.urldata = {};
|
||||
const entries = searchParams.entries();
|
||||
for(const entry of entries) {
|
||||
this.urldata[entry[0]] = entry[1];
|
||||
this.urldata = {}
|
||||
const entries = searchParams.entries()
|
||||
for (const entry of entries) {
|
||||
this.urldata[entry[0]] = entry[1]
|
||||
}
|
||||
|
||||
[ 'initStroke', 'initFill' ].forEach((prop) => {
|
||||
['initStroke', 'initFill'].forEach((prop) => {
|
||||
if (searchParams.has(`${prop}[color]`)) {
|
||||
// Restore back to original non-deparamed value to avoid color
|
||||
// strings being converted to numbers
|
||||
if(this.urldata[prop] === undefined) { this.urldata[prop] = {}; }
|
||||
this.urldata[prop].color = searchParams.get(`${prop}[color]`);
|
||||
if (this.urldata[prop] === undefined) { this.urldata[prop] = {} }
|
||||
this.urldata[prop].color = searchParams.get(`${prop}[color]`)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
if (searchParams.has('bkgd_color')) {
|
||||
this.urldata.bkgd_color = '#' + searchParams.get('bkgd_color');
|
||||
this.urldata.bkgd_color = '#' + searchParams.get('bkgd_color')
|
||||
}
|
||||
|
||||
if (this.urldata.dimensions) {
|
||||
this.urldata.dimensions = this.urldata.dimensions.split(',');
|
||||
this.urldata.dimensions = this.urldata.dimensions.split(',')
|
||||
}
|
||||
|
||||
if (this.urldata.extensions) {
|
||||
|
@ -265,54 +268,55 @@ export default class ConfigObj {
|
|||
// extensions via URL
|
||||
this.urldata.extensions = (/[:/\\]/).test(this.urldata.extensions)
|
||||
? ''
|
||||
: this.urldata.extensions.split(',');
|
||||
: this.urldata.extensions.split(',')
|
||||
}
|
||||
|
||||
// Disallowing extension paths via URL for
|
||||
// security reasons, even for same-domain
|
||||
// ones given potential to interact in undesirable
|
||||
// ways with other script resources
|
||||
[ 'userExtensions', 'imgPath' ]
|
||||
['userExtensions', 'imgPath']
|
||||
.forEach(function (pathConfig) {
|
||||
if (self.urldata[pathConfig]) {
|
||||
delete self.urldata[pathConfig];
|
||||
delete self.urldata[pathConfig]
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// Note: `source` and `url` (as with `storagePrompt` later) are not
|
||||
// set on config but are used below
|
||||
this.setConfig(this.urldata, { overwrite: false });
|
||||
this.setupCurConfig();
|
||||
this.setConfig(this.urldata, { overwrite: false })
|
||||
this.setupCurConfig()
|
||||
|
||||
if (!this.curConfig.preventURLContentLoading) {
|
||||
let { source } = this.urldata;
|
||||
let { source } = this.urldata
|
||||
if (!source) { // urldata.source may have been null if it ended with '='
|
||||
const src = searchParams.get('source');
|
||||
const src = searchParams.get('source')
|
||||
if (src && src.startsWith('data:')) {
|
||||
source = src;
|
||||
source = src
|
||||
}
|
||||
}
|
||||
if (source) {
|
||||
if (source.startsWith('data:')) {
|
||||
this.editor.loadFromDataURI(source);
|
||||
this.editor.loadFromDataURI(source)
|
||||
} else {
|
||||
this.editor.loadFromString(source);
|
||||
this.editor.loadFromString(source)
|
||||
}
|
||||
return;
|
||||
return
|
||||
}
|
||||
if (this.urldata.url) {
|
||||
this.editor.loadFromURL(this.urldata.url);
|
||||
return;
|
||||
this.editor.loadFromURL(this.urldata.url)
|
||||
return
|
||||
}
|
||||
}
|
||||
if (!this.urldata.noStorageOnLoad || this.curConfig.forceStorage) {
|
||||
this.loadContentAndPrefs();
|
||||
this.loadContentAndPrefs()
|
||||
}
|
||||
} else {
|
||||
this.setupCurConfig();
|
||||
this.loadContentAndPrefs();
|
||||
this.setupCurConfig()
|
||||
this.loadContentAndPrefs()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Where permitted, sets canvas and/or `configObj.defaultPrefs` based on previous
|
||||
* storage. This will override URL settings (for security reasons) but
|
||||
|
@ -333,7 +337,7 @@ export default class ConfigObj {
|
|||
!(/(?:^|;\s*)svgeditstore=(?:prefsAndContent|prefsOnly)/).test(document.cookie)
|
||||
)
|
||||
) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// LOAD CONTENT
|
||||
|
@ -343,32 +347,32 @@ export default class ConfigObj {
|
|||
(/(?:^|;\s*)svgeditstore=prefsAndContent/).test(document.cookie))
|
||||
)
|
||||
) {
|
||||
const name = 'svgedit-' + this.curConfig.canvasName;
|
||||
const cached = this.editor.storage.getItem(name);
|
||||
const name = 'svgedit-' + this.curConfig.canvasName
|
||||
const cached = this.editor.storage.getItem(name)
|
||||
if (cached) {
|
||||
this.editor.loadFromString(cached);
|
||||
this.editor.loadFromString(cached)
|
||||
}
|
||||
}
|
||||
|
||||
// LOAD PREFS
|
||||
Object.keys(this.defaultPrefs).forEach((key) => {
|
||||
const storeKey = 'svg-edit-' + key;
|
||||
const storeKey = 'svg-edit-' + key
|
||||
if (this.editor.storage) {
|
||||
const val = this.editor.storage.getItem(storeKey);
|
||||
const val = this.editor.storage.getItem(storeKey)
|
||||
if (val) {
|
||||
this.defaultPrefs[key] = String(val); // Convert to string for FF (.value fails in Webkit)
|
||||
this.defaultPrefs[key] = String(val) // Convert to string for FF (.value fails in Webkit)
|
||||
}
|
||||
} else if (window.widget) {
|
||||
this.defaultPrefs[key] = window.widget.preferenceForKey(storeKey);
|
||||
this.defaultPrefs[key] = window.widget.preferenceForKey(storeKey)
|
||||
} else {
|
||||
const result = document.cookie.match(
|
||||
new RegExp('(?:^|;\\s*)' + regexEscape(
|
||||
encodeURIComponent(storeKey)
|
||||
) + '=([^;]+)')
|
||||
);
|
||||
this.defaultPrefs[key] = result ? decodeURIComponent(result[1]) : '';
|
||||
)
|
||||
this.defaultPrefs[key] = result ? decodeURIComponent(result[1]) : ''
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -402,61 +406,62 @@ export default class ConfigObj {
|
|||
*/
|
||||
const extendOrAdd = (cfgObj, key, val) => {
|
||||
if (cfgObj[key] && typeof cfgObj[key] === 'object') {
|
||||
cfgObj[key] = mergeDeep(cfgObj[key], val);
|
||||
cfgObj[key] = mergeDeep(cfgObj[key], val)
|
||||
} else {
|
||||
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...
|
||||
if (this.defaultPrefs[key]) {
|
||||
if (cfgCfg.overwrite === false && (
|
||||
this.curConfig.preventAllURLConfig ||
|
||||
this.curPrefs[key])
|
||||
) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
if (cfgCfg.allowInitialUserOverride === true) {
|
||||
this.defaultPrefs[key] = val;
|
||||
this.defaultPrefs[key] = val
|
||||
} 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 &&
|
||||
(
|
||||
this.curConfig.preventAllURLConfig ||
|
||||
[ 'allowedOrigins' ].includes(key) ||
|
||||
['allowedOrigins'].includes(key) ||
|
||||
(key === 'extensions' && this.curConfig.lockExtensions)
|
||||
)
|
||||
) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
this.curConfig[key] = this.curConfig[key].concat(val); // We will handle any dupes later
|
||||
this.curConfig[key] = this.curConfig[key].concat(val) // We will handle any dupes later
|
||||
// Only allow other configObj.curConfig if defined in configObj.defaultConfig
|
||||
} else if ({}.hasOwnProperty.call(this.defaultConfig, key)) {
|
||||
if (cfgCfg.overwrite === false && (
|
||||
this.curConfig.preventAllURLConfig ||
|
||||
{}.hasOwnProperty.call(this.curConfig, key)
|
||||
)) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
// Potentially overwriting of previously set config
|
||||
if ({}.hasOwnProperty.call(this.curConfig, key)) {
|
||||
if (cfgCfg.overwrite === false) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
extendOrAdd(this.curConfig, key, val);
|
||||
extendOrAdd(this.curConfig, key, val)
|
||||
} else if (cfgCfg.allowInitialUserOverride === true) {
|
||||
extendOrAdd(this.defaultConfig, key, val);
|
||||
extendOrAdd(this.defaultConfig, key, val)
|
||||
} else if (this.defaultConfig[key] && typeof this.defaultConfig[key] === 'object') {
|
||||
this.curConfig[key] = Array.isArray(this.defaultConfig[key]) ? [] : {};
|
||||
this.curConfig[key] = mergeDeep(this.curConfig[key], val);
|
||||
this.curConfig[key] = Array.isArray(this.defaultConfig[key]) ? [] : {}
|
||||
this.curConfig[key] = mergeDeep(this.curConfig[key], val)
|
||||
} else {
|
||||
this.curConfig[key] = val;
|
||||
this.curConfig[key] = val
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Store and retrieve preferences.
|
||||
* @function pref
|
||||
|
@ -475,17 +480,18 @@ export default class ConfigObj {
|
|||
*/
|
||||
pref (key, val, mayBeEmpty) {
|
||||
if (mayBeEmpty || val) {
|
||||
this.curPrefs[key] = val;
|
||||
return undefined;
|
||||
this.curPrefs[key] = val
|
||||
return undefined
|
||||
}
|
||||
return (key in this.curPrefs) ? this.curPrefs[key] : this.defaultPrefs[key];
|
||||
return (key in this.curPrefs) ? this.curPrefs[key] : this.defaultPrefs[key]
|
||||
}
|
||||
|
||||
/**
|
||||
* @function load load Config
|
||||
* @returns {void}
|
||||
*/
|
||||
load () {
|
||||
this.loadFromURL(this.editor);
|
||||
this.setupCurPrefs(this.editor);
|
||||
this.loadFromURL(this.editor)
|
||||
this.setupCurPrefs(this.editor)
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,10 @@
|
|||
/* globals seConfirm, seAlert */
|
||||
import SvgCanvas from "../svgcanvas/svgcanvas.js";
|
||||
import { convertUnit, isValidUnit } from '../common/units.js';
|
||||
import { isChrome } from '../common/browser.js';
|
||||
import SvgCanvas from '../svgcanvas/svgcanvas.js'
|
||||
import { convertUnit, isValidUnit } from '../common/units.js'
|
||||
import { isChrome } from '../common/browser.js'
|
||||
|
||||
const { $id } = SvgCanvas;
|
||||
const homePage = 'https://github.com/SVG-Edit/svgedit';
|
||||
const { $id } = SvgCanvas
|
||||
const homePage = 'https://github.com/SVG-Edit/svgedit'
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -13,89 +13,91 @@ class MainMenu {
|
|||
/**
|
||||
* @param {PlainObject} editor svgedit handler
|
||||
*/
|
||||
constructor(editor) {
|
||||
this.editor = editor;
|
||||
constructor (editor) {
|
||||
this.editor = editor
|
||||
/**
|
||||
* @type {Integer}
|
||||
*/
|
||||
this.exportWindowCt = 0;
|
||||
this.exportWindowCt = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* @fires module:svgcanvas.SvgCanvas#event:ext_onNewDocument
|
||||
* @returns {void}
|
||||
*/
|
||||
async clickClear() {
|
||||
const [ x, y ] = this.editor.configObj.curConfig.dimensions;
|
||||
const ok = await seConfirm(this.editor.i18next.t('notification.QwantToClear'));
|
||||
if (ok === "Cancel") {
|
||||
return;
|
||||
async clickClear () {
|
||||
const [x, y] = this.editor.configObj.curConfig.dimensions
|
||||
const ok = await seConfirm(this.editor.i18next.t('notification.QwantToClear'))
|
||||
if (ok === 'Cancel') {
|
||||
return
|
||||
}
|
||||
this.editor.leftPanel.clickSelect();
|
||||
this.editor.svgCanvas.clear();
|
||||
this.editor.svgCanvas.setResolution(x, y);
|
||||
this.editor.updateCanvas(true);
|
||||
this.editor.zoomImage();
|
||||
this.editor.layersPanel.populateLayers();
|
||||
this.editor.topPanel.updateContextPanel();
|
||||
this.editor.svgCanvas.runExtensions("onNewDocument");
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
hideDocProperties() {
|
||||
const $imgDialog = $id("se-img-prop");
|
||||
$imgDialog.setAttribute("dialog", "close");
|
||||
$imgDialog.setAttribute("save", this.editor.configObj.pref("img_save"));
|
||||
this.editor.docprops = false;
|
||||
this.editor.leftPanel.clickSelect()
|
||||
this.editor.svgCanvas.clear()
|
||||
this.editor.svgCanvas.setResolution(x, y)
|
||||
this.editor.updateCanvas(true)
|
||||
this.editor.zoomImage()
|
||||
this.editor.layersPanel.populateLayers()
|
||||
this.editor.topPanel.updateContextPanel()
|
||||
this.editor.svgCanvas.runExtensions('onNewDocument')
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
hidePreferences() {
|
||||
const $editDialog = $id("se-edit-prefs");
|
||||
$editDialog.setAttribute("dialog", "close");
|
||||
this.editor.configObj.preferences = false;
|
||||
hideDocProperties () {
|
||||
const $imgDialog = $id('se-img-prop')
|
||||
$imgDialog.setAttribute('dialog', 'close')
|
||||
$imgDialog.setAttribute('save', this.editor.configObj.pref('img_save'))
|
||||
this.editor.docprops = false
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
hidePreferences () {
|
||||
const $editDialog = $id('se-edit-prefs')
|
||||
$editDialog.setAttribute('dialog', 'close')
|
||||
this.editor.configObj.preferences = false
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Event} e
|
||||
* @returns {boolean} Whether there were problems saving the document properties
|
||||
*/
|
||||
saveDocProperties(e) {
|
||||
saveDocProperties (e) {
|
||||
// set title
|
||||
const { title, w, h, save } = e.detail;
|
||||
const { title, w, h, save } = e.detail
|
||||
// set document title
|
||||
this.editor.svgCanvas.setDocumentTitle(title);
|
||||
this.editor.svgCanvas.setDocumentTitle(title)
|
||||
|
||||
if (w !== "fit" && !isValidUnit("width", w)) {
|
||||
seAlert(this.editor.i18next.t('notification.invalidAttrValGiven'));
|
||||
return false;
|
||||
if (w !== 'fit' && !isValidUnit('width', w)) {
|
||||
seAlert(this.editor.i18next.t('notification.invalidAttrValGiven'))
|
||||
return false
|
||||
}
|
||||
if (h !== "fit" && !isValidUnit("height", h)) {
|
||||
seAlert(this.editor.i18next.t('notification.invalidAttrValGiven'));
|
||||
return false;
|
||||
if (h !== 'fit' && !isValidUnit('height', h)) {
|
||||
seAlert(this.editor.i18next.t('notification.invalidAttrValGiven'))
|
||||
return false
|
||||
}
|
||||
if (!this.editor.svgCanvas.setResolution(w, h)) {
|
||||
seAlert(this.editor.i18next.t('notification.noContentToFitTo'));
|
||||
return false;
|
||||
seAlert(this.editor.i18next.t('notification.noContentToFitTo'))
|
||||
return false
|
||||
}
|
||||
// Set image save option
|
||||
this.editor.configObj.pref("img_save", save);
|
||||
this.editor.updateCanvas();
|
||||
this.hideDocProperties();
|
||||
return true;
|
||||
this.editor.configObj.pref('img_save', save)
|
||||
this.editor.updateCanvas()
|
||||
this.hideDocProperties()
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Save user preferences based on current values in the UI.
|
||||
* @param {Event} e
|
||||
* @function module:SVGthis.savePreferences
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async savePreferences(e) {
|
||||
async savePreferences (e) {
|
||||
const {
|
||||
lang,
|
||||
bgcolor,
|
||||
|
@ -105,57 +107,58 @@ class MainMenu {
|
|||
gridcolor,
|
||||
showrulers,
|
||||
baseunit
|
||||
} = e.detail;
|
||||
} = e.detail
|
||||
// Set background
|
||||
this.editor.setBackground(bgcolor, bgurl);
|
||||
this.editor.setBackground(bgcolor, bgurl)
|
||||
|
||||
// set language
|
||||
if (lang && lang !== this.editor.configObj.pref("lang")) {
|
||||
this.editor.configObj.pref("lang", lang);
|
||||
seAlert('Changing the language needs reload');
|
||||
if (lang && lang !== this.editor.configObj.pref('lang')) {
|
||||
this.editor.configObj.pref('lang', lang)
|
||||
seAlert('Changing the language needs reload')
|
||||
}
|
||||
|
||||
// set grid setting
|
||||
this.editor.configObj.curConfig.gridSnapping = gridsnappingon;
|
||||
this.editor.configObj.curConfig.snappingStep = gridsnappingstep;
|
||||
this.editor.configObj.curConfig.gridColor = gridcolor;
|
||||
this.editor.configObj.curConfig.showRulers = showrulers;
|
||||
this.editor.configObj.curConfig.gridSnapping = gridsnappingon
|
||||
this.editor.configObj.curConfig.snappingStep = gridsnappingstep
|
||||
this.editor.configObj.curConfig.gridColor = gridcolor
|
||||
this.editor.configObj.curConfig.showRulers = showrulers
|
||||
if (this.editor.configObj.curConfig.showRulers) {
|
||||
this.editor.rulers.updateRulers();
|
||||
this.editor.rulers.updateRulers()
|
||||
}
|
||||
this.editor.configObj.curConfig.baseUnit = baseunit;
|
||||
this.editor.svgCanvas.setConfig(this.editor.configObj.curConfig);
|
||||
this.editor.updateCanvas();
|
||||
this.hidePreferences();
|
||||
this.editor.configObj.curConfig.baseUnit = baseunit
|
||||
this.editor.svgCanvas.setConfig(this.editor.configObj.curConfig)
|
||||
this.editor.updateCanvas()
|
||||
this.hidePreferences()
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param e
|
||||
* @returns {Promise<void>} Resolves to `undefined`
|
||||
*/
|
||||
async clickExport(e) {
|
||||
if (e?.detail?.trigger !== "ok" || e?.detail?.imgType === undefined) {
|
||||
return;
|
||||
async clickExport (e) {
|
||||
if (e?.detail?.trigger !== 'ok' || e?.detail?.imgType === undefined) {
|
||||
return
|
||||
}
|
||||
const imgType = e?.detail?.imgType;
|
||||
const quality = e?.detail?.quality ? e?.detail?.quality / 100 : 1;
|
||||
const imgType = e?.detail?.imgType
|
||||
const quality = e?.detail?.quality ? e?.detail?.quality / 100 : 1
|
||||
// Open placeholder window (prevents popup)
|
||||
let exportWindowName;
|
||||
let exportWindowName
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
const openExportWindow = () => {
|
||||
const loadingImage = this.editor.i18next.t('notification.loadingImage');
|
||||
if (this.editor.configObj.curConfig.exportWindowType === "new") {
|
||||
this.editor.exportWindowCt++;
|
||||
const loadingImage = this.editor.i18next.t('notification.loadingImage')
|
||||
if (this.editor.configObj.curConfig.exportWindowType === 'new') {
|
||||
this.editor.exportWindowCt++
|
||||
}
|
||||
this.editor.exportWindowName =
|
||||
this.editor.configObj.curConfig.canvasName + this.editor.exportWindowCt;
|
||||
let popHTML; let popURL;
|
||||
this.editor.configObj.curConfig.canvasName + this.editor.exportWindowCt
|
||||
let popHTML; let popURL
|
||||
if (this.editor.loadingURL) {
|
||||
popURL = this.editor.loadingURL;
|
||||
popURL = this.editor.loadingURL
|
||||
} else {
|
||||
popHTML = `<!DOCTYPE html><html>
|
||||
<head>
|
||||
|
@ -163,35 +166,35 @@ class MainMenu {
|
|||
<title>${loadingImage}</title>
|
||||
</head>
|
||||
<body><h1>${loadingImage}</h1></body>
|
||||
<html>`;
|
||||
if (typeof URL !== "undefined" && URL.createObjectURL) {
|
||||
const blob = new Blob([ popHTML ], { type: "text/html" });
|
||||
popURL = URL.createObjectURL(blob);
|
||||
<html>`
|
||||
if (typeof URL !== 'undefined' && URL.createObjectURL) {
|
||||
const blob = new Blob([popHTML], { type: 'text/html' })
|
||||
popURL = URL.createObjectURL(blob)
|
||||
} else {
|
||||
popURL = "data:text/html;base64;charset=utf-8," + popHTML;
|
||||
popURL = 'data:text/html;base64;charset=utf-8,' + popHTML
|
||||
}
|
||||
this.editor.loadingURL = popURL;
|
||||
this.editor.loadingURL = popURL
|
||||
}
|
||||
this.editor.exportWindow = window.open(
|
||||
popURL,
|
||||
this.editor.exportWindowName
|
||||
);
|
||||
};
|
||||
const chrome = isChrome();
|
||||
if (imgType === "PDF") {
|
||||
)
|
||||
}
|
||||
const chrome = isChrome()
|
||||
if (imgType === 'PDF') {
|
||||
if (!this.editor.customExportPDF && !chrome) {
|
||||
openExportWindow();
|
||||
openExportWindow()
|
||||
}
|
||||
this.editor.svgCanvas.exportPDF(exportWindowName);
|
||||
this.editor.svgCanvas.exportPDF(exportWindowName)
|
||||
} else {
|
||||
if (!this.editor.customExportImage) {
|
||||
openExportWindow();
|
||||
openExportWindow()
|
||||
}
|
||||
/* const results = */ await this.editor.svgCanvas.rasterExport(
|
||||
imgType,
|
||||
quality,
|
||||
this.editor.exportWindowName
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,129 +202,129 @@ class MainMenu {
|
|||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
showDocProperties() {
|
||||
showDocProperties () {
|
||||
if (this.editor.docprops) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
this.editor.docprops = true;
|
||||
const $imgDialog = $id("se-img-prop");
|
||||
this.editor.docprops = true
|
||||
const $imgDialog = $id('se-img-prop')
|
||||
|
||||
// update resolution option with actual resolution
|
||||
const resolution = this.editor.svgCanvas.getResolution();
|
||||
if (this.editor.configObj.curConfig.baseUnit !== "px") {
|
||||
const resolution = this.editor.svgCanvas.getResolution()
|
||||
if (this.editor.configObj.curConfig.baseUnit !== 'px') {
|
||||
resolution.w =
|
||||
convertUnit(resolution.w) + this.editor.configObj.curConfig.baseUnit;
|
||||
convertUnit(resolution.w) + this.editor.configObj.curConfig.baseUnit
|
||||
resolution.h =
|
||||
convertUnit(resolution.h) + this.editor.configObj.curConfig.baseUnit;
|
||||
convertUnit(resolution.h) + this.editor.configObj.curConfig.baseUnit
|
||||
}
|
||||
$imgDialog.setAttribute("save", this.editor.configObj.pref("img_save"));
|
||||
$imgDialog.setAttribute("width", resolution.w);
|
||||
$imgDialog.setAttribute("height", resolution.h);
|
||||
$imgDialog.setAttribute("title", this.editor.svgCanvas.getDocumentTitle());
|
||||
$imgDialog.setAttribute("dialog", "open");
|
||||
$imgDialog.setAttribute('save', this.editor.configObj.pref('img_save'))
|
||||
$imgDialog.setAttribute('width', resolution.w)
|
||||
$imgDialog.setAttribute('height', resolution.h)
|
||||
$imgDialog.setAttribute('title', this.editor.svgCanvas.getDocumentTitle())
|
||||
$imgDialog.setAttribute('dialog', 'open')
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
showPreferences() {
|
||||
showPreferences () {
|
||||
if (this.editor.configObj.preferences) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
this.editor.configObj.preferences = true;
|
||||
const $editDialog = $id("se-edit-prefs");
|
||||
this.editor.configObj.preferences = true
|
||||
const $editDialog = $id('se-edit-prefs')
|
||||
// Update background color with current one
|
||||
const canvasBg = this.editor.configObj.curPrefs.bkgd_color;
|
||||
const url = this.editor.configObj.pref("bkgd_url");
|
||||
const canvasBg = this.editor.configObj.curPrefs.bkgd_color
|
||||
const url = this.editor.configObj.pref('bkgd_url')
|
||||
if (url) {
|
||||
$editDialog.setAttribute("bgurl", url);
|
||||
$editDialog.setAttribute('bgurl', url)
|
||||
}
|
||||
$editDialog.setAttribute(
|
||||
"gridsnappingon",
|
||||
'gridsnappingon',
|
||||
this.editor.configObj.curConfig.gridSnapping
|
||||
);
|
||||
)
|
||||
$editDialog.setAttribute(
|
||||
"gridsnappingstep",
|
||||
'gridsnappingstep',
|
||||
this.editor.configObj.curConfig.snappingStep
|
||||
);
|
||||
)
|
||||
$editDialog.setAttribute(
|
||||
"gridcolor",
|
||||
'gridcolor',
|
||||
this.editor.configObj.curConfig.gridColor
|
||||
);
|
||||
$editDialog.setAttribute("canvasbg", canvasBg);
|
||||
$editDialog.setAttribute("dialog", "open");
|
||||
)
|
||||
$editDialog.setAttribute('canvasbg', canvasBg)
|
||||
$editDialog.setAttribute('dialog', 'open')
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
openHomePage() {
|
||||
window.open(homePage, "_blank");
|
||||
openHomePage () {
|
||||
window.open(homePage, '_blank')
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {module}
|
||||
*/
|
||||
init() {
|
||||
init () {
|
||||
// add Top panel
|
||||
const template = document.createElement("template");
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<se-menu id="main_button" label="SVG-Edit" src="logo.svg" alt="logo">
|
||||
<se-menu-item id="tool_export" label="tools.export_img" src="export.svg"></se-menu-item>
|
||||
<se-menu-item id="tool_docprops" label="tools.docprops" shortcut="D" src="docprop.svg"></se-menu-item>
|
||||
<se-menu-item id="tool_editor_prefs" label="config.editor_prefs" src="editPref.svg"></se-menu-item>
|
||||
<se-menu-item id="tool_editor_homepage" label="tools.editor_homepage" src="logo.svg"></se-menu-item>
|
||||
</se-menu>`;
|
||||
this.editor.$svgEditor.append(template.content.cloneNode(true));
|
||||
</se-menu>`
|
||||
this.editor.$svgEditor.append(template.content.cloneNode(true))
|
||||
|
||||
// register action to main menu entries
|
||||
/**
|
||||
* Associate all button actions as well as non-button keyboard shortcuts.
|
||||
*/
|
||||
$id("tool_export").addEventListener("click", function() {
|
||||
$id('tool_export').addEventListener('click', function () {
|
||||
document
|
||||
.getElementById("se-export-dialog")
|
||||
.setAttribute("dialog", "open");
|
||||
});
|
||||
$id("se-export-dialog").addEventListener(
|
||||
"change",
|
||||
.getElementById('se-export-dialog')
|
||||
.setAttribute('dialog', 'open')
|
||||
})
|
||||
$id('se-export-dialog').addEventListener(
|
||||
'change',
|
||||
this.clickExport.bind(this)
|
||||
);
|
||||
$id("tool_docprops").addEventListener(
|
||||
"click",
|
||||
)
|
||||
$id('tool_docprops').addEventListener(
|
||||
'click',
|
||||
this.showDocProperties.bind(this)
|
||||
);
|
||||
$id("tool_editor_prefs").addEventListener(
|
||||
"click",
|
||||
)
|
||||
$id('tool_editor_prefs').addEventListener(
|
||||
'click',
|
||||
this.showPreferences.bind(this)
|
||||
);
|
||||
$id("tool_editor_homepage").addEventListener(
|
||||
"click",
|
||||
)
|
||||
$id('tool_editor_homepage').addEventListener(
|
||||
'click',
|
||||
this.openHomePage.bind(this)
|
||||
);
|
||||
$id("se-img-prop").addEventListener(
|
||||
"change",
|
||||
function(e) {
|
||||
if (e.detail.dialog === "closed") {
|
||||
this.hideDocProperties();
|
||||
)
|
||||
$id('se-img-prop').addEventListener(
|
||||
'change',
|
||||
function (e) {
|
||||
if (e.detail.dialog === 'closed') {
|
||||
this.hideDocProperties()
|
||||
} else {
|
||||
this.saveDocProperties(e);
|
||||
this.saveDocProperties(e)
|
||||
}
|
||||
}.bind(this)
|
||||
);
|
||||
$id("se-edit-prefs").addEventListener(
|
||||
"change",
|
||||
function(e) {
|
||||
if (e.detail.dialog === "closed") {
|
||||
this.hidePreferences();
|
||||
)
|
||||
$id('se-edit-prefs').addEventListener(
|
||||
'change',
|
||||
function (e) {
|
||||
if (e.detail.dialog === 'closed') {
|
||||
this.hidePreferences()
|
||||
} else {
|
||||
this.savePreferences(e);
|
||||
this.savePreferences(e)
|
||||
}
|
||||
}.bind(this)
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default MainMenu;
|
||||
export default MainMenu
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { getTypeMap } from '../common/units.js';
|
||||
import rulersTemplate from './templates/rulersTemplate.html';
|
||||
import SvgCanvas from '../svgcanvas/svgcanvas.js';
|
||||
import { getTypeMap } from '../common/units.js'
|
||||
import rulersTemplate from './templates/rulersTemplate.html'
|
||||
import SvgCanvas from '../svgcanvas/svgcanvas.js'
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -10,41 +10,42 @@ class Rulers {
|
|||
*/
|
||||
constructor (editor) {
|
||||
// Make [1,2,5] array
|
||||
this.rulerIntervals = [];
|
||||
this.rulerIntervals = []
|
||||
for (let i = 0.1; i < 1e5; i *= 10) {
|
||||
this.rulerIntervals.push(i);
|
||||
this.rulerIntervals.push(2 * i);
|
||||
this.rulerIntervals.push(5 * i);
|
||||
this.rulerIntervals.push(i)
|
||||
this.rulerIntervals.push(2 * i)
|
||||
this.rulerIntervals.push(5 * i)
|
||||
}
|
||||
this.svgCanvas = editor.svgCanvas;
|
||||
this.editor = editor;
|
||||
this.svgCanvas = editor.svgCanvas
|
||||
this.editor = editor
|
||||
// add rulers component to the DOM
|
||||
const template = document.createElement('template');
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
template.innerHTML = rulersTemplate;
|
||||
this.editor.$svgEditor.append(template.content.cloneNode(true));
|
||||
const { $id } = SvgCanvas;
|
||||
this.rulerX = $id('ruler_x');
|
||||
this.rulerY = $id('ruler_y');
|
||||
this.rulerCorner = $id('ruler_corner');
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = rulersTemplate
|
||||
this.editor.$svgEditor.append(template.content.cloneNode(true))
|
||||
const { $id } = SvgCanvas
|
||||
this.rulerX = $id('ruler_x')
|
||||
this.rulerY = $id('ruler_y')
|
||||
this.rulerCorner = $id('ruler_corner')
|
||||
}
|
||||
|
||||
display (on) {
|
||||
if (on) {
|
||||
this.rulerX.style.removeProperty('display');
|
||||
this.rulerY.style.removeProperty('display');
|
||||
this.rulerCorner.style.removeProperty('display');
|
||||
this.rulerX.style.removeProperty('display')
|
||||
this.rulerY.style.removeProperty('display')
|
||||
this.rulerCorner.style.removeProperty('display')
|
||||
} else {
|
||||
this.rulerX.style.display = 'none';
|
||||
this.rulerY.style.display = 'none';
|
||||
this.rulerCorner.style.display = 'none';
|
||||
this.rulerX.style.display = 'none'
|
||||
this.rulerY.style.display = 'none'
|
||||
this.rulerCorner.style.display = 'none'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {Module}
|
||||
*/
|
||||
manageScroll () {
|
||||
if (this.rulerX) this.rulerX.scrollLeft = this.editor.workarea.scrollLeft;
|
||||
if (this.rulerY) this.rulerY.scrollTop = this.editor.workarea.scrollTop;
|
||||
if (this.rulerX) this.rulerX.scrollLeft = this.editor.workarea.scrollLeft
|
||||
if (this.rulerY) this.rulerY.scrollTop = this.editor.workarea.scrollTop
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,165 +55,165 @@ class Rulers {
|
|||
* @returns {void}
|
||||
*/
|
||||
updateRulers (scanvas, zoom) {
|
||||
if (!zoom) { zoom = this.svgCanvas.getZoom(); }
|
||||
if (!scanvas) { scanvas = document.getElementById('svgcanvas'); }
|
||||
if (!zoom) { zoom = this.svgCanvas.getZoom() }
|
||||
if (!scanvas) { scanvas = document.getElementById('svgcanvas') }
|
||||
|
||||
let d; let i;
|
||||
const limit = 30000;
|
||||
const contentElem = this.svgCanvas.getSvgContent();
|
||||
const units = getTypeMap();
|
||||
const unit = units[this.editor.configObj.curConfig.baseUnit]; // 1 = 1px
|
||||
let d; let i
|
||||
const limit = 30000
|
||||
const contentElem = this.svgCanvas.getSvgContent()
|
||||
const units = getTypeMap()
|
||||
const unit = units[this.editor.configObj.curConfig.baseUnit] // 1 = 1px
|
||||
|
||||
// draw x ruler then y ruler
|
||||
for (d = 0; d < 2; d++) {
|
||||
const isX = (d === 0);
|
||||
const dim = isX ? 'x' : 'y';
|
||||
const lentype = isX ? 'width' : 'height';
|
||||
const contentDim = Number(contentElem.getAttribute(dim));
|
||||
const { $id } = SvgCanvas;
|
||||
const $hcanvOrig = $id('ruler_' + dim).querySelector('canvas');
|
||||
const isX = (d === 0)
|
||||
const dim = isX ? 'x' : 'y'
|
||||
const lentype = isX ? 'width' : 'height'
|
||||
const contentDim = Number(contentElem.getAttribute(dim))
|
||||
const { $id } = SvgCanvas
|
||||
const $hcanvOrig = $id('ruler_' + dim).querySelector('canvas')
|
||||
|
||||
// Bit of a hack to fully clear the canvas in Safari & IE9
|
||||
const $hcanv = $hcanvOrig.cloneNode(true);
|
||||
$hcanvOrig.replaceWith($hcanv);
|
||||
const $hcanv = $hcanvOrig.cloneNode(true)
|
||||
$hcanvOrig.replaceWith($hcanv)
|
||||
|
||||
const hcanv = $hcanv;
|
||||
const hcanv = $hcanv
|
||||
|
||||
// Set the canvas size to the width of the container
|
||||
let rulerLen;
|
||||
if(lentype === 'width'){
|
||||
rulerLen = parseFloat(getComputedStyle(scanvas, null).width.replace("px", ""));
|
||||
} else if(lentype === 'height'){
|
||||
rulerLen = parseFloat(getComputedStyle(scanvas, null).height.replace("px", ""));
|
||||
let rulerLen
|
||||
if (lentype === 'width') {
|
||||
rulerLen = parseFloat(getComputedStyle(scanvas, null).width.replace('px', ''))
|
||||
} else if (lentype === 'height') {
|
||||
rulerLen = parseFloat(getComputedStyle(scanvas, null).height.replace('px', ''))
|
||||
}
|
||||
const totalLen = rulerLen;
|
||||
hcanv.parentNode.style[lentype] = totalLen + 'px';
|
||||
let ctx = hcanv.getContext('2d');
|
||||
let ctxArr; let num; let ctxArrNum;
|
||||
const totalLen = rulerLen
|
||||
hcanv.parentNode.style[lentype] = totalLen + 'px'
|
||||
let ctx = hcanv.getContext('2d')
|
||||
let ctxArr; let num; let ctxArrNum
|
||||
|
||||
ctx.fillStyle = 'rgb(200,0,0)';
|
||||
ctx.fillRect(0, 0, hcanv.width, hcanv.height);
|
||||
ctx.fillStyle = 'rgb(200,0,0)'
|
||||
ctx.fillRect(0, 0, hcanv.width, hcanv.height)
|
||||
|
||||
// Remove any existing canvasses
|
||||
const elements = Array.prototype.filter.call($hcanv.parentNode.children, function(child){
|
||||
return child !== $hcanv;
|
||||
});
|
||||
Array.from(elements).forEach(function(element) {
|
||||
element.remove();
|
||||
});
|
||||
const elements = Array.prototype.filter.call($hcanv.parentNode.children, function (child) {
|
||||
return child !== $hcanv
|
||||
})
|
||||
Array.from(elements).forEach(function (element) {
|
||||
element.remove()
|
||||
})
|
||||
|
||||
// Create multiple canvases when necessary (due to browser limits)
|
||||
if (rulerLen >= limit) {
|
||||
ctxArrNum = Number.parseInt(rulerLen / limit) + 1;
|
||||
ctxArr = [];
|
||||
ctxArr[0] = ctx;
|
||||
let copy;
|
||||
ctxArrNum = Number.parseInt(rulerLen / limit) + 1
|
||||
ctxArr = []
|
||||
ctxArr[0] = ctx
|
||||
let copy
|
||||
for (i = 1; i < ctxArrNum; i++) {
|
||||
hcanv[lentype] = limit;
|
||||
copy = hcanv.cloneNode(true);
|
||||
hcanv.parentNode.append(copy);
|
||||
ctxArr[i] = copy.getContext('2d');
|
||||
hcanv[lentype] = limit
|
||||
copy = hcanv.cloneNode(true)
|
||||
hcanv.parentNode.append(copy)
|
||||
ctxArr[i] = copy.getContext('2d')
|
||||
}
|
||||
|
||||
copy[lentype] = rulerLen % limit;
|
||||
copy[lentype] = rulerLen % limit
|
||||
|
||||
// set copy width to last
|
||||
rulerLen = limit;
|
||||
rulerLen = limit
|
||||
}
|
||||
|
||||
hcanv[lentype] = rulerLen;
|
||||
hcanv[lentype] = rulerLen
|
||||
|
||||
const uMulti = unit * zoom;
|
||||
const uMulti = unit * zoom
|
||||
|
||||
// Calculate the main number interval
|
||||
const rawM = 50 / uMulti;
|
||||
let multi = 1;
|
||||
const rawM = 50 / uMulti
|
||||
let multi = 1
|
||||
for (i = 0; i < this.rulerIntervals.length; i++) {
|
||||
num = this.rulerIntervals[i];
|
||||
multi = num;
|
||||
num = this.rulerIntervals[i]
|
||||
multi = num
|
||||
if (rawM <= num) {
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const bigInt = multi * uMulti;
|
||||
const bigInt = multi * uMulti
|
||||
|
||||
ctx.font = '9px sans-serif';
|
||||
ctx.font = '9px sans-serif'
|
||||
|
||||
let rulerD = ((contentDim / uMulti) % multi) * uMulti;
|
||||
let labelPos = rulerD - bigInt;
|
||||
let rulerD = ((contentDim / uMulti) % multi) * uMulti
|
||||
let labelPos = rulerD - bigInt
|
||||
// draw big intervals
|
||||
let ctxNum = 0;
|
||||
let ctxNum = 0
|
||||
while (rulerD < totalLen) {
|
||||
labelPos += bigInt;
|
||||
labelPos += bigInt
|
||||
// const realD = rulerD - contentDim; // Currently unused
|
||||
|
||||
const curD = Math.round(rulerD) + 0.5;
|
||||
const curD = Math.round(rulerD) + 0.5
|
||||
if (isX) {
|
||||
ctx.moveTo(curD, 15);
|
||||
ctx.lineTo(curD, 0);
|
||||
ctx.moveTo(curD, 15)
|
||||
ctx.lineTo(curD, 0)
|
||||
} else {
|
||||
ctx.moveTo(15, curD);
|
||||
ctx.lineTo(0, curD);
|
||||
ctx.moveTo(15, curD)
|
||||
ctx.lineTo(0, curD)
|
||||
}
|
||||
|
||||
num = (labelPos - contentDim) / uMulti;
|
||||
let label;
|
||||
num = (labelPos - contentDim) / uMulti
|
||||
let label
|
||||
if (multi >= 1) {
|
||||
label = Math.round(num);
|
||||
label = Math.round(num)
|
||||
} else {
|
||||
const decs = String(multi).split('.')[1].length;
|
||||
label = num.toFixed(decs);
|
||||
const decs = String(multi).split('.')[1].length
|
||||
label = num.toFixed(decs)
|
||||
}
|
||||
|
||||
// Change 1000s to Ks
|
||||
if (label !== 0 && label !== 1000 && label % 1000 === 0) {
|
||||
label = (label / 1000) + 'K';
|
||||
label = (label / 1000) + 'K'
|
||||
}
|
||||
|
||||
if (isX) {
|
||||
ctx.fillText(label, rulerD + 2, 8);
|
||||
ctx.fillText(label, rulerD + 2, 8)
|
||||
} else {
|
||||
// draw label vertically
|
||||
const str = String(label).split('');
|
||||
const str = String(label).split('')
|
||||
for (i = 0; i < str.length; i++) {
|
||||
ctx.fillText(str[i], 1, (rulerD + 9) + i * 9);
|
||||
ctx.fillText(str[i], 1, (rulerD + 9) + i * 9)
|
||||
}
|
||||
}
|
||||
|
||||
const part = bigInt / 10;
|
||||
const part = bigInt / 10
|
||||
// draw the small intervals
|
||||
for (i = 1; i < 10; i++) {
|
||||
let subD = Math.round(rulerD + part * i) + 0.5;
|
||||
let subD = Math.round(rulerD + part * i) + 0.5
|
||||
if (ctxArr && subD > rulerLen) {
|
||||
ctxNum++;
|
||||
ctx.stroke();
|
||||
ctxNum++
|
||||
ctx.stroke()
|
||||
if (ctxNum >= ctxArrNum) {
|
||||
i = 10;
|
||||
rulerD = totalLen;
|
||||
continue;
|
||||
i = 10
|
||||
rulerD = totalLen
|
||||
continue
|
||||
}
|
||||
ctx = ctxArr[ctxNum];
|
||||
rulerD -= limit;
|
||||
subD = Math.round(rulerD + part * i) + 0.5;
|
||||
ctx = ctxArr[ctxNum]
|
||||
rulerD -= limit
|
||||
subD = Math.round(rulerD + part * i) + 0.5
|
||||
}
|
||||
|
||||
// odd lines are slighly longer
|
||||
const lineNum = (i % 2) ? 12 : 10;
|
||||
const lineNum = (i % 2) ? 12 : 10
|
||||
if (isX) {
|
||||
ctx.moveTo(subD, 15);
|
||||
ctx.lineTo(subD, lineNum);
|
||||
ctx.moveTo(subD, 15)
|
||||
ctx.lineTo(subD, lineNum)
|
||||
} else {
|
||||
ctx.moveTo(15, subD);
|
||||
ctx.lineTo(lineNum, subD);
|
||||
ctx.moveTo(15, subD)
|
||||
ctx.lineTo(lineNum, subD)
|
||||
}
|
||||
}
|
||||
rulerD += bigInt;
|
||||
rulerD += bigInt
|
||||
}
|
||||
ctx.strokeStyle = '#000';
|
||||
ctx.stroke();
|
||||
ctx.strokeStyle = '#000'
|
||||
ctx.stroke()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Rulers;
|
||||
export default Rulers
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
const supportsSvg = function () {
|
||||
return Boolean(document.createElementNS && document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect);
|
||||
};
|
||||
return Boolean(document.createElementNS && document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect)
|
||||
}
|
||||
|
||||
if (!supportsSvg()) {
|
||||
window.location = './browser-not-supported.html';
|
||||
window.location = './browser-not-supported.html'
|
||||
}
|
||||
export {};
|
||||
export {}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { jGraduate } from './jgraduate/jQuery.jGraduate.js';
|
||||
import { jGraduate } from './jgraduate/jQuery.jGraduate.js'
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -16,17 +16,17 @@ class PaintBox {
|
|||
<defs><linearGradient id="gradbox_${PaintBox.ctr++}"/></defs>
|
||||
</svg>`,
|
||||
'text/xml'
|
||||
);
|
||||
)
|
||||
|
||||
let docElem = svgdocbox.documentElement;
|
||||
docElem = document.importNode(docElem, true);
|
||||
container.appendChild(docElem);
|
||||
let docElem = svgdocbox.documentElement
|
||||
docElem = document.importNode(docElem, true)
|
||||
container.appendChild(docElem)
|
||||
|
||||
this.rect = docElem.firstElementChild;
|
||||
this.defs = docElem.getElementsByTagName('defs')[0];
|
||||
this.grad = this.defs.firstElementChild;
|
||||
this.rect = docElem.firstElementChild
|
||||
this.defs = docElem.getElementsByTagName('defs')[0]
|
||||
this.grad = this.defs.firstElementChild
|
||||
// this.paint = new $.jGraduate.Paint({solidColor: color});
|
||||
this.type = type;
|
||||
this.type = type
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,30 +34,31 @@ class PaintBox {
|
|||
* @returns {void}
|
||||
*/
|
||||
setPaint (paint) {
|
||||
this.paint = paint;
|
||||
this.paint = paint
|
||||
|
||||
const ptype = paint.type;
|
||||
const opac = paint.alpha / 100;
|
||||
const ptype = paint.type
|
||||
const opac = paint.alpha / 100
|
||||
|
||||
let fillAttr = 'none';
|
||||
let fillAttr = 'none'
|
||||
switch (ptype) {
|
||||
case 'solidColor':
|
||||
fillAttr = (paint[ptype] !== 'none') ? '#' + paint[ptype] : paint[ptype];
|
||||
break;
|
||||
case 'linearGradient':
|
||||
case 'radialGradient': {
|
||||
this.grad.remove();
|
||||
this.grad = paint[ptype];
|
||||
this.defs.appendChild(this.grad);
|
||||
const id = this.grad.id = 'gradbox_' + this.type;
|
||||
fillAttr = 'url(#' + id + ')';
|
||||
break;
|
||||
}
|
||||
case 'solidColor':
|
||||
fillAttr = (paint[ptype] !== 'none') ? '#' + paint[ptype] : paint[ptype]
|
||||
break
|
||||
case 'linearGradient':
|
||||
case 'radialGradient': {
|
||||
this.grad.remove()
|
||||
this.grad = paint[ptype]
|
||||
this.defs.appendChild(this.grad)
|
||||
const id = this.grad.id = 'gradbox_' + this.type
|
||||
fillAttr = 'url(#' + id + ')'
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
this.rect.setAttribute('fill', fillAttr);
|
||||
this.rect.setAttribute('opacity', opac);
|
||||
this.rect.setAttribute('fill', fillAttr)
|
||||
this.rect.setAttribute('opacity', opac)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PlainObject} svgCanvas
|
||||
* @param {string} color
|
||||
|
@ -67,20 +68,20 @@ class PaintBox {
|
|||
*/
|
||||
static getPaint (svgCanvas, color, opac, type) {
|
||||
// update the editor's fill paint
|
||||
const opts = { alpha: opac };
|
||||
const opts = { alpha: opac }
|
||||
if (color.startsWith('url(#')) {
|
||||
let refElem = svgCanvas.getRefElem(color);
|
||||
refElem = (refElem) ? refElem.cloneNode(true) : document.querySelectorAll('#' + type + '_color defs *')[0];
|
||||
let refElem = svgCanvas.getRefElem(color)
|
||||
refElem = (refElem) ? refElem.cloneNode(true) : document.querySelectorAll('#' + type + '_color defs *')[0]
|
||||
if (!refElem) {
|
||||
console.error(`the color ${color} is referenced by an url that can't be identified - using 'none'`);
|
||||
opts.solidColor = 'none';
|
||||
console.error(`the color ${color} is referenced by an url that can't be identified - using 'none'`)
|
||||
opts.solidColor = 'none'
|
||||
} else {
|
||||
opts[refElem.tagName] = refElem;
|
||||
opts[refElem.tagName] = refElem
|
||||
}
|
||||
} else if (color.startsWith('#')) {
|
||||
opts.solidColor = color.substr(1);
|
||||
opts.solidColor = color.substr(1)
|
||||
}
|
||||
return new jGraduate.Paint(opts);
|
||||
return new jGraduate.Paint(opts)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,59 +90,59 @@ class PaintBox {
|
|||
* @returns {any}
|
||||
*/
|
||||
update (svgcanvas, selectedElement) {
|
||||
if (!selectedElement) { return null; }
|
||||
if (!selectedElement) { return null }
|
||||
|
||||
const { type } = this;
|
||||
const { type } = this
|
||||
switch (selectedElement.tagName) {
|
||||
case 'use':
|
||||
case 'image':
|
||||
case 'foreignObject':
|
||||
case 'use':
|
||||
case 'image':
|
||||
case 'foreignObject':
|
||||
// These elements don't have fill or stroke, so don't change
|
||||
// the current value
|
||||
return null;
|
||||
case 'g':
|
||||
case 'a': {
|
||||
const childs = selectedElement.getElementsByTagName('*');
|
||||
return null
|
||||
case 'g':
|
||||
case 'a': {
|
||||
const childs = selectedElement.getElementsByTagName('*')
|
||||
|
||||
let gPaint = null;
|
||||
for (let i = 0, len = childs.length; i < len; i++) {
|
||||
const elem = childs[i];
|
||||
const p = elem.getAttribute(type);
|
||||
if (i === 0) {
|
||||
gPaint = p;
|
||||
} else if (gPaint !== p) {
|
||||
gPaint = null;
|
||||
break;
|
||||
let gPaint = null
|
||||
for (let i = 0, len = childs.length; i < len; i++) {
|
||||
const elem = childs[i]
|
||||
const p = elem.getAttribute(type)
|
||||
if (i === 0) {
|
||||
gPaint = p
|
||||
} else if (gPaint !== p) {
|
||||
gPaint = null
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gPaint === null) {
|
||||
if (gPaint === null) {
|
||||
// No common color, don't update anything
|
||||
this._paintColor = null;
|
||||
return null;
|
||||
}
|
||||
this._paintColor = gPaint;
|
||||
this._paintOpacity = 1;
|
||||
break;
|
||||
} default: {
|
||||
this._paintOpacity = Number.parseFloat(selectedElement.getAttribute(type + '-opacity'));
|
||||
if (Number.isNaN(this._paintOpacity)) {
|
||||
this._paintOpacity = 1.0;
|
||||
}
|
||||
this._paintColor = null
|
||||
return null
|
||||
}
|
||||
this._paintColor = gPaint
|
||||
this._paintOpacity = 1
|
||||
break
|
||||
} default: {
|
||||
this._paintOpacity = Number.parseFloat(selectedElement.getAttribute(type + '-opacity'))
|
||||
if (Number.isNaN(this._paintOpacity)) {
|
||||
this._paintOpacity = 1.0
|
||||
}
|
||||
|
||||
const defColor = type === 'fill' ? 'black' : 'none';
|
||||
this._paintColor = selectedElement.getAttribute(type) || defColor;
|
||||
}
|
||||
const defColor = type === 'fill' ? 'black' : 'none'
|
||||
this._paintColor = selectedElement.getAttribute(type) || defColor
|
||||
}
|
||||
}
|
||||
|
||||
this._paintOpacity *= 100;
|
||||
this._paintOpacity *= 100
|
||||
|
||||
const paint = PaintBox.getPaint(svgcanvas, this._paintColor, this._paintOpacity, type);
|
||||
const paint = PaintBox.getPaint(svgcanvas, this._paintColor, this._paintOpacity, type)
|
||||
// update the rect inside #fill_color/#stroke_color
|
||||
this.setPaint(paint);
|
||||
return (paint);
|
||||
this.setPaint(paint)
|
||||
return (paint)
|
||||
}
|
||||
}
|
||||
PaintBox.ctr = 0;
|
||||
PaintBox.ctr = 0
|
||||
|
||||
export default PaintBox;
|
||||
export default PaintBox
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import './seButton.js';
|
||||
import './seFlyingButton.js';
|
||||
import './seExplorerButton.js';
|
||||
import './seZoom.js';
|
||||
import './seInput.js';
|
||||
import './seSpinInput.js';
|
||||
import './sePalette.js';
|
||||
import './seMenu.js';
|
||||
import './seMenuItem.js';
|
||||
import './seList.js';
|
||||
import './seListItem.js';
|
||||
import './seColorPicker.js';
|
||||
import './seSelect.js';
|
||||
import './seText.js';
|
||||
|
||||
import './seButton.js'
|
||||
import './seFlyingButton.js'
|
||||
import './seExplorerButton.js'
|
||||
import './seZoom.js'
|
||||
import './seInput.js'
|
||||
import './seSpinInput.js'
|
||||
import './sePalette.js'
|
||||
import './seMenu.js'
|
||||
import './seMenuItem.js'
|
||||
import './seList.js'
|
||||
import './seListItem.js'
|
||||
import './seColorPicker.js'
|
||||
import './seSelect.js'
|
||||
import './seText.js'
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
* @returns {Float}
|
||||
*/
|
||||
function toFixedNumeric (value, precision) {
|
||||
if (precision === undefined) precision = 0;
|
||||
return Math.round(value * (10 ** precision)) / (10 ** precision);
|
||||
if (precision === undefined) precision = 0
|
||||
return Math.round(value * (10 ** precision)) / (10 ** precision)
|
||||
}
|
||||
/**
|
||||
* Whether a value is `null` or `undefined`.
|
||||
|
@ -17,8 +17,8 @@ function toFixedNumeric (value, precision) {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
const isNullish = (val) => {
|
||||
return val === null || val === undefined;
|
||||
};
|
||||
return val === null || val === undefined
|
||||
}
|
||||
/**
|
||||
* Controls for all the input elements for the typing in color values.
|
||||
*/
|
||||
|
@ -30,8 +30,8 @@ export default class ColorValuePicker {
|
|||
* @param {Float} alphaPrecision
|
||||
*/
|
||||
constructor (picker, color, bindedHex, alphaPrecision) {
|
||||
const that = this; // private properties and methods
|
||||
const inputs = picker.querySelectorAll('td.Text input');
|
||||
const that = this // private properties and methods
|
||||
const inputs = picker.querySelectorAll('td.Text input')
|
||||
// input box key down - use arrows to alter color
|
||||
/**
|
||||
*
|
||||
|
@ -39,95 +39,95 @@ export default class ColorValuePicker {
|
|||
* @returns {Event|false|void}
|
||||
*/
|
||||
function keyDown (e) {
|
||||
if (e.target.value === '' && e.target !== hex && ((!isNullish(bindedHex) && e.target !== bindedHex) || isNullish(bindedHex))) return undefined;
|
||||
if (!validateKey(e)) return e;
|
||||
if (e.target.value === '' && e.target !== hex && ((!isNullish(bindedHex) && e.target !== bindedHex) || isNullish(bindedHex))) return undefined
|
||||
if (!validateKey(e)) return e
|
||||
switch (e.target) {
|
||||
case red:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
red.value = setValueInRange.call(that, (red.value << 0) + 1, 0, 255);
|
||||
color.val('r', red.value, e.target);
|
||||
return false;
|
||||
case 40:
|
||||
red.value = setValueInRange.call(that, (red.value << 0) - 1, 0, 255);
|
||||
color.val('r', red.value, e.target);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case green:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
green.value = setValueInRange.call(that, (green.value << 0) + 1, 0, 255);
|
||||
color.val('g', green.value, e.target);
|
||||
return false;
|
||||
case 40:
|
||||
green.value = setValueInRange.call(that, (green.value << 0) - 1, 0, 255);
|
||||
color.val('g', green.value, e.target);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case blue:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
blue.value = setValueInRange.call(that, (blue.value << 0) + 1, 0, 255);
|
||||
color.val('b', blue.value, e.target);
|
||||
return false;
|
||||
case 40:
|
||||
blue.value = setValueInRange.call(that, (blue.value << 0) - 1, 0, 255);
|
||||
color.val('b', blue.value, e.target);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case alpha:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
alpha.value = setValueInRange.call(that, Number.parseFloat(alpha.value) + 1, 0, 100);
|
||||
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target);
|
||||
return false;
|
||||
case 40:
|
||||
alpha.value = setValueInRange.call(that, Number.parseFloat(alpha.value) - 1, 0, 100);
|
||||
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case hue:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
hue.value = setValueInRange.call(that, (hue.value << 0) + 1, 0, 360);
|
||||
color.val('h', hue.value, e.target);
|
||||
return false;
|
||||
case 40:
|
||||
hue.value =setValueInRange.call(that, (hue.value << 0) - 1, 0, 360);
|
||||
color.val('h', hue.value, e.target);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case saturation:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
saturation.value = setValueInRange.call(that, (saturation.value << 0) + 1, 0, 100);
|
||||
color.val('s', saturation.value, e.target);
|
||||
return false;
|
||||
case 40:
|
||||
saturation.value = setValueInRange.call(that, (saturation.value << 0) - 1, 0, 100);
|
||||
color.val('s', saturation.value, e.target);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case value:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
value.value = setValueInRange.call(that, (value.value << 0) + 1, 0, 100);
|
||||
color.val('v', value.value, e.target);
|
||||
return false;
|
||||
case 40:
|
||||
value.value = setValueInRange.call(that, (value.value << 0) - 1, 0, 100);
|
||||
color.val('v', value.value, e.target);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case red:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
red.value = setValueInRange.call(that, (red.value << 0) + 1, 0, 255)
|
||||
color.val('r', red.value, e.target)
|
||||
return false
|
||||
case 40:
|
||||
red.value = setValueInRange.call(that, (red.value << 0) - 1, 0, 255)
|
||||
color.val('r', red.value, e.target)
|
||||
return false
|
||||
}
|
||||
break
|
||||
case green:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
green.value = setValueInRange.call(that, (green.value << 0) + 1, 0, 255)
|
||||
color.val('g', green.value, e.target)
|
||||
return false
|
||||
case 40:
|
||||
green.value = setValueInRange.call(that, (green.value << 0) - 1, 0, 255)
|
||||
color.val('g', green.value, e.target)
|
||||
return false
|
||||
}
|
||||
break
|
||||
case blue:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
blue.value = setValueInRange.call(that, (blue.value << 0) + 1, 0, 255)
|
||||
color.val('b', blue.value, e.target)
|
||||
return false
|
||||
case 40:
|
||||
blue.value = setValueInRange.call(that, (blue.value << 0) - 1, 0, 255)
|
||||
color.val('b', blue.value, e.target)
|
||||
return false
|
||||
}
|
||||
break
|
||||
case alpha:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
alpha.value = setValueInRange.call(that, Number.parseFloat(alpha.value) + 1, 0, 100)
|
||||
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target)
|
||||
return false
|
||||
case 40:
|
||||
alpha.value = setValueInRange.call(that, Number.parseFloat(alpha.value) - 1, 0, 100)
|
||||
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target)
|
||||
return false
|
||||
}
|
||||
break
|
||||
case hue:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
hue.value = setValueInRange.call(that, (hue.value << 0) + 1, 0, 360)
|
||||
color.val('h', hue.value, e.target)
|
||||
return false
|
||||
case 40:
|
||||
hue.value = setValueInRange.call(that, (hue.value << 0) - 1, 0, 360)
|
||||
color.val('h', hue.value, e.target)
|
||||
return false
|
||||
}
|
||||
break
|
||||
case saturation:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
saturation.value = setValueInRange.call(that, (saturation.value << 0) + 1, 0, 100)
|
||||
color.val('s', saturation.value, e.target)
|
||||
return false
|
||||
case 40:
|
||||
saturation.value = setValueInRange.call(that, (saturation.value << 0) - 1, 0, 100)
|
||||
color.val('s', saturation.value, e.target)
|
||||
return false
|
||||
}
|
||||
break
|
||||
case value:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
value.value = setValueInRange.call(that, (value.value << 0) + 1, 0, 100)
|
||||
color.val('v', value.value, e.target)
|
||||
return false
|
||||
case 40:
|
||||
value.value = setValueInRange.call(that, (value.value << 0) - 1, 0, 100)
|
||||
color.val('v', value.value, e.target)
|
||||
return false
|
||||
}
|
||||
break
|
||||
}
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
// input box key up - validate value and set color
|
||||
/**
|
||||
|
@ -138,53 +138,53 @@ export default class ColorValuePicker {
|
|||
function keyUp (e) {
|
||||
if (e.target.value === '' && e.target !== hex &&
|
||||
((!isNullish(bindedHex) && e.target !== bindedHex) ||
|
||||
isNullish(bindedHex))) return undefined;
|
||||
if (!validateKey(e)) return e;
|
||||
isNullish(bindedHex))) return undefined
|
||||
if (!validateKey(e)) return e
|
||||
switch (e.target) {
|
||||
case red:
|
||||
red.value = setValueInRange.call(that, red.value, 0, 255);
|
||||
color.val('r', red.value, e.target);
|
||||
break;
|
||||
case green:
|
||||
green.value = setValueInRange.call(that, green.value, 0, 255);
|
||||
color.val('g', green.value, e.target);
|
||||
break;
|
||||
case blue:
|
||||
blue.value = setValueInRange.call(that, blue.value, 0, 255);
|
||||
color.val('b', blue.value, e.target);
|
||||
break;
|
||||
case alpha:
|
||||
alpha.value = setValueInRange.call(that, alpha.value, 0, 100);
|
||||
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target);
|
||||
break;
|
||||
case hue:
|
||||
hue.value = setValueInRange.call(that, hue.value, 0, 360);
|
||||
color.val('h', hue.value, e.target);
|
||||
break;
|
||||
case saturation:
|
||||
saturation.value = setValueInRange.call(that, saturation.value, 0, 100);
|
||||
color.val('s', saturation.value, e.target);
|
||||
break;
|
||||
case value:
|
||||
value.value = setValueInRange.call(that, value.value, 0, 100);
|
||||
color.val('v', value.value, e.target);
|
||||
break;
|
||||
case hex:
|
||||
hex.value = hex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 6);
|
||||
bindedHex && bindedHex.val(hex.value);
|
||||
color.val('hex', hex.value !== '' ? hex.value : null, e.target);
|
||||
break;
|
||||
case bindedHex:
|
||||
bindedHex.value = bindedHex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 6);
|
||||
hex.val(bindedHex.value);
|
||||
color.val('hex', bindedHex.value !== '' ? bindedHex.value : null, e.target);
|
||||
break;
|
||||
case ahex:
|
||||
ahex.value = ahex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 2);
|
||||
color.val('a', !isNullish(ahex.value) ? Number.parseInt(ahex.value, 16) : null, e.target);
|
||||
break;
|
||||
case red:
|
||||
red.value = setValueInRange.call(that, red.value, 0, 255)
|
||||
color.val('r', red.value, e.target)
|
||||
break
|
||||
case green:
|
||||
green.value = setValueInRange.call(that, green.value, 0, 255)
|
||||
color.val('g', green.value, e.target)
|
||||
break
|
||||
case blue:
|
||||
blue.value = setValueInRange.call(that, blue.value, 0, 255)
|
||||
color.val('b', blue.value, e.target)
|
||||
break
|
||||
case alpha:
|
||||
alpha.value = setValueInRange.call(that, alpha.value, 0, 100)
|
||||
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target)
|
||||
break
|
||||
case hue:
|
||||
hue.value = setValueInRange.call(that, hue.value, 0, 360)
|
||||
color.val('h', hue.value, e.target)
|
||||
break
|
||||
case saturation:
|
||||
saturation.value = setValueInRange.call(that, saturation.value, 0, 100)
|
||||
color.val('s', saturation.value, e.target)
|
||||
break
|
||||
case value:
|
||||
value.value = setValueInRange.call(that, value.value, 0, 100)
|
||||
color.val('v', value.value, e.target)
|
||||
break
|
||||
case hex:
|
||||
hex.value = hex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 6)
|
||||
bindedHex && bindedHex.val(hex.value)
|
||||
color.val('hex', hex.value !== '' ? hex.value : null, e.target)
|
||||
break
|
||||
case bindedHex:
|
||||
bindedHex.value = bindedHex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 6)
|
||||
hex.val(bindedHex.value)
|
||||
color.val('hex', bindedHex.value !== '' ? bindedHex.value : null, e.target)
|
||||
break
|
||||
case ahex:
|
||||
ahex.value = ahex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 2)
|
||||
color.val('a', !isNullish(ahex.value) ? Number.parseInt(ahex.value, 16) : null, e.target)
|
||||
break
|
||||
}
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
// input box blur - reset to original if value empty
|
||||
/**
|
||||
|
@ -194,44 +194,44 @@ export default class ColorValuePicker {
|
|||
function blur (e) {
|
||||
if (!isNullish(color.value)) {
|
||||
switch (e.target) {
|
||||
case red:
|
||||
color.value = 'r';
|
||||
red.value = color.value;
|
||||
break;
|
||||
case green:
|
||||
color.value = 'g';
|
||||
green.value = color.value;
|
||||
break;
|
||||
case blue:
|
||||
color.value = 'b';
|
||||
blue.value = color.value;
|
||||
break;
|
||||
case alpha:
|
||||
color.value = 'a';
|
||||
alpha.value = toFixedNumeric((color.value * 100) / 255, alphaPrecision);
|
||||
break;
|
||||
case hue:
|
||||
color.value = 'h';
|
||||
hue.value = color.value;
|
||||
break;
|
||||
case saturation:
|
||||
color.value = 's';
|
||||
saturation.value = color.value;
|
||||
break;
|
||||
case value:
|
||||
color.value = 'v';
|
||||
value.value = color.value;
|
||||
break;
|
||||
case hex:
|
||||
case bindedHex:
|
||||
color.value = 'hex';
|
||||
hex.value = color.value;
|
||||
bindedHex.value = color.value;
|
||||
break;
|
||||
case ahex:
|
||||
color.value = 'ahex';
|
||||
ahex.value = color.value.substring(6);
|
||||
break;
|
||||
case red:
|
||||
color.value = 'r'
|
||||
red.value = color.value
|
||||
break
|
||||
case green:
|
||||
color.value = 'g'
|
||||
green.value = color.value
|
||||
break
|
||||
case blue:
|
||||
color.value = 'b'
|
||||
blue.value = color.value
|
||||
break
|
||||
case alpha:
|
||||
color.value = 'a'
|
||||
alpha.value = toFixedNumeric((color.value * 100) / 255, alphaPrecision)
|
||||
break
|
||||
case hue:
|
||||
color.value = 'h'
|
||||
hue.value = color.value
|
||||
break
|
||||
case saturation:
|
||||
color.value = 's'
|
||||
saturation.value = color.value
|
||||
break
|
||||
case value:
|
||||
color.value = 'v'
|
||||
value.value = color.value
|
||||
break
|
||||
case hex:
|
||||
case bindedHex:
|
||||
color.value = 'hex'
|
||||
hex.value = color.value
|
||||
bindedHex.value = color.value
|
||||
break
|
||||
case ahex:
|
||||
color.value = 'ahex'
|
||||
ahex.value = color.value.substring(6)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -241,17 +241,17 @@ export default class ColorValuePicker {
|
|||
*/
|
||||
function validateKey (e) {
|
||||
switch (e.keyCode) {
|
||||
case 9:
|
||||
case 16:
|
||||
case 29:
|
||||
case 37:
|
||||
case 39:
|
||||
return false;
|
||||
case 'c'.charCodeAt():
|
||||
case 'v'.charCodeAt():
|
||||
if (e.ctrlKey) return false;
|
||||
case 9:
|
||||
case 16:
|
||||
case 29:
|
||||
case 37:
|
||||
case 39:
|
||||
return false
|
||||
case 'c'.charCodeAt():
|
||||
case 'v'.charCodeAt():
|
||||
if (e.ctrlKey) return false
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -262,10 +262,10 @@ export default class ColorValuePicker {
|
|||
* @returns {Float|string} Returns a number or numeric string
|
||||
*/
|
||||
function setValueInRange (value, min, max) {
|
||||
if (value === '' || isNaN(value)) return min;
|
||||
if (value > max) return max;
|
||||
if (value < min) return min;
|
||||
return value;
|
||||
if (value === '' || isNaN(value)) return min
|
||||
if (value > max) return max
|
||||
if (value < min) return min
|
||||
return value
|
||||
}
|
||||
/**
|
||||
* @param {external:jQuery} ui
|
||||
|
@ -273,117 +273,117 @@ export default class ColorValuePicker {
|
|||
* @returns {void}
|
||||
*/
|
||||
function colorChanged (ui, context) {
|
||||
const all = ui.val('all');
|
||||
if (context !== red) red.value = (!isNullish(all) ? all.r : '');
|
||||
if (context !== green) green.value = (!isNullish(all) ? all.g : '');
|
||||
if (context !== blue) blue.value = (!isNullish(all) ? all.b : '');
|
||||
if (alpha && context !== alpha) alpha.value = (!isNullish(all) ? toFixedNumeric((all.a * 100) / 255, alphaPrecision) : '');
|
||||
if (context !== hue) hue.value = (!isNullish(all) ? all.h : '');
|
||||
if (context !== saturation) saturation.value = (!isNullish(all) ? all.s : '');
|
||||
if (context !== value) value.value = (!isNullish(all) ? all.v : '');
|
||||
if (context !== hex && ((bindedHex && context !== bindedHex) || !bindedHex)) hex.value = (!isNullish(all) ? all.hex : '');
|
||||
if (bindedHex && context !== bindedHex && context !== hex) bindedHex.value = (!isNullish(all) ? all.hex : '');
|
||||
if (ahex && context !== ahex) ahex.value = (!isNullish(all) ? all.ahex.substring(6) : '');
|
||||
const all = ui.val('all')
|
||||
if (context !== red) red.value = (!isNullish(all) ? all.r : '')
|
||||
if (context !== green) green.value = (!isNullish(all) ? all.g : '')
|
||||
if (context !== blue) blue.value = (!isNullish(all) ? all.b : '')
|
||||
if (alpha && context !== alpha) alpha.value = (!isNullish(all) ? toFixedNumeric((all.a * 100) / 255, alphaPrecision) : '')
|
||||
if (context !== hue) hue.value = (!isNullish(all) ? all.h : '')
|
||||
if (context !== saturation) saturation.value = (!isNullish(all) ? all.s : '')
|
||||
if (context !== value) value.value = (!isNullish(all) ? all.v : '')
|
||||
if (context !== hex && ((bindedHex && context !== bindedHex) || !bindedHex)) hex.value = (!isNullish(all) ? all.hex : '')
|
||||
if (bindedHex && context !== bindedHex && context !== hex) bindedHex.value = (!isNullish(all) ? all.hex : '')
|
||||
if (ahex && context !== ahex) ahex.value = (!isNullish(all) ? all.ahex.substring(6) : '')
|
||||
}
|
||||
/**
|
||||
* Unbind all events and null objects.
|
||||
* @returns {void}
|
||||
*/
|
||||
function destroy () {
|
||||
red.removeEventListener('keyup', keyUp);
|
||||
green.removeEventListener('keyup', keyUp);
|
||||
blue.removeEventListener('keyup', keyUp);
|
||||
hue.removeEventListener('keyup', keyUp);
|
||||
saturation.removeEventListener('keyup', keyUp);
|
||||
value.removeEventListener('keyup', keyUp);
|
||||
hex.removeEventListener('keyup', keyUp);
|
||||
red.removeEventListener('keyup', keyUp)
|
||||
green.removeEventListener('keyup', keyUp)
|
||||
blue.removeEventListener('keyup', keyUp)
|
||||
hue.removeEventListener('keyup', keyUp)
|
||||
saturation.removeEventListener('keyup', keyUp)
|
||||
value.removeEventListener('keyup', keyUp)
|
||||
hex.removeEventListener('keyup', keyUp)
|
||||
|
||||
red.removeEventListener('blur', blur);
|
||||
green.removeEventListener('blur', blur);
|
||||
blue.removeEventListener('blur', blur);
|
||||
hue.removeEventListener('blur', blur);
|
||||
saturation.removeEventListener('blur', blur);
|
||||
value.removeEventListener('blur', blur);
|
||||
hex.removeEventListener('blur', blur);
|
||||
red.removeEventListener('blur', blur)
|
||||
green.removeEventListener('blur', blur)
|
||||
blue.removeEventListener('blur', blur)
|
||||
hue.removeEventListener('blur', blur)
|
||||
saturation.removeEventListener('blur', blur)
|
||||
value.removeEventListener('blur', blur)
|
||||
hex.removeEventListener('blur', blur)
|
||||
|
||||
red.removeEventListener('keydown', keyDown);
|
||||
green.removeEventListener('keydown', keyDown);
|
||||
blue.removeEventListener('keydown', keyDown);
|
||||
hue.removeEventListener('keydown', keyDown);
|
||||
saturation.removeEventListener('keydown', keyDown);
|
||||
value.removeEventListener('keydown', keyDown);
|
||||
red.removeEventListener('keydown', keyDown)
|
||||
green.removeEventListener('keydown', keyDown)
|
||||
blue.removeEventListener('keydown', keyDown)
|
||||
hue.removeEventListener('keydown', keyDown)
|
||||
saturation.removeEventListener('keydown', keyDown)
|
||||
value.removeEventListener('keydown', keyDown)
|
||||
|
||||
if (alpha !== null) {
|
||||
alpha.removeEventListener('keyup', keyUp);
|
||||
alpha.removeEventListener('blur', blur);
|
||||
alpha.removeEventListener('keydown', keyDown);
|
||||
alpha.removeEventListener('keyup', keyUp)
|
||||
alpha.removeEventListener('blur', blur)
|
||||
alpha.removeEventListener('keydown', keyDown)
|
||||
}
|
||||
if (ahex !== null) {
|
||||
ahex.removeEventListener('keyup', keyUp);
|
||||
ahex.removeEventListener('blur', blur);
|
||||
ahex.removeEventListener('keyup', keyUp)
|
||||
ahex.removeEventListener('blur', blur)
|
||||
}
|
||||
if (bindedHex !== null) {
|
||||
bindedHex.removeEventListener('keyup', keyUp);
|
||||
bindedHex.removeEventListener('blur', blur);
|
||||
bindedHex.removeEventListener('keyup', keyUp)
|
||||
bindedHex.removeEventListener('blur', blur)
|
||||
}
|
||||
color.unbind(colorChanged);
|
||||
red = null;
|
||||
green = null;
|
||||
blue = null;
|
||||
alpha = null;
|
||||
hue = null;
|
||||
saturation = null;
|
||||
value = null;
|
||||
hex = null;
|
||||
ahex = null;
|
||||
color.unbind(colorChanged)
|
||||
red = null
|
||||
green = null
|
||||
blue = null
|
||||
alpha = null
|
||||
hue = null
|
||||
saturation = null
|
||||
value = null
|
||||
hex = null
|
||||
ahex = null
|
||||
}
|
||||
let
|
||||
red = inputs[3];
|
||||
let green = inputs[4];
|
||||
let blue = inputs[5];
|
||||
let alpha = inputs.length > 7 ? inputs[6] : null;
|
||||
let hue = inputs[0];
|
||||
let saturation = inputs[1];
|
||||
let value = inputs[2];
|
||||
let hex = inputs[(inputs.length > 7) ? 7 : 6];
|
||||
let ahex = inputs.length > 7 ? inputs[8] : null;
|
||||
Object.assign(that, { destroy });
|
||||
red.addEventListener('keyup', keyUp);
|
||||
green.addEventListener('keyup', keyUp);
|
||||
blue.addEventListener('keyup', keyUp);
|
||||
hue.addEventListener('keyup', keyUp);
|
||||
saturation.addEventListener('keyup', keyUp);
|
||||
value.addEventListener('keyup', keyUp);
|
||||
hex.addEventListener('keyup', keyUp);
|
||||
red = inputs[3]
|
||||
let green = inputs[4]
|
||||
let blue = inputs[5]
|
||||
let alpha = inputs.length > 7 ? inputs[6] : null
|
||||
let hue = inputs[0]
|
||||
let saturation = inputs[1]
|
||||
let value = inputs[2]
|
||||
let hex = inputs[(inputs.length > 7) ? 7 : 6]
|
||||
let ahex = inputs.length > 7 ? inputs[8] : null
|
||||
Object.assign(that, { destroy })
|
||||
red.addEventListener('keyup', keyUp)
|
||||
green.addEventListener('keyup', keyUp)
|
||||
blue.addEventListener('keyup', keyUp)
|
||||
hue.addEventListener('keyup', keyUp)
|
||||
saturation.addEventListener('keyup', keyUp)
|
||||
value.addEventListener('keyup', keyUp)
|
||||
hex.addEventListener('keyup', keyUp)
|
||||
|
||||
red.addEventListener('blur', blur);
|
||||
green.addEventListener('blur', blur);
|
||||
blue.addEventListener('blur', blur);
|
||||
hue.addEventListener('blur', blur);
|
||||
saturation.addEventListener('blur', blur);
|
||||
value.addEventListener('blur', blur);
|
||||
hex.addEventListener('blur', blur);
|
||||
red.addEventListener('blur', blur)
|
||||
green.addEventListener('blur', blur)
|
||||
blue.addEventListener('blur', blur)
|
||||
hue.addEventListener('blur', blur)
|
||||
saturation.addEventListener('blur', blur)
|
||||
value.addEventListener('blur', blur)
|
||||
hex.addEventListener('blur', blur)
|
||||
|
||||
red.addEventListener('keydown', keyDown);
|
||||
green.addEventListener('keydown', keyDown);
|
||||
blue.addEventListener('keydown', keyDown);
|
||||
hue.addEventListener('keydown', keyDown);
|
||||
saturation.addEventListener('keydown', keyDown);
|
||||
value.addEventListener('keydown', keyDown);
|
||||
red.addEventListener('keydown', keyDown)
|
||||
green.addEventListener('keydown', keyDown)
|
||||
blue.addEventListener('keydown', keyDown)
|
||||
hue.addEventListener('keydown', keyDown)
|
||||
saturation.addEventListener('keydown', keyDown)
|
||||
value.addEventListener('keydown', keyDown)
|
||||
|
||||
if (alpha !== null) {
|
||||
alpha.addEventListener('keyup', keyUp);
|
||||
alpha.addEventListener('blur', blur);
|
||||
alpha.addEventListener('keydown', keyDown);
|
||||
alpha.addEventListener('keyup', keyUp)
|
||||
alpha.addEventListener('blur', blur)
|
||||
alpha.addEventListener('keydown', keyDown)
|
||||
}
|
||||
if (ahex !== null) {
|
||||
ahex.addEventListener('keyup', keyUp);
|
||||
ahex.addEventListener('blur', blur);
|
||||
ahex.addEventListener('keyup', keyUp)
|
||||
ahex.addEventListener('blur', blur)
|
||||
}
|
||||
if (bindedHex !== null) {
|
||||
bindedHex.addEventListener('keyup', keyUp);
|
||||
bindedHex.addEventListener('blur', blur);
|
||||
bindedHex.addEventListener('keyup', keyUp)
|
||||
bindedHex.addEventListener('blur', blur)
|
||||
}
|
||||
color.bind(colorChanged);
|
||||
color.bind(colorChanged)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { findPos } from './Util.js';
|
||||
import { findPos } from './Util.js'
|
||||
/**
|
||||
* Whether a value is `null` or `undefined`.
|
||||
* @param {any} val
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isNullish = (val) => {
|
||||
return val === null || val === undefined;
|
||||
};
|
||||
return val === null || val === undefined
|
||||
}
|
||||
/**
|
||||
* Encapsulate slider functionality for the ColorMap and ColorBar -
|
||||
* could be useful to use a jQuery UI draggable for this with certain extensions.
|
||||
|
@ -18,7 +18,7 @@ export default class Slider {
|
|||
* @param {module:jPicker.SliderOptions} options
|
||||
*/
|
||||
constructor (bar, options) {
|
||||
const that = this;
|
||||
const that = this
|
||||
/**
|
||||
* Fire events on the supplied `context`
|
||||
* @param {module:jPicker.JPickerInit} context
|
||||
|
@ -26,8 +26,8 @@ export default class Slider {
|
|||
*/
|
||||
function fireChangeEvents (context) {
|
||||
changeEvents.forEach((changeEvent) => {
|
||||
changeEvent.call(that, that, context);
|
||||
});
|
||||
changeEvent.call(that, that, context)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,17 +36,17 @@ export default class Slider {
|
|||
* @returns {void}
|
||||
*/
|
||||
function mouseDown (e) {
|
||||
const off = findPos(bar);
|
||||
offset = { l: off.left | 0, t: off.top | 0 };
|
||||
clearTimeout(timeout);
|
||||
const off = findPos(bar)
|
||||
offset = { l: off.left | 0, t: off.top | 0 }
|
||||
clearTimeout(timeout)
|
||||
// using setTimeout for visual updates - once the style is updated the browser will re-render internally allowing the next Javascript to run
|
||||
timeout = setTimeout(function () {
|
||||
setValuesFromMousePosition.call(that, e);
|
||||
}, 0);
|
||||
setValuesFromMousePosition.call(that, e)
|
||||
}, 0)
|
||||
// Bind mousemove and mouseup event to the document so it responds when dragged of of the bar - we will unbind these when on mouseup to save processing
|
||||
document.addEventListener('mousemove', mouseMove);
|
||||
document.addEventListener('mouseup', mouseUp);
|
||||
e.preventDefault(); // don't try to select anything or drag the image to the desktop
|
||||
document.addEventListener('mousemove', mouseMove)
|
||||
document.addEventListener('mouseup', mouseUp)
|
||||
e.preventDefault() // don't try to select anything or drag the image to the desktop
|
||||
}
|
||||
/**
|
||||
* Set the values as the mouse moves.
|
||||
|
@ -54,13 +54,13 @@ export default class Slider {
|
|||
* @returns {false}
|
||||
*/
|
||||
function mouseMove (e) {
|
||||
clearTimeout(timeout);
|
||||
clearTimeout(timeout)
|
||||
timeout = setTimeout(function () {
|
||||
setValuesFromMousePosition.call(that, e);
|
||||
}, 0);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
setValuesFromMousePosition.call(that, e)
|
||||
}, 0)
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
return false
|
||||
}
|
||||
/**
|
||||
* Unbind the document events - they aren't needed when not dragging.
|
||||
|
@ -68,11 +68,11 @@ export default class Slider {
|
|||
* @returns {false}
|
||||
*/
|
||||
function mouseUp (e) {
|
||||
document.removeEventListener('mousemove', mouseMove);
|
||||
document.removeEventListener('mouseup', mouseUp);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
document.removeEventListener('mousemove', mouseMove)
|
||||
document.removeEventListener('mouseup', mouseUp)
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,19 +81,19 @@ export default class Slider {
|
|||
* @returns {void}
|
||||
*/
|
||||
function setValuesFromMousePosition (e) {
|
||||
const barW = bar.w; // local copies for YUI compressor
|
||||
const barH = bar.h;
|
||||
let locX = e.pageX - offset.l;
|
||||
let locY = e.pageY - offset.t;
|
||||
const barW = bar.w // local copies for YUI compressor
|
||||
const barH = bar.h
|
||||
let locX = e.pageX - offset.l
|
||||
let locY = e.pageY - offset.t
|
||||
// keep the arrow within the bounds of the bar
|
||||
if (locX < 0) locX = 0;
|
||||
else if (locX > barW) locX = barW;
|
||||
if (locY < 0) locY = 0;
|
||||
else if (locY > barH) locY = barH;
|
||||
if (locX < 0) locX = 0
|
||||
else if (locX > barW) locX = barW
|
||||
if (locY < 0) locY = 0
|
||||
else if (locY > barH) locY = barH
|
||||
val.call(that, 'xy', {
|
||||
x: ((locX / barW) * rangeX) + minX,
|
||||
y: ((locY / barH) * rangeY) + minY
|
||||
});
|
||||
})
|
||||
}
|
||||
/**
|
||||
*
|
||||
|
@ -101,33 +101,33 @@ export default class Slider {
|
|||
*/
|
||||
function draw () {
|
||||
const
|
||||
barW = bar.w;
|
||||
const barH = bar.h;
|
||||
const arrowW = arrow.w;
|
||||
const arrowH = arrow.h;
|
||||
let arrowOffsetX = 0;
|
||||
let arrowOffsetY = 0;
|
||||
barW = bar.w
|
||||
const barH = bar.h
|
||||
const arrowW = arrow.w
|
||||
const arrowH = arrow.h
|
||||
let arrowOffsetX = 0
|
||||
let arrowOffsetY = 0
|
||||
setTimeout(function () {
|
||||
if (rangeX > 0) { // range is greater than zero
|
||||
// constrain to bounds
|
||||
if (x === maxX) arrowOffsetX = barW;
|
||||
else arrowOffsetX = ((x / rangeX) * barW) | 0;
|
||||
if (x === maxX) arrowOffsetX = barW
|
||||
else arrowOffsetX = ((x / rangeX) * barW) | 0
|
||||
}
|
||||
if (rangeY > 0) { // range is greater than zero
|
||||
// constrain to bounds
|
||||
if (y === maxY) arrowOffsetY = barH;
|
||||
else arrowOffsetY = ((y / rangeY) * barH) | 0;
|
||||
if (y === maxY) arrowOffsetY = barH
|
||||
else arrowOffsetY = ((y / rangeY) * barH) | 0
|
||||
}
|
||||
// if arrow width is greater than bar width, center arrow and prevent horizontal dragging
|
||||
if (arrowW >= barW) arrowOffsetX = (barW >> 1) - (arrowW >> 1); // number >> 1 - superfast bitwise divide by two and truncate (move bits over one bit discarding lowest)
|
||||
else arrowOffsetX -= arrowW >> 1;
|
||||
if (arrowW >= barW) arrowOffsetX = (barW >> 1) - (arrowW >> 1) // number >> 1 - superfast bitwise divide by two and truncate (move bits over one bit discarding lowest)
|
||||
else arrowOffsetX -= arrowW >> 1
|
||||
// if arrow height is greater than bar height, center arrow and prevent vertical dragging
|
||||
if (arrowH >= barH) arrowOffsetY = (barH >> 1) - (arrowH >> 1);
|
||||
else arrowOffsetY -= arrowH >> 1;
|
||||
if (arrowH >= barH) arrowOffsetY = (barH >> 1) - (arrowH >> 1)
|
||||
else arrowOffsetY -= arrowH >> 1
|
||||
// set the arrow position based on these offsets
|
||||
arrow.style.left = arrowOffsetX + 'px';
|
||||
arrow.style.top = arrowOffsetY + 'px';
|
||||
});
|
||||
arrow.style.left = arrowOffsetX + 'px'
|
||||
arrow.style.top = arrowOffsetY + 'px'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,52 +138,52 @@ export default class Slider {
|
|||
* @returns {module:math.XYObject|Float|void}
|
||||
*/
|
||||
function val (name, value, context) {
|
||||
const set = value !== undefined;
|
||||
const set = value !== undefined
|
||||
if (!set) {
|
||||
if (isNullish(name)) name = 'xy';
|
||||
if (isNullish(name)) name = 'xy'
|
||||
switch (name.toLowerCase()) {
|
||||
case 'x': return x;
|
||||
case 'y': return y;
|
||||
case 'xy':
|
||||
default: return { x, y };
|
||||
case 'x': return x
|
||||
case 'y': return y
|
||||
case 'xy':
|
||||
default: return { x, y }
|
||||
}
|
||||
}
|
||||
if (!isNullish(context) && context === that) return undefined;
|
||||
let changed = false;
|
||||
if (!isNullish(context) && context === that) return undefined
|
||||
let changed = false
|
||||
|
||||
let newX; let newY;
|
||||
if (isNullish(name)) name = 'xy';
|
||||
let newX; let newY
|
||||
if (isNullish(name)) name = 'xy'
|
||||
switch (name.toLowerCase()) {
|
||||
case 'x':
|
||||
newX = (value && ((value.x && value.x | 0) || value | 0)) || 0;
|
||||
break;
|
||||
case 'y':
|
||||
newY = (value && ((value.y && value.y | 0) || value | 0)) || 0;
|
||||
break;
|
||||
case 'xy':
|
||||
default:
|
||||
newX = (value && value.x && value.x | 0) || 0;
|
||||
newY = (value && value.y && value.y | 0) || 0;
|
||||
break;
|
||||
case 'x':
|
||||
newX = (value && ((value.x && value.x | 0) || value | 0)) || 0
|
||||
break
|
||||
case 'y':
|
||||
newY = (value && ((value.y && value.y | 0) || value | 0)) || 0
|
||||
break
|
||||
case 'xy':
|
||||
default:
|
||||
newX = (value && value.x && value.x | 0) || 0
|
||||
newY = (value && value.y && value.y | 0) || 0
|
||||
break
|
||||
}
|
||||
if (!isNullish(newX)) {
|
||||
if (newX < minX) newX = minX;
|
||||
else if (newX > maxX) newX = maxX;
|
||||
if (newX < minX) newX = minX
|
||||
else if (newX > maxX) newX = maxX
|
||||
if (x !== newX) {
|
||||
x = newX;
|
||||
changed = true;
|
||||
x = newX
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
if (!isNullish(newY)) {
|
||||
if (newY < minY) newY = minY;
|
||||
else if (newY > maxY) newY = maxY;
|
||||
if (newY < minY) newY = minY
|
||||
else if (newY > maxY) newY = maxY
|
||||
if (y !== newY) {
|
||||
y = newY;
|
||||
changed = true;
|
||||
y = newY
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
changed && fireChangeEvents.call(that, context || that);
|
||||
return undefined;
|
||||
changed && fireChangeEvents.call(that, context || that)
|
||||
return undefined
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -209,89 +209,89 @@ export default class Slider {
|
|||
* @returns {module:jPicker.MinMaxRangeXY|module:jPicker.MinMaxRangeX|module:jPicker.MinMaxRangeY|void}
|
||||
*/
|
||||
function range (name, value) {
|
||||
const set = value !== undefined;
|
||||
const set = value !== undefined
|
||||
if (!set) {
|
||||
if (isNullish(name)) name = 'all';
|
||||
if (isNullish(name)) name = 'all'
|
||||
switch (name.toLowerCase()) {
|
||||
case 'minx': return minX;
|
||||
case 'maxx': return maxX;
|
||||
case 'rangex': return { minX, maxX, rangeX };
|
||||
case 'miny': return minY;
|
||||
case 'maxy': return maxY;
|
||||
case 'rangey': return { minY, maxY, rangeY };
|
||||
case 'all':
|
||||
default: return { minX, maxX, rangeX, minY, maxY, rangeY };
|
||||
case 'minx': return minX
|
||||
case 'maxx': return maxX
|
||||
case 'rangex': return { minX, maxX, rangeX }
|
||||
case 'miny': return minY
|
||||
case 'maxy': return maxY
|
||||
case 'rangey': return { minY, maxY, rangeY }
|
||||
case 'all':
|
||||
default: return { minX, maxX, rangeX, minY, maxY, rangeY }
|
||||
}
|
||||
}
|
||||
let // changed = false,
|
||||
newMinX;
|
||||
let newMaxX;
|
||||
let newMinY;
|
||||
let newMaxY;
|
||||
if (isNullish(name)) name = 'all';
|
||||
newMinX
|
||||
let newMaxX
|
||||
let newMinY
|
||||
let newMaxY
|
||||
if (isNullish(name)) name = 'all'
|
||||
switch (name.toLowerCase()) {
|
||||
case 'minx':
|
||||
newMinX = (value && ((value.minX && value.minX | 0) || value | 0)) || 0;
|
||||
break;
|
||||
case 'maxx':
|
||||
newMaxX = (value && ((value.maxX && value.maxX | 0) || value | 0)) || 0;
|
||||
break;
|
||||
case 'rangex':
|
||||
newMinX = (value && value.minX && value.minX | 0) || 0;
|
||||
newMaxX = (value && value.maxX && value.maxX | 0) || 0;
|
||||
break;
|
||||
case 'miny':
|
||||
newMinY = (value && ((value.minY && value.minY | 0) || value | 0)) || 0;
|
||||
break;
|
||||
case 'maxy':
|
||||
newMaxY = (value && ((value.maxY && value.maxY | 0) || value | 0)) || 0;
|
||||
break;
|
||||
case 'rangey':
|
||||
newMinY = (value && value.minY && value.minY | 0) || 0;
|
||||
newMaxY = (value && value.maxY && value.maxY | 0) || 0;
|
||||
break;
|
||||
case 'all':
|
||||
default:
|
||||
newMinX = (value && value.minX && value.minX | 0) || 0;
|
||||
newMaxX = (value && value.maxX && value.maxX | 0) || 0;
|
||||
newMinY = (value && value.minY && value.minY | 0) || 0;
|
||||
newMaxY = (value && value.maxY && value.maxY | 0) || 0;
|
||||
break;
|
||||
case 'minx':
|
||||
newMinX = (value && ((value.minX && value.minX | 0) || value | 0)) || 0
|
||||
break
|
||||
case 'maxx':
|
||||
newMaxX = (value && ((value.maxX && value.maxX | 0) || value | 0)) || 0
|
||||
break
|
||||
case 'rangex':
|
||||
newMinX = (value && value.minX && value.minX | 0) || 0
|
||||
newMaxX = (value && value.maxX && value.maxX | 0) || 0
|
||||
break
|
||||
case 'miny':
|
||||
newMinY = (value && ((value.minY && value.minY | 0) || value | 0)) || 0
|
||||
break
|
||||
case 'maxy':
|
||||
newMaxY = (value && ((value.maxY && value.maxY | 0) || value | 0)) || 0
|
||||
break
|
||||
case 'rangey':
|
||||
newMinY = (value && value.minY && value.minY | 0) || 0
|
||||
newMaxY = (value && value.maxY && value.maxY | 0) || 0
|
||||
break
|
||||
case 'all':
|
||||
default:
|
||||
newMinX = (value && value.minX && value.minX | 0) || 0
|
||||
newMaxX = (value && value.maxX && value.maxX | 0) || 0
|
||||
newMinY = (value && value.minY && value.minY | 0) || 0
|
||||
newMaxY = (value && value.maxY && value.maxY | 0) || 0
|
||||
break
|
||||
}
|
||||
|
||||
if (!isNullish(newMinX) && minX !== newMinX) {
|
||||
minX = newMinX;
|
||||
rangeX = maxX - minX;
|
||||
minX = newMinX
|
||||
rangeX = maxX - minX
|
||||
}
|
||||
if (!isNullish(newMaxX) && maxX !== newMaxX) {
|
||||
maxX = newMaxX;
|
||||
rangeX = maxX - minX;
|
||||
maxX = newMaxX
|
||||
rangeX = maxX - minX
|
||||
}
|
||||
if (!isNullish(newMinY) && minY !== newMinY) {
|
||||
minY = newMinY;
|
||||
rangeY = maxY - minY;
|
||||
minY = newMinY
|
||||
rangeY = maxY - minY
|
||||
}
|
||||
if (!isNullish(newMaxY) && maxY !== newMaxY) {
|
||||
maxY = newMaxY;
|
||||
rangeY = maxY - minY;
|
||||
maxY = newMaxY
|
||||
rangeY = maxY - minY
|
||||
}
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
/**
|
||||
* @param {GenericCallback} callback
|
||||
* @returns {void}
|
||||
*/
|
||||
function bind (callback) {
|
||||
if (typeof callback === 'function') changeEvents.push(callback);
|
||||
if (typeof callback === 'function') changeEvents.push(callback)
|
||||
}
|
||||
/**
|
||||
* @param {GenericCallback} callback
|
||||
* @returns {void}
|
||||
*/
|
||||
function unbind (callback) {
|
||||
if (typeof callback !== 'function') return;
|
||||
let i;
|
||||
while ((i = changeEvents.includes(callback))) changeEvents.splice(i, 1);
|
||||
if (typeof callback !== 'function') return
|
||||
let i
|
||||
while ((i = changeEvents.includes(callback))) changeEvents.splice(i, 1)
|
||||
}
|
||||
/**
|
||||
*
|
||||
|
@ -299,39 +299,39 @@ export default class Slider {
|
|||
*/
|
||||
function destroy () {
|
||||
// unbind all possible events and null objects
|
||||
document.removeEventListener('mousemove', mouseMove);
|
||||
document.removeEventListener('mouseup', mouseUp);
|
||||
bar.removeEventListener('mousedown', mouseDown);
|
||||
bar = null;
|
||||
arrow = null;
|
||||
changeEvents = null;
|
||||
document.removeEventListener('mousemove', mouseMove)
|
||||
document.removeEventListener('mouseup', mouseUp)
|
||||
bar.removeEventListener('mousedown', mouseDown)
|
||||
bar = null
|
||||
arrow = null
|
||||
changeEvents = null
|
||||
}
|
||||
let offset;
|
||||
let timeout;
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
let minX = 0;
|
||||
let maxX = 100;
|
||||
let rangeX = 100;
|
||||
let minY = 0;
|
||||
let maxY = 100;
|
||||
let rangeY = 100;
|
||||
let arrow = bar.querySelector('img'); // the arrow image to drag
|
||||
let changeEvents = [];
|
||||
let offset
|
||||
let timeout
|
||||
let x = 0
|
||||
let y = 0
|
||||
let minX = 0
|
||||
let maxX = 100
|
||||
let rangeX = 100
|
||||
let minY = 0
|
||||
let maxY = 100
|
||||
let rangeY = 100
|
||||
let arrow = bar.querySelector('img') // the arrow image to drag
|
||||
let changeEvents = []
|
||||
Object.assign(that, {
|
||||
val,
|
||||
range,
|
||||
bind,
|
||||
unbind,
|
||||
destroy
|
||||
});
|
||||
})
|
||||
// initialize this control
|
||||
arrow.src = options.arrow && options.arrow.image;
|
||||
arrow.w = (options.arrow && options.arrow.width) || parseFloat(getComputedStyle(arrow, null).width.replace("px", ""));
|
||||
arrow.h = (options.arrow && options.arrow.height) || parseFloat(getComputedStyle(arrow, null).height.replace("px", ""));
|
||||
bar.w = (options.map && options.map.width) || parseFloat(getComputedStyle(bar, null).width.replace("px", ""));
|
||||
bar.h = (options.map && options.map.height) || parseFloat(getComputedStyle(bar, null).height.replace("px", ""));
|
||||
bar.addEventListener('mousedown', mouseDown);
|
||||
bind.call(that, draw);
|
||||
arrow.src = options.arrow && options.arrow.image
|
||||
arrow.w = (options.arrow && options.arrow.width) || parseFloat(getComputedStyle(arrow, null).width.replace('px', ''))
|
||||
arrow.h = (options.arrow && options.arrow.height) || parseFloat(getComputedStyle(arrow, null).height.replace('px', ''))
|
||||
bar.w = (options.map && options.map.width) || parseFloat(getComputedStyle(bar, null).width.replace('px', ''))
|
||||
bar.h = (options.map && options.map.height) || parseFloat(getComputedStyle(bar, null).height.replace('px', ''))
|
||||
bar.addEventListener('mousedown', mouseDown)
|
||||
bind.call(that, draw)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,39 +2,36 @@
|
|||
* @param {any} obj
|
||||
* @returns {any}
|
||||
*/
|
||||
export function findPos(obj) {
|
||||
let curleft = 0;
|
||||
let curtop = 0;
|
||||
export function findPos (obj) {
|
||||
let curleft = 0
|
||||
let curtop = 0
|
||||
if (obj.offsetParent) {
|
||||
do {
|
||||
curleft += obj.offsetLeft;
|
||||
curtop += obj.offsetTop;
|
||||
curleft += obj.offsetLeft
|
||||
curtop += obj.offsetTop
|
||||
// eslint-disable-next-line no-cond-assign
|
||||
} while (obj = obj.offsetParent);
|
||||
return { left: curleft, top: curtop };
|
||||
} while (obj = obj.offsetParent)
|
||||
return { left: curleft, top: curtop }
|
||||
}
|
||||
return { left: curleft, top: curtop };
|
||||
return { left: curleft, top: curtop }
|
||||
}
|
||||
|
||||
export function isObject(item) {
|
||||
return (item && typeof item === 'object' && !Array.isArray(item));
|
||||
export function isObject (item) {
|
||||
return (item && typeof item === 'object' && !Array.isArray(item))
|
||||
}
|
||||
|
||||
export function mergeDeep(target, source) {
|
||||
const output = Object.assign({}, target);
|
||||
export function mergeDeep (target, source) {
|
||||
const output = Object.assign({}, target)
|
||||
if (isObject(target) && isObject(source)) {
|
||||
Object.keys(source).forEach((key) => {
|
||||
if (isObject(source[key])) {
|
||||
if (!(key in target))
|
||||
Object.assign(output, { [key]: source[key] });
|
||||
else
|
||||
output[key] = mergeDeep(target[key], source[key]);
|
||||
if (!(key in target)) { Object.assign(output, { [key]: source[key] }) } else { output[key] = mergeDeep(target[key], source[key]) }
|
||||
} else {
|
||||
Object.assign(output, { [key]: source[key] });
|
||||
Object.assign(output, { [key]: source[key] })
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
return output;
|
||||
return output
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,17 +40,17 @@ export function mergeDeep(target, source) {
|
|||
* @param {String} selector Selector to match against (class, ID, data attribute, or tag)
|
||||
* @return {Boolean|Element} Returns null if not match found
|
||||
*/
|
||||
export function getClosest(elem, selector) {
|
||||
const firstChar = selector.charAt(0);
|
||||
const supports = 'classList' in document.documentElement;
|
||||
let attribute; let value;
|
||||
export function getClosest (elem, selector) {
|
||||
const firstChar = selector.charAt(0)
|
||||
const supports = 'classList' in document.documentElement
|
||||
let attribute; let value
|
||||
// If selector is a data attribute, split attribute from value
|
||||
if (firstChar === '[') {
|
||||
selector = selector.substr(1, selector.length - 2);
|
||||
attribute = selector.split('=');
|
||||
selector = selector.substr(1, selector.length - 2)
|
||||
attribute = selector.split('=')
|
||||
if (attribute.length > 1) {
|
||||
value = true;
|
||||
attribute[1] = attribute[1].replace(/"/g, '').replace(/'/g, '');
|
||||
value = true
|
||||
attribute[1] = attribute[1].replace(/"/g, '').replace(/'/g, '')
|
||||
}
|
||||
}
|
||||
// Get closest match
|
||||
|
@ -62,18 +59,18 @@ export function getClosest(elem, selector) {
|
|||
if (firstChar === '.') {
|
||||
if (supports) {
|
||||
if (elem.classList.contains(selector.substr(1))) {
|
||||
return elem;
|
||||
return elem
|
||||
}
|
||||
} else {
|
||||
if (new RegExp('(^|\\s)' + selector.substr(1) + '(\\s|$)').test(elem.className)) {
|
||||
return elem;
|
||||
return elem
|
||||
}
|
||||
}
|
||||
}
|
||||
// If selector is an ID
|
||||
if (firstChar === '#') {
|
||||
if (elem.id === selector.substr(1)) {
|
||||
return elem;
|
||||
return elem
|
||||
}
|
||||
}
|
||||
// If selector is a data attribute
|
||||
|
@ -81,19 +78,19 @@ export function getClosest(elem, selector) {
|
|||
if (elem.hasAttribute(attribute[0])) {
|
||||
if (value) {
|
||||
if (elem.getAttribute(attribute[0]) === attribute[1]) {
|
||||
return elem;
|
||||
return elem
|
||||
}
|
||||
} else {
|
||||
return elem;
|
||||
return elem
|
||||
}
|
||||
}
|
||||
}
|
||||
// If selector is a tag
|
||||
if (elem.tagName.toLowerCase() === selector) {
|
||||
return elem;
|
||||
return elem
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -102,100 +99,100 @@ export function getClosest(elem, selector) {
|
|||
* @param {String} selector The class, id, data attribute, or tag to look for
|
||||
* @return {Array} Null if no match
|
||||
*/
|
||||
export function getParents(elem, selector) {
|
||||
const parents = [];
|
||||
const firstChar = selector?.charAt(0);
|
||||
export function getParents (elem, selector) {
|
||||
const parents = []
|
||||
const firstChar = selector?.charAt(0)
|
||||
// Get matches
|
||||
for ( ; elem && elem !== document; elem = elem.parentNode ) {
|
||||
if ( selector ) {
|
||||
for (; elem && elem !== document; elem = elem.parentNode) {
|
||||
if (selector) {
|
||||
// If selector is a class
|
||||
if ( firstChar === '.' ) {
|
||||
if ( elem.classList.contains( selector.substr(1) ) ) {
|
||||
parents.push( elem );
|
||||
if (firstChar === '.') {
|
||||
if (elem.classList.contains(selector.substr(1))) {
|
||||
parents.push(elem)
|
||||
}
|
||||
}
|
||||
// If selector is an ID
|
||||
if ( firstChar === '#' ) {
|
||||
if ( elem.id === selector.substr(1) ) {
|
||||
parents.push( elem );
|
||||
if (firstChar === '#') {
|
||||
if (elem.id === selector.substr(1)) {
|
||||
parents.push(elem)
|
||||
}
|
||||
}
|
||||
// If selector is a data attribute
|
||||
if ( firstChar === '[' ) {
|
||||
if ( elem.hasAttribute( selector.substr(1, selector.length - 1) ) ) {
|
||||
parents.push( elem );
|
||||
if (firstChar === '[') {
|
||||
if (elem.hasAttribute(selector.substr(1, selector.length - 1))) {
|
||||
parents.push(elem)
|
||||
}
|
||||
}
|
||||
// If selector is a tag
|
||||
if ( elem.tagName.toLowerCase() === selector ) {
|
||||
parents.push( elem );
|
||||
if (elem.tagName.toLowerCase() === selector) {
|
||||
parents.push(elem)
|
||||
}
|
||||
} else {
|
||||
parents.push( elem );
|
||||
parents.push(elem)
|
||||
}
|
||||
}
|
||||
// Return parents if any exist
|
||||
return parents.length? parents : null;
|
||||
return parents.length ? parents : null
|
||||
}
|
||||
|
||||
export function getParentsUntil(elem, parent, selector) {
|
||||
const parents = [];
|
||||
const parentType = parent?.charAt(0);
|
||||
const selectorType = selector?.selector.charAt(0);
|
||||
export function getParentsUntil (elem, parent, selector) {
|
||||
const parents = []
|
||||
const parentType = parent?.charAt(0)
|
||||
const selectorType = selector?.selector.charAt(0)
|
||||
// Get matches
|
||||
for ( ; elem && elem !== document; elem = elem.parentNode ) {
|
||||
for (; elem && elem !== document; elem = elem.parentNode) {
|
||||
// Check if parent has been reached
|
||||
if ( parent ) {
|
||||
if (parent) {
|
||||
// If parent is a class
|
||||
if ( parentType === '.' ) {
|
||||
if ( elem.classList.contains( parent.substr(1) ) ) {
|
||||
break;
|
||||
if (parentType === '.') {
|
||||
if (elem.classList.contains(parent.substr(1))) {
|
||||
break
|
||||
}
|
||||
}
|
||||
// If parent is an ID
|
||||
if ( parentType === '#' ) {
|
||||
if ( elem.id === parent.substr(1) ) {
|
||||
break;
|
||||
if (parentType === '#') {
|
||||
if (elem.id === parent.substr(1)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
// If parent is a data attribute
|
||||
if ( parentType === '[' ) {
|
||||
if ( elem.hasAttribute( parent.substr(1, parent.length - 1) ) ) {
|
||||
break;
|
||||
if (parentType === '[') {
|
||||
if (elem.hasAttribute(parent.substr(1, parent.length - 1))) {
|
||||
break
|
||||
}
|
||||
}
|
||||
// If parent is a tag
|
||||
if ( elem.tagName.toLowerCase() === parent ) {
|
||||
break;
|
||||
if (elem.tagName.toLowerCase() === parent) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if ( selector ) {
|
||||
if (selector) {
|
||||
// If selector is a class
|
||||
if ( selectorType === '.' ) {
|
||||
if ( elem.classList.contains( selector.substr(1) ) ) {
|
||||
parents.push( elem );
|
||||
if (selectorType === '.') {
|
||||
if (elem.classList.contains(selector.substr(1))) {
|
||||
parents.push(elem)
|
||||
}
|
||||
}
|
||||
// If selector is an ID
|
||||
if ( selectorType === '#' ) {
|
||||
if ( elem.id === selector.substr(1) ) {
|
||||
parents.push( elem );
|
||||
if (selectorType === '#') {
|
||||
if (elem.id === selector.substr(1)) {
|
||||
parents.push(elem)
|
||||
}
|
||||
}
|
||||
// If selector is a data attribute
|
||||
if ( selectorType === '[' ) {
|
||||
if ( elem.hasAttribute( selector.substr(1, selector.length - 1) ) ) {
|
||||
parents.push( elem );
|
||||
if (selectorType === '[') {
|
||||
if (elem.hasAttribute(selector.substr(1, selector.length - 1))) {
|
||||
parents.push(elem)
|
||||
}
|
||||
}
|
||||
// If selector is a tag
|
||||
if ( elem.tagName.toLowerCase() === selector ) {
|
||||
parents.push( elem );
|
||||
if (elem.tagName.toLowerCase() === selector) {
|
||||
parents.push(elem)
|
||||
}
|
||||
} else {
|
||||
parents.push( elem );
|
||||
parents.push(elem)
|
||||
}
|
||||
}
|
||||
// Return parents if any exist
|
||||
return parents.length? parents : null;
|
||||
}
|
||||
return parents.length ? parents : null
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -6,83 +6,83 @@ export default class Paint {
|
|||
* @param {module:jGraduate.jGraduatePaintOptions} [opt]
|
||||
*/
|
||||
constructor (opt) {
|
||||
const options = opt || {};
|
||||
this.alpha = isNaN(options.alpha) ? 100 : options.alpha;
|
||||
const options = opt || {}
|
||||
this.alpha = isNaN(options.alpha) ? 100 : options.alpha
|
||||
// copy paint object
|
||||
if (options.copy) {
|
||||
/**
|
||||
* @name module:jGraduate~Paint#type
|
||||
* @type {"none"|"solidColor"|"linearGradient"|"radialGradient"}
|
||||
*/
|
||||
this.type = options.copy.type;
|
||||
this.type = options.copy.type
|
||||
/**
|
||||
* Represents opacity (0-100).
|
||||
* @name module:jGraduate~Paint#alpha
|
||||
* @type {Float}
|
||||
*/
|
||||
this.alpha = options.copy.alpha;
|
||||
this.alpha = options.copy.alpha
|
||||
/**
|
||||
* Represents #RRGGBB hex of color.
|
||||
* @name module:jGraduate~Paint#solidColor
|
||||
* @type {string}
|
||||
*/
|
||||
this.solidColor = null;
|
||||
this.solidColor = null
|
||||
/**
|
||||
* @name module:jGraduate~Paint#linearGradient
|
||||
* @type {SVGLinearGradientElement}
|
||||
*/
|
||||
this.linearGradient = null;
|
||||
this.linearGradient = null
|
||||
/**
|
||||
* @name module:jGraduate~Paint#radialGradient
|
||||
* @type {SVGRadialGradientElement}
|
||||
*/
|
||||
this.radialGradient = null;
|
||||
this.radialGradient = null
|
||||
|
||||
switch (this.type) {
|
||||
case 'none':
|
||||
break;
|
||||
case 'solidColor':
|
||||
this.solidColor = options.copy.solidColor;
|
||||
break;
|
||||
case 'linearGradient':
|
||||
this.linearGradient = options.copy.linearGradient.cloneNode(true);
|
||||
break;
|
||||
case 'radialGradient':
|
||||
this.radialGradient = options.copy.radialGradient.cloneNode(true);
|
||||
break;
|
||||
case 'none':
|
||||
break
|
||||
case 'solidColor':
|
||||
this.solidColor = options.copy.solidColor
|
||||
break
|
||||
case 'linearGradient':
|
||||
this.linearGradient = options.copy.linearGradient.cloneNode(true)
|
||||
break
|
||||
case 'radialGradient':
|
||||
this.radialGradient = options.copy.radialGradient.cloneNode(true)
|
||||
break
|
||||
}
|
||||
// create linear gradient paint
|
||||
} else if (options.linearGradient) {
|
||||
this.type = 'linearGradient';
|
||||
this.solidColor = null;
|
||||
this.radialGradient = null;
|
||||
if(options.linearGradient.hasAttribute('xlink:href')) {
|
||||
const xhref = document.getElementById(options.linearGradient.getAttribute('xlink:href').substr(1));
|
||||
this.linearGradient = xhref.cloneNode(true);
|
||||
this.type = 'linearGradient'
|
||||
this.solidColor = null
|
||||
this.radialGradient = null
|
||||
if (options.linearGradient.hasAttribute('xlink:href')) {
|
||||
const xhref = document.getElementById(options.linearGradient.getAttribute('xlink:href').substr(1))
|
||||
this.linearGradient = xhref.cloneNode(true)
|
||||
} else {
|
||||
this.linearGradient = options.linearGradient.cloneNode(true);
|
||||
this.linearGradient = options.linearGradient.cloneNode(true)
|
||||
}
|
||||
// create linear gradient paint
|
||||
} else if (options.radialGradient) {
|
||||
this.type = 'radialGradient';
|
||||
this.solidColor = null;
|
||||
this.linearGradient = null;
|
||||
if(options.radialGradient.hasAttribute('xlink:href')) {
|
||||
const xhref = document.getElementById(options.radialGradient.getAttribute('xlink:href').substr(1));
|
||||
this.radialGradient = xhref.cloneNode(true);
|
||||
this.type = 'radialGradient'
|
||||
this.solidColor = null
|
||||
this.linearGradient = null
|
||||
if (options.radialGradient.hasAttribute('xlink:href')) {
|
||||
const xhref = document.getElementById(options.radialGradient.getAttribute('xlink:href').substr(1))
|
||||
this.radialGradient = xhref.cloneNode(true)
|
||||
} else {
|
||||
this.radialGradient = options.radialGradient.cloneNode(true);
|
||||
this.radialGradient = options.radialGradient.cloneNode(true)
|
||||
}
|
||||
// create solid color paint
|
||||
} else if (options.solidColor) {
|
||||
this.type = 'solidColor';
|
||||
this.solidColor = options.solidColor;
|
||||
this.type = 'solidColor'
|
||||
this.solidColor = options.solidColor
|
||||
// create empty paint
|
||||
} else {
|
||||
this.type = 'none';
|
||||
this.solidColor = null;
|
||||
this.linearGradient = null;
|
||||
this.radialGradient = null;
|
||||
this.type = 'none'
|
||||
this.solidColor = null
|
||||
this.linearGradient = null
|
||||
this.radialGradient = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* globals svgEditor */
|
||||
import { t } from '../locale.js';
|
||||
const template = document.createElement('template');
|
||||
import { t } from '../locale.js'
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
:host(:hover) :not(.disabled)
|
||||
|
@ -39,7 +39,7 @@ template.innerHTML = `
|
|||
<div title="title">
|
||||
<img alt="icon">
|
||||
</div>
|
||||
`;
|
||||
`
|
||||
/**
|
||||
* @class ToolButton
|
||||
*/
|
||||
|
@ -48,22 +48,24 @@ export class ToolButton extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
// locate the component
|
||||
this.$div = this._shadowRoot.querySelector('div');
|
||||
this.$img = this._shadowRoot.querySelector('img');
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath;
|
||||
this.$div = this._shadowRoot.querySelector('div')
|
||||
this.$img = this._shadowRoot.querySelector('img')
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'title', 'src', 'pressed', 'disabled', 'size', 'style' ];
|
||||
return ['title', 'src', 'pressed', 'disabled', 'size', 'style']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -72,56 +74,57 @@ export class ToolButton extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'title':
|
||||
{
|
||||
const shortcut = this.getAttribute('shortcut');
|
||||
this.$div.setAttribute('title', `${t(newValue)} ${shortcut ? `[${t(shortcut)}]` : ''}`);
|
||||
}
|
||||
break;
|
||||
case 'style':
|
||||
this.$div.style = newValue;
|
||||
break;
|
||||
case 'src':
|
||||
if (newValue.indexOf("data:") !== -1) {
|
||||
this.$img.setAttribute('src', newValue);
|
||||
} else {
|
||||
this.$img.setAttribute('src', this.imgPath + "/" + newValue);
|
||||
}
|
||||
break;
|
||||
case 'pressed':
|
||||
if (newValue === null) {
|
||||
this.$div.classList.remove('pressed');
|
||||
} else {
|
||||
this.$div.classList.add('pressed');
|
||||
}
|
||||
break;
|
||||
case 'size':
|
||||
if (newValue === 'small') {
|
||||
this.$div.classList.add('small');
|
||||
} else {
|
||||
this.$div.classList.remove('small');
|
||||
}
|
||||
break;
|
||||
case 'disabled':
|
||||
if (newValue) {
|
||||
this.$div.classList.add('disabled');
|
||||
} else {
|
||||
this.$div.classList.remove('disabled');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
case 'title':
|
||||
{
|
||||
const shortcut = this.getAttribute('shortcut')
|
||||
this.$div.setAttribute('title', `${t(newValue)} ${shortcut ? `[${t(shortcut)}]` : ''}`)
|
||||
}
|
||||
break
|
||||
case 'style':
|
||||
this.$div.style = newValue
|
||||
break
|
||||
case 'src':
|
||||
if (newValue.indexOf('data:') !== -1) {
|
||||
this.$img.setAttribute('src', newValue)
|
||||
} else {
|
||||
this.$img.setAttribute('src', this.imgPath + '/' + newValue)
|
||||
}
|
||||
break
|
||||
case 'pressed':
|
||||
if (newValue === null) {
|
||||
this.$div.classList.remove('pressed')
|
||||
} else {
|
||||
this.$div.classList.add('pressed')
|
||||
}
|
||||
break
|
||||
case 'size':
|
||||
if (newValue === 'small') {
|
||||
this.$div.classList.add('small')
|
||||
} else {
|
||||
this.$div.classList.remove('small')
|
||||
}
|
||||
break
|
||||
case 'disabled':
|
||||
if (newValue) {
|
||||
this.$div.classList.add('disabled')
|
||||
} else {
|
||||
this.$div.classList.remove('disabled')
|
||||
}
|
||||
break
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get title () {
|
||||
return this.getAttribute('title');
|
||||
return this.getAttribute('title')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -129,14 +132,15 @@ export class ToolButton extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set title (value) {
|
||||
this.setAttribute('title', value);
|
||||
this.setAttribute('title', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get pressed () {
|
||||
return this.hasAttribute('pressed');
|
||||
return this.hasAttribute('pressed')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,17 +150,18 @@ export class ToolButton extends HTMLElement {
|
|||
set pressed (value) {
|
||||
// boolean value => existence = true
|
||||
if (value) {
|
||||
this.setAttribute('pressed', 'true');
|
||||
this.setAttribute('pressed', 'true')
|
||||
} else {
|
||||
this.removeAttribute('pressed');
|
||||
this.removeAttribute('pressed')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get disabled () {
|
||||
return this.hasAttribute('disabled');
|
||||
return this.hasAttribute('disabled')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -166,17 +171,18 @@ export class ToolButton extends HTMLElement {
|
|||
set disabled (value) {
|
||||
// boolean value => existence = true
|
||||
if (value) {
|
||||
this.setAttribute('disabled', 'true');
|
||||
this.setAttribute('disabled', 'true')
|
||||
} else {
|
||||
this.removeAttribute('disabled');
|
||||
this.removeAttribute('disabled')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get src () {
|
||||
return this.getAttribute('src');
|
||||
return this.getAttribute('src')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,7 +190,7 @@ export class ToolButton extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set src (value) {
|
||||
this.setAttribute('src', value);
|
||||
this.setAttribute('src', value)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -192,7 +198,7 @@ export class ToolButton extends HTMLElement {
|
|||
* @returns {any}
|
||||
*/
|
||||
get size () {
|
||||
return this.getAttribute('size');
|
||||
return this.getAttribute('size')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -200,7 +206,7 @@ export class ToolButton extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set size (value) {
|
||||
this.setAttribute('size', value);
|
||||
this.setAttribute('size', value)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -209,22 +215,22 @@ export class ToolButton extends HTMLElement {
|
|||
*/
|
||||
connectedCallback () {
|
||||
// capture shortcuts
|
||||
const shortcut = this.getAttribute('shortcut');
|
||||
const shortcut = this.getAttribute('shortcut')
|
||||
if (shortcut) {
|
||||
// register the keydown event
|
||||
document.addEventListener('keydown', (e) => {
|
||||
// only track keyboard shortcuts for the body containing the SVG-Editor
|
||||
if (e.target.nodeName !== 'BODY') return;
|
||||
if (e.target.nodeName !== 'BODY') return
|
||||
// normalize key
|
||||
const key = `${(e.metaKey) ? 'meta+' : ''}${(e.ctrlKey) ? 'ctrl+' : ''}${e.key.toUpperCase()}`;
|
||||
if (shortcut !== key) return;
|
||||
const key = `${(e.metaKey) ? 'meta+' : ''}${(e.ctrlKey) ? 'ctrl+' : ''}${e.key.toUpperCase()}`
|
||||
if (shortcut !== key) return
|
||||
// launch the click event
|
||||
this.click();
|
||||
e.preventDefault();
|
||||
});
|
||||
this.click()
|
||||
e.preventDefault()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-button', ToolButton);
|
||||
customElements.define('se-button', ToolButton)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* globals svgEditor */
|
||||
import { jGraduate, jGraduateMethod } from './jgraduate/jQuery.jGraduate.js';
|
||||
import PaintBox from './PaintBox.js';
|
||||
import { t } from '../locale.js';
|
||||
import { jGraduate, jGraduateMethod } from './jgraduate/jQuery.jGraduate.js'
|
||||
import PaintBox from './PaintBox.js'
|
||||
import { t } from '../locale.js'
|
||||
|
||||
const template = document.createElement('template');
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
.jPicker .Icon {
|
||||
|
@ -645,7 +645,7 @@ div.jGraduate_Slider img {
|
|||
</div>
|
||||
<!-- hidden div -->
|
||||
<div id="color_picker"></div>
|
||||
`;
|
||||
`
|
||||
/**
|
||||
* @class SeColorPicker
|
||||
*/
|
||||
|
@ -654,35 +654,38 @@ export class SeColorPicker extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$logo = this._shadowRoot.getElementById('logo');
|
||||
this.$label = this._shadowRoot.getElementById('label');
|
||||
this.$block = this._shadowRoot.getElementById('block');
|
||||
this.paintBox = null;
|
||||
this.i18next = null;
|
||||
this.$picker = this._shadowRoot.getElementById('picker');
|
||||
this.$color_picker = this._shadowRoot.getElementById('color_picker');
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath;
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
this.$logo = this._shadowRoot.getElementById('logo')
|
||||
this.$label = this._shadowRoot.getElementById('label')
|
||||
this.$block = this._shadowRoot.getElementById('block')
|
||||
this.paintBox = null
|
||||
this.i18next = null
|
||||
this.$picker = this._shadowRoot.getElementById('picker')
|
||||
this.$color_picker = this._shadowRoot.getElementById('color_picker')
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath
|
||||
}
|
||||
|
||||
/**
|
||||
* @function init
|
||||
* @param {any} name
|
||||
* @returns {void}
|
||||
*/
|
||||
init (i18next) {
|
||||
this.i18next = i18next;
|
||||
this.setAttribute('config-change_xxx_color', t('config.change_xxx_color'));
|
||||
this.i18next = i18next
|
||||
this.setAttribute('config-change_xxx_color', t('config.change_xxx_color'))
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'label', 'src', 'type', 'config-change_xxx_color' ];
|
||||
return ['label', 'src', 'type', 'config-change_xxx_color']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -691,31 +694,32 @@ export class SeColorPicker extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'src':
|
||||
this.$logo.setAttribute('src', this.imgPath + '/' + newValue);
|
||||
break;
|
||||
case 'label':
|
||||
this.setAttribute('title', t(newValue));
|
||||
break;
|
||||
case 'type':
|
||||
this.$label.setAttribute('title', 'config.pick_paint_opavity');
|
||||
break;
|
||||
case 'config-change_xxx_color':
|
||||
this.$label.setAttribute('title', newValue);
|
||||
break;
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
case 'src':
|
||||
this.$logo.setAttribute('src', this.imgPath + '/' + newValue)
|
||||
break
|
||||
case 'label':
|
||||
this.setAttribute('title', t(newValue))
|
||||
break
|
||||
case 'type':
|
||||
this.$label.setAttribute('title', 'config.pick_paint_opavity')
|
||||
break
|
||||
case 'config-change_xxx_color':
|
||||
this.$label.setAttribute('title', newValue)
|
||||
break
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get label () {
|
||||
return this.$label.getAttribute('title');
|
||||
return this.$label.getAttribute('title')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -723,14 +727,15 @@ export class SeColorPicker extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set label (value) {
|
||||
this.setAttribute('label', value);
|
||||
this.setAttribute('label', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get type () {
|
||||
return this.getAttribute('type');
|
||||
return this.getAttribute('type')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -738,14 +743,15 @@ export class SeColorPicker extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set type (value) {
|
||||
this.setAttribute('type', value);
|
||||
this.setAttribute('type', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get src () {
|
||||
return this.getAttribute('src');
|
||||
return this.getAttribute('src')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -753,7 +759,7 @@ export class SeColorPicker extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set src (value) {
|
||||
this.setAttribute('src', value);
|
||||
this.setAttribute('src', value)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -763,20 +769,23 @@ export class SeColorPicker extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
update (svgCanvas, selectedElement, apply) {
|
||||
const paint = this.paintBox.update(svgCanvas, selectedElement);
|
||||
const paint = this.paintBox.update(svgCanvas, selectedElement)
|
||||
if (paint && apply) {
|
||||
const changeEvent = new CustomEvent('change', { detail: {
|
||||
paint
|
||||
} });
|
||||
this.dispatchEvent(changeEvent);
|
||||
const changeEvent = new CustomEvent('change', {
|
||||
detail: {
|
||||
paint
|
||||
}
|
||||
})
|
||||
this.dispatchEvent(changeEvent)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PlainObject} paint
|
||||
* @returns {void}
|
||||
*/
|
||||
setPaint (paint) {
|
||||
this.paintBox.setPaint(paint);
|
||||
this.paintBox.setPaint(paint)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -784,9 +793,9 @@ export class SeColorPicker extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
connectedCallback () {
|
||||
this.paintBox = new PaintBox(this.$block, this.type);
|
||||
this.paintBox = new PaintBox(this.$block, this.type)
|
||||
this.$picker.addEventListener('click', () => {
|
||||
let { paint } = this.paintBox;
|
||||
let { paint } = this.paintBox
|
||||
jGraduateMethod(
|
||||
this.$color_picker,
|
||||
{
|
||||
|
@ -796,22 +805,24 @@ export class SeColorPicker extends HTMLElement {
|
|||
newstop: 'inverse'
|
||||
},
|
||||
(p) => {
|
||||
paint = new jGraduate.Paint(p);
|
||||
this.setPaint(paint);
|
||||
const changeEvent = new CustomEvent('change', { detail: {
|
||||
paint
|
||||
} });
|
||||
this.dispatchEvent(changeEvent);
|
||||
this.$color_picker.style.display = 'none';
|
||||
paint = new jGraduate.Paint(p)
|
||||
this.setPaint(paint)
|
||||
const changeEvent = new CustomEvent('change', {
|
||||
detail: {
|
||||
paint
|
||||
}
|
||||
})
|
||||
this.dispatchEvent(changeEvent)
|
||||
this.$color_picker.style.display = 'none'
|
||||
},
|
||||
() => {
|
||||
this.$color_picker.style.display = 'none';
|
||||
this.$color_picker.style.display = 'none'
|
||||
},
|
||||
this.i18next
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-colorpicker', SeColorPicker);
|
||||
customElements.define('se-colorpicker', SeColorPicker)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import ListComboBox from 'elix/define/ListComboBox.js';
|
||||
import { defaultState } from 'elix/src/base/internal.js';
|
||||
import { templateFrom, fragmentFrom } from 'elix/src/core/htmlLiterals.js';
|
||||
import { internal } from 'elix';
|
||||
import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js';
|
||||
import ListComboBox from 'elix/define/ListComboBox.js'
|
||||
import { defaultState } from 'elix/src/base/internal.js'
|
||||
import { templateFrom, fragmentFrom } from 'elix/src/core/htmlLiterals.js'
|
||||
import { internal } from 'elix'
|
||||
import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js'
|
||||
|
||||
/**
|
||||
* @class Dropdown
|
||||
|
@ -15,21 +15,22 @@ class Dropdown extends ListComboBox {
|
|||
get [defaultState] () {
|
||||
return Object.assign(super[defaultState], {
|
||||
inputPartType: NumberSpinBox,
|
||||
src: "logo.svg",
|
||||
src: 'logo.svg',
|
||||
inputsize: '100%'
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {PlainObject}
|
||||
*/
|
||||
get [internal.template] () {
|
||||
const result = super[internal.template];
|
||||
const source = result.content.getElementById('source');
|
||||
const result = super[internal.template]
|
||||
const source = result.content.getElementById('source')
|
||||
// add a icon before our dropdown
|
||||
source.prepend(fragmentFrom.html`
|
||||
<img src="dropdown.svg" alt="icon" width="18" height="18"></img>
|
||||
`.cloneNode(true));
|
||||
`.cloneNode(true))
|
||||
// change the style so it fits in our toolbar
|
||||
result.content.append(
|
||||
templateFrom.html`
|
||||
|
@ -48,16 +49,18 @@ class Dropdown extends ListComboBox {
|
|||
}
|
||||
</style>
|
||||
`.content
|
||||
);
|
||||
return result;
|
||||
)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'title', 'src', 'inputsize', 'value' ];
|
||||
return ['title', 'src', 'inputsize', 'value']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -66,97 +69,104 @@ class Dropdown extends ListComboBox {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'title':
|
||||
case 'title':
|
||||
// this.$span.setAttribute('title', `${newValue} ${shortcut ? `[${shortcut}]` : ''}`);
|
||||
break;
|
||||
case 'src':
|
||||
this.src = newValue;
|
||||
break;
|
||||
case 'inputsize':
|
||||
this.inputsize = newValue;
|
||||
break;
|
||||
default:
|
||||
super.attributeChangedCallback(name, oldValue, newValue);
|
||||
break;
|
||||
break
|
||||
case 'src':
|
||||
this.src = newValue
|
||||
break
|
||||
case 'inputsize':
|
||||
this.inputsize = newValue
|
||||
break
|
||||
default:
|
||||
super.attributeChangedCallback(name, oldValue, newValue)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function [internal.render]
|
||||
* @param {PlainObject} changed
|
||||
* @returns {void}
|
||||
*/
|
||||
[internal.render] (changed) {
|
||||
super[internal.render](changed);
|
||||
super[internal.render](changed)
|
||||
if (this[internal.firstRender]) {
|
||||
this.$img = this.shadowRoot.querySelector('img');
|
||||
this.$input = this.shadowRoot.getElementById('input');
|
||||
this.$img = this.shadowRoot.querySelector('img')
|
||||
this.$input = this.shadowRoot.getElementById('input')
|
||||
}
|
||||
if (changed.src) {
|
||||
this.$img.setAttribute('src', this[internal.state].src);
|
||||
this.$img.setAttribute('src', this[internal.state].src)
|
||||
}
|
||||
if (changed.inputsize) {
|
||||
this.$input.shadowRoot.querySelector('[part~="input"]').style.width = this[internal.state].inputsize;
|
||||
this.$input.shadowRoot.querySelector('[part~="input"]').style.width = this[internal.state].inputsize
|
||||
}
|
||||
if (changed.inputPartType) {
|
||||
// Wire up handler on new input.
|
||||
this.addEventListener('close', (e) => {
|
||||
e.preventDefault();
|
||||
const value = e.detail?.closeResult?.getAttribute('value');
|
||||
e.preventDefault()
|
||||
const value = e.detail?.closeResult?.getAttribute('value')
|
||||
if (value) {
|
||||
const closeEvent = new CustomEvent('change', { detail: { value } });
|
||||
this.dispatchEvent(closeEvent);
|
||||
const closeEvent = new CustomEvent('change', { detail: { value } })
|
||||
this.dispatchEvent(closeEvent)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function src
|
||||
* @returns {string} src
|
||||
*/
|
||||
get src () {
|
||||
return this[internal.state].src;
|
||||
return this[internal.state].src
|
||||
}
|
||||
|
||||
/**
|
||||
* @function src
|
||||
* @returns {void}
|
||||
*/
|
||||
set src (src) {
|
||||
this[internal.setState]({ src });
|
||||
this[internal.setState]({ src })
|
||||
}
|
||||
|
||||
/**
|
||||
* @function inputsize
|
||||
* @returns {string} src
|
||||
*/
|
||||
get inputsize () {
|
||||
return this[internal.state].inputsize;
|
||||
return this[internal.state].inputsize
|
||||
}
|
||||
|
||||
/**
|
||||
* @function src
|
||||
* @returns {void}
|
||||
*/
|
||||
set inputsize (inputsize) {
|
||||
this[internal.setState]({ inputsize });
|
||||
this[internal.setState]({ inputsize })
|
||||
}
|
||||
|
||||
/**
|
||||
* @function value
|
||||
* @returns {string} src
|
||||
*/
|
||||
get value () {
|
||||
return this[internal.state].value;
|
||||
return this[internal.state].value
|
||||
}
|
||||
|
||||
/**
|
||||
* @function value
|
||||
* @returns {void}
|
||||
*/
|
||||
set value (value) {
|
||||
this[internal.setState]({ value });
|
||||
this[internal.setState]({ value })
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-dropdown', Dropdown);
|
||||
customElements.define('se-dropdown', Dropdown)
|
||||
|
||||
/*
|
||||
{TODO
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* globals svgEditor */
|
||||
/* eslint-disable no-unsanitized/property */
|
||||
const template = document.createElement('template');
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
:host {
|
||||
|
@ -98,7 +97,7 @@ template.innerHTML = `
|
|||
</div>
|
||||
</div>
|
||||
|
||||
`;
|
||||
`
|
||||
/**
|
||||
* @class ExplorerButton
|
||||
*/
|
||||
|
@ -107,28 +106,30 @@ export class ExplorerButton extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
// locate the component
|
||||
this.$button = this._shadowRoot.querySelector('.menu-button');
|
||||
this.$overall = this._shadowRoot.querySelector('.overall');
|
||||
this.$img = this._shadowRoot.querySelector('.menu-button img');
|
||||
this.$menu = this._shadowRoot.querySelector('.menu');
|
||||
this.$handle = this._shadowRoot.querySelector('.handle');
|
||||
this.$lib = this._shadowRoot.querySelector('.image-lib');
|
||||
this.files = [];
|
||||
this.request = new XMLHttpRequest();
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath;
|
||||
this.$button = this._shadowRoot.querySelector('.menu-button')
|
||||
this.$overall = this._shadowRoot.querySelector('.overall')
|
||||
this.$img = this._shadowRoot.querySelector('.menu-button img')
|
||||
this.$menu = this._shadowRoot.querySelector('.menu')
|
||||
this.$handle = this._shadowRoot.querySelector('.handle')
|
||||
this.$lib = this._shadowRoot.querySelector('.image-lib')
|
||||
this.files = []
|
||||
this.request = new XMLHttpRequest()
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'title', 'pressed', 'disabled', 'lib', 'src' ];
|
||||
return ['title', 'pressed', 'disabled', 'lib', 'src']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -137,55 +138,56 @@ export class ExplorerButton extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
async attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'title':
|
||||
{
|
||||
const shortcut = this.getAttribute('shortcut');
|
||||
this.$button.setAttribute('title', `${newValue} [${shortcut}]`);
|
||||
}
|
||||
break;
|
||||
case 'pressed':
|
||||
if (newValue) {
|
||||
this.$overall.classList.add('pressed');
|
||||
} else {
|
||||
this.$overall.classList.remove('pressed');
|
||||
}
|
||||
break;
|
||||
case 'disabled':
|
||||
if (newValue) {
|
||||
this.$overall.classList.add('disabled');
|
||||
} else {
|
||||
this.$overall.classList.remove('disabled');
|
||||
}
|
||||
break;
|
||||
case 'lib':
|
||||
try {
|
||||
const response = await fetch(`${newValue}index.json`);
|
||||
const json = await response.json();
|
||||
const { lib } = json;
|
||||
this.$menu.innerHTML = lib.map((menu, i) => (
|
||||
case 'title':
|
||||
{
|
||||
const shortcut = this.getAttribute('shortcut')
|
||||
this.$button.setAttribute('title', `${newValue} [${shortcut}]`)
|
||||
}
|
||||
break
|
||||
case 'pressed':
|
||||
if (newValue) {
|
||||
this.$overall.classList.add('pressed')
|
||||
} else {
|
||||
this.$overall.classList.remove('pressed')
|
||||
}
|
||||
break
|
||||
case 'disabled':
|
||||
if (newValue) {
|
||||
this.$overall.classList.add('disabled')
|
||||
} else {
|
||||
this.$overall.classList.remove('disabled')
|
||||
}
|
||||
break
|
||||
case 'lib':
|
||||
try {
|
||||
const response = await fetch(`${newValue}index.json`)
|
||||
const json = await response.json()
|
||||
const { lib } = json
|
||||
this.$menu.innerHTML = lib.map((menu, i) => (
|
||||
`<div data-menu="${menu}" class="menu-item ${(i === 0) ? 'pressed' : ''} ">${menu}</div>`
|
||||
)).join('');
|
||||
await this.updateLib(lib[0]);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
break;
|
||||
case 'src':
|
||||
this.$img.setAttribute('src', this.imgPath + '/' + newValue);
|
||||
break;
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
)).join('')
|
||||
await this.updateLib(lib[0])
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
break
|
||||
case 'src':
|
||||
this.$img.setAttribute('src', this.imgPath + '/' + newValue)
|
||||
break
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get title () {
|
||||
return this.getAttribute('title');
|
||||
return this.getAttribute('title')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -193,14 +195,15 @@ export class ExplorerButton extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set title (value) {
|
||||
this.setAttribute('title', value);
|
||||
this.setAttribute('title', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get pressed () {
|
||||
return this.hasAttribute('pressed');
|
||||
return this.hasAttribute('pressed')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,17 +213,18 @@ export class ExplorerButton extends HTMLElement {
|
|||
set pressed (value) {
|
||||
// boolean value => existence = true
|
||||
if (value) {
|
||||
this.setAttribute('pressed', 'true');
|
||||
this.setAttribute('pressed', 'true')
|
||||
} else {
|
||||
this.removeAttribute('pressed', '');
|
||||
this.removeAttribute('pressed', '')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get disabled () {
|
||||
return this.hasAttribute('disabled');
|
||||
return this.hasAttribute('disabled')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,11 +234,12 @@ export class ExplorerButton extends HTMLElement {
|
|||
set disabled (value) {
|
||||
// boolean value => existence = true
|
||||
if (value) {
|
||||
this.setAttribute('disabled', 'true');
|
||||
this.setAttribute('disabled', 'true')
|
||||
} else {
|
||||
this.removeAttribute('disabled', '');
|
||||
this.removeAttribute('disabled', '')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function connectedCallback
|
||||
* @returns {void}
|
||||
|
@ -242,73 +247,74 @@ export class ExplorerButton extends HTMLElement {
|
|||
connectedCallback () {
|
||||
// capture click event on the button to manage the logic
|
||||
const onClickHandler = (ev) => {
|
||||
ev.stopPropagation();
|
||||
ev.stopPropagation()
|
||||
switch (ev.target.nodeName) {
|
||||
case 'SE-EXPLORERBUTTON':
|
||||
this.$menu.classList.add('open');
|
||||
this.$lib.classList.add('open-lib');
|
||||
break;
|
||||
case 'SE-BUTTON':
|
||||
case 'SE-EXPLORERBUTTON':
|
||||
this.$menu.classList.add('open')
|
||||
this.$lib.classList.add('open-lib')
|
||||
break
|
||||
case 'SE-BUTTON':
|
||||
// change to the current action
|
||||
this.currentAction = ev.target;
|
||||
this.$img.setAttribute('src', this.currentAction.getAttribute('src'));
|
||||
this.dataset.draw = this.data[this.currentAction.dataset.shape];
|
||||
this._shadowRoot.querySelectorAll('.image-lib [pressed]').forEach((b) => { b.pressed = false; });
|
||||
this.currentAction.setAttribute('pressed', 'pressed');
|
||||
// and close the menu
|
||||
this.$menu.classList.remove('open');
|
||||
this.$lib.classList.remove('open-lib');
|
||||
break;
|
||||
case 'DIV':
|
||||
if (ev.target.classList[0] === 'handle') {
|
||||
this.currentAction = ev.target
|
||||
this.$img.setAttribute('src', this.currentAction.getAttribute('src'))
|
||||
this.dataset.draw = this.data[this.currentAction.dataset.shape]
|
||||
this._shadowRoot.querySelectorAll('.image-lib [pressed]').forEach((b) => { b.pressed = false })
|
||||
this.currentAction.setAttribute('pressed', 'pressed')
|
||||
// and close the menu
|
||||
this.$menu.classList.remove('open')
|
||||
this.$lib.classList.remove('open-lib')
|
||||
break
|
||||
case 'DIV':
|
||||
if (ev.target.classList[0] === 'handle') {
|
||||
// this is a click on the handle so let's open/close the menu.
|
||||
this.$menu.classList.toggle('open');
|
||||
this.$lib.classList.toggle('open-lib');
|
||||
} else {
|
||||
this._shadowRoot.querySelectorAll('.menu > .pressed').forEach((b) => { b.classList.remove('pressed'); });
|
||||
ev.target.classList.add('pressed');
|
||||
this.updateLib(ev.target.dataset.menu);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.error('unknown nodeName for:', ev.target, ev.target.className);
|
||||
this.$menu.classList.toggle('open')
|
||||
this.$lib.classList.toggle('open-lib')
|
||||
} else {
|
||||
this._shadowRoot.querySelectorAll('.menu > .pressed').forEach((b) => { b.classList.remove('pressed') })
|
||||
ev.target.classList.add('pressed')
|
||||
this.updateLib(ev.target.dataset.menu)
|
||||
}
|
||||
break
|
||||
default:
|
||||
console.error('unknown nodeName for:', ev.target, ev.target.className)
|
||||
}
|
||||
};
|
||||
}
|
||||
// capture event from slots
|
||||
this.addEventListener('click', onClickHandler);
|
||||
this.$menu.addEventListener('click', onClickHandler);
|
||||
this.$lib.addEventListener('click', onClickHandler);
|
||||
this.$handle.addEventListener('click', onClickHandler);
|
||||
this.addEventListener('click', onClickHandler)
|
||||
this.$menu.addEventListener('click', onClickHandler)
|
||||
this.$lib.addEventListener('click', onClickHandler)
|
||||
this.$handle.addEventListener('click', onClickHandler)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function updateLib
|
||||
* @param {string} lib
|
||||
* @returns {void}
|
||||
*/
|
||||
async updateLib (lib) {
|
||||
const libDir = this.getAttribute('lib');
|
||||
const libDir = this.getAttribute('lib')
|
||||
try {
|
||||
// initialize buttons for all shapes defined for this library
|
||||
const response = await fetch(`${libDir}${lib}.json`);
|
||||
const json = await response.json();
|
||||
this.data = json.data;
|
||||
const size = json.size ?? 300;
|
||||
const fill = json.fill ? '#333' : 'none';
|
||||
const off = size * 0.05;
|
||||
const vb = [ -off, -off, size + off * 2, size + off * 2 ].join(' ');
|
||||
const stroke = json.fill ? 0 : (size / 30);
|
||||
this.$lib.innerHTML = Object.entries(this.data).map(([ key, path ]) => {
|
||||
const response = await fetch(`${libDir}${lib}.json`)
|
||||
const json = await response.json()
|
||||
this.data = json.data
|
||||
const size = json.size ?? 300
|
||||
const fill = json.fill ? '#333' : 'none'
|
||||
const off = size * 0.05
|
||||
const vb = [-off, -off, size + off * 2, size + off * 2].join(' ')
|
||||
const stroke = json.fill ? 0 : (size / 30)
|
||||
this.$lib.innerHTML = Object.entries(this.data).map(([key, path]) => {
|
||||
const encoded = btoa(`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">
|
||||
<svg viewBox="${vb}"><path fill="${fill}" stroke="#f8bb00" stroke-width="${stroke}" d="${path}"></path></svg>
|
||||
</svg>`);
|
||||
return `<se-button data-shape="${key}"src="data:image/svg+xml;base64,${encoded}"></se-button>`;
|
||||
}).join('');
|
||||
</svg>`)
|
||||
return `<se-button data-shape="${key}"src="data:image/svg+xml;base64,${encoded}"></se-button>`
|
||||
}).join('')
|
||||
} catch (error) {
|
||||
console.error(`could not read file:${libDir}${lib}.json`, error);
|
||||
console.error(`could not read file:${libDir}${lib}.json`, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-explorerbutton', ExplorerButton);
|
||||
customElements.define('se-explorerbutton', ExplorerButton)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* globals svgEditor */
|
||||
import { t } from '../locale.js';
|
||||
const template = document.createElement('template');
|
||||
import { t } from '../locale.js'
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
:host {
|
||||
|
@ -79,7 +79,7 @@ template.innerHTML = `
|
|||
|
||||
</div>
|
||||
|
||||
`;
|
||||
`
|
||||
/**
|
||||
* @class FlyingButton
|
||||
*/
|
||||
|
@ -88,28 +88,30 @@ export class FlyingButton extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
// locate the component
|
||||
this.$button = this._shadowRoot.querySelector('.menu-button');
|
||||
this.$handle = this._shadowRoot.querySelector('.handle');
|
||||
this.$overall = this._shadowRoot.querySelector('.overall');
|
||||
this.$img = this._shadowRoot.querySelector('img');
|
||||
this.$menu = this._shadowRoot.querySelector('.menu');
|
||||
this.$button = this._shadowRoot.querySelector('.menu-button')
|
||||
this.$handle = this._shadowRoot.querySelector('.handle')
|
||||
this.$overall = this._shadowRoot.querySelector('.overall')
|
||||
this.$img = this._shadowRoot.querySelector('img')
|
||||
this.$menu = this._shadowRoot.querySelector('.menu')
|
||||
// the last element of the div is the slot
|
||||
// we retrieve all elements added in the slot (i.e. se-buttons)
|
||||
this.$elements = this.$menu.lastElementChild.assignedElements();
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath;
|
||||
this.$elements = this.$menu.lastElementChild.assignedElements()
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'title', 'pressed', 'disabled', 'opened' ];
|
||||
return ['title', 'pressed', 'disabled', 'opened']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -118,46 +120,47 @@ export class FlyingButton extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'title':
|
||||
{
|
||||
const shortcut = this.getAttribute('shortcut');
|
||||
this.$button.setAttribute('title', `${t(newValue)} ${shortcut ? `[${t(shortcut)}]` : ''}`);
|
||||
}
|
||||
break;
|
||||
case 'pressed':
|
||||
if (newValue) {
|
||||
this.$overall.classList.add('pressed');
|
||||
} else {
|
||||
this.$overall.classList.remove('pressed');
|
||||
}
|
||||
break;
|
||||
case 'opened':
|
||||
if (newValue) {
|
||||
this.$menu.classList.add('open');
|
||||
} else {
|
||||
this.$menu.classList.remove('open');
|
||||
}
|
||||
break;
|
||||
case 'disabled':
|
||||
if (newValue) {
|
||||
this.$overall.classList.add('disabled');
|
||||
} else {
|
||||
this.$overall.classList.remove('disabled');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
case 'title':
|
||||
{
|
||||
const shortcut = this.getAttribute('shortcut')
|
||||
this.$button.setAttribute('title', `${t(newValue)} ${shortcut ? `[${t(shortcut)}]` : ''}`)
|
||||
}
|
||||
break
|
||||
case 'pressed':
|
||||
if (newValue) {
|
||||
this.$overall.classList.add('pressed')
|
||||
} else {
|
||||
this.$overall.classList.remove('pressed')
|
||||
}
|
||||
break
|
||||
case 'opened':
|
||||
if (newValue) {
|
||||
this.$menu.classList.add('open')
|
||||
} else {
|
||||
this.$menu.classList.remove('open')
|
||||
}
|
||||
break
|
||||
case 'disabled':
|
||||
if (newValue) {
|
||||
this.$overall.classList.add('disabled')
|
||||
} else {
|
||||
this.$overall.classList.remove('disabled')
|
||||
}
|
||||
break
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get title () {
|
||||
return this.getAttribute('title');
|
||||
return this.getAttribute('title')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,14 +168,15 @@ export class FlyingButton extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set title (value) {
|
||||
this.setAttribute('title', value);
|
||||
this.setAttribute('title', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get pressed () {
|
||||
return this.hasAttribute('pressed');
|
||||
return this.hasAttribute('pressed')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -182,19 +186,20 @@ export class FlyingButton extends HTMLElement {
|
|||
set pressed (value) {
|
||||
// boolean value => existence = true
|
||||
if (value) {
|
||||
this.setAttribute('pressed', 'true');
|
||||
this.setAttribute('pressed', 'true')
|
||||
} else {
|
||||
this.removeAttribute('pressed', '');
|
||||
this.removeAttribute('pressed', '')
|
||||
// close also the menu if open
|
||||
this.removeAttribute('opened');
|
||||
this.removeAttribute('opened')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get opened () {
|
||||
return this.hasAttribute('opened');
|
||||
return this.hasAttribute('opened')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -204,17 +209,18 @@ export class FlyingButton extends HTMLElement {
|
|||
set opened (value) {
|
||||
// boolean value => existence = true
|
||||
if (value) {
|
||||
this.setAttribute('opened', 'opened');
|
||||
this.setAttribute('opened', 'opened')
|
||||
} else {
|
||||
this.removeAttribute('opened');
|
||||
this.removeAttribute('opened')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get disabled () {
|
||||
return this.hasAttribute('disabled');
|
||||
return this.hasAttribute('disabled')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -224,59 +230,60 @@ export class FlyingButton extends HTMLElement {
|
|||
set disabled (value) {
|
||||
// boolean value => existence = true
|
||||
if (value) {
|
||||
this.setAttribute('disabled', 'true');
|
||||
this.setAttribute('disabled', 'true')
|
||||
} else {
|
||||
this.removeAttribute('disabled', '');
|
||||
this.removeAttribute('disabled', '')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function connectedCallback
|
||||
* @returns {void}
|
||||
*/
|
||||
connectedCallback () {
|
||||
this.activeSlot = this.shadowRoot.querySelector('slot').assignedElements()[0];
|
||||
this.$img.setAttribute('src', this.imgPath + '/' + this.activeSlot.getAttribute('src'));
|
||||
this.activeSlot = this.shadowRoot.querySelector('slot').assignedElements()[0]
|
||||
this.$img.setAttribute('src', this.imgPath + '/' + this.activeSlot.getAttribute('src'))
|
||||
// capture click event on the button to manage the logic
|
||||
const onClickHandler = (ev) => {
|
||||
ev.stopPropagation();
|
||||
ev.stopPropagation()
|
||||
switch (ev.target.nodeName) {
|
||||
case 'SE-FLYINGBUTTON':
|
||||
if (this.pressed) {
|
||||
this.setAttribute('opened', 'opened');
|
||||
} else {
|
||||
case 'SE-FLYINGBUTTON':
|
||||
if (this.pressed) {
|
||||
this.setAttribute('opened', 'opened')
|
||||
} else {
|
||||
// launch current action
|
||||
this.activeSlot.click();
|
||||
this.setAttribute('pressed', 'pressed');
|
||||
}
|
||||
break;
|
||||
case 'SE-BUTTON':
|
||||
this.activeSlot.click()
|
||||
this.setAttribute('pressed', 'pressed')
|
||||
}
|
||||
break
|
||||
case 'SE-BUTTON':
|
||||
// change to the current action
|
||||
this.$img.setAttribute('src', this.imgPath + '/' + ev.target.getAttribute('src'));
|
||||
this.activeSlot = ev.target;
|
||||
this.setAttribute('pressed', 'pressed');
|
||||
// and close the menu
|
||||
this.$menu.classList.remove('open');
|
||||
break;
|
||||
case 'DIV':
|
||||
this.$img.setAttribute('src', this.imgPath + '/' + ev.target.getAttribute('src'))
|
||||
this.activeSlot = ev.target
|
||||
this.setAttribute('pressed', 'pressed')
|
||||
// and close the menu
|
||||
this.$menu.classList.remove('open')
|
||||
break
|
||||
case 'DIV':
|
||||
// this is a click on the handle so let's open/close the menu.
|
||||
if (this.opened) {
|
||||
this.removeAttribute('opened');
|
||||
} else {
|
||||
this.setAttribute('opened', 'opened');
|
||||
// In case menu scroll on top or bottom position based popup position set
|
||||
const rect = this.getBoundingClientRect();
|
||||
this.$menu.style.top = rect.top + "px";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.error('unkonw nodeName for:', ev.target, ev.target.className);
|
||||
if (this.opened) {
|
||||
this.removeAttribute('opened')
|
||||
} else {
|
||||
this.setAttribute('opened', 'opened')
|
||||
// In case menu scroll on top or bottom position based popup position set
|
||||
const rect = this.getBoundingClientRect()
|
||||
this.$menu.style.top = rect.top + 'px'
|
||||
}
|
||||
break
|
||||
default:
|
||||
console.error('unkonw nodeName for:', ev.target, ev.target.className)
|
||||
}
|
||||
};
|
||||
}
|
||||
// capture event from slots
|
||||
this.addEventListener('click', onClickHandler);
|
||||
this.$handle.addEventListener('click', onClickHandler);
|
||||
this.addEventListener('click', onClickHandler)
|
||||
this.$handle.addEventListener('click', onClickHandler)
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-flyingbutton', FlyingButton);
|
||||
customElements.define('se-flyingbutton', FlyingButton)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'elix/define/Input.js';
|
||||
import { t } from '../locale.js';
|
||||
import 'elix/define/Input.js'
|
||||
import { t } from '../locale.js'
|
||||
|
||||
const template = document.createElement('template');
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
div {
|
||||
|
@ -32,7 +32,7 @@ template.innerHTML = `
|
|||
<span id="label">label</span>
|
||||
<elix-input></elix-input>
|
||||
</div>
|
||||
`;
|
||||
`
|
||||
|
||||
/**
|
||||
* @class SEInput
|
||||
|
@ -42,24 +42,26 @@ export class SEInput extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
// locate the component
|
||||
this.$div = this._shadowRoot.querySelector('div');
|
||||
this.$img = this._shadowRoot.querySelector('img');
|
||||
this.$label = this.shadowRoot.getElementById('label');
|
||||
this.$event = new CustomEvent('change');
|
||||
this.$input = this._shadowRoot.querySelector('elix-input');
|
||||
this.$div = this._shadowRoot.querySelector('div')
|
||||
this.$img = this._shadowRoot.querySelector('img')
|
||||
this.$label = this.shadowRoot.getElementById('label')
|
||||
this.$event = new CustomEvent('change')
|
||||
this.$input = this._shadowRoot.querySelector('elix-input')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'value', 'label', 'src', 'size', 'title' ];
|
||||
return ['value', 'label', 'src', 'size', 'title']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -68,36 +70,37 @@ export class SEInput extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'title':
|
||||
this.$div.setAttribute('title', `${t(newValue)}`);
|
||||
break;
|
||||
case 'src':
|
||||
this.$img.setAttribute('src', newValue);
|
||||
this.$label.remove();
|
||||
break;
|
||||
case 'size':
|
||||
this.$input.setAttribute('size', newValue);
|
||||
break;
|
||||
case 'label':
|
||||
this.$label.textContent = t(newValue);
|
||||
this.$img.remove();
|
||||
break;
|
||||
case 'value':
|
||||
this.$input.value = newValue;
|
||||
break;
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
case 'title':
|
||||
this.$div.setAttribute('title', `${t(newValue)}`)
|
||||
break
|
||||
case 'src':
|
||||
this.$img.setAttribute('src', newValue)
|
||||
this.$label.remove()
|
||||
break
|
||||
case 'size':
|
||||
this.$input.setAttribute('size', newValue)
|
||||
break
|
||||
case 'label':
|
||||
this.$label.textContent = t(newValue)
|
||||
this.$img.remove()
|
||||
break
|
||||
case 'value':
|
||||
this.$input.value = newValue
|
||||
break
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get title () {
|
||||
return this.getAttribute('title');
|
||||
return this.getAttribute('title')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,14 +108,15 @@ export class SEInput extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set title (value) {
|
||||
this.setAttribute('title', value);
|
||||
this.setAttribute('title', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get label () {
|
||||
return this.getAttribute('label');
|
||||
return this.getAttribute('label')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -120,14 +124,15 @@ export class SEInput extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set label (value) {
|
||||
this.setAttribute('label', value);
|
||||
this.setAttribute('label', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get value () {
|
||||
return this.$input.value;
|
||||
return this.$input.value
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,14 +140,15 @@ export class SEInput extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set value (value) {
|
||||
this.$input.value = value;
|
||||
this.$input.value = value
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get src () {
|
||||
return this.getAttribute('src');
|
||||
return this.getAttribute('src')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -150,7 +156,7 @@ export class SEInput extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set src (value) {
|
||||
this.setAttribute('src', value);
|
||||
this.setAttribute('src', value)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,7 +164,7 @@ export class SEInput extends HTMLElement {
|
|||
* @returns {any}
|
||||
*/
|
||||
get size () {
|
||||
return this.getAttribute('size');
|
||||
return this.getAttribute('size')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -166,7 +172,7 @@ export class SEInput extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set size (value) {
|
||||
this.setAttribute('size', value);
|
||||
this.setAttribute('size', value)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,16 +181,16 @@ export class SEInput extends HTMLElement {
|
|||
*/
|
||||
connectedCallback () {
|
||||
this.$input.addEventListener('change', (e) => {
|
||||
e.preventDefault();
|
||||
this.value = e.target.value;
|
||||
this.dispatchEvent(this.$event);
|
||||
});
|
||||
e.preventDefault()
|
||||
this.value = e.target.value
|
||||
this.dispatchEvent(this.$event)
|
||||
})
|
||||
this.$input.addEventListener('keyup', (e) => {
|
||||
e.preventDefault();
|
||||
this.value = e.target.value;
|
||||
this.dispatchEvent(this.$event);
|
||||
});
|
||||
e.preventDefault()
|
||||
this.value = e.target.value
|
||||
this.dispatchEvent(this.$event)
|
||||
})
|
||||
}
|
||||
}
|
||||
// Register
|
||||
customElements.define('se-input', SEInput);
|
||||
customElements.define('se-input', SEInput)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* globals svgEditor */
|
||||
import 'elix/define/DropdownList.js';
|
||||
import { t } from '../locale.js';
|
||||
import 'elix/define/DropdownList.js'
|
||||
import { t } from '../locale.js'
|
||||
|
||||
const template = document.createElement('template');
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
elix-dropdown-list {
|
||||
|
@ -30,7 +30,7 @@ elix-dropdown-list::part(popup-toggle) {
|
|||
<slot></slot>
|
||||
</elix-dropdown-list>
|
||||
|
||||
`;
|
||||
`
|
||||
/**
|
||||
* @class SeList
|
||||
*/
|
||||
|
@ -39,22 +39,23 @@ export class SeList extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$dropdown = this._shadowRoot.querySelector('elix-dropdown-list');
|
||||
this.$label = this._shadowRoot.querySelector('label');
|
||||
this.$selection = this.$dropdown.shadowRoot.querySelector('#value');
|
||||
this.items = this.querySelectorAll("se-list-item");
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath;
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
this.$dropdown = this._shadowRoot.querySelector('elix-dropdown-list')
|
||||
this.$label = this._shadowRoot.querySelector('label')
|
||||
this.$selection = this.$dropdown.shadowRoot.querySelector('#value')
|
||||
this.items = this.querySelectorAll('se-list-item')
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'label', 'width', 'height', 'title', 'value' ];
|
||||
return ['label', 'width', 'height', 'title', 'value']
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,51 +66,51 @@ export class SeList extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
const currentObj = this;
|
||||
if (oldValue === newValue) return;
|
||||
const currentObj = this
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'title':
|
||||
this.$dropdown.setAttribute('title', t(newValue));
|
||||
break;
|
||||
case 'label':
|
||||
this.$label.textContent = t(newValue);
|
||||
break;
|
||||
case 'height':
|
||||
this.$dropdown.style.height = newValue;
|
||||
break;
|
||||
case 'width':
|
||||
this.$dropdown.style.width = newValue;
|
||||
break;
|
||||
case 'value':
|
||||
Array.from(this.items).forEach(function (element) {
|
||||
if(element.getAttribute("value") === newValue) {
|
||||
if (element.hasAttribute("src")) {
|
||||
case 'title':
|
||||
this.$dropdown.setAttribute('title', t(newValue))
|
||||
break
|
||||
case 'label':
|
||||
this.$label.textContent = t(newValue)
|
||||
break
|
||||
case 'height':
|
||||
this.$dropdown.style.height = newValue
|
||||
break
|
||||
case 'width':
|
||||
this.$dropdown.style.width = newValue
|
||||
break
|
||||
case 'value':
|
||||
Array.from(this.items).forEach(function (element) {
|
||||
if (element.getAttribute('value') === newValue) {
|
||||
if (element.hasAttribute('src')) {
|
||||
// empty current selection children
|
||||
while(currentObj.$selection.firstChild)
|
||||
currentObj.$selection.removeChild(currentObj.$selection.firstChild);
|
||||
// replace selection child with image of new value
|
||||
const img = document.createElement('img');
|
||||
img.src = currentObj.imgPath + '/' + element.getAttribute("src");
|
||||
img.style.height = element.getAttribute("img-height");
|
||||
img.setAttribute('title', t(element.getAttribute("title")));
|
||||
currentObj.$selection.append(img);
|
||||
} else {
|
||||
currentObj.$selection.textContent = t(element.getAttribute('option'));
|
||||
while (currentObj.$selection.firstChild) { currentObj.$selection.removeChild(currentObj.$selection.firstChild) }
|
||||
// replace selection child with image of new value
|
||||
const img = document.createElement('img')
|
||||
img.src = currentObj.imgPath + '/' + element.getAttribute('src')
|
||||
img.style.height = element.getAttribute('img-height')
|
||||
img.setAttribute('title', t(element.getAttribute('title')))
|
||||
currentObj.$selection.append(img)
|
||||
} else {
|
||||
currentObj.$selection.textContent = t(element.getAttribute('option'))
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
})
|
||||
break
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get title () {
|
||||
return this.getAttribute('title');
|
||||
return this.getAttribute('title')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,14 +118,15 @@ export class SeList extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set title (value) {
|
||||
this.setAttribute('title', value);
|
||||
this.setAttribute('title', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get label () {
|
||||
return this.getAttribute('label');
|
||||
return this.getAttribute('label')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,14 +134,15 @@ export class SeList extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set label (value) {
|
||||
this.setAttribute('label', value);
|
||||
this.setAttribute('label', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get width () {
|
||||
return this.getAttribute('width');
|
||||
return this.getAttribute('width')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,14 +150,15 @@ export class SeList extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set width (value) {
|
||||
this.setAttribute('width', value);
|
||||
this.setAttribute('width', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get height () {
|
||||
return this.getAttribute('height');
|
||||
return this.getAttribute('height')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -162,31 +166,32 @@ export class SeList extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set height (value) {
|
||||
this.setAttribute('height', value);
|
||||
this.setAttribute('height', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function connectedCallback
|
||||
* @returns {void}
|
||||
*/
|
||||
connectedCallback () {
|
||||
const currentObj = this;
|
||||
const currentObj = this
|
||||
this.$dropdown.addEventListener('selectedindexchange', (e) => {
|
||||
if (e?.detail?.selectedIndex !== undefined) {
|
||||
const value = this.$dropdown.selectedItem.getAttribute('value');
|
||||
const closeEvent = new CustomEvent('change', { detail: { value } });
|
||||
currentObj.dispatchEvent(closeEvent);
|
||||
currentObj.value = value;
|
||||
currentObj.setAttribute("value", value);
|
||||
const value = this.$dropdown.selectedItem.getAttribute('value')
|
||||
const closeEvent = new CustomEvent('change', { detail: { value } })
|
||||
currentObj.dispatchEvent(closeEvent)
|
||||
currentObj.value = value
|
||||
currentObj.setAttribute('value', value)
|
||||
}
|
||||
});
|
||||
})
|
||||
this.$dropdown.addEventListener('close', (_e) => {
|
||||
/** with Chrome, selectedindexchange does not fire consistently
|
||||
* unless you forec change in this close event
|
||||
*/
|
||||
this.$dropdown.selectedIndex = this.$dropdown.currentIndex;
|
||||
});
|
||||
this.$dropdown.selectedIndex = this.$dropdown.currentIndex
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-list', SeList);
|
||||
customElements.define('se-list', SeList)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* globals svgEditor */
|
||||
import 'elix/define/Option.js';
|
||||
import { t } from '../locale.js';
|
||||
import 'elix/define/Option.js'
|
||||
import { t } from '../locale.js'
|
||||
|
||||
const template = document.createElement('template');
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
elix-option{
|
||||
|
@ -17,7 +17,7 @@ template.innerHTML = `
|
|||
<img alt="icon" />
|
||||
<slot></slot>
|
||||
</elix-option>
|
||||
`;
|
||||
`
|
||||
/**
|
||||
* @class SeMenu
|
||||
*/
|
||||
|
@ -26,23 +26,24 @@ export class SeListItem extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$menuitem = this._shadowRoot.querySelector('elix-option');
|
||||
this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark');
|
||||
this.$svg.setAttribute('style', 'display: none;');
|
||||
this.$img = this._shadowRoot.querySelector('img');
|
||||
this.$img.setAttribute('style', 'display: none;');
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath;
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
this.$menuitem = this._shadowRoot.querySelector('elix-option')
|
||||
this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark')
|
||||
this.$svg.setAttribute('style', 'display: none;')
|
||||
this.$img = this._shadowRoot.querySelector('img')
|
||||
this.$img.setAttribute('style', 'display: none;')
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'option', 'src', 'title', 'img-height' ];
|
||||
return ['option', 'src', 'title', 'img-height']
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,33 +54,34 @@ export class SeListItem extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'option':
|
||||
this.$menuitem.setAttribute('option', newValue);
|
||||
this.$menuitem.textContent = t(newValue);
|
||||
break;
|
||||
case 'src':
|
||||
this.$img.setAttribute('style', 'display: block;');
|
||||
this.$img.setAttribute('src', this.imgPath + '/' + newValue);
|
||||
break;
|
||||
case 'title':
|
||||
this.$img.setAttribute('title', t(newValue));
|
||||
break;
|
||||
case 'img-height':
|
||||
this.$img.setAttribute('height', newValue);
|
||||
break;
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
case 'option':
|
||||
this.$menuitem.setAttribute('option', newValue)
|
||||
this.$menuitem.textContent = t(newValue)
|
||||
break
|
||||
case 'src':
|
||||
this.$img.setAttribute('style', 'display: block;')
|
||||
this.$img.setAttribute('src', this.imgPath + '/' + newValue)
|
||||
break
|
||||
case 'title':
|
||||
this.$img.setAttribute('title', t(newValue))
|
||||
break
|
||||
case 'img-height':
|
||||
this.$img.setAttribute('height', newValue)
|
||||
break
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get option () {
|
||||
return this.getAttribute('option');
|
||||
return this.getAttribute('option')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,14 +89,15 @@ export class SeListItem extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set option (value) {
|
||||
this.setAttribute('option', value);
|
||||
this.setAttribute('option', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get title () {
|
||||
return this.getAttribute('title');
|
||||
return this.getAttribute('title')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -102,14 +105,15 @@ export class SeListItem extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set title (value) {
|
||||
this.setAttribute('title', value);
|
||||
this.setAttribute('title', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get imgHeight () {
|
||||
return this.getAttribute('img-height');
|
||||
return this.getAttribute('img-height')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,14 +121,15 @@ export class SeListItem extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set imgHeight (value) {
|
||||
this.setAttribute('img-height', value);
|
||||
this.setAttribute('img-height', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get src () {
|
||||
return this.getAttribute('src');
|
||||
return this.getAttribute('src')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,9 +137,9 @@ export class SeListItem extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set src (value) {
|
||||
this.setAttribute('src', value);
|
||||
this.setAttribute('src', value)
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-list-item', SeListItem);
|
||||
customElements.define('se-list-item', SeListItem)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* globals svgEditor */
|
||||
import 'elix/define/MenuItem.js';
|
||||
import './sePlainMenuButton.js';
|
||||
import 'elix/define/MenuItem.js'
|
||||
import './sePlainMenuButton.js'
|
||||
|
||||
const template = document.createElement('template');
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
:host {
|
||||
|
@ -29,7 +29,7 @@ template.innerHTML = `
|
|||
<slot></slot>
|
||||
</elix-menu-button>
|
||||
|
||||
`;
|
||||
`
|
||||
/**
|
||||
* @class SeMenu
|
||||
*/
|
||||
|
@ -38,20 +38,21 @@ export class SeMenu extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$menu = this._shadowRoot.querySelector('elix-menu-button');
|
||||
this.$label = this.$menu.shadowRoot.querySelector('#popupToggle').shadowRoot;
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath;
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
this.$menu = this._shadowRoot.querySelector('elix-menu-button')
|
||||
this.$label = this.$menu.shadowRoot.querySelector('#popupToggle').shadowRoot
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'label', 'src' ];
|
||||
return ['label', 'src']
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,29 +63,30 @@ export class SeMenu extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
const image = new Image();
|
||||
if (oldValue === newValue) return;
|
||||
const image = new Image()
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'src':
|
||||
image.src = this.imgPath + '/' + newValue;
|
||||
image.width = 24;
|
||||
image.height = 24;
|
||||
this.$label.prepend(image);
|
||||
break;
|
||||
case 'label':
|
||||
this.$label.prepend(newValue);
|
||||
break;
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
case 'src':
|
||||
image.src = this.imgPath + '/' + newValue
|
||||
image.width = 24
|
||||
image.height = 24
|
||||
this.$label.prepend(image)
|
||||
break
|
||||
case 'label':
|
||||
this.$label.prepend(newValue)
|
||||
break
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get label () {
|
||||
return this.getAttribute('label');
|
||||
return this.getAttribute('label')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,14 +94,15 @@ export class SeMenu extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set label (value) {
|
||||
this.setAttribute('label', value);
|
||||
this.setAttribute('label', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get src () {
|
||||
return this.getAttribute('src');
|
||||
return this.getAttribute('src')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,7 +110,7 @@ export class SeMenu extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set src (value) {
|
||||
this.setAttribute('src', value);
|
||||
this.setAttribute('src', value)
|
||||
}
|
||||
/**
|
||||
* @function connectedCallback
|
||||
|
@ -125,4 +128,4 @@ export class SeMenu extends HTMLElement {
|
|||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-menu', SeMenu);
|
||||
customElements.define('se-menu', SeMenu)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* globals svgEditor */
|
||||
import 'elix/define/Menu.js';
|
||||
import 'elix/define/MenuItem.js';
|
||||
import { t } from '../locale.js';
|
||||
const template = document.createElement('template');
|
||||
import 'elix/define/Menu.js'
|
||||
import 'elix/define/MenuItem.js'
|
||||
import { t } from '../locale.js'
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
</style>
|
||||
|
@ -12,7 +12,7 @@ template.innerHTML = `
|
|||
<span style="margin-left: 7px;"></span>
|
||||
</div>
|
||||
</elix-menu-item>
|
||||
`;
|
||||
`
|
||||
/**
|
||||
* @class SeMenuItem
|
||||
*/
|
||||
|
@ -21,24 +21,26 @@ export class SeMenuItem extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$img = this._shadowRoot.querySelector('img');
|
||||
this.$label = this._shadowRoot.querySelector('span');
|
||||
this.$menuitem = this._shadowRoot.querySelector('elix-menu-item');
|
||||
this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark');
|
||||
this.$svg.setAttribute('style', 'display: none;');
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath;
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
this.$img = this._shadowRoot.querySelector('img')
|
||||
this.$label = this._shadowRoot.querySelector('span')
|
||||
this.$menuitem = this._shadowRoot.querySelector('elix-menu-item')
|
||||
this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark')
|
||||
this.$svg.setAttribute('style', 'display: none;')
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'label', 'src' ];
|
||||
return ['label', 'src']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -47,28 +49,29 @@ export class SeMenuItem extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
let shortcut = '';
|
||||
if (oldValue === newValue) return;
|
||||
let shortcut = ''
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'src':
|
||||
this.$img.style.display = 'inline-block';
|
||||
this.$img.setAttribute('src', this.imgPath + '/' + newValue);
|
||||
break;
|
||||
case 'label':
|
||||
shortcut = this.getAttribute('shortcut');
|
||||
this.$label.textContent = `${t(newValue)} ${shortcut ? `(${shortcut})` : ''}`;
|
||||
break;
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
case 'src':
|
||||
this.$img.style.display = 'inline-block'
|
||||
this.$img.setAttribute('src', this.imgPath + '/' + newValue)
|
||||
break
|
||||
case 'label':
|
||||
shortcut = this.getAttribute('shortcut')
|
||||
this.$label.textContent = `${t(newValue)} ${shortcut ? `(${shortcut})` : ''}`
|
||||
break
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get label () {
|
||||
return this.getAttribute('label');
|
||||
return this.getAttribute('label')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,14 +79,15 @@ export class SeMenuItem extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set label (value) {
|
||||
this.setAttribute('label', value);
|
||||
this.setAttribute('label', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get src () {
|
||||
return this.getAttribute('src');
|
||||
return this.getAttribute('src')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,7 +95,7 @@ export class SeMenuItem extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set src (value) {
|
||||
this.setAttribute('src', value);
|
||||
this.setAttribute('src', value)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,24 +104,24 @@ export class SeMenuItem extends HTMLElement {
|
|||
*/
|
||||
connectedCallback () {
|
||||
// capture shortcuts
|
||||
const shortcut = this.getAttribute('shortcut');
|
||||
const shortcut = this.getAttribute('shortcut')
|
||||
if (shortcut) {
|
||||
// register the keydown event
|
||||
document.addEventListener('keydown', (e) => {
|
||||
// only track keyboard shortcuts for the body containing the SVG-Editor
|
||||
if (e.target.nodeName !== 'BODY') return;
|
||||
if (e.target.nodeName !== 'BODY') return
|
||||
// normalize key
|
||||
const key = `${(e.metaKey) ? 'meta+' : ''}${(e.ctrlKey) ? 'ctrl+' : ''}${e.key.toUpperCase()}`;
|
||||
if (shortcut !== key) return;
|
||||
const key = `${(e.metaKey) ? 'meta+' : ''}${(e.ctrlKey) ? 'ctrl+' : ''}${e.key.toUpperCase()}`
|
||||
if (shortcut !== key) return
|
||||
// launch the click event
|
||||
if (this.id) {
|
||||
document.getElementById(this.id).click();
|
||||
document.getElementById(this.id).click()
|
||||
}
|
||||
e.preventDefault();
|
||||
});
|
||||
e.preventDefault()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-menu-item', SeMenuItem);
|
||||
customElements.define('se-menu-item', SeMenuItem)
|
||||
|
|
|
@ -11,9 +11,9 @@ const palette = [
|
|||
'#ffaaaa', '#ffd4aa', '#ffffaa', '#d4ffaa',
|
||||
'#aaffaa', '#aaffd4', '#aaffff', '#aad4ff',
|
||||
'#aaaaff', '#d4aaff', '#ffaaff', '#ffaad4'
|
||||
];
|
||||
]
|
||||
|
||||
const template = document.createElement('template');
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
.square {
|
||||
|
@ -50,7 +50,7 @@ template.innerHTML = `
|
|||
<div id="js-se-palette">
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
`
|
||||
|
||||
/**
|
||||
* @class SEPalette
|
||||
|
@ -60,38 +60,38 @@ export class SEPalette extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$strip = this._shadowRoot.querySelector('#js-se-palette');
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
this.$strip = this._shadowRoot.querySelector('#js-se-palette')
|
||||
palette.forEach((rgb) => {
|
||||
const newDiv = document.createElement('div');
|
||||
newDiv.classList.add('square');
|
||||
if(rgb === 'none') {
|
||||
const img = document.createElement('img');
|
||||
img.src = `data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgY2xhc3M9InN2Z19pY29uIj48c3ZnIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgICA8bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiNkNDAwMDAiIGlkPSJzdmdfOTAiIHkyPSIyNCIgeDI9IjI0IiB5MT0iMCIgeDE9IjAiLz4KICAgIDxsaW5lIGlkPSJzdmdfOTIiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2Q0MDAwMCIgeTI9IjI0IiB4Mj0iMCIgeTE9IjAiIHgxPSIyNCIvPgogIDwvc3ZnPjwvc3ZnPg==`;
|
||||
img.style.width = "15px";
|
||||
img.style.height = "15px";
|
||||
newDiv.append(img);
|
||||
const newDiv = document.createElement('div')
|
||||
newDiv.classList.add('square')
|
||||
if (rgb === 'none') {
|
||||
const img = document.createElement('img')
|
||||
img.src = 'data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgY2xhc3M9InN2Z19pY29uIj48c3ZnIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgICA8bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiNkNDAwMDAiIGlkPSJzdmdfOTAiIHkyPSIyNCIgeDI9IjI0IiB5MT0iMCIgeDE9IjAiLz4KICAgIDxsaW5lIGlkPSJzdmdfOTIiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2Q0MDAwMCIgeTI9IjI0IiB4Mj0iMCIgeTE9IjAiIHgxPSIyNCIvPgogIDwvc3ZnPjwvc3ZnPg=='
|
||||
img.style.width = '15px'
|
||||
img.style.height = '15px'
|
||||
newDiv.append(img)
|
||||
} else {
|
||||
newDiv.style.backgroundColor = rgb;
|
||||
newDiv.style.backgroundColor = rgb
|
||||
}
|
||||
newDiv.dataset.rgb = rgb;
|
||||
newDiv.dataset.rgb = rgb
|
||||
newDiv.addEventListener('click', (evt) => {
|
||||
evt.preventDefault();
|
||||
evt.preventDefault()
|
||||
// shift key or right click for stroke
|
||||
const picker = evt.shiftKey || evt.button === 2 ? 'stroke' : 'fill';
|
||||
let color = newDiv.dataset.rgb;
|
||||
const picker = evt.shiftKey || evt.button === 2 ? 'stroke' : 'fill'
|
||||
let color = newDiv.dataset.rgb
|
||||
// Webkit-based browsers returned 'initial' here for no stroke
|
||||
if (color === 'none' || color === 'transparent' || color === 'initial') {
|
||||
color = 'none';
|
||||
color = 'none'
|
||||
}
|
||||
const paletteEvent = new CustomEvent('change', { detail: { picker, color }, bubbles: false });
|
||||
this.dispatchEvent(paletteEvent);
|
||||
});
|
||||
this.$strip.append(newDiv);
|
||||
});
|
||||
const paletteEvent = new CustomEvent('change', { detail: { picker, color }, bubbles: false })
|
||||
this.dispatchEvent(paletteEvent)
|
||||
})
|
||||
this.$strip.append(newDiv)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,15 +100,17 @@ export class SEPalette extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
init (i18next) {
|
||||
this.setAttribute('ui-palette_info', i18next.t('ui.palette_info'));
|
||||
this.setAttribute('ui-palette_info', i18next.t('ui.palette_info'))
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'ui-palette_info' ];
|
||||
return ['ui-palette_info']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -117,12 +119,13 @@ export class SEPalette extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
let node;
|
||||
let node
|
||||
if (name === 'ui-palette_info') {
|
||||
node = this._shadowRoot.querySelector('#palette_holder');
|
||||
node.setAttribute('title', newValue);
|
||||
node = this._shadowRoot.querySelector('#palette_holder')
|
||||
node.setAttribute('title', newValue)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function connectedCallback
|
||||
* @returns {void}
|
||||
|
@ -132,4 +135,4 @@ export class SEPalette extends HTMLElement {
|
|||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-palette', SEPalette);
|
||||
customElements.define('se-palette', SEPalette)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { template } from 'elix/src/base/internal.js';
|
||||
import { fragmentFrom } from 'elix/src/core/htmlLiterals.js';
|
||||
import PlainButton from 'elix/src/plain/PlainButton.js';
|
||||
import { template } from 'elix/src/base/internal.js'
|
||||
import { fragmentFrom } from 'elix/src/core/htmlLiterals.js'
|
||||
import PlainButton from 'elix/src/plain/PlainButton.js'
|
||||
|
||||
/**
|
||||
* @class SePlainBorderButton
|
||||
|
@ -13,7 +13,7 @@ class SePlainBorderButton extends PlainButton {
|
|||
* @returns {PlainObject}
|
||||
*/
|
||||
get [template] () {
|
||||
const result = super[template];
|
||||
const result = super[template]
|
||||
result.content.append(
|
||||
fragmentFrom.html`
|
||||
<style>
|
||||
|
@ -23,9 +23,9 @@ class SePlainBorderButton extends PlainButton {
|
|||
}
|
||||
</style>
|
||||
`
|
||||
);
|
||||
return result;
|
||||
)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
export default SePlainBorderButton;
|
||||
export default SePlainBorderButton
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import PlainMenuButton from 'elix/src/plain/PlainMenuButton.js';
|
||||
import { defaultState } from 'elix/src/base/internal.js';
|
||||
import sePlainBorderButton from './sePlainBorderButton.js';
|
||||
import PlainMenuButton from 'elix/src/plain/PlainMenuButton.js'
|
||||
import { defaultState } from 'elix/src/base/internal.js'
|
||||
import sePlainBorderButton from './sePlainBorderButton.js'
|
||||
|
||||
/**
|
||||
* @class ElixMenuButton
|
||||
|
@ -13,8 +13,8 @@ export default class ElixMenuButton extends PlainMenuButton {
|
|||
get [defaultState] () {
|
||||
return Object.assign(super[defaultState], {
|
||||
sourcePartType: sePlainBorderButton
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('elix-menu-button', ElixMenuButton);
|
||||
customElements.define('elix-menu-button', ElixMenuButton)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { t } from '../locale.js';
|
||||
const template = document.createElement('template');
|
||||
import { t } from '../locale.js'
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
select {
|
||||
|
@ -21,7 +21,7 @@ label {
|
|||
<select>
|
||||
</select>
|
||||
|
||||
`;
|
||||
`
|
||||
/**
|
||||
* @class SeList
|
||||
*/
|
||||
|
@ -30,19 +30,20 @@ export class SeSelect extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$select = this._shadowRoot.querySelector('select');
|
||||
this.$label = this._shadowRoot.querySelector('label');
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
this.$select = this._shadowRoot.querySelector('select')
|
||||
this.$label = this._shadowRoot.querySelector('label')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'label', 'width', 'height', 'options', 'values', 'title', 'disabled' ];
|
||||
return ['label', 'width', 'height', 'options', 'values', 'title', 'disabled']
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,64 +54,63 @@ export class SeSelect extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
let options;
|
||||
if (oldValue === newValue) return;
|
||||
let options
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'label':
|
||||
this.$label.textContent = t(newValue);
|
||||
break;
|
||||
case 'title':
|
||||
this.$select.setAttribute("title", t(newValue));
|
||||
break;
|
||||
case 'disabled':
|
||||
if(newValue === null) {
|
||||
this.$select.removeAttribute("disabled");
|
||||
} else {
|
||||
this.$select.setAttribute("disabled", newValue);
|
||||
}
|
||||
break;
|
||||
case 'height':
|
||||
this.$select.style.height = newValue;
|
||||
break;
|
||||
case 'width':
|
||||
this.$select.style.width = newValue;
|
||||
break;
|
||||
case 'options':
|
||||
if(newValue === "") {
|
||||
while(this.$select.firstChild)
|
||||
this.$select.removeChild(this.$select.firstChild);
|
||||
} else {
|
||||
options = newValue.split(',');
|
||||
options.forEach((option) => {
|
||||
const optionNode = document.createElement("OPTION");
|
||||
const text = document.createTextNode(t(option));
|
||||
optionNode.appendChild(text);
|
||||
this.$select.appendChild(optionNode);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'values':
|
||||
if(newValue === "") {
|
||||
while(this.$select.firstChild)
|
||||
this.$select.removeChild(this.$select.firstChild);
|
||||
} else {
|
||||
options = newValue.split('::');
|
||||
options.forEach((option, index) => {
|
||||
this.$select.children[index].setAttribute('value', option);
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
case 'label':
|
||||
this.$label.textContent = t(newValue)
|
||||
break
|
||||
case 'title':
|
||||
this.$select.setAttribute('title', t(newValue))
|
||||
break
|
||||
case 'disabled':
|
||||
if (newValue === null) {
|
||||
this.$select.removeAttribute('disabled')
|
||||
} else {
|
||||
this.$select.setAttribute('disabled', newValue)
|
||||
}
|
||||
break
|
||||
case 'height':
|
||||
this.$select.style.height = newValue
|
||||
break
|
||||
case 'width':
|
||||
this.$select.style.width = newValue
|
||||
break
|
||||
case 'options':
|
||||
if (newValue === '') {
|
||||
while (this.$select.firstChild) { this.$select.removeChild(this.$select.firstChild) }
|
||||
} else {
|
||||
options = newValue.split(',')
|
||||
options.forEach((option) => {
|
||||
const optionNode = document.createElement('OPTION')
|
||||
const text = document.createTextNode(t(option))
|
||||
optionNode.appendChild(text)
|
||||
this.$select.appendChild(optionNode)
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'values':
|
||||
if (newValue === '') {
|
||||
while (this.$select.firstChild) { this.$select.removeChild(this.$select.firstChild) }
|
||||
} else {
|
||||
options = newValue.split('::')
|
||||
options.forEach((option, index) => {
|
||||
this.$select.children[index].setAttribute('value', option)
|
||||
})
|
||||
}
|
||||
break
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get label () {
|
||||
return this.getAttribute('label');
|
||||
return this.getAttribute('label')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -118,14 +118,15 @@ export class SeSelect extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set label (value) {
|
||||
this.setAttribute('label', value);
|
||||
this.setAttribute('label', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get width () {
|
||||
return this.getAttribute('width');
|
||||
return this.getAttribute('width')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,14 +134,15 @@ export class SeSelect extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set width (value) {
|
||||
this.setAttribute('width', value);
|
||||
this.setAttribute('width', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get height () {
|
||||
return this.getAttribute('height');
|
||||
return this.getAttribute('height')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -148,14 +150,15 @@ export class SeSelect extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set height (value) {
|
||||
this.setAttribute('height', value);
|
||||
this.setAttribute('height', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get value () {
|
||||
return this.$select.value;
|
||||
return this.$select.value
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -163,14 +166,15 @@ export class SeSelect extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set value (value) {
|
||||
this.$select.value = value;
|
||||
this.$select.value = value
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get disabled () {
|
||||
return this.$select.getAttribute('disabled');
|
||||
return this.$select.getAttribute('disabled')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -178,22 +182,23 @@ export class SeSelect extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set disabled (value) {
|
||||
this.$select.setAttribute('disabled', value);
|
||||
this.$select.setAttribute('disabled', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function connectedCallback
|
||||
* @returns {void}
|
||||
*/
|
||||
connectedCallback () {
|
||||
const currentObj = this;
|
||||
const currentObj = this
|
||||
this.$select.addEventListener('change', () => {
|
||||
const value = this.$select.value;
|
||||
const closeEvent = new CustomEvent('change', { detail: { value } });
|
||||
currentObj.dispatchEvent(closeEvent);
|
||||
currentObj.value = value;
|
||||
});
|
||||
const value = this.$select.value
|
||||
const closeEvent = new CustomEvent('change', { detail: { value } })
|
||||
currentObj.dispatchEvent(closeEvent)
|
||||
currentObj.value = value
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-select', SeSelect);
|
||||
customElements.define('se-select', SeSelect)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* globals svgEditor */
|
||||
import '../dialogs/se-elix/define/NumberSpinBox.js';
|
||||
import { t } from '../locale.js';
|
||||
import '../dialogs/se-elix/define/NumberSpinBox.js'
|
||||
import { t } from '../locale.js'
|
||||
|
||||
const template = document.createElement('template');
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
div {
|
||||
|
@ -49,7 +49,7 @@ template.innerHTML = `
|
|||
<span id="label">label</span>
|
||||
<elix-number-spin-box min="1" step="1"></elix-number-spin-box>
|
||||
</div>
|
||||
`;
|
||||
`
|
||||
|
||||
/**
|
||||
* @class SESpinInput
|
||||
|
@ -59,25 +59,27 @@ export class SESpinInput extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
// locate the component
|
||||
this.$div = this._shadowRoot.querySelector('div');
|
||||
this.$img = this._shadowRoot.querySelector('img');
|
||||
this.$label = this.shadowRoot.getElementById('label');
|
||||
this.$event = new CustomEvent('change');
|
||||
this.$input = this._shadowRoot.querySelector('elix-number-spin-box');
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath;
|
||||
this.$div = this._shadowRoot.querySelector('div')
|
||||
this.$img = this._shadowRoot.querySelector('img')
|
||||
this.$label = this.shadowRoot.getElementById('label')
|
||||
this.$event = new CustomEvent('change')
|
||||
this.$input = this._shadowRoot.querySelector('elix-number-spin-box')
|
||||
this.imgPath = svgEditor.configObj.curConfig.imgPath
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'value', 'label', 'src', 'size', 'min', 'max', 'step', 'title' ];
|
||||
return ['value', 'label', 'src', 'size', 'min', 'max', 'step', 'title']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -86,52 +88,53 @@ export class SESpinInput extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'title':
|
||||
{
|
||||
const shortcut = this.getAttribute('shortcut');
|
||||
this.$div.setAttribute('title', `${t(newValue)} ${shortcut ? `[${t(shortcut)}]` : ''}`);
|
||||
}
|
||||
break;
|
||||
case 'src':
|
||||
this.$img.setAttribute('src', this.imgPath + '/' + newValue);
|
||||
this.$label.remove();
|
||||
this.$div.classList.add('imginside');
|
||||
break;
|
||||
case 'size':
|
||||
case 'title':
|
||||
{
|
||||
const shortcut = this.getAttribute('shortcut')
|
||||
this.$div.setAttribute('title', `${t(newValue)} ${shortcut ? `[${t(shortcut)}]` : ''}`)
|
||||
}
|
||||
break
|
||||
case 'src':
|
||||
this.$img.setAttribute('src', this.imgPath + '/' + newValue)
|
||||
this.$label.remove()
|
||||
this.$div.classList.add('imginside')
|
||||
break
|
||||
case 'size':
|
||||
// access to the underlying input box
|
||||
this.$input.shadowRoot.getElementById('input').size = newValue;
|
||||
// below seems mandatory to override the default width style that takes precedence on size
|
||||
this.$input.shadowRoot.getElementById('input').style.width = 'unset';
|
||||
break;
|
||||
case 'step':
|
||||
this.$input.setAttribute('step', newValue);
|
||||
break;
|
||||
case 'min':
|
||||
this.$input.setAttribute('min', newValue);
|
||||
break;
|
||||
case 'max':
|
||||
this.$input.setAttribute('max', newValue);
|
||||
break;
|
||||
case 'label':
|
||||
this.$label.textContent = t(newValue);
|
||||
this.$img.remove();
|
||||
break;
|
||||
case 'value':
|
||||
this.$input.value = newValue;
|
||||
break;
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
this.$input.shadowRoot.getElementById('input').size = newValue
|
||||
// below seems mandatory to override the default width style that takes precedence on size
|
||||
this.$input.shadowRoot.getElementById('input').style.width = 'unset'
|
||||
break
|
||||
case 'step':
|
||||
this.$input.setAttribute('step', newValue)
|
||||
break
|
||||
case 'min':
|
||||
this.$input.setAttribute('min', newValue)
|
||||
break
|
||||
case 'max':
|
||||
this.$input.setAttribute('max', newValue)
|
||||
break
|
||||
case 'label':
|
||||
this.$label.textContent = t(newValue)
|
||||
this.$img.remove()
|
||||
break
|
||||
case 'value':
|
||||
this.$input.value = newValue
|
||||
break
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get title () {
|
||||
return this.getAttribute('title');
|
||||
return this.getAttribute('title')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,14 +142,15 @@ export class SESpinInput extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set title (value) {
|
||||
this.setAttribute('title', value);
|
||||
this.setAttribute('title', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get label () {
|
||||
return this.getAttribute('label');
|
||||
return this.getAttribute('label')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -154,14 +158,15 @@ export class SESpinInput extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set label (value) {
|
||||
this.setAttribute('label', value);
|
||||
this.setAttribute('label', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get value () {
|
||||
return this.$input.value;
|
||||
return this.$input.value
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -169,14 +174,15 @@ export class SESpinInput extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set value (value) {
|
||||
this.$input.value = value;
|
||||
this.$input.value = value
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get src () {
|
||||
return this.getAttribute('src');
|
||||
return this.getAttribute('src')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,7 +190,7 @@ export class SESpinInput extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set src (value) {
|
||||
this.setAttribute('src', value);
|
||||
this.setAttribute('src', value)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -192,7 +198,7 @@ export class SESpinInput extends HTMLElement {
|
|||
* @returns {any}
|
||||
*/
|
||||
get size () {
|
||||
return this.getAttribute('size');
|
||||
return this.getAttribute('size')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -200,7 +206,7 @@ export class SESpinInput extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set size (value) {
|
||||
this.setAttribute('size', value);
|
||||
this.setAttribute('size', value)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -208,31 +214,31 @@ export class SESpinInput extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
connectedCallback () {
|
||||
const shadow = this.$input.shadowRoot;
|
||||
const childNodes = Array.from(shadow.childNodes);
|
||||
childNodes.forEach( (childNode) => {
|
||||
if(childNode?.id === "input") {
|
||||
const shadow = this.$input.shadowRoot
|
||||
const childNodes = Array.from(shadow.childNodes)
|
||||
childNodes.forEach((childNode) => {
|
||||
if (childNode?.id === 'input') {
|
||||
childNode.addEventListener('keyup', (e) => {
|
||||
e.preventDefault();
|
||||
e.preventDefault()
|
||||
if (!isNaN(e.target.value)) {
|
||||
this.value = e.target.value;
|
||||
this.dispatchEvent(this.$event);
|
||||
this.value = e.target.value
|
||||
this.dispatchEvent(this.$event)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
});
|
||||
})
|
||||
this.$input.addEventListener('change', (e) => {
|
||||
e.preventDefault();
|
||||
this.value = e.target.value;
|
||||
this.dispatchEvent(this.$event);
|
||||
});
|
||||
e.preventDefault()
|
||||
this.value = e.target.value
|
||||
this.dispatchEvent(this.$event)
|
||||
})
|
||||
this.$input.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
this.value = e.target.value;
|
||||
this.dispatchEvent(this.$event);
|
||||
});
|
||||
e.preventDefault()
|
||||
this.value = e.target.value
|
||||
this.dispatchEvent(this.$event)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-spin-input', SESpinInput);
|
||||
customElements.define('se-spin-input', SESpinInput)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { t } from '../locale.js';
|
||||
const template = document.createElement('template');
|
||||
import { t } from '../locale.js'
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
#layersLabel {
|
||||
|
@ -9,7 +9,7 @@ template.innerHTML = `
|
|||
}
|
||||
</style>
|
||||
<div></div>
|
||||
`;
|
||||
`
|
||||
/**
|
||||
* @class SeText
|
||||
*/
|
||||
|
@ -18,20 +18,22 @@ export class SeText extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
// locate the component
|
||||
this.$div = this._shadowRoot.querySelector('div');
|
||||
this.$div = this._shadowRoot.querySelector('div')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'text', 'value', 'style', 'title', 'id' ];
|
||||
return ['text', 'value', 'style', 'title', 'id']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -40,35 +42,36 @@ export class SeText extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'text':
|
||||
this.$div.textContent = t(newValue);
|
||||
break;
|
||||
case 'title':
|
||||
this.$div.setAttribute("title", t(newValue));
|
||||
break;
|
||||
case 'style':
|
||||
this.$div.style = newValue;
|
||||
break;
|
||||
case 'id':
|
||||
this.$div.id = newValue;
|
||||
break;
|
||||
case 'value':
|
||||
this.$div.value = newValue;
|
||||
//this.$div.setAttribute("value", newValue);
|
||||
break;
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
case 'text':
|
||||
this.$div.textContent = t(newValue)
|
||||
break
|
||||
case 'title':
|
||||
this.$div.setAttribute('title', t(newValue))
|
||||
break
|
||||
case 'style':
|
||||
this.$div.style = newValue
|
||||
break
|
||||
case 'id':
|
||||
this.$div.id = newValue
|
||||
break
|
||||
case 'value':
|
||||
this.$div.value = newValue
|
||||
// this.$div.setAttribute("value", newValue);
|
||||
break
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get text () {
|
||||
return this.$div.textContent;
|
||||
return this.$div.textContent
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,14 +79,15 @@ export class SeText extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set text (value) {
|
||||
this.$div.setAttribute("title", t(value));
|
||||
this.$div.setAttribute('title', t(value))
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get value () {
|
||||
return this.value;
|
||||
return this.value
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,14 +95,15 @@ export class SeText extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set value (value) {
|
||||
this.value = value;
|
||||
this.value = value
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get title () {
|
||||
return this.getAttribute('title');
|
||||
return this.getAttribute('title')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,8 +111,9 @@ export class SeText extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set title (value) {
|
||||
this.setAttribute('title', value);
|
||||
this.setAttribute('title', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function connectedCallback
|
||||
* @returns {void}
|
||||
|
@ -118,4 +124,4 @@ export class SeText extends HTMLElement {
|
|||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-text', SeText);
|
||||
customElements.define('se-text', SeText)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* globals svgEditor */
|
||||
import ListComboBox from 'elix/define/ListComboBox.js';
|
||||
import * as internal from 'elix/src/base/internal.js';
|
||||
import { templateFrom, fragmentFrom } from 'elix/src/core/htmlLiterals.js';
|
||||
import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js';
|
||||
import ListComboBox from 'elix/define/ListComboBox.js'
|
||||
import * as internal from 'elix/src/base/internal.js'
|
||||
import { templateFrom, fragmentFrom } from 'elix/src/core/htmlLiterals.js'
|
||||
import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js'
|
||||
|
||||
/**
|
||||
* @class Dropdown
|
||||
|
@ -17,20 +17,21 @@ class Zoom extends ListComboBox {
|
|||
inputPartType: NumberSpinBox,
|
||||
src: 'logo.svg',
|
||||
inputsize: '100%'
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {PlainObject}
|
||||
*/
|
||||
get [internal.template] () {
|
||||
const result = super[internal.template];
|
||||
const source = result.content.getElementById('source');
|
||||
const result = super[internal.template]
|
||||
const source = result.content.getElementById('source')
|
||||
// add a icon before our dropdown
|
||||
source.prepend(fragmentFrom.html`
|
||||
<img src="zoom" alt="icon" width="18" height="18">
|
||||
</img>
|
||||
`.cloneNode(true));
|
||||
`.cloneNode(true))
|
||||
// change the style so it fits in our toolbar
|
||||
result.content.append(
|
||||
templateFrom.html`
|
||||
|
@ -57,16 +58,18 @@ class Zoom extends ListComboBox {
|
|||
|
||||
</style>
|
||||
`.content
|
||||
);
|
||||
return result;
|
||||
)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'title', 'src', 'inputsize', 'value' ];
|
||||
return ['title', 'src', 'inputsize', 'value']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -75,97 +78,104 @@ class Zoom extends ListComboBox {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue && name !== "src") return;
|
||||
if (oldValue === newValue && name !== 'src') return
|
||||
switch (name) {
|
||||
case 'title':
|
||||
case 'title':
|
||||
// this.$span.setAttribute('title', `${newValue} ${shortcut ? `[${shortcut}]` : ''}`);
|
||||
break;
|
||||
case 'src':
|
||||
{
|
||||
const { imgPath } = svgEditor.configObj.curConfig;
|
||||
this.src = imgPath + '/' + newValue;
|
||||
}
|
||||
break;
|
||||
case 'inputsize':
|
||||
this.inputsize = newValue;
|
||||
break;
|
||||
default:
|
||||
super.attributeChangedCallback(name, oldValue, newValue);
|
||||
break;
|
||||
break
|
||||
case 'src':
|
||||
{
|
||||
const { imgPath } = svgEditor.configObj.curConfig
|
||||
this.src = imgPath + '/' + newValue
|
||||
}
|
||||
break
|
||||
case 'inputsize':
|
||||
this.inputsize = newValue
|
||||
break
|
||||
default:
|
||||
super.attributeChangedCallback(name, oldValue, newValue)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function [internal.render]
|
||||
* @param {PlainObject} changed
|
||||
* @returns {void}
|
||||
*/
|
||||
[internal.render] (changed) {
|
||||
super[internal.render](changed);
|
||||
super[internal.render](changed)
|
||||
if (this[internal.firstRender]) {
|
||||
this.$img = this.shadowRoot.querySelector('img');
|
||||
this.$input = this.shadowRoot.getElementById('input');
|
||||
this.$img = this.shadowRoot.querySelector('img')
|
||||
this.$input = this.shadowRoot.getElementById('input')
|
||||
}
|
||||
if (changed.src) {
|
||||
this.$img.setAttribute('src', this[internal.state].src);
|
||||
this.$img.setAttribute('src', this[internal.state].src)
|
||||
}
|
||||
if (changed.inputsize) {
|
||||
this.$input.shadowRoot.querySelector('[part~="input"]').style.width = this[internal.state].inputsize;
|
||||
this.$input.shadowRoot.querySelector('[part~="input"]').style.width = this[internal.state].inputsize
|
||||
}
|
||||
if (changed.inputPartType) {
|
||||
// Wire up handler on new input.
|
||||
this.addEventListener('close', (e) => {
|
||||
e.preventDefault();
|
||||
const value = e.detail?.closeResult?.getAttribute('value');
|
||||
e.preventDefault()
|
||||
const value = e.detail?.closeResult?.getAttribute('value')
|
||||
if (value) {
|
||||
const closeEvent = new CustomEvent('change', { detail: { value } });
|
||||
this.dispatchEvent(closeEvent);
|
||||
const closeEvent = new CustomEvent('change', { detail: { value } })
|
||||
this.dispatchEvent(closeEvent)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function src
|
||||
* @returns {string} src
|
||||
*/
|
||||
get src () {
|
||||
return this[internal.state].src;
|
||||
return this[internal.state].src
|
||||
}
|
||||
|
||||
/**
|
||||
* @function src
|
||||
* @returns {void}
|
||||
*/
|
||||
set src (src) {
|
||||
this[internal.setState]({ src });
|
||||
this[internal.setState]({ src })
|
||||
}
|
||||
|
||||
/**
|
||||
* @function inputsize
|
||||
* @returns {string} src
|
||||
*/
|
||||
get inputsize () {
|
||||
return this[internal.state].inputsize;
|
||||
return this[internal.state].inputsize
|
||||
}
|
||||
|
||||
/**
|
||||
* @function src
|
||||
* @returns {void}
|
||||
*/
|
||||
set inputsize (inputsize) {
|
||||
this[internal.setState]({ inputsize });
|
||||
this[internal.setState]({ inputsize })
|
||||
}
|
||||
|
||||
/**
|
||||
* @function value
|
||||
* @returns {string} src
|
||||
*/
|
||||
get value () {
|
||||
return this[internal.state].value;
|
||||
return this[internal.state].value
|
||||
}
|
||||
|
||||
/**
|
||||
* @function value
|
||||
* @returns {void}
|
||||
*/
|
||||
set value (value) {
|
||||
this[internal.setState]({ value });
|
||||
this[internal.setState]({ value })
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-zoom', Zoom);
|
||||
customElements.define('se-zoom', Zoom)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* @author Adam Bender
|
||||
*/
|
||||
|
||||
let contextMenuExtensions = {};
|
||||
let contextMenuExtensions = {}
|
||||
|
||||
/**
|
||||
* Signature depends on what the user adds; in the case of our uses with
|
||||
|
@ -27,8 +27,8 @@ let contextMenuExtensions = {};
|
|||
* @returns {boolean}
|
||||
*/
|
||||
const menuItemIsValid = function (menuItem) {
|
||||
return menuItem && menuItem.id && menuItem.label && menuItem.action && typeof menuItem.action === 'function';
|
||||
};
|
||||
return menuItem && menuItem.id && menuItem.label && menuItem.action && typeof menuItem.action === 'function'
|
||||
}
|
||||
|
||||
/**
|
||||
* @function module:contextmenu.add
|
||||
|
@ -42,15 +42,15 @@ export const add = function (menuItem) {
|
|||
throw new TypeError(
|
||||
'Menu items must be defined and have at least properties: ' +
|
||||
'id, label, action, where action must be a function'
|
||||
);
|
||||
)
|
||||
}
|
||||
if (menuItem.id in contextMenuExtensions) {
|
||||
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
|
||||
contextMenuExtensions[menuItem.id] = menuItem;
|
||||
contextMenuExtensions[menuItem.id] = menuItem
|
||||
// TODO: Need to consider how to handle custom enable/disable behavior
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @function module:contextmenu.hasCustomHandler
|
||||
|
@ -58,8 +58,8 @@ export const add = function (menuItem) {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
export const hasCustomHandler = function (handlerKey) {
|
||||
return Boolean(contextMenuExtensions[handlerKey]);
|
||||
};
|
||||
return Boolean(contextMenuExtensions[handlerKey])
|
||||
}
|
||||
|
||||
/**
|
||||
* @function module:contextmenu.getCustomHandler
|
||||
|
@ -67,8 +67,8 @@ export const hasCustomHandler = function (handlerKey) {
|
|||
* @returns {module:contextmenu.MenuItemAction}
|
||||
*/
|
||||
export const getCustomHandler = function (handlerKey) {
|
||||
return contextMenuExtensions[handlerKey].action;
|
||||
};
|
||||
return contextMenuExtensions[handlerKey].action
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:contextmenu.MenuItem} menuItem
|
||||
|
@ -78,12 +78,12 @@ const injectExtendedContextMenuItemIntoDom = function (menuItem) {
|
|||
if (!Object.keys(contextMenuExtensions).length) {
|
||||
// all menuItems appear at the bottom of the menu in their own container.
|
||||
// if this is the first extension menu we need to add the separator.
|
||||
document.getElementById('cmenu_canvas').appendChild(`<li class='separator'>`);
|
||||
document.getElementById('cmenu_canvas').appendChild('<li class=\'separator\'>')
|
||||
}
|
||||
const shortcut = menuItem.shortcut || '';
|
||||
const shortcut = menuItem.shortcut || ''
|
||||
document.getElementById('cmenu_canvas').appendChild(`
|
||||
<li class='disabled'><a href='#${menuItem.id}'>${menuItem.label}<span class='shortcut'>${shortcut}</span></a></li>`);
|
||||
};
|
||||
<li class='disabled'><a href='#${menuItem.id}'>${menuItem.label}<span class='shortcut'>${shortcut}</span></a></li>`)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function module:contextmenu.injectExtendedContextMenuItemsIntoDom
|
||||
|
@ -91,11 +91,11 @@ const injectExtendedContextMenuItemIntoDom = function (menuItem) {
|
|||
*/
|
||||
export const injectExtendedContextMenuItemsIntoDom = function () {
|
||||
Object.values(contextMenuExtensions).forEach((menuItem) => {
|
||||
injectExtendedContextMenuItemIntoDom(menuItem);
|
||||
});
|
||||
};
|
||||
injectExtendedContextMenuItemIntoDom(menuItem)
|
||||
})
|
||||
}
|
||||
/**
|
||||
* @function module:contextmenu.resetCustomMenus
|
||||
* @returns {void}
|
||||
*/
|
||||
export const resetCustomMenus = function () { contextMenuExtensions = {}; };
|
||||
export const resetCustomMenus = function () { contextMenuExtensions = {} }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import PlainAlertDialog from 'elix/src/plain/PlainAlertDialog.js';
|
||||
import { template } from 'elix/src/base/internal.js';
|
||||
import { fragmentFrom } from 'elix/src/core/htmlLiterals.js';
|
||||
import PlainAlertDialog from 'elix/src/plain/PlainAlertDialog.js'
|
||||
import { template } from 'elix/src/base/internal.js'
|
||||
import { fragmentFrom } from 'elix/src/core/htmlLiterals.js'
|
||||
|
||||
/**
|
||||
* @class SePlainAlertDialog
|
||||
|
@ -11,9 +11,9 @@ export default class SePlainAlertDialog extends PlainAlertDialog {
|
|||
* @returns {PlainObject}
|
||||
*/
|
||||
get [template] () {
|
||||
const result = super[template];
|
||||
const result = super[template]
|
||||
// Replace the default slot with a new default slot and a button container.
|
||||
const defaultSlot = result.content.querySelector('#frameContent');
|
||||
const defaultSlot = result.content.querySelector('#frameContent')
|
||||
if (defaultSlot) {
|
||||
defaultSlot.replaceWith(fragmentFrom.html`
|
||||
<div id="alertDialogContent">
|
||||
|
@ -22,7 +22,7 @@ export default class SePlainAlertDialog extends PlainAlertDialog {
|
|||
</div>
|
||||
<div id="choiceButtonContainer" part="choice-button-container"></div>
|
||||
</div>
|
||||
`);
|
||||
`)
|
||||
}
|
||||
result.content.append(
|
||||
fragmentFrom.html`
|
||||
|
@ -60,9 +60,9 @@ export default class SePlainAlertDialog extends PlainAlertDialog {
|
|||
}
|
||||
</style>
|
||||
`
|
||||
);
|
||||
return result;
|
||||
)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('se-elix-alert-dialog', SePlainAlertDialog);
|
||||
customElements.define('se-elix-alert-dialog', SePlainAlertDialog)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import cMenuDialogHTML from './cmenuDialog.html';
|
||||
const template = document.createElement('template');
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
template.innerHTML = cMenuDialogHTML;
|
||||
import cMenuDialogHTML from './cmenuDialog.html'
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = cMenuDialogHTML
|
||||
/**
|
||||
* @class SeCMenuDialog
|
||||
*/
|
||||
|
@ -10,52 +9,55 @@ export class SeCMenuDialog extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this._workarea = document.getElementById('workarea');
|
||||
this.$dialog = this._shadowRoot.querySelector('#cmenu_canvas');
|
||||
this.$copyLink = this._shadowRoot.querySelector('#se-copy');
|
||||
this.$cutLink = this._shadowRoot.querySelector('#se-cut');
|
||||
this.$pasteLink = this._shadowRoot.querySelector('#se-paste');
|
||||
this.$pasteInPlaceLink = this._shadowRoot.querySelector('#se-paste-in-place');
|
||||
this.$deleteLink = this._shadowRoot.querySelector('#se-delete');
|
||||
this.$groupLink = this._shadowRoot.querySelector('#se-group');
|
||||
this.$ungroupLink = this._shadowRoot.querySelector('#se-ungroup');
|
||||
this.$moveFrontLink = this._shadowRoot.querySelector('#se-move-front');
|
||||
this.$moveUpLink = this._shadowRoot.querySelector('#se-move-up');
|
||||
this.$moveDownLink = this._shadowRoot.querySelector('#se-move-down');
|
||||
this.$moveBackLink = this._shadowRoot.querySelector('#se-move-back');
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
this._workarea = document.getElementById('workarea')
|
||||
this.$dialog = this._shadowRoot.querySelector('#cmenu_canvas')
|
||||
this.$copyLink = this._shadowRoot.querySelector('#se-copy')
|
||||
this.$cutLink = this._shadowRoot.querySelector('#se-cut')
|
||||
this.$pasteLink = this._shadowRoot.querySelector('#se-paste')
|
||||
this.$pasteInPlaceLink = this._shadowRoot.querySelector('#se-paste-in-place')
|
||||
this.$deleteLink = this._shadowRoot.querySelector('#se-delete')
|
||||
this.$groupLink = this._shadowRoot.querySelector('#se-group')
|
||||
this.$ungroupLink = this._shadowRoot.querySelector('#se-ungroup')
|
||||
this.$moveFrontLink = this._shadowRoot.querySelector('#se-move-front')
|
||||
this.$moveUpLink = this._shadowRoot.querySelector('#se-move-up')
|
||||
this.$moveDownLink = this._shadowRoot.querySelector('#se-move-down')
|
||||
this.$moveBackLink = this._shadowRoot.querySelector('#se-move-back')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function init
|
||||
* @param {any} name
|
||||
* @returns {void}
|
||||
*/
|
||||
init (i18next) {
|
||||
this.setAttribute('tools-cut', i18next.t('tools.cut'));
|
||||
this.setAttribute('tools-copy', i18next.t('tools.copy'));
|
||||
this.setAttribute('tools-paste', i18next.t('tools.paste'));
|
||||
this.setAttribute('tools-paste_in_place', i18next.t('tools.paste_in_place'));
|
||||
this.setAttribute('tools-delete', i18next.t('tools.delete'));
|
||||
this.setAttribute('tools-group', i18next.t('tools.group'));
|
||||
this.setAttribute('tools-ungroup', i18next.t('tools.ungroup'));
|
||||
this.setAttribute('tools-move_front', i18next.t('tools.move_front'));
|
||||
this.setAttribute('tools-move_up', i18next.t('tools.move_up'));
|
||||
this.setAttribute('tools-move_down', i18next.t('tools.move_down'));
|
||||
this.setAttribute('tools-move_back', i18next.t('tools.move_back'));
|
||||
this.setAttribute('tools-cut', i18next.t('tools.cut'))
|
||||
this.setAttribute('tools-copy', i18next.t('tools.copy'))
|
||||
this.setAttribute('tools-paste', i18next.t('tools.paste'))
|
||||
this.setAttribute('tools-paste_in_place', i18next.t('tools.paste_in_place'))
|
||||
this.setAttribute('tools-delete', i18next.t('tools.delete'))
|
||||
this.setAttribute('tools-group', i18next.t('tools.group'))
|
||||
this.setAttribute('tools-ungroup', i18next.t('tools.ungroup'))
|
||||
this.setAttribute('tools-move_front', i18next.t('tools.move_front'))
|
||||
this.setAttribute('tools-move_up', i18next.t('tools.move_up'))
|
||||
this.setAttribute('tools-move_down', i18next.t('tools.move_down'))
|
||||
this.setAttribute('tools-move_back', i18next.t('tools.move_back'))
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'disableallmenu', 'enablemenuitems', 'disablemenuitems', 'tools-cut',
|
||||
return ['disableallmenu', 'enablemenuitems', 'disablemenuitems', 'tools-cut',
|
||||
'tools-copy', 'tools-paste', 'tools-paste_in_place', 'tools-delete', 'tools-group',
|
||||
'tools-ungroup', 'tools-move_front', 'tools-move_up', 'tools-move_down',
|
||||
'tools-move_back' ];
|
||||
'tools-move_back']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -64,85 +66,86 @@ export class SeCMenuDialog extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
let eles = [];
|
||||
let textnode;
|
||||
const sdowRoot = this._shadowRoot;
|
||||
let eles = []
|
||||
let textnode
|
||||
const sdowRoot = this._shadowRoot
|
||||
switch (name) {
|
||||
case 'disableallmenu':
|
||||
if (newValue === 'true') {
|
||||
const elesli = sdowRoot.querySelectorAll('li');
|
||||
elesli.forEach(function (eleli) {
|
||||
eleli.classList.add('disabled');
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'enablemenuitems':
|
||||
eles = newValue.split(',');
|
||||
eles.forEach(function (ele) {
|
||||
const selEle = sdowRoot.querySelector('a[href*="' + ele + '"]');
|
||||
selEle.parentElement.classList.remove('disabled');
|
||||
});
|
||||
break;
|
||||
case 'disablemenuitems':
|
||||
eles = newValue.split(',');
|
||||
eles.forEach(function (ele) {
|
||||
const selEle = sdowRoot.querySelector('a[href*="' + ele + '"]');
|
||||
selEle.parentElement.classList.add('disabled');
|
||||
});
|
||||
break;
|
||||
case 'tools-cut':
|
||||
textnode = document.createTextNode(newValue);
|
||||
this.$cutLink.prepend(textnode);
|
||||
break;
|
||||
case 'tools-copy':
|
||||
textnode = document.createTextNode(newValue);
|
||||
this.$copyLink.prepend(textnode);
|
||||
break;
|
||||
case 'tools-paste':
|
||||
this.$pasteLink.textContent = newValue;
|
||||
break;
|
||||
case 'tools-paste_in_place':
|
||||
this.$pasteInPlaceLink.textContent = newValue;
|
||||
break;
|
||||
case 'tools-delete':
|
||||
textnode = document.createTextNode(newValue);
|
||||
this.$deleteLink.prepend(textnode);
|
||||
break;
|
||||
case 'tools-group':
|
||||
textnode = document.createTextNode(newValue);
|
||||
this.$groupLink.prepend(textnode);
|
||||
break;
|
||||
case 'tools-ungroup':
|
||||
textnode = document.createTextNode(newValue);
|
||||
this.$ungroupLink.prepend(textnode);
|
||||
break;
|
||||
case 'tools-move_front':
|
||||
textnode = document.createTextNode(newValue);
|
||||
this.$moveFrontLink.prepend(textnode);
|
||||
break;
|
||||
case 'tools-move_up':
|
||||
textnode = document.createTextNode(newValue);
|
||||
this.$moveUpLink.prepend(textnode);
|
||||
break;
|
||||
case 'tools-move_down':
|
||||
textnode = document.createTextNode(newValue);
|
||||
this.$moveDownLink.prepend(textnode);
|
||||
break;
|
||||
case 'tools-move_back':
|
||||
textnode = document.createTextNode(newValue);
|
||||
this.$moveBackLink.prepend(textnode);
|
||||
break;
|
||||
default:
|
||||
case 'disableallmenu':
|
||||
if (newValue === 'true') {
|
||||
const elesli = sdowRoot.querySelectorAll('li')
|
||||
elesli.forEach(function (eleli) {
|
||||
eleli.classList.add('disabled')
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'enablemenuitems':
|
||||
eles = newValue.split(',')
|
||||
eles.forEach(function (ele) {
|
||||
const selEle = sdowRoot.querySelector('a[href*="' + ele + '"]')
|
||||
selEle.parentElement.classList.remove('disabled')
|
||||
})
|
||||
break
|
||||
case 'disablemenuitems':
|
||||
eles = newValue.split(',')
|
||||
eles.forEach(function (ele) {
|
||||
const selEle = sdowRoot.querySelector('a[href*="' + ele + '"]')
|
||||
selEle.parentElement.classList.add('disabled')
|
||||
})
|
||||
break
|
||||
case 'tools-cut':
|
||||
textnode = document.createTextNode(newValue)
|
||||
this.$cutLink.prepend(textnode)
|
||||
break
|
||||
case 'tools-copy':
|
||||
textnode = document.createTextNode(newValue)
|
||||
this.$copyLink.prepend(textnode)
|
||||
break
|
||||
case 'tools-paste':
|
||||
this.$pasteLink.textContent = newValue
|
||||
break
|
||||
case 'tools-paste_in_place':
|
||||
this.$pasteInPlaceLink.textContent = newValue
|
||||
break
|
||||
case 'tools-delete':
|
||||
textnode = document.createTextNode(newValue)
|
||||
this.$deleteLink.prepend(textnode)
|
||||
break
|
||||
case 'tools-group':
|
||||
textnode = document.createTextNode(newValue)
|
||||
this.$groupLink.prepend(textnode)
|
||||
break
|
||||
case 'tools-ungroup':
|
||||
textnode = document.createTextNode(newValue)
|
||||
this.$ungroupLink.prepend(textnode)
|
||||
break
|
||||
case 'tools-move_front':
|
||||
textnode = document.createTextNode(newValue)
|
||||
this.$moveFrontLink.prepend(textnode)
|
||||
break
|
||||
case 'tools-move_up':
|
||||
textnode = document.createTextNode(newValue)
|
||||
this.$moveUpLink.prepend(textnode)
|
||||
break
|
||||
case 'tools-move_down':
|
||||
textnode = document.createTextNode(newValue)
|
||||
this.$moveDownLink.prepend(textnode)
|
||||
break
|
||||
case 'tools-move_back':
|
||||
textnode = document.createTextNode(newValue)
|
||||
this.$moveBackLink.prepend(textnode)
|
||||
break
|
||||
default:
|
||||
// super.attributeChangedCallback(name, oldValue, newValue);
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get disableallmenu () {
|
||||
return this.getAttribute('disableallmenu');
|
||||
return this.getAttribute('disableallmenu')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -150,14 +153,15 @@ export class SeCMenuDialog extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set disableallmenu (value) {
|
||||
this.setAttribute('disableallmenu', value);
|
||||
this.setAttribute('disableallmenu', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get enablemenuitems () {
|
||||
return this.getAttribute('enablemenuitems');
|
||||
return this.getAttribute('enablemenuitems')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,14 +169,15 @@ export class SeCMenuDialog extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set enablemenuitems (value) {
|
||||
this.setAttribute('enablemenuitems', value);
|
||||
this.setAttribute('enablemenuitems', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get disablemenuitems () {
|
||||
return this.getAttribute('disablemenuitems');
|
||||
return this.getAttribute('disablemenuitems')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -180,59 +185,62 @@ export class SeCMenuDialog extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set disablemenuitems (value) {
|
||||
this.setAttribute('disablemenuitems', value);
|
||||
this.setAttribute('disablemenuitems', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function connectedCallback
|
||||
* @returns {void}
|
||||
*/
|
||||
connectedCallback () {
|
||||
const current = this;
|
||||
const current = this
|
||||
const onMenuOpenHandler = (e) => {
|
||||
e.preventDefault();
|
||||
e.preventDefault()
|
||||
// Detect mouse position
|
||||
let x = e.pageX;
|
||||
let y = e.pageY;
|
||||
let x = e.pageX
|
||||
let y = e.pageY
|
||||
|
||||
const xOff = screen.width - 250; // menu width
|
||||
const yOff = screen.height - (276 + 150); // menu height + bottom panel height and scroll bar
|
||||
const xOff = screen.width - 250 // menu width
|
||||
const yOff = screen.height - (276 + 150) // menu height + bottom panel height and scroll bar
|
||||
|
||||
if (x > xOff) {
|
||||
x = xOff;
|
||||
x = xOff
|
||||
}
|
||||
if (y > yOff) {
|
||||
y = yOff;
|
||||
y = yOff
|
||||
}
|
||||
current.$dialog.style.top = y + 'px';
|
||||
current.$dialog.style.left = x + 'px';
|
||||
current.$dialog.style.display = 'block';
|
||||
};
|
||||
current.$dialog.style.top = y + 'px'
|
||||
current.$dialog.style.left = x + 'px'
|
||||
current.$dialog.style.display = 'block'
|
||||
}
|
||||
const onMenuCloseHandler = (e) => {
|
||||
if (e.button !== 2) {
|
||||
current.$dialog.style.display = 'none';
|
||||
current.$dialog.style.display = 'none'
|
||||
}
|
||||
};
|
||||
}
|
||||
const onMenuClickHandler = (e, action) => {
|
||||
const triggerEvent = new CustomEvent('change', { detail: {
|
||||
trigger: action
|
||||
} });
|
||||
this.dispatchEvent(triggerEvent);
|
||||
};
|
||||
this._workarea.addEventListener('contextmenu', onMenuOpenHandler);
|
||||
this._workarea.addEventListener('mousedown', onMenuCloseHandler);
|
||||
this.$cutLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'cut'));
|
||||
this.$copyLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'copy'));
|
||||
this.$pasteLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'paste'));
|
||||
this.$pasteInPlaceLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'paste_in_place'));
|
||||
this.$deleteLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'delete'));
|
||||
this.$groupLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'group'));
|
||||
this.$ungroupLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'ungroup'));
|
||||
this.$moveFrontLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'move_front'));
|
||||
this.$moveUpLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'move_up'));
|
||||
this.$moveDownLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'move_down'));
|
||||
this.$moveBackLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'move_back'));
|
||||
const triggerEvent = new CustomEvent('change', {
|
||||
detail: {
|
||||
trigger: action
|
||||
}
|
||||
})
|
||||
this.dispatchEvent(triggerEvent)
|
||||
}
|
||||
this._workarea.addEventListener('contextmenu', onMenuOpenHandler)
|
||||
this._workarea.addEventListener('mousedown', onMenuCloseHandler)
|
||||
this.$cutLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'cut'))
|
||||
this.$copyLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'copy'))
|
||||
this.$pasteLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'paste'))
|
||||
this.$pasteInPlaceLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'paste_in_place'))
|
||||
this.$deleteLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'delete'))
|
||||
this.$groupLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'group'))
|
||||
this.$ungroupLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'ungroup'))
|
||||
this.$moveFrontLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'move_front'))
|
||||
this.$moveUpLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'move_up'))
|
||||
this.$moveDownLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'move_down'))
|
||||
this.$moveBackLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'move_back'))
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-cmenu_canvas-dialog', SeCMenuDialog);
|
||||
customElements.define('se-cmenu_canvas-dialog', SeCMenuDialog)
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import cMenuLayersDialog from './cmenuLayersDialog.html';
|
||||
import cMenuLayersDialog from './cmenuLayersDialog.html'
|
||||
|
||||
const template = document.createElement('template');
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
template.innerHTML = cMenuLayersDialog;
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = cMenuLayersDialog
|
||||
/**
|
||||
* @class SeCMenuLayerDialog
|
||||
*/
|
||||
|
@ -11,37 +10,40 @@ export class SeCMenuLayerDialog extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.source = '';
|
||||
this._workarea = undefined;
|
||||
this.$sidePanels = document.getElementById('sidepanels');
|
||||
this.$dialog = this._shadowRoot.querySelector('#cmenu_layers');
|
||||
this.$duplicateLink = this._shadowRoot.querySelector('#se-dupe');
|
||||
this.$deleteLink = this._shadowRoot.querySelector('#se-layer-delete');
|
||||
this.$mergeDownLink = this._shadowRoot.querySelector('#se-merge-down');
|
||||
this.$mergeAllLink = this._shadowRoot.querySelector('#se-merge-all');
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
this.source = ''
|
||||
this._workarea = undefined
|
||||
this.$sidePanels = document.getElementById('sidepanels')
|
||||
this.$dialog = this._shadowRoot.querySelector('#cmenu_layers')
|
||||
this.$duplicateLink = this._shadowRoot.querySelector('#se-dupe')
|
||||
this.$deleteLink = this._shadowRoot.querySelector('#se-layer-delete')
|
||||
this.$mergeDownLink = this._shadowRoot.querySelector('#se-merge-down')
|
||||
this.$mergeAllLink = this._shadowRoot.querySelector('#se-merge-all')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function init
|
||||
* @param {any} name
|
||||
* @returns {void}
|
||||
*/
|
||||
init (i18next) {
|
||||
this.setAttribute('layers-dupe', i18next.t('layers.dupe'));
|
||||
this.setAttribute('layers-del', i18next.t('layers.del'));
|
||||
this.setAttribute('layers-merge_down', i18next.t('layers.merge_down'));
|
||||
this.setAttribute('layers-merge_all', i18next.t('layers.merge_all'));
|
||||
this.setAttribute('layers-dupe', i18next.t('layers.dupe'))
|
||||
this.setAttribute('layers-del', i18next.t('layers.del'))
|
||||
this.setAttribute('layers-merge_down', i18next.t('layers.merge_down'))
|
||||
this.setAttribute('layers-merge_all', i18next.t('layers.merge_all'))
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'value', 'leftclick', 'layers-dupe', 'layers-del', 'layers-merge_down', 'layers-merge_all' ];
|
||||
return ['value', 'leftclick', 'layers-dupe', 'layers-del', 'layers-merge_down', 'layers-merge_all']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -50,37 +52,38 @@ export class SeCMenuLayerDialog extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'value':
|
||||
this.source = newValue;
|
||||
if (newValue !== '' && newValue !== undefined) {
|
||||
this._workarea = document.getElementById(this.source);
|
||||
}
|
||||
break;
|
||||
case 'layers-dupe':
|
||||
this.$duplicateLink.textContent = newValue;
|
||||
break;
|
||||
case 'layers-del':
|
||||
this.$deleteLink.textContent = newValue;
|
||||
break;
|
||||
case 'layers-merge_down':
|
||||
this.$mergeDownLink.textContent = newValue;
|
||||
break;
|
||||
case 'layers-merge_all':
|
||||
this.$mergeAllLink.textContent = newValue;
|
||||
break;
|
||||
default:
|
||||
case 'value':
|
||||
this.source = newValue
|
||||
if (newValue !== '' && newValue !== undefined) {
|
||||
this._workarea = document.getElementById(this.source)
|
||||
}
|
||||
break
|
||||
case 'layers-dupe':
|
||||
this.$duplicateLink.textContent = newValue
|
||||
break
|
||||
case 'layers-del':
|
||||
this.$deleteLink.textContent = newValue
|
||||
break
|
||||
case 'layers-merge_down':
|
||||
this.$mergeDownLink.textContent = newValue
|
||||
break
|
||||
case 'layers-merge_all':
|
||||
this.$mergeAllLink.textContent = newValue
|
||||
break
|
||||
default:
|
||||
// super.attributeChangedCallback(name, oldValue, newValue);
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get value () {
|
||||
return this.getAttribute('value');
|
||||
return this.getAttribute('value')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,14 +91,15 @@ export class SeCMenuLayerDialog extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set value (value) {
|
||||
this.setAttribute('value', value);
|
||||
this.setAttribute('value', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get leftclick () {
|
||||
return this.getAttribute('leftclick');
|
||||
return this.getAttribute('leftclick')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,47 +107,50 @@ export class SeCMenuLayerDialog extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set leftclick (value) {
|
||||
this.setAttribute('leftclick', value);
|
||||
this.setAttribute('leftclick', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function connectedCallback
|
||||
* @returns {void}
|
||||
*/
|
||||
connectedCallback () {
|
||||
const current = this;
|
||||
const current = this
|
||||
const onMenuOpenHandler = (e) => {
|
||||
e.preventDefault();
|
||||
current.$dialog.style.top = e.pageY + 'px';
|
||||
current.$dialog.style.left = e.pageX - 126 + 'px';
|
||||
current.$dialog.style.display = 'block';
|
||||
};
|
||||
e.preventDefault()
|
||||
current.$dialog.style.top = e.pageY + 'px'
|
||||
current.$dialog.style.left = e.pageX - 126 + 'px'
|
||||
current.$dialog.style.display = 'block'
|
||||
}
|
||||
const onMenuCloseHandler = (e) => {
|
||||
if (e.button !== 2) {
|
||||
current.$dialog.style.display = 'none';
|
||||
current.$dialog.style.display = 'none'
|
||||
}
|
||||
};
|
||||
const onMenuClickHandler = (e, action, id) => {
|
||||
const triggerEvent = new CustomEvent('change', { detail: {
|
||||
trigger: action,
|
||||
source: id
|
||||
} });
|
||||
this.dispatchEvent(triggerEvent);
|
||||
current.$dialog.style.display = 'none';
|
||||
};
|
||||
if (this._workarea !== undefined) {
|
||||
this._workarea.addEventListener('contextmenu', onMenuOpenHandler);
|
||||
if (this.getAttribute('leftclick') === 'true') {
|
||||
this._workarea.addEventListener('click', onMenuOpenHandler);
|
||||
}
|
||||
this._workarea.addEventListener('mousedown', onMenuCloseHandler);
|
||||
this.$sidePanels.addEventListener('mousedown', onMenuCloseHandler);
|
||||
}
|
||||
this.$duplicateLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'dupe', this.source));
|
||||
this.$deleteLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'delete', this.source));
|
||||
this.$mergeDownLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'merge_down', this.source));
|
||||
this.$mergeAllLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'merge_all', this.source));
|
||||
const onMenuClickHandler = (e, action, id) => {
|
||||
const triggerEvent = new CustomEvent('change', {
|
||||
detail: {
|
||||
trigger: action,
|
||||
source: id
|
||||
}
|
||||
})
|
||||
this.dispatchEvent(triggerEvent)
|
||||
current.$dialog.style.display = 'none'
|
||||
}
|
||||
if (this._workarea !== undefined) {
|
||||
this._workarea.addEventListener('contextmenu', onMenuOpenHandler)
|
||||
if (this.getAttribute('leftclick') === 'true') {
|
||||
this._workarea.addEventListener('click', onMenuOpenHandler)
|
||||
}
|
||||
this._workarea.addEventListener('mousedown', onMenuCloseHandler)
|
||||
this.$sidePanels.addEventListener('mousedown', onMenuCloseHandler)
|
||||
}
|
||||
this.$duplicateLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'dupe', this.source))
|
||||
this.$deleteLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'delete', this.source))
|
||||
this.$mergeDownLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'merge_down', this.source))
|
||||
this.$mergeAllLink.addEventListener('click', (evt) => onMenuClickHandler(evt, 'merge_all', this.source))
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-cmenu-layers', SeCMenuLayerDialog);
|
||||
customElements.define('se-cmenu-layers', SeCMenuLayerDialog)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import editorPreferencesDialog from './editorPreferencesDialog.html';
|
||||
const template = document.createElement('template');
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
template.innerHTML = editorPreferencesDialog;
|
||||
import editorPreferencesDialog from './editorPreferencesDialog.html'
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = editorPreferencesDialog
|
||||
/**
|
||||
* @class SeEditPrefsDialog
|
||||
*/
|
||||
|
@ -10,52 +9,55 @@ export class SeEditPrefsDialog extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this.colorBlocks = [ '#FFF', '#888', '#000', 'chessboard' ];
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$dialog = this._shadowRoot.querySelector('#svg_prefs');
|
||||
this.$saveBtn = this._shadowRoot.querySelector('#tool_prefs_save');
|
||||
this.$cancelBtn = this._shadowRoot.querySelector('#tool_prefs_cancel');
|
||||
this.$langSelect = this._shadowRoot.querySelector('#lang_select');
|
||||
this.$bgBlocks = this._shadowRoot.querySelector('#bg_blocks');
|
||||
this.$bgURL = this._shadowRoot.querySelector('#canvas_bg_url');
|
||||
this.$gridSnappingOn = this._shadowRoot.querySelector('#grid_snapping_on');
|
||||
this.$gridSnappingStep = this._shadowRoot.querySelector('#grid_snapping_step');
|
||||
this.$gridColor = this._shadowRoot.querySelector('#grid_color');
|
||||
this.$showRulers = this._shadowRoot.querySelector('#show_rulers');
|
||||
this.$baseUnit = this._shadowRoot.querySelector('#base_unit');
|
||||
this.colorBlocks = ['#FFF', '#888', '#000', 'chessboard']
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
this.$dialog = this._shadowRoot.querySelector('#svg_prefs')
|
||||
this.$saveBtn = this._shadowRoot.querySelector('#tool_prefs_save')
|
||||
this.$cancelBtn = this._shadowRoot.querySelector('#tool_prefs_cancel')
|
||||
this.$langSelect = this._shadowRoot.querySelector('#lang_select')
|
||||
this.$bgBlocks = this._shadowRoot.querySelector('#bg_blocks')
|
||||
this.$bgURL = this._shadowRoot.querySelector('#canvas_bg_url')
|
||||
this.$gridSnappingOn = this._shadowRoot.querySelector('#grid_snapping_on')
|
||||
this.$gridSnappingStep = this._shadowRoot.querySelector('#grid_snapping_step')
|
||||
this.$gridColor = this._shadowRoot.querySelector('#grid_color')
|
||||
this.$showRulers = this._shadowRoot.querySelector('#show_rulers')
|
||||
this.$baseUnit = this._shadowRoot.querySelector('#base_unit')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function init
|
||||
* @param {any} name
|
||||
* @returns {void}
|
||||
*/
|
||||
init (i18next) {
|
||||
this.setAttribute('common-ok', i18next.t('common.ok'));
|
||||
this.setAttribute('common-cancel', i18next.t('common.cancel'));
|
||||
this.setAttribute('config-editor_prefs', i18next.t('config.editor_prefs'));
|
||||
this.setAttribute('config-language', i18next.t('config.language'));
|
||||
this.setAttribute('config-background', i18next.t('config.background'));
|
||||
this.setAttribute('common-url', i18next.t('common.url'));
|
||||
this.setAttribute('config-editor_bg_note', i18next.t('config.editor_bg_note'));
|
||||
this.setAttribute('config-grid', i18next.t('config.grid'));
|
||||
this.setAttribute('config-snapping_onoff', i18next.t('config.snapping_onoff'));
|
||||
this.setAttribute('config-snapping_stepsize', i18next.t('config.snapping_stepsize'));
|
||||
this.setAttribute('config-grid_color', i18next.t('config.grid_color'));
|
||||
this.setAttribute('config-units_and_rulers', i18next.t('config.units_and_rulers'));
|
||||
this.setAttribute('config-show_rulers', i18next.t('config.show_rulers'));
|
||||
this.setAttribute('config-base_unit', i18next.t('config.base_unit'));
|
||||
this.setAttribute('common-ok', i18next.t('common.ok'))
|
||||
this.setAttribute('common-cancel', i18next.t('common.cancel'))
|
||||
this.setAttribute('config-editor_prefs', i18next.t('config.editor_prefs'))
|
||||
this.setAttribute('config-language', i18next.t('config.language'))
|
||||
this.setAttribute('config-background', i18next.t('config.background'))
|
||||
this.setAttribute('common-url', i18next.t('common.url'))
|
||||
this.setAttribute('config-editor_bg_note', i18next.t('config.editor_bg_note'))
|
||||
this.setAttribute('config-grid', i18next.t('config.grid'))
|
||||
this.setAttribute('config-snapping_onoff', i18next.t('config.snapping_onoff'))
|
||||
this.setAttribute('config-snapping_stepsize', i18next.t('config.snapping_stepsize'))
|
||||
this.setAttribute('config-grid_color', i18next.t('config.grid_color'))
|
||||
this.setAttribute('config-units_and_rulers', i18next.t('config.units_and_rulers'))
|
||||
this.setAttribute('config-show_rulers', i18next.t('config.show_rulers'))
|
||||
this.setAttribute('config-base_unit', i18next.t('config.base_unit'))
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
// eslint-disable-next-line max-len
|
||||
return [ 'dialog', 'lang', 'canvasbg', 'bgurl', 'gridsnappingon', 'gridsnappingstep', 'gridcolor', 'showrulers', 'baseunit', 'common-ok', 'common-cancel', 'config-editor_prefs', 'config-language', 'config-background', 'common-url', 'config-editor_bg_note', 'config-grid', 'config-snapping_onoff', 'config-snapping_stepsize', 'config-grid_color', 'config-units_and_rulers', 'config-show_rulers', 'config-base_unit' ];
|
||||
return ['dialog', 'lang', 'canvasbg', 'bgurl', 'gridsnappingon', 'gridsnappingstep', 'gridcolor', 'showrulers', 'baseunit', 'common-ok', 'common-cancel', 'config-editor_prefs', 'config-language', 'config-background', 'common-url', 'config-editor_bg_note', 'config-grid', 'config-snapping_onoff', 'config-snapping_stepsize', 'config-grid_color', 'config-units_and_rulers', 'config-show_rulers', 'config-base_unit']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -64,128 +66,129 @@ export class SeEditPrefsDialog extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
const blocks = this.$bgBlocks.querySelectorAll('div');
|
||||
const curBg = 'cur_background';
|
||||
let node;
|
||||
if (oldValue === newValue) return
|
||||
const blocks = this.$bgBlocks.querySelectorAll('div')
|
||||
const curBg = 'cur_background'
|
||||
let node
|
||||
switch (name) {
|
||||
case 'dialog':
|
||||
if (newValue === 'open') {
|
||||
this.$dialog.open();
|
||||
} else {
|
||||
this.$dialog.close();
|
||||
}
|
||||
break;
|
||||
case 'lang':
|
||||
this.$langSelect.value = newValue;
|
||||
break;
|
||||
case 'canvasbg':
|
||||
if (!newValue) {
|
||||
if (blocks.length > 0) {
|
||||
blocks[0].classList.add(curBg);
|
||||
case 'dialog':
|
||||
if (newValue === 'open') {
|
||||
this.$dialog.open()
|
||||
} else {
|
||||
this.$dialog.close()
|
||||
}
|
||||
} else {
|
||||
blocks.forEach(function (blk) {
|
||||
const isBg = blk.dataset.bgColor === newValue;
|
||||
if (isBg) {
|
||||
blk.classList.add(curBg);
|
||||
} else {
|
||||
blk.classList.remove(curBg);
|
||||
break
|
||||
case 'lang':
|
||||
this.$langSelect.value = newValue
|
||||
break
|
||||
case 'canvasbg':
|
||||
if (!newValue) {
|
||||
if (blocks.length > 0) {
|
||||
blocks[0].classList.add(curBg)
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'bgurl':
|
||||
this.$bgURL.value = newValue;
|
||||
break;
|
||||
case 'gridsnappingon':
|
||||
if (newValue === 'true') {
|
||||
this.$gridSnappingOn.checked = true;
|
||||
} else if (newValue === 'false') {
|
||||
this.$gridSnappingOn.checked = false;
|
||||
}
|
||||
break;
|
||||
case 'gridsnappingstep':
|
||||
this.$gridSnappingStep.value = newValue;
|
||||
break;
|
||||
case 'gridcolor':
|
||||
this.$gridColor.value = newValue;
|
||||
break;
|
||||
case 'showrulers':
|
||||
if (newValue === 'true') {
|
||||
this.$showRulers.checked = true;
|
||||
} else if (newValue === 'false') {
|
||||
this.$showRulers.checked = false;
|
||||
}
|
||||
break;
|
||||
case 'baseunit':
|
||||
this.$baseUnit.value = newValue;
|
||||
break;
|
||||
case 'common-ok':
|
||||
this.$saveBtn.textContent = newValue;
|
||||
break;
|
||||
case 'common-cancel':
|
||||
this.$cancelBtn.textContent = newValue;
|
||||
break;
|
||||
case 'config-editor_prefs':
|
||||
node = this._shadowRoot.querySelector('#svginfo_editor_prefs');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-language':
|
||||
node = this._shadowRoot.querySelector('#svginfo_lang');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-background':
|
||||
node = this._shadowRoot.querySelector('#svginfo_change_background');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'common-url':
|
||||
node = this._shadowRoot.querySelector('#svginfo_bg_url');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-editor_bg_note':
|
||||
node = this._shadowRoot.querySelector('#svginfo_bg_note');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-grid':
|
||||
node = this._shadowRoot.querySelector('#svginfo_grid_settings');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-snapping_onoff':
|
||||
node = this._shadowRoot.querySelector('#svginfo_snap_onoff');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-snapping_stepsize':
|
||||
node = this._shadowRoot.querySelector('#svginfo_snap_step');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-grid_color':
|
||||
node = this._shadowRoot.querySelector('#svginfo_grid_color');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-units_and_rulers':
|
||||
node = this._shadowRoot.querySelector('#svginfo_units_rulers');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-show_rulers':
|
||||
node = this._shadowRoot.querySelector('#svginfo_rulers_onoff');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-base_unit':
|
||||
node = this._shadowRoot.querySelector('#svginfo_unit');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
default:
|
||||
super.attributeChangedCallback(name, oldValue, newValue);
|
||||
break;
|
||||
} else {
|
||||
blocks.forEach(function (blk) {
|
||||
const isBg = blk.dataset.bgColor === newValue
|
||||
if (isBg) {
|
||||
blk.classList.add(curBg)
|
||||
} else {
|
||||
blk.classList.remove(curBg)
|
||||
}
|
||||
})
|
||||
}
|
||||
break
|
||||
case 'bgurl':
|
||||
this.$bgURL.value = newValue
|
||||
break
|
||||
case 'gridsnappingon':
|
||||
if (newValue === 'true') {
|
||||
this.$gridSnappingOn.checked = true
|
||||
} else if (newValue === 'false') {
|
||||
this.$gridSnappingOn.checked = false
|
||||
}
|
||||
break
|
||||
case 'gridsnappingstep':
|
||||
this.$gridSnappingStep.value = newValue
|
||||
break
|
||||
case 'gridcolor':
|
||||
this.$gridColor.value = newValue
|
||||
break
|
||||
case 'showrulers':
|
||||
if (newValue === 'true') {
|
||||
this.$showRulers.checked = true
|
||||
} else if (newValue === 'false') {
|
||||
this.$showRulers.checked = false
|
||||
}
|
||||
break
|
||||
case 'baseunit':
|
||||
this.$baseUnit.value = newValue
|
||||
break
|
||||
case 'common-ok':
|
||||
this.$saveBtn.textContent = newValue
|
||||
break
|
||||
case 'common-cancel':
|
||||
this.$cancelBtn.textContent = newValue
|
||||
break
|
||||
case 'config-editor_prefs':
|
||||
node = this._shadowRoot.querySelector('#svginfo_editor_prefs')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-language':
|
||||
node = this._shadowRoot.querySelector('#svginfo_lang')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-background':
|
||||
node = this._shadowRoot.querySelector('#svginfo_change_background')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'common-url':
|
||||
node = this._shadowRoot.querySelector('#svginfo_bg_url')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-editor_bg_note':
|
||||
node = this._shadowRoot.querySelector('#svginfo_bg_note')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-grid':
|
||||
node = this._shadowRoot.querySelector('#svginfo_grid_settings')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-snapping_onoff':
|
||||
node = this._shadowRoot.querySelector('#svginfo_snap_onoff')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-snapping_stepsize':
|
||||
node = this._shadowRoot.querySelector('#svginfo_snap_step')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-grid_color':
|
||||
node = this._shadowRoot.querySelector('#svginfo_grid_color')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-units_and_rulers':
|
||||
node = this._shadowRoot.querySelector('#svginfo_units_rulers')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-show_rulers':
|
||||
node = this._shadowRoot.querySelector('#svginfo_rulers_onoff')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-base_unit':
|
||||
node = this._shadowRoot.querySelector('#svginfo_unit')
|
||||
node.textContent = newValue
|
||||
break
|
||||
default:
|
||||
super.attributeChangedCallback(name, oldValue, newValue)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get lang () {
|
||||
return this.getAttribute('lang');
|
||||
return this.getAttribute('lang')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -193,173 +196,194 @@ export class SeEditPrefsDialog extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set lang (value) {
|
||||
this.setAttribute('lang', value);
|
||||
this.setAttribute('lang', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get canvasbg () {
|
||||
return this.getAttribute('canvasbg');
|
||||
return this.getAttribute('canvasbg')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set canvasbg (value) {
|
||||
this.setAttribute('canvasbg', value);
|
||||
this.setAttribute('canvasbg', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get bgurl () {
|
||||
return this.getAttribute('bgurl');
|
||||
return this.getAttribute('bgurl')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set bgurl (value) {
|
||||
this.setAttribute('bgurl', value);
|
||||
this.setAttribute('bgurl', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get dialog () {
|
||||
return this.getAttribute('dialog');
|
||||
return this.getAttribute('dialog')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set dialog (value) {
|
||||
this.setAttribute('dialog', value);
|
||||
this.setAttribute('dialog', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get gridsnappingon () {
|
||||
return this.getAttribute('gridsnappingon');
|
||||
return this.getAttribute('gridsnappingon')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set gridsnappingon (value) {
|
||||
this.setAttribute('gridsnappingon', value);
|
||||
this.setAttribute('gridsnappingon', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get gridsnappingstep () {
|
||||
return this.getAttribute('gridsnappingstep');
|
||||
return this.getAttribute('gridsnappingstep')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set gridsnappingstep (value) {
|
||||
this.setAttribute('gridsnappingstep', value);
|
||||
this.setAttribute('gridsnappingstep', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get gridcolor () {
|
||||
return this.getAttribute('gridcolor');
|
||||
return this.getAttribute('gridcolor')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set gridcolor (value) {
|
||||
this.setAttribute('gridcolor', value);
|
||||
this.setAttribute('gridcolor', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get showrulers () {
|
||||
return this.getAttribute('showrulers');
|
||||
return this.getAttribute('showrulers')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set showrulers (value) {
|
||||
this.setAttribute('showrulers', value);
|
||||
this.setAttribute('showrulers', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get baseunit () {
|
||||
return this.getAttribute('baseunit');
|
||||
return this.getAttribute('baseunit')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set baseunit (value) {
|
||||
this.setAttribute('baseunit', value);
|
||||
this.setAttribute('baseunit', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function connectedCallback
|
||||
* @returns {void}
|
||||
*/
|
||||
connectedCallback () {
|
||||
const onCancelHandler = () => {
|
||||
const closeEvent = new CustomEvent('change', { detail: {
|
||||
dialog: 'closed'
|
||||
} });
|
||||
this.dispatchEvent(closeEvent);
|
||||
};
|
||||
const closeEvent = new CustomEvent('change', {
|
||||
detail: {
|
||||
dialog: 'closed'
|
||||
}
|
||||
})
|
||||
this.dispatchEvent(closeEvent)
|
||||
}
|
||||
const onSaveHandler = () => {
|
||||
const color = this.$bgBlocks.querySelector('.cur_background').dataset.bgColor || '#FFF';
|
||||
const closeEvent = new CustomEvent('change', { detail: {
|
||||
lang: this.$langSelect.value,
|
||||
dialog: 'close',
|
||||
bgcolor: color,
|
||||
bgurl: this.$bgURL.value,
|
||||
gridsnappingon: this.$gridSnappingOn.checked,
|
||||
gridsnappingstep: this.$gridSnappingStep.value,
|
||||
showrulers: this.$showRulers.checked,
|
||||
baseunit: this.$baseUnit.value
|
||||
} });
|
||||
this.dispatchEvent(closeEvent);
|
||||
};
|
||||
const color = this.$bgBlocks.querySelector('.cur_background').dataset.bgColor || '#FFF'
|
||||
const closeEvent = new CustomEvent('change', {
|
||||
detail: {
|
||||
lang: this.$langSelect.value,
|
||||
dialog: 'close',
|
||||
bgcolor: color,
|
||||
bgurl: this.$bgURL.value,
|
||||
gridsnappingon: this.$gridSnappingOn.checked,
|
||||
gridsnappingstep: this.$gridSnappingStep.value,
|
||||
showrulers: this.$showRulers.checked,
|
||||
baseunit: this.$baseUnit.value
|
||||
}
|
||||
})
|
||||
this.dispatchEvent(closeEvent)
|
||||
}
|
||||
// Set up editor background functionality
|
||||
const currentObj = this;
|
||||
const currentObj = this
|
||||
this.colorBlocks.forEach(function (e) {
|
||||
const newdiv = document.createElement('div');
|
||||
const newdiv = document.createElement('div')
|
||||
if (e === 'chessboard') {
|
||||
newdiv.dataset.bgColor = e;
|
||||
newdiv.style.backgroundImage = 'url(data:image/gif;base64,R0lGODlhEAAQAIAAAP///9bW1iH5BAAAAAAALAAAAAAQABAAAAIfjG+gq4jM3IFLJgpswNly/XkcBpIiVaInlLJr9FZWAQA7)';
|
||||
newdiv.classList.add('color_block');
|
||||
newdiv.dataset.bgColor = e
|
||||
newdiv.style.backgroundImage = 'url(data:image/gif;base64,R0lGODlhEAAQAIAAAP///9bW1iH5BAAAAAAALAAAAAAQABAAAAIfjG+gq4jM3IFLJgpswNly/XkcBpIiVaInlLJr9FZWAQA7)'
|
||||
newdiv.classList.add('color_block')
|
||||
} else {
|
||||
newdiv.dataset.bgColor = e; // setAttribute('data-bgcolor', e);
|
||||
newdiv.style.backgroundColor = e;
|
||||
newdiv.classList.add('color_block');
|
||||
newdiv.dataset.bgColor = e // setAttribute('data-bgcolor', e);
|
||||
newdiv.style.backgroundColor = e
|
||||
newdiv.classList.add('color_block')
|
||||
}
|
||||
currentObj.$bgBlocks.append(newdiv);
|
||||
});
|
||||
const blocks = this.$bgBlocks.querySelectorAll('div');
|
||||
const curBg = 'cur_background';
|
||||
currentObj.$bgBlocks.append(newdiv)
|
||||
})
|
||||
const blocks = this.$bgBlocks.querySelectorAll('div')
|
||||
const curBg = 'cur_background'
|
||||
blocks.forEach(function (blk) {
|
||||
blk.addEventListener('click', function () {
|
||||
blocks.forEach((el) => el.classList.remove(curBg));
|
||||
blk.classList.add(curBg);
|
||||
});
|
||||
});
|
||||
this.$saveBtn.addEventListener('click', onSaveHandler);
|
||||
this.$cancelBtn.addEventListener('click', onCancelHandler);
|
||||
this.$dialog.addEventListener('close', onCancelHandler);
|
||||
blocks.forEach((el) => el.classList.remove(curBg))
|
||||
blk.classList.add(curBg)
|
||||
})
|
||||
})
|
||||
this.$saveBtn.addEventListener('click', onSaveHandler)
|
||||
this.$cancelBtn.addEventListener('click', onCancelHandler)
|
||||
this.$dialog.addEventListener('close', onCancelHandler)
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-edit-prefs-dialog', SeEditPrefsDialog);
|
||||
customElements.define('se-edit-prefs-dialog', SeEditPrefsDialog)
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import './se-elix/define/NumberSpinBox.js';
|
||||
import './se-elix/define/NumberSpinBox.js'
|
||||
|
||||
import exportDialogHTML from './exportDialog.html';
|
||||
const template = document.createElement('template');
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
template.innerHTML = exportDialogHTML;
|
||||
import exportDialogHTML from './exportDialog.html'
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = exportDialogHTML
|
||||
/**
|
||||
* @class SeExportDialog
|
||||
*/
|
||||
|
@ -12,36 +11,39 @@ export class SeExportDialog extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$dialog = this._shadowRoot.querySelector('#export_box');
|
||||
this.$okBtn = this._shadowRoot.querySelector('#export_ok');
|
||||
this.$cancelBtn = this._shadowRoot.querySelector('#export_cancel');
|
||||
this.$exportOption = this._shadowRoot.querySelector('#se-storage-pref');
|
||||
this.$qualityCont = this._shadowRoot.querySelector('#se-quality');
|
||||
this.$input = this._shadowRoot.querySelector('elix-number-spin-box');
|
||||
this.value = 1;
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
this.$dialog = this._shadowRoot.querySelector('#export_box')
|
||||
this.$okBtn = this._shadowRoot.querySelector('#export_ok')
|
||||
this.$cancelBtn = this._shadowRoot.querySelector('#export_cancel')
|
||||
this.$exportOption = this._shadowRoot.querySelector('#se-storage-pref')
|
||||
this.$qualityCont = this._shadowRoot.querySelector('#se-quality')
|
||||
this.$input = this._shadowRoot.querySelector('elix-number-spin-box')
|
||||
this.value = 1
|
||||
}
|
||||
|
||||
/**
|
||||
* @function init
|
||||
* @param {any} name
|
||||
* @returns {void}
|
||||
*/
|
||||
init (i18next) {
|
||||
this.setAttribute('common-ok', i18next.t('common.ok'));
|
||||
this.setAttribute('common-cancel', i18next.t('common.cancel'));
|
||||
this.setAttribute('ui-quality', i18next.t('ui.quality'));
|
||||
this.setAttribute('ui-export_type_label', i18next.t('ui.export_type_label'));
|
||||
this.setAttribute('common-ok', i18next.t('common.ok'))
|
||||
this.setAttribute('common-cancel', i18next.t('common.cancel'))
|
||||
this.setAttribute('ui-quality', i18next.t('ui.quality'))
|
||||
this.setAttribute('ui-export_type_label', i18next.t('ui.export_type_label'))
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'dialog', 'common-ok', 'common-cancel', 'ui-quality', 'ui-export_type_label' ];
|
||||
return ['dialog', 'common-ok', 'common-cancel', 'ui-quality', 'ui-export_type_label']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -50,86 +52,91 @@ export class SeExportDialog extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
let node;
|
||||
let node
|
||||
switch (name) {
|
||||
case 'dialog':
|
||||
if (newValue === 'open') {
|
||||
this.$dialog.open();
|
||||
} else {
|
||||
this.$dialog.close();
|
||||
}
|
||||
break;
|
||||
case 'common-ok':
|
||||
this.$okBtn.textContent = newValue;
|
||||
break;
|
||||
case 'common-cancel':
|
||||
this.$cancelBtn.textContent = newValue;
|
||||
break;
|
||||
case 'ui-quality':
|
||||
node = this._shadowRoot.querySelector('#se-quality');
|
||||
node.prepend(newValue);
|
||||
break;
|
||||
case 'ui-export_type_label':
|
||||
node = this._shadowRoot.querySelector('#export_select');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
default:
|
||||
case 'dialog':
|
||||
if (newValue === 'open') {
|
||||
this.$dialog.open()
|
||||
} else {
|
||||
this.$dialog.close()
|
||||
}
|
||||
break
|
||||
case 'common-ok':
|
||||
this.$okBtn.textContent = newValue
|
||||
break
|
||||
case 'common-cancel':
|
||||
this.$cancelBtn.textContent = newValue
|
||||
break
|
||||
case 'ui-quality':
|
||||
node = this._shadowRoot.querySelector('#se-quality')
|
||||
node.prepend(newValue)
|
||||
break
|
||||
case 'ui-export_type_label':
|
||||
node = this._shadowRoot.querySelector('#export_select')
|
||||
node.textContent = newValue
|
||||
break
|
||||
default:
|
||||
// super.attributeChangedCallback(name, oldValue, newValue);
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get dialog () {
|
||||
return this.getAttribute('dialog');
|
||||
return this.getAttribute('dialog')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set dialog (value) {
|
||||
this.setAttribute('dialog', value);
|
||||
this.setAttribute('dialog', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function connectedCallback
|
||||
* @returns {void}
|
||||
*/
|
||||
connectedCallback () {
|
||||
this.$input.addEventListener('change', (e) => {
|
||||
e.preventDefault();
|
||||
this.value = e.target.value;
|
||||
});
|
||||
e.preventDefault()
|
||||
this.value = e.target.value
|
||||
})
|
||||
this.$input.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
this.value = e.target.value;
|
||||
});
|
||||
e.preventDefault()
|
||||
this.value = e.target.value
|
||||
})
|
||||
const onSubmitHandler = (e, action) => {
|
||||
if (action === 'cancel') {
|
||||
document.getElementById('se-export-dialog').setAttribute('dialog', 'close');
|
||||
document.getElementById('se-export-dialog').setAttribute('dialog', 'close')
|
||||
} else {
|
||||
const triggerEvent = new CustomEvent('change', { detail: {
|
||||
trigger: action,
|
||||
imgType: this.$exportOption.value,
|
||||
quality: this.value
|
||||
} });
|
||||
this.dispatchEvent(triggerEvent);
|
||||
document.getElementById('se-export-dialog').setAttribute('dialog', 'close');
|
||||
const triggerEvent = new CustomEvent('change', {
|
||||
detail: {
|
||||
trigger: action,
|
||||
imgType: this.$exportOption.value,
|
||||
quality: this.value
|
||||
}
|
||||
})
|
||||
this.dispatchEvent(triggerEvent)
|
||||
document.getElementById('se-export-dialog').setAttribute('dialog', 'close')
|
||||
}
|
||||
};
|
||||
}
|
||||
const onChangeHandler = (e) => {
|
||||
if (e.target.value === 'PDF') {
|
||||
this.$qualityCont.style.display = 'none';
|
||||
this.$qualityCont.style.display = 'none'
|
||||
} else {
|
||||
this.$qualityCont.style.display = 'block';
|
||||
this.$qualityCont.style.display = 'block'
|
||||
}
|
||||
};
|
||||
this.$okBtn.addEventListener('click', (evt) => onSubmitHandler(evt, 'ok'));
|
||||
this.$cancelBtn.addEventListener('click', (evt) => onSubmitHandler(evt, 'cancel'));
|
||||
this.$exportOption.addEventListener('change', (evt) => onChangeHandler(evt));
|
||||
}
|
||||
this.$okBtn.addEventListener('click', (evt) => onSubmitHandler(evt, 'ok'))
|
||||
this.$cancelBtn.addEventListener('click', (evt) => onSubmitHandler(evt, 'cancel'))
|
||||
this.$exportOption.addEventListener('change', (evt) => onChangeHandler(evt))
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-export-dialog', SeExportDialog);
|
||||
customElements.define('se-export-dialog', SeExportDialog)
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { isValidUnit } from '../../common/units.js';
|
||||
import imagePropertiesDialogHTML from './imagePropertiesDialog.html';
|
||||
import { isValidUnit } from '../../common/units.js'
|
||||
import imagePropertiesDialogHTML from './imagePropertiesDialog.html'
|
||||
|
||||
const template = document.createElement('template');
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
template.innerHTML = imagePropertiesDialogHTML;
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = imagePropertiesDialogHTML
|
||||
/**
|
||||
* @class SeImgPropDialog
|
||||
*/
|
||||
|
@ -12,39 +11,40 @@ export class SeImgPropDialog extends HTMLElement {
|
|||
* @function constructor
|
||||
*/
|
||||
constructor () {
|
||||
super();
|
||||
super()
|
||||
// create the shadowDom and insert the template
|
||||
this.eventlisten = false;
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$saveBtn = this._shadowRoot.querySelector('#tool_docprops_save');
|
||||
this.$cancelBtn = this._shadowRoot.querySelector('#tool_docprops_cancel');
|
||||
this.$resolution = this._shadowRoot.querySelector('#resolution');
|
||||
this.$canvasTitle = this._shadowRoot.querySelector('#canvas_title');
|
||||
this.$canvasWidth = this._shadowRoot.querySelector('#canvas_width');
|
||||
this.$canvasHeight = this._shadowRoot.querySelector('#canvas_height');
|
||||
this.$imageOptEmbed = this._shadowRoot.querySelector('#image_embed');
|
||||
this.$imageOptRef = this._shadowRoot.querySelector('#image_ref');
|
||||
this.$dialog = this._shadowRoot.querySelector('#svg_docprops');
|
||||
this.eventlisten = false
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
this.$saveBtn = this._shadowRoot.querySelector('#tool_docprops_save')
|
||||
this.$cancelBtn = this._shadowRoot.querySelector('#tool_docprops_cancel')
|
||||
this.$resolution = this._shadowRoot.querySelector('#resolution')
|
||||
this.$canvasTitle = this._shadowRoot.querySelector('#canvas_title')
|
||||
this.$canvasWidth = this._shadowRoot.querySelector('#canvas_width')
|
||||
this.$canvasHeight = this._shadowRoot.querySelector('#canvas_height')
|
||||
this.$imageOptEmbed = this._shadowRoot.querySelector('#image_embed')
|
||||
this.$imageOptRef = this._shadowRoot.querySelector('#image_ref')
|
||||
this.$dialog = this._shadowRoot.querySelector('#svg_docprops')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function init
|
||||
* @param {any} name
|
||||
* @returns {void}
|
||||
*/
|
||||
init (i18next) {
|
||||
this.setAttribute('common-ok', i18next.t('common.ok'));
|
||||
this.setAttribute('common-cancel', i18next.t('common.cancel'));
|
||||
this.setAttribute('config-image_props', i18next.t('config.image_props'));
|
||||
this.setAttribute('config-doc_title', i18next.t('config.doc_title'));
|
||||
this.setAttribute('config-doc_dims', i18next.t('config.doc_dims'));
|
||||
this.setAttribute('common-width', i18next.t('common.width'));
|
||||
this.setAttribute('common-height', i18next.t('common.height'));
|
||||
this.setAttribute('config-select_predefined', i18next.t('config.select_predefined'));
|
||||
this.setAttribute('tools-fit-to-content', i18next.t('tools.fitToContent'));
|
||||
this.setAttribute('config-included_images', i18next.t('config.included_images'));
|
||||
this.setAttribute('config-image_opt_embed', i18next.t('config.image_opt_embed'));
|
||||
this.setAttribute('config-image_opt_ref', i18next.t('config.image_opt_ref'));
|
||||
this.setAttribute('common-ok', i18next.t('common.ok'))
|
||||
this.setAttribute('common-cancel', i18next.t('common.cancel'))
|
||||
this.setAttribute('config-image_props', i18next.t('config.image_props'))
|
||||
this.setAttribute('config-doc_title', i18next.t('config.doc_title'))
|
||||
this.setAttribute('config-doc_dims', i18next.t('config.doc_dims'))
|
||||
this.setAttribute('common-width', i18next.t('common.width'))
|
||||
this.setAttribute('common-height', i18next.t('common.height'))
|
||||
this.setAttribute('config-select_predefined', i18next.t('config.select_predefined'))
|
||||
this.setAttribute('tools-fit-to-content', i18next.t('tools.fitToContent'))
|
||||
this.setAttribute('config-included_images', i18next.t('config.included_images'))
|
||||
this.setAttribute('config-image_opt_embed', i18next.t('config.image_opt_embed'))
|
||||
this.setAttribute('config-image_opt_ref', i18next.t('config.image_opt_ref'))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,12 +52,13 @@ export class SeImgPropDialog extends HTMLElement {
|
|||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return [ 'title', 'width', 'height', 'save', 'dialog', 'embed', 'common-ok',
|
||||
return ['title', 'width', 'height', 'save', 'dialog', 'embed', 'common-ok',
|
||||
'common-cancel', 'config-image_props', 'config-doc_title', 'config-doc_dims',
|
||||
'common-width', 'common-height', 'config-select_predefined',
|
||||
'tools-fit-to-content', 'config-included_images', 'config-image_opt_embed',
|
||||
'config-image_opt_ref' ];
|
||||
'config-image_opt_ref']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
|
@ -66,117 +67,118 @@ export class SeImgPropDialog extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
let node ;
|
||||
if (oldValue === newValue) return
|
||||
let node
|
||||
switch (name) {
|
||||
case 'title':
|
||||
this.$canvasTitle.value = newValue;
|
||||
break;
|
||||
case 'width':
|
||||
if (newValue === 'fit') {
|
||||
this.$canvasWidth.removeAttribute('disabled');
|
||||
this.$canvasWidth.value = 100;
|
||||
this.$canvasHeight.removeAttribute('disabled');
|
||||
this.$canvasHeight.value = 100;
|
||||
} else {
|
||||
this.$canvasWidth.value = newValue;
|
||||
}
|
||||
break;
|
||||
case 'height':
|
||||
if (newValue === 'fit') {
|
||||
this.$canvasWidth.removeAttribute('disabled');
|
||||
this.$canvasWidth.value = 100;
|
||||
this.$canvasHeight.removeAttribute('disabled');
|
||||
this.$canvasHeight.value = 100;
|
||||
} else {
|
||||
this.$canvasHeight.value = newValue;
|
||||
}
|
||||
break;
|
||||
case 'dialog':
|
||||
if (this.eventlisten) {
|
||||
if (newValue === 'open') {
|
||||
this.$dialog.open();
|
||||
case 'title':
|
||||
this.$canvasTitle.value = newValue
|
||||
break
|
||||
case 'width':
|
||||
if (newValue === 'fit') {
|
||||
this.$canvasWidth.removeAttribute('disabled')
|
||||
this.$canvasWidth.value = 100
|
||||
this.$canvasHeight.removeAttribute('disabled')
|
||||
this.$canvasHeight.value = 100
|
||||
} else {
|
||||
this.$dialog.close();
|
||||
this.$canvasWidth.value = newValue
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'save':
|
||||
if (newValue === 'ref') {
|
||||
this.$imageOptEmbed.setAttribute('checked', false);
|
||||
this.$imageOptRef.setAttribute('checked', true);
|
||||
} else {
|
||||
this.$imageOptEmbed.setAttribute('checked', true);
|
||||
this.$imageOptRef.setAttribute('checked', false);
|
||||
}
|
||||
break;
|
||||
case 'embed':
|
||||
if (newValue.includes('one')) {
|
||||
const data = newValue.split('|');
|
||||
if (data.length > 1) {
|
||||
this._shadowRoot.querySelector('#image_opt_embed').setAttribute('title', data[1]);
|
||||
this._shadowRoot.querySelector('#image_opt_embed').setAttribute('disabled', 'disabled');
|
||||
this._shadowRoot.querySelector('#image_opt_embed').style.color = '#666';
|
||||
break
|
||||
case 'height':
|
||||
if (newValue === 'fit') {
|
||||
this.$canvasWidth.removeAttribute('disabled')
|
||||
this.$canvasWidth.value = 100
|
||||
this.$canvasHeight.removeAttribute('disabled')
|
||||
this.$canvasHeight.value = 100
|
||||
} else {
|
||||
this.$canvasHeight.value = newValue
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'common-ok':
|
||||
this.$saveBtn.textContent = newValue;
|
||||
break;
|
||||
case 'common-cancel':
|
||||
this.$cancelBtn.textContent = newValue;
|
||||
break;
|
||||
case 'config-image_props':
|
||||
node = this._shadowRoot.querySelector('#svginfo_image_props');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-doc_title':
|
||||
node = this._shadowRoot.querySelector('#svginfo_title');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-doc_dims':
|
||||
node = this._shadowRoot.querySelector('#svginfo_dim');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'common-width':
|
||||
node = this._shadowRoot.querySelector('#svginfo_width');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'common-height':
|
||||
node = this._shadowRoot.querySelector('#svginfo_height');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-select_predefined':
|
||||
node = this._shadowRoot.querySelector('#selectedPredefined');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'tools-fit-to-content':
|
||||
node = this._shadowRoot.querySelector('#fitToContent');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-included_images':
|
||||
node = this._shadowRoot.querySelector('#includedImages');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-image_opt_embed':
|
||||
node = this._shadowRoot.querySelector('#image_opt_embed');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
case 'config-image_opt_ref':
|
||||
node = this._shadowRoot.querySelector('#image_opt_ref');
|
||||
node.textContent = newValue;
|
||||
break;
|
||||
default:
|
||||
super.attributeChangedCallback(name, oldValue, newValue);
|
||||
break;
|
||||
break
|
||||
case 'dialog':
|
||||
if (this.eventlisten) {
|
||||
if (newValue === 'open') {
|
||||
this.$dialog.open()
|
||||
} else {
|
||||
this.$dialog.close()
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'save':
|
||||
if (newValue === 'ref') {
|
||||
this.$imageOptEmbed.setAttribute('checked', false)
|
||||
this.$imageOptRef.setAttribute('checked', true)
|
||||
} else {
|
||||
this.$imageOptEmbed.setAttribute('checked', true)
|
||||
this.$imageOptRef.setAttribute('checked', false)
|
||||
}
|
||||
break
|
||||
case 'embed':
|
||||
if (newValue.includes('one')) {
|
||||
const data = newValue.split('|')
|
||||
if (data.length > 1) {
|
||||
this._shadowRoot.querySelector('#image_opt_embed').setAttribute('title', data[1])
|
||||
this._shadowRoot.querySelector('#image_opt_embed').setAttribute('disabled', 'disabled')
|
||||
this._shadowRoot.querySelector('#image_opt_embed').style.color = '#666'
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'common-ok':
|
||||
this.$saveBtn.textContent = newValue
|
||||
break
|
||||
case 'common-cancel':
|
||||
this.$cancelBtn.textContent = newValue
|
||||
break
|
||||
case 'config-image_props':
|
||||
node = this._shadowRoot.querySelector('#svginfo_image_props')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-doc_title':
|
||||
node = this._shadowRoot.querySelector('#svginfo_title')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-doc_dims':
|
||||
node = this._shadowRoot.querySelector('#svginfo_dim')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'common-width':
|
||||
node = this._shadowRoot.querySelector('#svginfo_width')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'common-height':
|
||||
node = this._shadowRoot.querySelector('#svginfo_height')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-select_predefined':
|
||||
node = this._shadowRoot.querySelector('#selectedPredefined')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'tools-fit-to-content':
|
||||
node = this._shadowRoot.querySelector('#fitToContent')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-included_images':
|
||||
node = this._shadowRoot.querySelector('#includedImages')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-image_opt_embed':
|
||||
node = this._shadowRoot.querySelector('#image_opt_embed')
|
||||
node.textContent = newValue
|
||||
break
|
||||
case 'config-image_opt_ref':
|
||||
node = this._shadowRoot.querySelector('#image_opt_ref')
|
||||
node.textContent = newValue
|
||||
break
|
||||
default:
|
||||
super.attributeChangedCallback(name, oldValue, newValue)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get title () {
|
||||
return this.getAttribute('title');
|
||||
return this.getAttribute('title')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,78 +186,89 @@ export class SeImgPropDialog extends HTMLElement {
|
|||
* @returns {void}
|
||||
*/
|
||||
set title (value) {
|
||||
this.setAttribute('title', value);
|
||||
this.setAttribute('title', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get width () {
|
||||
return this.getAttribute('width');
|
||||
return this.getAttribute('width')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set width (value) {
|
||||
this.setAttribute('width', value);
|
||||
this.setAttribute('width', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get height () {
|
||||
return this.getAttribute('height');
|
||||
return this.getAttribute('height')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set height (value) {
|
||||
this.setAttribute('height', value);
|
||||
this.setAttribute('height', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get save () {
|
||||
return this.getAttribute('save');
|
||||
return this.getAttribute('save')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set save (value) {
|
||||
this.setAttribute('save', value);
|
||||
this.setAttribute('save', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get dialog () {
|
||||
return this.getAttribute('dialog');
|
||||
return this.getAttribute('dialog')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set dialog (value) {
|
||||
this.setAttribute('dialog', value);
|
||||
this.setAttribute('dialog', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get embed () {
|
||||
return this.getAttribute('embed');
|
||||
return this.getAttribute('embed')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set embed (value) {
|
||||
this.setAttribute('embed', value);
|
||||
this.setAttribute('embed', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function connectedCallback
|
||||
* @returns {void}
|
||||
|
@ -264,72 +277,76 @@ export class SeImgPropDialog extends HTMLElement {
|
|||
const onChangeHandler = (ev) => {
|
||||
if (!ev.target.selectedIndex) {
|
||||
if (this.$canvasWidth.getAttribute('value') === 'fit') {
|
||||
this.$canvasWidth.removeAttribute('disabled');
|
||||
this.$canvasWidth.value = 100;
|
||||
this.$canvasHeight.removeAttribute('disabled');
|
||||
this.$canvasHeight.value = 100;
|
||||
this.$canvasWidth.removeAttribute('disabled')
|
||||
this.$canvasWidth.value = 100
|
||||
this.$canvasHeight.removeAttribute('disabled')
|
||||
this.$canvasHeight.value = 100
|
||||
}
|
||||
} else if (ev.target.value === 'content') {
|
||||
this.$canvasWidth.setAttribute('disabled', 'disabled');
|
||||
this.$canvasWidth.value = 'fit';
|
||||
this.$canvasHeight.setAttribute('disabled', 'disabled');
|
||||
this.$canvasHeight.value = 'fit';
|
||||
this.$canvasWidth.setAttribute('disabled', 'disabled')
|
||||
this.$canvasWidth.value = 'fit'
|
||||
this.$canvasHeight.setAttribute('disabled', 'disabled')
|
||||
this.$canvasHeight.value = 'fit'
|
||||
} else {
|
||||
const dims = ev.target.value.split('x');
|
||||
this.$canvasWidth.value = dims[0];
|
||||
this.$canvasWidth.removeAttribute('disabled');
|
||||
this.$canvasHeight.value = dims[1];
|
||||
this.$canvasHeight.removeAttribute('disabled');
|
||||
const dims = ev.target.value.split('x')
|
||||
this.$canvasWidth.value = dims[0]
|
||||
this.$canvasWidth.removeAttribute('disabled')
|
||||
this.$canvasHeight.value = dims[1]
|
||||
this.$canvasHeight.removeAttribute('disabled')
|
||||
}
|
||||
};
|
||||
}
|
||||
const onSaveHandler = () => {
|
||||
let saveOpt = '';
|
||||
const w = this.$canvasWidth.value;
|
||||
const h = this.$canvasHeight.value;
|
||||
let saveOpt = ''
|
||||
const w = this.$canvasWidth.value
|
||||
const h = this.$canvasHeight.value
|
||||
if (w !== 'fit' && !isValidUnit('width', w)) {
|
||||
this.$canvasWidth.parentElement.classList.add('error');
|
||||
this.$canvasWidth.parentElement.classList.add('error')
|
||||
} else {
|
||||
this.$canvasWidth.parentElement.classList.remove('error');
|
||||
this.$canvasWidth.parentElement.classList.remove('error')
|
||||
}
|
||||
if (h !== 'fit' && !isValidUnit('height', w)) {
|
||||
this.$canvasHeight.parentElement.classList.add('error');
|
||||
this.$canvasHeight.parentElement.classList.add('error')
|
||||
} else {
|
||||
this.$canvasHeight.parentElement.classList.remove('error');
|
||||
this.$canvasHeight.parentElement.classList.remove('error')
|
||||
}
|
||||
if (this.$imageOptEmbed.getAttribute('checked') === 'true') {
|
||||
saveOpt = 'embed';
|
||||
saveOpt = 'embed'
|
||||
}
|
||||
if (this.$imageOptRef.getAttribute('checked') === 'true') {
|
||||
saveOpt = 'ref';
|
||||
saveOpt = 'ref'
|
||||
}
|
||||
const closeEvent = new CustomEvent('change', { detail: {
|
||||
title: this.$canvasTitle.value,
|
||||
w: this.$canvasWidth.value,
|
||||
h: this.$canvasHeight.value,
|
||||
save: saveOpt,
|
||||
dialog: 'close'
|
||||
} });
|
||||
this.$canvasWidth.removeAttribute('disabled');
|
||||
this.$canvasHeight.removeAttribute('disabled');
|
||||
this.$resolution.selectedIndex = 0;
|
||||
this.dispatchEvent(closeEvent);
|
||||
};
|
||||
const closeEvent = new CustomEvent('change', {
|
||||
detail: {
|
||||
title: this.$canvasTitle.value,
|
||||
w: this.$canvasWidth.value,
|
||||
h: this.$canvasHeight.value,
|
||||
save: saveOpt,
|
||||
dialog: 'close'
|
||||
}
|
||||
})
|
||||
this.$canvasWidth.removeAttribute('disabled')
|
||||
this.$canvasHeight.removeAttribute('disabled')
|
||||
this.$resolution.selectedIndex = 0
|
||||
this.dispatchEvent(closeEvent)
|
||||
}
|
||||
const onCancelHandler = () => {
|
||||
const closeEvent = new CustomEvent('change', { detail: {
|
||||
dialog: 'closed'
|
||||
} });
|
||||
this.$canvasWidth.removeAttribute('disabled');
|
||||
this.$canvasHeight.removeAttribute('disabled');
|
||||
this.$resolution.selectedIndex = 0;
|
||||
this.dispatchEvent(closeEvent);
|
||||
};
|
||||
this.$resolution.addEventListener('change', onChangeHandler);
|
||||
this.$saveBtn.addEventListener('click', onSaveHandler);
|
||||
this.$cancelBtn.addEventListener('click', onCancelHandler);
|
||||
this.$dialog.addEventListener('close', onCancelHandler);
|
||||
this.eventlisten = true;
|
||||
const closeEvent = new CustomEvent('change', {
|
||||
detail: {
|
||||
dialog: 'closed'
|
||||
}
|
||||
})
|
||||
this.$canvasWidth.removeAttribute('disabled')
|
||||
this.$canvasHeight.removeAttribute('disabled')
|
||||
this.$resolution.selectedIndex = 0
|
||||
this.dispatchEvent(closeEvent)
|
||||
}
|
||||
this.$resolution.addEventListener('change', onChangeHandler)
|
||||
this.$saveBtn.addEventListener('click', onSaveHandler)
|
||||
this.$cancelBtn.addEventListener('click', onCancelHandler)
|
||||
this.$dialog.addEventListener('close', onCancelHandler)
|
||||
this.eventlisten = true
|
||||
}
|
||||
}
|
||||
|
||||
// Register
|
||||
customElements.define('se-img-prop-dialog', SeImgPropDialog);
|
||||
customElements.define('se-img-prop-dialog', SeImgPropDialog)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import 'elix/define/Dialog.js';
|
||||
import './imagePropertiesDialog.js';
|
||||
import './editorPreferencesDialog.js';
|
||||
import './svgSourceDialog.js';
|
||||
import './cmenuDialog.js';
|
||||
import './cmenuLayersDialog.js';
|
||||
import './seSelectDialog.js';
|
||||
import './seConfirmDialog.js';
|
||||
import './sePromptDialog.js';
|
||||
import './seAlertDialog.js';
|
||||
import './exportDialog.js';
|
||||
import 'elix/define/Dialog.js'
|
||||
import './imagePropertiesDialog.js'
|
||||
import './editorPreferencesDialog.js'
|
||||
import './svgSourceDialog.js'
|
||||
import './cmenuDialog.js'
|
||||
import './cmenuLayersDialog.js'
|
||||
import './seSelectDialog.js'
|
||||
import './seConfirmDialog.js'
|
||||
import './sePromptDialog.js'
|
||||
import './seAlertDialog.js'
|
||||
import './exportDialog.js'
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import PlainNumberSpinBox from '../src/plain/PlainNumberSpinBox.js';
|
||||
import PlainNumberSpinBox from '../src/plain/PlainNumberSpinBox.js'
|
||||
/**
|
||||
* @class ElixNumberSpinBox
|
||||
*/
|
||||
export default class ElixNumberSpinBox extends PlainNumberSpinBox {}
|
||||
|
||||
|
||||
customElements.define('elix-number-spin-box', ElixNumberSpinBox);
|
||||
customElements.define('elix-number-spin-box', ElixNumberSpinBox)
|
||||
|
|
|
@ -3,10 +3,10 @@ import {
|
|||
setState,
|
||||
state,
|
||||
stateEffects
|
||||
} from 'elix/src/base/internal.js';
|
||||
} from 'elix/src/base/internal.js'
|
||||
import {
|
||||
SpinBox
|
||||
} from 'elix/src/base/SpinBox.js';
|
||||
} from 'elix/src/base/SpinBox.js'
|
||||
|
||||
/**
|
||||
* @class NumberSpinBox
|
||||
|
@ -21,15 +21,16 @@ class NumberSpinBox extends SpinBox {
|
|||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
if (name === 'max') {
|
||||
this.max = parseFloat(newValue);
|
||||
this.max = parseFloat(newValue)
|
||||
} else if (name === 'min') {
|
||||
this.min = parseFloat(newValue);
|
||||
this.min = parseFloat(newValue)
|
||||
} else if (name === 'step') {
|
||||
this.step = parseFloat(newValue);
|
||||
this.step = parseFloat(newValue)
|
||||
} else {
|
||||
super.attributeChangedCallback(name, oldValue, newValue);
|
||||
super.attributeChangedCallback(name, oldValue, newValue)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function observedAttributes
|
||||
* @returns {any} observed
|
||||
|
@ -39,7 +40,7 @@ class NumberSpinBox extends SpinBox {
|
|||
max: null,
|
||||
min: null,
|
||||
step: 1
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,7 +55,7 @@ class NumberSpinBox extends SpinBox {
|
|||
* @returns {number}
|
||||
*/
|
||||
formatValue (value, precision) {
|
||||
return Number(value).toFixed(precision);
|
||||
return Number(value).toFixed(precision)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -64,8 +65,9 @@ class NumberSpinBox extends SpinBox {
|
|||
* @default 1
|
||||
*/
|
||||
get max () {
|
||||
return this[state].max;
|
||||
return this[state].max
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum allowable value of the `value` property.
|
||||
*
|
||||
|
@ -75,7 +77,7 @@ class NumberSpinBox extends SpinBox {
|
|||
set max (max) {
|
||||
this[setState]({
|
||||
max
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -85,8 +87,9 @@ class NumberSpinBox extends SpinBox {
|
|||
* @default 1
|
||||
*/
|
||||
get min () {
|
||||
return this[state].min;
|
||||
return this[state].min
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
|
@ -94,7 +97,7 @@ class NumberSpinBox extends SpinBox {
|
|||
set min (min) {
|
||||
this[setState]({
|
||||
min
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,9 +107,10 @@ class NumberSpinBox extends SpinBox {
|
|||
* @returns {int}
|
||||
*/
|
||||
parseValue (value, precision) {
|
||||
const parsed = precision === 0 ? parseInt(value) : parseFloat(value);
|
||||
return isNaN(parsed) ? 0 : parsed;
|
||||
const parsed = precision === 0 ? parseInt(value) : parseFloat(value)
|
||||
return isNaN(parsed) ? 0 : parsed
|
||||
}
|
||||
|
||||
/**
|
||||
* @function stateEffects
|
||||
* @param {any} state
|
||||
|
@ -114,19 +118,19 @@ class NumberSpinBox extends SpinBox {
|
|||
* @returns {any}
|
||||
*/
|
||||
[stateEffects] (state, changed) {
|
||||
const effects = super[stateEffects];
|
||||
const effects = super[stateEffects]
|
||||
// If step changed, calculate its precision (number of digits after
|
||||
// the decimal).
|
||||
if (changed.step) {
|
||||
const {
|
||||
step
|
||||
} = state;
|
||||
const decimalRegex = /\.(\d)+$/;
|
||||
const match = decimalRegex.exec(String(step));
|
||||
const precision = match && match[1] ? match[1].length : 0;
|
||||
} = state
|
||||
const decimalRegex = /\.(\d)+$/
|
||||
const match = decimalRegex.exec(String(step))
|
||||
const precision = match && match[1] ? match[1].length : 0
|
||||
Object.assign(effects, {
|
||||
precision
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
if (changed.max || changed.min || changed.value) {
|
||||
|
@ -140,41 +144,41 @@ class NumberSpinBox extends SpinBox {
|
|||
min,
|
||||
precision,
|
||||
value
|
||||
} = state;
|
||||
const parsed = parseInt(value, precision);
|
||||
} = state
|
||||
const parsed = parseInt(value, precision)
|
||||
if (value !== '' && isNaN(parsed)) {
|
||||
Object.assign(effects, {
|
||||
valid: false,
|
||||
validationMessage: 'Value must be a number'
|
||||
});
|
||||
})
|
||||
} else if (!(max === null || parsed <= max)) {
|
||||
Object.assign(effects, {
|
||||
valid: false,
|
||||
validationMessage: `Value must be less than or equal to ${max}.`
|
||||
});
|
||||
})
|
||||
} else if (!(min === null || parsed >= min)) {
|
||||
Object.assign(effects, {
|
||||
valid: false,
|
||||
validationMessage: `Value must be greater than or equal to ${min}.`
|
||||
});
|
||||
})
|
||||
} else {
|
||||
Object.assign(effects, {
|
||||
valid: true,
|
||||
validationMessage: ''
|
||||
});
|
||||
})
|
||||
}
|
||||
// We can only go up if we're below max.
|
||||
Object.assign(effects, {
|
||||
canGoUp: isNaN(parsed) || state.max === null || parsed <= state.max
|
||||
});
|
||||
})
|
||||
|
||||
// We can only go down if we're above min.
|
||||
Object.assign(effects, {
|
||||
canGoDown: isNaN(parsed) || state.min === null || parsed >= state.min
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return effects;
|
||||
return effects
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -182,8 +186,9 @@ class NumberSpinBox extends SpinBox {
|
|||
* @returns {any}
|
||||
*/
|
||||
get step () {
|
||||
return this[state].step;
|
||||
return this[state].step
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
|
@ -192,7 +197,7 @@ class NumberSpinBox extends SpinBox {
|
|||
if (!isNaN(step)) {
|
||||
this[setState]({
|
||||
step
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,21 +206,21 @@ class NumberSpinBox extends SpinBox {
|
|||
* @returns {void}
|
||||
*/
|
||||
stepDown () {
|
||||
super.stepDown();
|
||||
super.stepDown()
|
||||
const {
|
||||
max,
|
||||
precision,
|
||||
value
|
||||
} = this[state];
|
||||
let result = this.parseValue(value, precision) - this.step;
|
||||
} = this[state]
|
||||
let result = this.parseValue(value, precision) - this.step
|
||||
if (max !== null) {
|
||||
result = Math.min(result, max);
|
||||
result = Math.min(result, max)
|
||||
}
|
||||
const {
|
||||
min
|
||||
} = this[state];
|
||||
} = this[state]
|
||||
if (min === null || result >= min) {
|
||||
this.value = this.formatValue(result, precision);
|
||||
this.value = this.formatValue(result, precision)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,23 +229,23 @@ class NumberSpinBox extends SpinBox {
|
|||
* @returns {void}
|
||||
*/
|
||||
stepUp () {
|
||||
super.stepUp();
|
||||
super.stepUp()
|
||||
const {
|
||||
min,
|
||||
precision,
|
||||
value
|
||||
} = this[state];
|
||||
let result = this.parseValue(value, precision) + this.step;
|
||||
} = this[state]
|
||||
let result = this.parseValue(value, precision) + this.step
|
||||
if (min !== null) {
|
||||
result = Math.max(result, min);
|
||||
result = Math.max(result, min)
|
||||
}
|
||||
const {
|
||||
max
|
||||
} = this[state];
|
||||
} = this[state]
|
||||
if (max === null || result <= max) {
|
||||
this.value = this.formatValue(result, precision);
|
||||
this.value = this.formatValue(result, precision)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default NumberSpinBox;
|
||||
export default NumberSpinBox
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import PlainSpinBoxMixin from 'elix/src/plain/PlainSpinBoxMixin.js';
|
||||
import NumberSpinBox from '../base/NumberSpinBox.js';
|
||||
import PlainSpinBoxMixin from 'elix/src/plain/PlainSpinBoxMixin.js'
|
||||
import NumberSpinBox from '../base/NumberSpinBox.js'
|
||||
|
||||
/**
|
||||
* @class PlainNumberSpinBox
|
||||
*/
|
||||
class PlainNumberSpinBox extends PlainSpinBoxMixin(NumberSpinBox) {}
|
||||
|
||||
export default PlainNumberSpinBox;
|
||||
export default PlainNumberSpinBox
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue