Merge pull request #687 from SVG-Edit/refactor-svgcanvas
Refactor svgcanvas and move to standard lintmaster
commit
88207acc98
|
@ -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/**
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,91 +1,78 @@
|
|||
exports[`use all parts of svg-edit > check tool_source_set #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
width="640"
|
||||
height="480"
|
||||
id="svgcontent"
|
||||
overflow="visible"
|
||||
x="640"
|
||||
y="480"
|
||||
viewBox="0 0 640 480"
|
||||
>
|
||||
<g class="layer"><title>Layer 1</title></g>
|
||||
</svg>
|
||||
<body>
|
||||
<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>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_shape #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
width="640"
|
||||
height="480"
|
||||
id="svgcontent"
|
||||
overflow="visible"
|
||||
x="640"
|
||||
y="480"
|
||||
viewBox="0 0 640 480"
|
||||
>
|
||||
<g class="layer" style="pointer-events:all">
|
||||
<title style="pointer-events:inherit">Layer 1</title>
|
||||
<path
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
d="m208.99746606586632,203.82033218045854 c4.117685576066451,-11.81303239035457 20.250912669179264,0 0,15.18818450188445 c-20.250912669179264,-15.18818450188445 -4.117685576066451,-27.00121689223902 0,-15.18818450188445 z"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
transform="rotate(43.2545 208.997 209.008)"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
<body>
|
||||
<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>
|
||||
<path
|
||||
d="m208.99747,203.82033c4.11769,-11.81303 20.25091,0 0,15.18818c-20.25091,-15.18818 -4.11769,-27.00122 0,-15.18818z"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
transform="rotate(43.2545 208.997 209.008)"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_image #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
width="640"
|
||||
height="480"
|
||||
id="svgcontent"
|
||||
overflow="visible"
|
||||
x="640"
|
||||
y="480"
|
||||
viewBox="0 0 640 480"
|
||||
>
|
||||
<g class="layer" style="pointer-events:all">
|
||||
<title style="pointer-events:inherit">Layer 1</title>
|
||||
<path
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
d="m208.99746606586632,203.82033218045854 c4.117685576066451,-11.81303239035457 20.250912669179264,0 0,15.18818450188445 c-20.250912669179264,-15.18818450188445 -4.117685576066451,-27.00121689223902 0,-15.18818450188445 z"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
transform="rotate(43.2545 208.997 209.008)"
|
||||
></path>
|
||||
<image
|
||||
x="295"
|
||||
y="295"
|
||||
width="20"
|
||||
height="20"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
style="pointer-events:inherit"
|
||||
xlink:href="./images/logo.svg"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
begin="indefinite"
|
||||
dur="0.2"
|
||||
fill="freeze"
|
||||
to="1"
|
||||
></animate>
|
||||
</image>
|
||||
</g>
|
||||
</svg>
|
||||
<body>
|
||||
<svg
|
||||
width="640"
|
||||
height="480"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<path
|
||||
d="m208.99747,203.82033c4.11769,-11.81303 20.25091,0 0,15.18818c-20.25091,-15.18818 -4.11769,-27.00122 0,-15.18818z"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
transform="rotate(43.2545 208.997 209.008)"
|
||||
></path>
|
||||
<image
|
||||
height="20"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
width="20"
|
||||
x="295"
|
||||
xlink:href="./images/logo.svg"
|
||||
y="295"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
begin="indefinite"
|
||||
dur="0.2"
|
||||
fill="freeze"
|
||||
to="1"
|
||||
></animate>
|
||||
</image>
|
||||
</g>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,158 +1,133 @@
|
|||
exports[`use all parts of svg-edit > check tool_source_set #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
width="640"
|
||||
height="480"
|
||||
id="svgcontent"
|
||||
overflow="visible"
|
||||
x="640"
|
||||
y="480"
|
||||
viewBox="0 0 640 480"
|
||||
>
|
||||
<g class="layer"><title>Layer 1</title></g>
|
||||
</svg>
|
||||
<body>
|
||||
<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>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_path #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
width="640"
|
||||
height="480"
|
||||
id="svgcontent"
|
||||
overflow="visible"
|
||||
x="640"
|
||||
y="480"
|
||||
viewBox="0 0 640 480"
|
||||
>
|
||||
<g class="layer" style="pointer-events:all">
|
||||
<title style="pointer-events:inherit">Layer 1</title>
|
||||
<path
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
opacity="0.5"
|
||||
style="pointer-events:inherit"
|
||||
d="M 50 50 L 150 100 L 125 200 L 50 50 z"
|
||||
id="svg_1"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
begin="indefinite"
|
||||
dur="0.2"
|
||||
fill="freeze"
|
||||
to="1"
|
||||
></animate>
|
||||
</path>
|
||||
</g>
|
||||
</svg>
|
||||
<body>
|
||||
<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>
|
||||
<path
|
||||
d="m50,50l100,50l-25,100l-75,-150z"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
begin="indefinite"
|
||||
dur="0.2"
|
||||
fill="freeze"
|
||||
to="1"
|
||||
></animate>
|
||||
</path>
|
||||
</g>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_path_change_node_xy #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
width="640"
|
||||
height="480"
|
||||
id="svgcontent"
|
||||
overflow="visible"
|
||||
x="640"
|
||||
y="480"
|
||||
viewBox="0 0 640 480"
|
||||
>
|
||||
<g class="layer" style="pointer-events:all">
|
||||
<title style="pointer-events:inherit">Layer 1</title>
|
||||
<path
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
d="M 75 75 L 150 100 L 125 200 L 75 75 z"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_path_change_seg_type #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
width="640"
|
||||
height="480"
|
||||
id="svgcontent"
|
||||
overflow="visible"
|
||||
x="640"
|
||||
y="480"
|
||||
viewBox="0 0 640 480"
|
||||
>
|
||||
<g class="layer" style="pointer-events:all">
|
||||
<title style="pointer-events:inherit">Layer 1</title>
|
||||
<path
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
d="M 75 75 L 150 100 L 125 200 C 235.33333333333331 330.33333333333337 91.66666666666667 116.66666666666666 75 75 z"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_path_change_clone_node #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
width="640"
|
||||
height="480"
|
||||
id="svgcontent"
|
||||
overflow="visible"
|
||||
x="640"
|
||||
y="480"
|
||||
viewBox="0 0 640 480"
|
||||
>
|
||||
<g class="layer" style="pointer-events:all">
|
||||
<title style="pointer-events:inherit">Layer 1</title>
|
||||
<path
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
d="M 201 246 L 150 100 L 125 200 C 180.16666666666666 265.1666666666667 297.8333333333333 415.33333333333337 273.625 373 C 249.41666666666669 330.66666666666663 209.33333333333334 266.8333333333333 201 246 z"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
<body>
|
||||
<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>
|
||||
<path
|
||||
d="m75,75l75,25l-25,100l-50,-125z"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_path_openclose #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
width="640"
|
||||
height="480"
|
||||
id="svgcontent"
|
||||
overflow="visible"
|
||||
x="640"
|
||||
y="480"
|
||||
viewBox="0 0 640 480"
|
||||
>
|
||||
<g class="layer" style="pointer-events:all">
|
||||
<title style="pointer-events:inherit">Layer 1</title>
|
||||
<path
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
d="M 201 246 L 150 100 L 125 200 C 180.16666666666666 265.1666666666667 297.8333333333333 415.33333333333337 273.625 373 C 249.41666666666669 330.66666666666663 209.33333333333334 266.8333333333333 201 246 z"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
<body>
|
||||
<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>
|
||||
<path
|
||||
d="m201,246l-51,-146l-25,100c55.16667,65.16667 172.83333,215.33333 148.625,173c-24.20833,-42.33333 -64.29167,-106.16667 -72.625,-127z"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_path_change_seg_type #0`] = `
|
||||
<body>
|
||||
<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>
|
||||
<path
|
||||
d="m75,75l75,25l-25,100c110.33333,130.33333 -33.33333,-83.33333 -50,-125z"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_path_change_clone_node #0`] = `
|
||||
<body>
|
||||
<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>
|
||||
<path
|
||||
d="m201,246l-51,-146l-25,100c55.16667,65.16667 172.83333,215.33333 148.625,173c-24.20833,-42.33333 -64.29167,-106.16667 -72.625,-127z"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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');
|
||||
});
|
||||
});
|
||||
it('cmd-A on empty canvas should not cause an error', function () {
|
||||
cy.get('body').type('{cmd}a')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,188 +1,184 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
visitAndApproveStorage, testSnapshot
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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");
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_font_family').shadow().find('select').select('Serif')
|
||||
testSnapshot()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,55 +1,51 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
visitAndApproveStorage, testSnapshot
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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');
|
||||
});
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
cy.stub($win, 'prompt').returns('./images/logo.svg')
|
||||
cy.contains('OK')
|
||||
})
|
||||
testSnapshot()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,124 +1,120 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
visitAndApproveStorage, testSnapshot
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_ellipse_bring_to_back', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#tool_move_bottom').click({ force: true });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
cy.get('#svg_2').click({ force: true })
|
||||
cy.get('#tool_clone').click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,31 +1,27 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
visitAndApproveStorage, testSnapshot
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
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 +33,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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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', { force: true }).should('have.value', '6')
|
||||
cy.get('#ctrlpointgrip_3c1')
|
||||
.trigger('mousedown', { force: true })
|
||||
.trigger('mousemove', 130, 175, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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')
|
||||
|
@ -95,6 +91,6 @@ describe('use all parts of svg-edit', function () {
|
|||
.trigger('mousedown', 0, 0, { force: true })
|
||||
.trigger('mouseup', { force: true });
|
||||
cy.get('#tool_select').click({ force: true });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
testSnapshot();
|
||||
}); */
|
||||
});
|
||||
})
|
||||
|
|
|
@ -1,164 +1,160 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
visitAndApproveStorage, testSnapshot
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_square_clone', function () {
|
||||
cy.get('#svg_3').click({ force: true });
|
||||
cy.get('#tool_clone').click({ force: true });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_rect_change_to_path', function () {
|
||||
cy.get('#svg_2').click({ force: true });
|
||||
cy.get('#tool_topath').click({ force: true });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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,149 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
visitAndApproveStorage, testSnapshot
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_line_delete', function () {
|
||||
cy.get('#svg_1_id').click({ force: true });
|
||||
cy.get('#tool_delete').click({ force: true });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,108 +1,104 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
visitAndApproveStorage, testSnapshot
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 ++){
|
||||
|
@ -113,38 +109,38 @@ describe('use all parts of svg-edit', function () {
|
|||
cy.get('#selected_y').shadow().find('elix-number-spin-box').eq(0).shadow().find('#upButton').eq(0)
|
||||
.click({ force: true });
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,138 +1,134 @@
|
|||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
|
||||
const testSnapshot = () => {
|
||||
cy.get('#svgcontent').cleanSnapshot();
|
||||
};
|
||||
visitAndApproveStorage, testSnapshot
|
||||
} from '../../support/ui-test-helper.js'
|
||||
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 })
|
||||
}
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
.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 });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
.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 hstory 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 hstory.Command {
|
||||
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 hstory.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(hstory);
|
||||
assert.ok(hstory.MoveElementCommand);
|
||||
assert.ok(hstory.InsertElementCommand);
|
||||
assert.ok(hstory.ChangeElementCommand);
|
||||
assert.ok(hstory.RemoveElementCommand);
|
||||
assert.ok(hstory.BatchCommand);
|
||||
assert.ok(hstory.UndoManager);
|
||||
assert.equal(typeof hstory.MoveElementCommand, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof hstory.InsertElementCommand, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof hstory.ChangeElementCommand, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof hstory.RemoveElementCommand, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof hstory.BatchCommand, typeof function () { /* empty fn */ });
|
||||
assert.equal(typeof hstory.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 hstory.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 hstory.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 hstory.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 hstory.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 hstory.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 hstory.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 hstory.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');
|
||||
let change = new hstory.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 */ });
|
||||
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 */ })
|
||||
|
||||
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';
|
||||
change = new hstory.ChangeElementCommand(this.div1,
|
||||
{ '#text': null });
|
||||
this.div1.textContent = 'inner text'
|
||||
change = new history.ChangeElementCommand(this.div1,
|
||||
{ '#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 = '';
|
||||
change = new hstory.ChangeElementCommand(this.div1,
|
||||
{ '#text': 'old text' });
|
||||
this.div1.textContent = ''
|
||||
change = new history.ChangeElementCommand(this.div1,
|
||||
{ '#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';
|
||||
change = new hstory.ChangeElementCommand(rect,
|
||||
{ '#href': '#oldhref' });
|
||||
assert.equal(justCalled, 'getHref');
|
||||
gethrefvalue = '#newhref'
|
||||
change = new history.ChangeElementCommand(rect,
|
||||
{ '#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 hstory.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 hstory.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; },
|
||||
getCurrentZoom () { 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)
|
||||
new Path(path) // eslint-disable-line no-new
|
||||
|
||||
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)
|
||||
new Path(path) // eslint-disable-line no-new
|
||||
|
||||
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)
|
||||
new Path(path) // eslint-disable-line no-new
|
||||
|
||||
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)
|
||||
new Path(path) // eslint-disable-line no-new
|
||||
|
||||
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,71 +1,72 @@
|
|||
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}
|
||||
*/
|
||||
const mockFactory = {
|
||||
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
|
||||
},
|
||||
svgRoot () { return svgroot; },
|
||||
svgContent () { return svgcontent; },
|
||||
getDataStorage () { return dataStorage; }
|
||||
};
|
||||
getSvgRoot () { return svgroot },
|
||||
getSvgContent () { return svgContent },
|
||||
getDataStorage () { return dataStorage }
|
||||
}
|
||||
|
||||
/**
|
||||
* Potentially reusable test set-up.
|
||||
* @returns {void}
|
||||
*/
|
||||
beforeEach(() => {
|
||||
svgroot = mockFactory.createSVGElement({
|
||||
svgroot = mockSvgCanvas.createSVGElement({
|
||||
element: 'svg',
|
||||
attr: { id: 'svgroot' }
|
||||
});
|
||||
svgcontent = mockFactory.createSVGElement({
|
||||
})
|
||||
svgContent = mockSvgCanvas.createSVGElement({
|
||||
element: 'svg',
|
||||
attr: { id: 'svgcontent' }
|
||||
});
|
||||
})
|
||||
|
||||
svgroot.append(svgcontent);
|
||||
/* const rect = */ svgcontent.append(
|
||||
mockFactory.createSVGElement({
|
||||
svgroot.append(svgContent)
|
||||
/* const rect = */ svgContent.append(
|
||||
mockSvgCanvas.createSVGElement({
|
||||
element: 'rect',
|
||||
attr: {
|
||||
id: 'rect',
|
||||
|
@ -75,9 +76,9 @@ describe('select', function () {
|
|||
height: '100'
|
||||
}
|
||||
})
|
||||
);
|
||||
sandbox.append(svgroot);
|
||||
});
|
||||
)
|
||||
sandbox.append(svgroot)
|
||||
})
|
||||
|
||||
/*
|
||||
function setUpWithInit () {
|
||||
|
@ -91,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(mockConfig, mockFactory);
|
||||
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');
|
||||
// ellipses = svgcontent.getElementsByTagNameNS(svgns, 'ellipse'),
|
||||
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 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')
|
||||
// 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')
|
||||
// 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,439 +16,449 @@ 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 mockaddSVGElementFromJsonCallCount = 0;
|
||||
let mockaddSVGElementsFromJsonCallCount = 0
|
||||
|
||||
/**
|
||||
* Mock of {@link module:utilities.EditorContext#addSVGElementFromJson}.
|
||||
* Mock of {@link module:utilities.EditorContext#addSVGElementsFromJson}.
|
||||
* @param {module:utilities.SVGElementJSON} json
|
||||
* @returns {SVGElement}
|
||||
*/
|
||||
function mockaddSVGElementFromJson (json) {
|
||||
const elem = mockCreateSVGElement(json);
|
||||
svgroot.append(elem);
|
||||
mockaddSVGElementFromJsonCallCount++;
|
||||
return elem;
|
||||
function mockaddSVGElementsFromJson (json) {
|
||||
const elem = mockCreateSVGElement(json)
|
||||
svgroot.append(elem)
|
||||
mockaddSVGElementsFromJsonCallCount++
|
||||
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)
|
||||
}
|
||||
// path.reorientGrads(pth, m);
|
||||
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)
|
||||
|
||||
path.init(null);
|
||||
mockaddSVGElementFromJsonCallCount = 0;
|
||||
});
|
||||
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
|
||||
},
|
||||
getSvgRoot () { return svgroot }
|
||||
}
|
||||
|
||||
path.init(mockSvgCanvas)
|
||||
mockaddSVGElementsFromJsonCallCount = 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, mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 2, height: 2 });
|
||||
assert.equal(mockaddSVGElementFromJsonCallCount, 0);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
let bbox = getBBoxWithTransform(elem, mockaddSVGElementsFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 2, height: 2 })
|
||||
assert.equal(mockaddSVGElementsFromJsonCallCount, 0)
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'rect',
|
||||
attr: { id: 'rect', x: '0', y: '1', width: '5', height: '10' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
|
||||
assert.equal(mockaddSVGElementFromJsonCallCount, 0);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElementsFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 })
|
||||
assert.equal(mockaddSVGElementsFromJsonCallCount, 0)
|
||||
elem.remove()
|
||||
|
||||
elem = mockCreateSVGElement({
|
||||
element: 'line',
|
||||
attr: { id: 'line', x1: '0', y1: '1', x2: '5', y2: '6' }
|
||||
});
|
||||
svgroot.append(elem);
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 });
|
||||
assert.equal(mockaddSVGElementFromJsonCallCount, 0);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElementsFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 })
|
||||
assert.equal(mockaddSVGElementsFromJsonCallCount, 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, mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
|
||||
assert.equal(mockaddSVGElementFromJsonCallCount, 0);
|
||||
g.remove();
|
||||
});
|
||||
})
|
||||
g.append(elem)
|
||||
svgroot.append(g)
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElementsFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 })
|
||||
assert.equal(mockaddSVGElementsFromJsonCallCount, 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, mockaddSVGElementFromJson, 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, mockaddSVGElementsFromJson, 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, mockaddSVGElementFromJson, 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(mockaddSVGElementFromJsonCallCount, 1);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElementsFromJson, 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(mockaddSVGElementsFromJsonCallCount, 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);
|
||||
mockaddSVGElementFromJsonCallCount = 0;
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, 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(mockaddSVGElementFromJsonCallCount, 0);
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
mockaddSVGElementsFromJsonCallCount = 0
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElementsFromJson, 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(mockaddSVGElementsFromJsonCallCount, 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);
|
||||
mockaddSVGElementFromJsonCallCount = 0;
|
||||
bbox = getBBoxWithTransform(g, mockaddSVGElementFromJson, 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(mockaddSVGElementFromJsonCallCount, 0);
|
||||
g.remove();
|
||||
})
|
||||
g.append(elem)
|
||||
svgroot.append(g)
|
||||
mockaddSVGElementsFromJsonCallCount = 0
|
||||
bbox = getBBoxWithTransform(g, mockaddSVGElementsFromJson, 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(mockaddSVGElementsFromJsonCallCount, 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);
|
||||
mockaddSVGElementFromJsonCallCount = 0;
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElementFromJson, mockPathActions);
|
||||
})
|
||||
svgroot.append(elem)
|
||||
mockaddSVGElementsFromJsonCallCount = 0
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElementsFromJson, 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(mockaddSVGElementFromJsonCallCount, 1);
|
||||
elem.remove();
|
||||
});
|
||||
assert.equal(mockaddSVGElementsFromJsonCallCount, 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, mockaddSVGElementFromJson, 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, mockaddSVGElementsFromJson, 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, mockaddSVGElementFromJson, 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, mockaddSVGElementsFromJson, 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, mockaddSVGElementFromJson, 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, mockaddSVGElementsFromJson, 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, mockaddSVGElementFromJson, 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, mockaddSVGElementsFromJson, 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, mockaddSVGElementFromJson, mockPathActions);
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getBBoxWithTransform(elem, mockaddSVGElementsFromJson, 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 ], mockaddSVGElementFromJson, 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], mockaddSVGElementsFromJson, 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 ], mockaddSVGElementFromJson, 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], mockaddSVGElementsFromJson, 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 ], mockaddSVGElementFromJson, 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], mockaddSVGElementsFromJson, 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 ], mockaddSVGElementFromJson, 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], mockaddSVGElementsFromJson, 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 ], mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 2, height: 2 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
let bbox = getStrokedBBox([elem], mockaddSVGElementsFromJson, 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 ], mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElementsFromJson, 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 ], mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElementsFromJson, 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 ], mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
|
||||
g.remove();
|
||||
});
|
||||
})
|
||||
g.append(elem)
|
||||
svgroot.append(g)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElementsFromJson, 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 ], mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 2, height: 2 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
let bbox = getStrokedBBox([elem], mockaddSVGElementsFromJson, 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 ], mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElementsFromJson, 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 ], mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElementsFromJson, 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 ], mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
|
||||
g.remove();
|
||||
});
|
||||
})
|
||||
g.append(elem)
|
||||
svgroot.append(g)
|
||||
bbox = getStrokedBBox([elem], mockaddSVGElementsFromJson, mockPathActions)
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 })
|
||||
g.remove()
|
||||
})
|
||||
|
||||
/**
|
||||
* Returns radians for degrees.
|
||||
|
@ -455,7 +466,7 @@ describe('utilities bbox', function () {
|
|||
* @returns {Float}
|
||||
*/
|
||||
function radians (degrees) {
|
||||
return degrees * Math.PI / 180;
|
||||
return degrees * Math.PI / 180
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -467,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
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
|
@ -485,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,22 +79,22 @@ 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
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock of {@link module:utilities.EditorContext#addSVGElementFromJson}.
|
||||
* Mock of {@link module:utilities.EditorContext#addSVGElementsFromJson}.
|
||||
* @param {module:utilities.SVGElementJSON} json
|
||||
* @returns {SVGElement}
|
||||
*/
|
||||
function mockaddSVGElementFromJson (json) {
|
||||
const elem = mockCreateSVGElement(json);
|
||||
currentLayer.append(elem);
|
||||
return elem;
|
||||
function mockaddSVGElementsFromJson (json) {
|
||||
const elem = mockCreateSVGElement(json)
|
||||
currentLayer.append(elem)
|
||||
return elem
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,50 +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);
|
||||
}
|
||||
|
||||
// utilities.reorientGrads(path, m);
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////
|
||||
// Performance times with various browsers on Macbook 2011 8MB RAM OS X El Capitan 10.11.4
|
||||
|
@ -181,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 ], mockaddSVGElementFromJson, 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], mockaddSVGElementsFromJson, 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 ], mockaddSVGElementFromJson, 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], mockaddSVGElementsFromJson, 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,326 +8,335 @@ 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.
|
||||
* @param {module:utilities.SVGElementJSON} json
|
||||
* @returns {SVGElement}
|
||||
*/
|
||||
function mockaddSVGElementFromJson (json) {
|
||||
const elem = mockCreateSVGElement(json);
|
||||
svgroot.append(elem);
|
||||
return elem;
|
||||
function mockaddSVGElementsFromJson (json) {
|
||||
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;
|
||||
const mockSvgCanvas = {
|
||||
addSVGElementsFromJson: mockaddSVGElementsFromJson,
|
||||
pathActions: mockPathActions,
|
||||
clearSelection: mockClearSelection,
|
||||
addToSelection: mockAddToSelection,
|
||||
history: mockHistory,
|
||||
addCommandToHistory: mockAddCommandToHistory
|
||||
}
|
||||
|
||||
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 () {
|
||||
/**
|
||||
* Wrap `utilities.getBBoxOfElementAsPath` to convert bbox to object for testing.
|
||||
* @type {module:utilities.getBBoxOfElementAsPath}
|
||||
*/
|
||||
function getBBoxOfElementAsPath (elem, addSVGElementFromJson, pathActions) {
|
||||
const bbox = utilities.getBBoxOfElementAsPath(elem, addSVGElementFromJson, pathActions);
|
||||
return utilities.bboxToObj(bbox); // need this for assert.equal() to work.
|
||||
function getBBoxOfElementAsPath (elem, addSVGElementsFromJson, pathActions) {
|
||||
const bbox = utilities.getBBoxOfElementAsPath(elem, addSVGElementsFromJson, 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, mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 0, height: 0 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
let bbox = getBBoxOfElementAsPath(elem, mockaddSVGElementsFromJson, 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, mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 10 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getBBoxOfElementAsPath(elem, mockaddSVGElementsFromJson, 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, mockaddSVGElementFromJson, mockPathActions);
|
||||
assert.deepEqual(bbox, { x: 0, y: 1, width: 5, height: 5 });
|
||||
elem.remove();
|
||||
})
|
||||
svgroot.append(elem)
|
||||
bbox = getBBoxOfElementAsPath(elem, mockaddSVGElementsFromJson, 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, mockaddSVGElementFromJson, 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, mockSvgCanvas)
|
||||
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, mockaddSVGElementFromJson, 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, mockSvgCanvas)
|
||||
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,26 +23,3 @@
|
|||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
|
||||
// remove the style attributes that is causing differences in snapshots
|
||||
const ngAttributes = [ 'style' ];
|
||||
|
||||
Cypress.Commands.add(
|
||||
'cleanSnapshot',
|
||||
{
|
||||
prevSubject: true
|
||||
},
|
||||
(subject, _snapshotOptions) => {
|
||||
let html = subject[0].outerHTML;
|
||||
|
||||
for (const attribute of ngAttributes) {
|
||||
const expression = new RegExp(`${attribute}[^= ]*="[^"]*"`, 'g');
|
||||
html = html.replace(expression, '');
|
||||
}
|
||||
html = html.replace(/<!--[\s\S]*?-->/g, '');
|
||||
|
||||
const sanitisedBody = new DOMParser().parseFromString(html, 'text/html').querySelector('body');
|
||||
|
||||
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,31 @@
|
|||
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()
|
||||
}
|
||||
|
||||
export const testSnapshot = () => {
|
||||
cy.window().then((win) => { // access to the remote Window so we can get the svgEditor variable
|
||||
const svgString = win.svgEditor.svgCanvas.getSvgString()
|
||||
const svgDom = new DOMParser().parseFromString(svgString, 'text/html').querySelector('body')
|
||||
cy.wrap(svgDom).toMatchSnapshot()
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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.getSelectedElems().forEach((el) => {
|
||||
el.setAttribute('fill', colour);
|
||||
});
|
||||
};
|
||||
canvas.getSelectedElements().forEach((el) => {
|
||||
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.
|
||||
|
@ -259,33 +259,33 @@ export const convertToNum = function (attr, val) {
|
|||
* @param {Element} selectedElement
|
||||
* @returns {boolean} Whether the unit is valid
|
||||
*/
|
||||
export const isValidUnit = function (attr, val, selectedElement) {
|
||||
export const isValidUnit = (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;
|
||||
// because getElem() can throw an exception in the case of an invalid id
|
||||
let result = false
|
||||
// because getElement() 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) { console.error(e) }
|
||||
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,5 +1,6 @@
|
|||
import { getTypeMap } from '../common/units.js';
|
||||
import rulersTemplate from './templates/rulersTemplate.html';
|
||||
import { getTypeMap } from '../common/units.js'
|
||||
import rulersTemplate from './templates/rulersTemplate.html'
|
||||
import SvgCanvas from '../svgcanvas/svgcanvas.js'
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -9,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 } = this.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
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,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.getContentElem();
|
||||
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 } = this.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)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue