Merge branch 'master' into test-mobile
This commit is contained in:
@@ -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
|
||||
|
||||
94
.eslintrc.js
94
.eslintrc.js
@@ -1,94 +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
|
||||
}
|
||||
},
|
||||
{
|
||||
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"
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,7 +9,6 @@ coverage
|
||||
instrumented
|
||||
.nyc_output
|
||||
.vscode
|
||||
.eslintcache
|
||||
.DS_Store
|
||||
.idea
|
||||
dist
|
||||
|
||||
16
.npmignore
16
.npmignore
@@ -1,19 +1,5 @@
|
||||
ignore
|
||||
screencasts
|
||||
|
||||
.github/ISSUE_TEMPLATE/bug_report.md
|
||||
gh-disabled-workflows
|
||||
build
|
||||
lgtm.yml
|
||||
|
||||
cypress/**
|
||||
cypress.env.json
|
||||
|
||||
coverage/**
|
||||
.nyc_output
|
||||
instrumented/**
|
||||
|
||||
releases
|
||||
|
||||
tools
|
||||
.eslintcache
|
||||
node_modules/**
|
||||
|
||||
1
AUTHORS
1
AUTHORS
@@ -4,6 +4,7 @@ Jeff Schiller <codedread@gmail.com>
|
||||
Vidar Hokstad <vidar.hokstad@gmail.com>
|
||||
Alexis Deveria <adeveria@gmail.com>
|
||||
Brett Zamir <brettz9@yahoo.com>
|
||||
Optimistik SAS <contact@optimistik.io>
|
||||
|
||||
Translation credits:
|
||||
|
||||
|
||||
17
CHANGES.md
17
CHANGES.md
@@ -1,11 +1,20 @@
|
||||
# SVG-Edit CHANGES
|
||||
|
||||
## 7.0.0 (preview - work in progress)
|
||||
## 7.1.1
|
||||
- Fix an issue when moving a text with an existing transformation (issue #689)
|
||||
## 7.1.0
|
||||
- Large refactoring of svgcanvas (a lot of remaining work with the goal to separate in its own package).This explains the move to a minor version
|
||||
- move to a new linter (standard).
|
||||
- Several issues fixed
|
||||
## 7.0.2
|
||||
- create an IIFE build.
|
||||
## 7.0.1
|
||||
- remove ext-overview in default extensions for performance reasons
|
||||
## 7.0.0
|
||||
- New UI
|
||||
- Rearchitecture the code (more modular)
|
||||
- simplify and refresh the build process
|
||||
- Simplify and refresh the build process
|
||||
- Introduce Web Component to replace jQuery UI
|
||||
- update dependencies
|
||||
- Update dependencies
|
||||
## 6.0.0 (unreleased)
|
||||
|
||||
- Project: Add `FUNDING.yml` to accept contributions
|
||||
|
||||
45
README.md
45
README.md
@@ -1,6 +1,6 @@
|
||||
<img src="https://svg-edit.github.io/svgedit/src/editor/images/logo.svg" width="50" height="50" />
|
||||
|
||||
# SVG-Edit
|
||||
# SVGEdit
|
||||
|
||||
[](https://www.npmjs.com/package/svgedit)
|
||||
[](https://david-dm.org/SVG-Edit/svgedit)
|
||||
@@ -24,19 +24,25 @@ works in any modern browser.
|
||||

|
||||
[](https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg)
|
||||
|
||||
## Help wanted
|
||||
## Contributions
|
||||
|
||||
SVG-Edit is the most popular open source SVG editor. It was started more than 10 years ago by a fantastic team of developers. Unfortunately, the product was not maintained for a quite long period. We decided to give this tool a new life by refreshing many aspects.
|
||||
If you can help us to maintain SVG-Edit, you are more than welcome!
|
||||
SVGEdit is the most popular open source SVG editor. It was started more than 10 years ago by a fantastic team of developers. Unfortunately, the product was not maintained for a quite long period. We decided to give this tool a new life by refreshing many aspects.
|
||||
Please let us know with an issue or a discussions if you wish to contribute.
|
||||
## Demo
|
||||
|
||||
Thanks to Netlify, you can test the following builds:
|
||||
Thanks to **Netlify**, you can test the following builds:
|
||||
|
||||
### [Try SVG-edit V7-preview here](https://svgedit.netlify.app/editor/index.html)
|
||||
### [Try SVGEdit 7.1.x here](https://svgedit.netlify.app/editor/index.html)
|
||||
|
||||
[Try SVG-edit 5.1.0 here](https://6098683962bf91702907ee33--svgedit.netlify.app/editor/svg-editor.html)
|
||||
[Try SVGEdit 5.1.0 here](https://6098683962bf91702907ee33--svgedit.netlify.app/editor/svg-editor.html)
|
||||
|
||||
[Try SVG-edit 6.1.0 here](https://60a0000fc9900b0008fd268d--svgedit.netlify.app/editor/index.html)
|
||||
[Try SVGEdit 6.1.0 here](https://60a0000fc9900b0008fd268d--svgedit.netlify.app/editor/index.html)
|
||||
|
||||
Additional tip: you may try a version released on NPM using unpkg for example with version 7.1.0:
|
||||
[https://unpkg.com/svgedit@7.1.0/dist/editor/index.html](https://unpkg.com/svgedit@7.1.0/dist/editor/index.html)
|
||||
|
||||
Prior V7 for example with version 3.2.0:
|
||||
[https://unpkg.com/svgedit@3.2.0/editor/svg-editor.html](https://unpkg.com/svgedit@3.2.0/editor/svg-editor.html)
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -47,33 +53,20 @@ Thanks to Netlify, you can test the following builds:
|
||||
1. run `npm run start` to start a local server
|
||||
1. Use your browser to access `http://localhost:8000/src/editor/index.html`
|
||||
|
||||
### Integrating SVG-edit into your own application
|
||||
### Integrating SVGEdit into your own application
|
||||
|
||||
V7 is changing significantly the way to integrate and customize SVG-Edit. The documentation will be detailed here.
|
||||
V7 is changing significantly the way to integrate and customize SVG-Edit. You can have a look to index.html to see how you can insert a div element into your HTML code and inject the editor into the div.
|
||||
|
||||
SVG-Edit is made of two major components:
|
||||
1. The "svgcanvas" that takes care of the underlying svg edition. It can be used to build your own editor. See example in the demos folder or the svg-edit-react repository.
|
||||
1. The "editor" that takes care of the editor UI (menus, buttons, etc.)
|
||||
|
||||
For earlier versions of SVG-Edit, please look in their respective branches.
|
||||
For earlier versions of SVGEdit, please look in their respective branches.
|
||||
## Supported browsers
|
||||
|
||||
- Opera 59+,
|
||||
- Chrome 75+,
|
||||
- FireFox 68+,
|
||||
- Safari 11+
|
||||
- Edge 18+
|
||||
|
||||
Support for old browsers may require to use an older version of the package. However,
|
||||
please open an issue if you need support for a specific version of your browser so
|
||||
the project team can decide if we should support with the latest version.
|
||||
|
||||
Developments and Continuous Integration are done with a **Chrome** environment. Chrome, FireFox and Safari recent versions are supported (in the meaning that we will try to fix bugs for these browsers).
|
||||
Support for old browsers may require to use an older version of the package. However, please open an issue if you need support for a specific version of your browser so the project team can decide if we should support with the latest version.
|
||||
## Further reading and more information
|
||||
* Participate in [discussions](https://github.com/SVG-Edit/svgedit/discussions)
|
||||
* See [docs](docs/) for more documentation. See the
|
||||
[JSDocs for our latest release](https://svg-edit.github.io/svgedit/releases/latest/docs/jsdoc/index.html).
|
||||
* [Acknowledgements](docs/Acknowledgements.md) lists open source projects
|
||||
used in svg-edit.
|
||||
* See [AUTHORS](AUTHORS) file for authors.
|
||||
* [StackOverflow](https://stackoverflow.com/tags/svg-edit) group.
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ export default {
|
||||
const { svgCanvas } = svgEditor;
|
||||
const { getElem, $id, mergeDeep } = svgCanvas;
|
||||
const { svgroot } = S;
|
||||
const { imgPath } = svgEditor.configObj.curConfig;
|
||||
const addElem = svgCanvas.addSVGElementFromJson;
|
||||
const selManager = S.selectorManager;
|
||||
await loadExtensionTranslation(svgEditor);
|
||||
@@ -354,10 +353,10 @@ export default {
|
||||
return {
|
||||
name: svgEditor.i18next.t(`${name}:name`),
|
||||
callback() {
|
||||
const btitle = svgEditor.i18next.t(`${name}:langListTitle`);
|
||||
const btitle = `${name}:langListTitle`;
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
const buttonTemplate = `
|
||||
<se-button id="mode_connect" title="${btitle}" src="${imgPath}/conn.svg"></se-button>
|
||||
<se-button id="mode_connect" title="${btitle}" src="conn.svg"></se-button>
|
||||
`;
|
||||
svgCanvas.insertChildAtIndex($id('tools_left'), buttonTemplate, 13);
|
||||
$id('mode_connect').addEventListener("click", () => {
|
||||
@@ -1,623 +0,0 @@
|
||||
/**
|
||||
* @file ext-markers.js
|
||||
*
|
||||
* @license Apache-2.0
|
||||
*
|
||||
* @copyright 2010 Will Schleter based on ext-arrows.js by Copyright(c) 2010 Alexis Deveria
|
||||
*
|
||||
* This extension provides for the addition of markers to the either end
|
||||
* or the middle of a line, polyline, path, polygon.
|
||||
*
|
||||
* Markers may be either a graphic or arbitary text
|
||||
*
|
||||
* to simplify the coding and make the implementation as robust as possible,
|
||||
* markers are not shared - every object has its own set of markers.
|
||||
* this relationship is maintained by a naming convention between the
|
||||
* ids of the markers and the ids of the object
|
||||
*
|
||||
* The following restrictions exist for simplicty of use and programming
|
||||
* objects and their markers to have the same color
|
||||
* marker size is fixed
|
||||
* text marker font, size, and attributes are fixed
|
||||
* an application specific attribute - se_type - is added to each marker element
|
||||
* to store the type of marker
|
||||
*
|
||||
* @todo
|
||||
* remove some of the restrictions above
|
||||
* add option for keeping text aligned to horizontal
|
||||
* add support for dimension extension lines
|
||||
*
|
||||
*/
|
||||
|
||||
const loadExtensionTranslation = async function (lang) {
|
||||
let translationModule;
|
||||
try {
|
||||
// eslint-disable-next-line no-unsanitized/method
|
||||
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
|
||||
} catch (_error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`Missing translation (${lang}) - using 'en'`);
|
||||
translationModule = await import(`./locale/en.js`);
|
||||
}
|
||||
return translationModule.default;
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'markers',
|
||||
async init (S) {
|
||||
const svgEditor = this;
|
||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||
const { $ } = S;
|
||||
const { svgCanvas } = svgEditor;
|
||||
const { $id } = svgCanvas;
|
||||
const // {svgcontent} = S,
|
||||
addElem = svgCanvas.addSVGElementFromJson;
|
||||
const mtypes = [ 'start', 'mid', 'end' ];
|
||||
const markerPrefix = 'se_marker_';
|
||||
const idPrefix = 'mkr_';
|
||||
|
||||
// note - to add additional marker types add them below with a unique id
|
||||
// and add the associated icon(s) to marker-icons.svg
|
||||
// the geometry is normalized to a 100x100 box with the origin at lower left
|
||||
// Safari did not like negative values for low left of viewBox
|
||||
// remember that the coordinate system has +y downward
|
||||
const markerTypes = {
|
||||
nomarker: {},
|
||||
leftarrow:
|
||||
{ element: 'path', attr: { d: 'M0,50 L100,90 L70,50 L100,10 Z' } },
|
||||
rightarrow:
|
||||
{ element: 'path', attr: { d: 'M100,50 L0,90 L30,50 L0,10 Z' } },
|
||||
textmarker:
|
||||
{ element: 'text', attr: {
|
||||
x: 0, y: 0, 'stroke-width': 0, stroke: 'none',
|
||||
'font-size': 75, 'font-family': 'serif', 'text-anchor': 'left',
|
||||
'xml:space': 'preserve'
|
||||
} },
|
||||
forwardslash:
|
||||
{ element: 'path', attr: { d: 'M30,100 L70,0' } },
|
||||
reverseslash:
|
||||
{ element: 'path', attr: { d: 'M30,0 L70,100' } },
|
||||
verticalslash:
|
||||
{ element: 'path', attr: { d: 'M50,0 L50,100' } },
|
||||
box:
|
||||
{ element: 'path', attr: { d: 'M20,20 L20,80 L80,80 L80,20 Z' } },
|
||||
star:
|
||||
{ element: 'path', attr: { d: 'M10,30 L90,30 L20,90 L50,10 L80,90 Z' } },
|
||||
xmark:
|
||||
{ element: 'path', attr: { d: 'M20,80 L80,20 M80,80 L20,20' } },
|
||||
triangle:
|
||||
{ element: 'path', attr: { d: 'M10,80 L50,20 L80,80 Z' } },
|
||||
mcircle:
|
||||
{ element: 'circle', attr: { r: 30, cx: 50, cy: 50 } }
|
||||
};
|
||||
|
||||
// duplicate shapes to support unfilled (open) marker types with an _o suffix
|
||||
[ 'leftarrow', 'rightarrow', 'box', 'star', 'mcircle', 'triangle' ].forEach((v) => {
|
||||
markerTypes[v + '_o'] = markerTypes[v];
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {Element} elem - A graphic element will have an attribute like marker-start
|
||||
* @param {"marker-start"|"marker-mid"|"marker-end"} attr
|
||||
* @returns {Element} The marker element that is linked to the graphic element
|
||||
*/
|
||||
function getLinked (elem, attr) {
|
||||
const str = elem.getAttribute(attr);
|
||||
if (!str) { return null; }
|
||||
const m = str.match(/\(#(.*)\)/);
|
||||
// const m = str.match(/\(#(?<id>.+)\)/);
|
||||
// if (!m || !m.groups.id) {
|
||||
if (!m || m.length !== 2) {
|
||||
return null;
|
||||
}
|
||||
return svgCanvas.getElem(m[1]);
|
||||
// return svgCanvas.getElem(m.groups.id);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {"start"|"mid"|"end"} pos
|
||||
* @param {string} id
|
||||
* @returns {void}
|
||||
*/
|
||||
function setIcon (pos, id) {
|
||||
if (id.substr(0, 1) !== '\\') { id = '\\textmarker'; }
|
||||
const ci = idPrefix + pos + '_' + id.substr(1);
|
||||
svgEditor.setIcon('cur_' + pos + '_marker_list', $id(ci).children);
|
||||
$id(ci).classList.add('current');
|
||||
const siblings = Array.prototype.filter.call($id(ci).parentNode.children, function(child){
|
||||
return child !== $id(ci);
|
||||
});
|
||||
Array.from(siblings).forEach(function(sibling) {
|
||||
sibling.classList.remove('current');
|
||||
});
|
||||
}
|
||||
|
||||
let selElems;
|
||||
/**
|
||||
* Toggles context tool panel off/on. Sets the controls with the
|
||||
* selected element's settings.
|
||||
* @param {boolean} on
|
||||
* @returns {void}
|
||||
*/
|
||||
function showPanel (on) {
|
||||
$id('marker_panel').style.display = (on) ? 'block' : 'none';
|
||||
|
||||
if (on) {
|
||||
const el = selElems[0];
|
||||
|
||||
let val; let ci;
|
||||
$.each(mtypes, function (i, pos) {
|
||||
const m = getLinked(el, 'marker-' + pos);
|
||||
const txtbox = $id(pos + '_marker');
|
||||
if (!m) {
|
||||
val = '\\nomarker';
|
||||
ci = val;
|
||||
txtbox.style.display = 'none';
|
||||
} else {
|
||||
if (!m.attributes.se_type) { return; } // not created by this extension
|
||||
val = '\\' + m.attributes.se_type.textContent;
|
||||
ci = val;
|
||||
if (val === '\\textmarker') {
|
||||
val = m.lastChild.textContent;
|
||||
// txtbox.show(); // show text box
|
||||
} else {
|
||||
txtbox.style.display = 'none';
|
||||
}
|
||||
}
|
||||
txtbox.value = val;
|
||||
setIcon(pos, ci);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
* @param {""|"\\nomarker"|"nomarker"|"leftarrow"|"rightarrow"|"textmarker"|"forwardslash"|"reverseslash"|"verticalslash"|"box"|"star"|"xmark"|"triangle"|"mcircle"} val
|
||||
* @returns {SVGMarkerElement}
|
||||
*/
|
||||
function addMarker (id, val) {
|
||||
const txtBoxBg = '#ffffff';
|
||||
const txtBoxBorder = 'none';
|
||||
const txtBoxStrokeWidth = 0;
|
||||
|
||||
let marker = svgCanvas.getElem(id);
|
||||
if (marker) { return undefined; }
|
||||
|
||||
if (val === '' || val === '\\nomarker') { return undefined; }
|
||||
|
||||
const el = selElems[0];
|
||||
const color = el.getAttribute('stroke');
|
||||
// NOTE: Safari didn't like a negative value in viewBox
|
||||
// so we use a standardized 0 0 100 100
|
||||
// with 50 50 being mapped to the marker position
|
||||
const strokeWidth = 10;
|
||||
let refX = 50;
|
||||
let refY = 50;
|
||||
let viewBox = '0 0 100 100';
|
||||
let markerWidth = 5;
|
||||
let markerHeight = 5;
|
||||
const seType = (val.substr(0, 1) === '\\') ? val.substr(1) : 'textmarker';
|
||||
|
||||
if (!markerTypes[seType]) { return undefined; } // an unknown type!
|
||||
|
||||
// create a generic marker
|
||||
marker = addElem({
|
||||
element: 'marker',
|
||||
attr: {
|
||||
id,
|
||||
markerUnits: 'strokeWidth',
|
||||
orient: 'auto',
|
||||
style: 'pointer-events:none',
|
||||
se_type: seType
|
||||
}
|
||||
});
|
||||
|
||||
if (seType !== 'textmarker') {
|
||||
const mel = addElem(markerTypes[seType]);
|
||||
const fillcolor = (seType.substr(-2) === '_o')
|
||||
? 'none'
|
||||
: color;
|
||||
|
||||
mel.setAttribute('fill', fillcolor);
|
||||
mel.setAttribute('stroke', color);
|
||||
mel.setAttribute('stroke-width', strokeWidth);
|
||||
marker.append(mel);
|
||||
} else {
|
||||
const text = addElem(markerTypes[seType]);
|
||||
// have to add text to get bounding box
|
||||
text.textContent = val;
|
||||
const tb = text.getBBox();
|
||||
// alert(tb.x + ' ' + tb.y + ' ' + tb.width + ' ' + tb.height);
|
||||
const pad = 1;
|
||||
const bb = tb;
|
||||
bb.x = 0;
|
||||
bb.y = 0;
|
||||
bb.width += pad * 2;
|
||||
bb.height += pad * 2;
|
||||
// shift text according to its size
|
||||
text.setAttribute('x', pad);
|
||||
text.setAttribute('y', bb.height - pad - tb.height / 4); // kludge?
|
||||
text.setAttribute('fill', color);
|
||||
refX = bb.width / 2 + pad;
|
||||
refY = bb.height / 2 + pad;
|
||||
viewBox = bb.x + ' ' + bb.y + ' ' + bb.width + ' ' + bb.height;
|
||||
markerWidth = bb.width / 10;
|
||||
markerHeight = bb.height / 10;
|
||||
|
||||
const box = addElem({
|
||||
element: 'rect',
|
||||
attr: {
|
||||
x: bb.x,
|
||||
y: bb.y,
|
||||
width: bb.width,
|
||||
height: bb.height,
|
||||
fill: txtBoxBg,
|
||||
stroke: txtBoxBorder,
|
||||
'stroke-width': txtBoxStrokeWidth
|
||||
}
|
||||
});
|
||||
marker.setAttribute('orient', 0);
|
||||
marker.append(box, text);
|
||||
}
|
||||
|
||||
marker.setAttribute('viewBox', viewBox);
|
||||
marker.setAttribute('markerWidth', markerWidth);
|
||||
marker.setAttribute('markerHeight', markerHeight);
|
||||
marker.setAttribute('refX', refX);
|
||||
marker.setAttribute('refY', refY);
|
||||
svgCanvas.findDefs().append(marker);
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Element} elem
|
||||
* @returns {SVGPolylineElement}
|
||||
*/
|
||||
function convertline (elem) {
|
||||
// this routine came from the connectors extension
|
||||
// it is needed because midpoint markers don't work with line elements
|
||||
if (elem.tagName !== 'line') { return elem; }
|
||||
|
||||
// Convert to polyline to accept mid-arrow
|
||||
|
||||
const x1 = Number(elem.getAttribute('x1'));
|
||||
const x2 = Number(elem.getAttribute('x2'));
|
||||
const y1 = Number(elem.getAttribute('y1'));
|
||||
const y2 = Number(elem.getAttribute('y2'));
|
||||
const { id } = elem;
|
||||
|
||||
const midPt = (' ' + ((x1 + x2) / 2) + ',' + ((y1 + y2) / 2) + ' ');
|
||||
const pline = addElem({
|
||||
element: 'polyline',
|
||||
attr: {
|
||||
points: (x1 + ',' + y1 + midPt + x2 + ',' + y2),
|
||||
stroke: elem.getAttribute('stroke'),
|
||||
'stroke-width': elem.getAttribute('stroke-width'),
|
||||
fill: 'none',
|
||||
opacity: elem.getAttribute('opacity') || 1
|
||||
}
|
||||
});
|
||||
$.each(mtypes, function (i, pos) { // get any existing marker definitions
|
||||
const nam = 'marker-' + pos;
|
||||
const m = elem.getAttribute(nam);
|
||||
if (m) { pline.setAttribute(nam, elem.getAttribute(nam)); }
|
||||
});
|
||||
|
||||
const batchCmd = new S.BatchCommand();
|
||||
batchCmd.addSubCommand(new S.RemoveElementCommand(elem, elem.parentNode));
|
||||
batchCmd.addSubCommand(new S.InsertElementCommand(pline));
|
||||
|
||||
elem.insertAdjacentElement('afterend', pline);
|
||||
elem.remove();
|
||||
svgCanvas.clearSelection();
|
||||
pline.id = id;
|
||||
svgCanvas.addToSelection([ pline ]);
|
||||
S.addCommandToHistory(batchCmd);
|
||||
return pline;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function setMarker () {
|
||||
const poslist = { start_marker: 'start', mid_marker: 'mid', end_marker: 'end' };
|
||||
const pos = poslist[this.id];
|
||||
const markerName = 'marker-' + pos;
|
||||
const el = selElems[0];
|
||||
const marker = getLinked(el, markerName);
|
||||
if (marker) { marker.remove(); }
|
||||
el.removeAttribute(markerName);
|
||||
let val = this.value;
|
||||
if (val === '') { val = '\\nomarker'; }
|
||||
if (val === '\\nomarker') {
|
||||
setIcon(pos, val);
|
||||
svgCanvas.call('changed', selElems);
|
||||
return;
|
||||
}
|
||||
// Set marker on element
|
||||
const id = markerPrefix + pos + '_' + el.id;
|
||||
addMarker(id, val);
|
||||
svgCanvas.changeSelectedAttribute(markerName, 'url(#' + id + ')');
|
||||
if (el.tagName === 'line' && pos === 'mid') {
|
||||
convertline(el);
|
||||
}
|
||||
svgCanvas.call('changed', selElems);
|
||||
setIcon(pos, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the main system modifies an object. This routine changes
|
||||
* the associated markers to be the same color.
|
||||
* @param {Element} elem
|
||||
* @returns {void}
|
||||
*/
|
||||
function colorChanged (elem) {
|
||||
const color = elem.getAttribute('stroke');
|
||||
|
||||
$.each(mtypes, function (i, pos) {
|
||||
const marker = getLinked(elem, 'marker-' + pos);
|
||||
if (!marker) { return; }
|
||||
if (!marker.attributes.se_type) { return; } // not created by this extension
|
||||
const ch = marker.lastElementChild;
|
||||
if (!ch) { return; }
|
||||
const curfill = ch.getAttribute('fill');
|
||||
const curstroke = ch.getAttribute('stroke');
|
||||
if (curfill && curfill !== 'none') { ch.setAttribute('fill', color); }
|
||||
if (curstroke && curstroke !== 'none') { ch.setAttribute('stroke', color); }
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the main system creates or modifies an object.
|
||||
* Its primary purpose is to create new markers for cloned objects.
|
||||
* @param {Element} el
|
||||
* @returns {void}
|
||||
*/
|
||||
function updateReferences (el) {
|
||||
$.each(mtypes, function (i, pos) {
|
||||
const id = markerPrefix + pos + '_' + el.id;
|
||||
const markerName = 'marker-' + pos;
|
||||
const marker = getLinked(el, markerName);
|
||||
if (!marker || !marker.attributes.se_type) { return; } // not created by this extension
|
||||
const url = el.getAttribute(markerName);
|
||||
if (url) {
|
||||
const len = el.id.length;
|
||||
const linkid = url.substr(-len - 1, len);
|
||||
if (el.id !== linkid) {
|
||||
const val = $id(pos + '_marker').getAttribute('value');
|
||||
addMarker(id, val);
|
||||
svgCanvas.changeSelectedAttribute(markerName, 'url(#' + id + ')');
|
||||
if (el.tagName === 'line' && pos === 'mid') { el = convertline(el); }
|
||||
svgCanvas.call('changed', selElems);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// simulate a change event a text box that stores the current element's marker type
|
||||
/**
|
||||
* @param {"start"|"mid"|"end"} pos
|
||||
* @param {string} val
|
||||
* @returns {void}
|
||||
*/
|
||||
function triggerTextEntry (pos, val) {
|
||||
$id(pos + '_marker').value = val;
|
||||
$id(pos + '_marker').change();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {"start"|"mid"|"end"} pos
|
||||
* @returns {void} Resolves to `undefined`
|
||||
*/
|
||||
function showTextPrompt (pos) {
|
||||
let def = $id(pos + '_marker').value;
|
||||
if (def.substr(0, 1) === '\\') { def = ''; }
|
||||
// eslint-disable-next-line no-alert
|
||||
const txt = prompt('Enter text for ' + pos + ' marker', def);
|
||||
if (txt) {
|
||||
triggerTextEntry(pos, txt);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
function setMarkerSet(obj) {
|
||||
const parts = this.id.split('_');
|
||||
const set = parts[2];
|
||||
switch (set) {
|
||||
case 'off':
|
||||
triggerTextEntry('start','\\nomarker');
|
||||
triggerTextEntry('mid','\\nomarker');
|
||||
triggerTextEntry('end','\\nomarker');
|
||||
break;
|
||||
case 'dimension':
|
||||
triggerTextEntry('start','\\leftarrow');
|
||||
triggerTextEntry('end','\\rightarrow');
|
||||
await showTextPrompt('mid');
|
||||
break;
|
||||
case 'label':
|
||||
triggerTextEntry('mid','\\nomarker');
|
||||
triggerTextEntry('end','\\rightarrow');
|
||||
await showTextPrompt('start');
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// callback function for a toolbar button click
|
||||
/**
|
||||
* @param {Event} ev
|
||||
* @returns {Promise<void>} Resolves to `undefined`
|
||||
*/
|
||||
async function setArrowFromButton () {
|
||||
const parts = this.id.split('_');
|
||||
const pos = parts[1];
|
||||
let val = parts[2];
|
||||
if (parts[3]) { val += '_' + parts[3]; }
|
||||
|
||||
if (val !== 'textmarker') {
|
||||
triggerTextEntry(pos, '\\' + val);
|
||||
} else {
|
||||
await showTextPrompt(pos);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {"nomarker"|"leftarrow"|"rightarrow"|"textmarker"|"forwardslash"|"reverseslash"|"verticalslash"|"box"|"star"|"xmark"|"triangle"|"mcircle"} id
|
||||
* @returns {string}
|
||||
*/
|
||||
function getTitle (id) {
|
||||
const { langList } = strings;
|
||||
const item = langList.find((itm) => {
|
||||
return itm.id === id;
|
||||
});
|
||||
return item ? item.title : id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the toolbar button array from the marker definitions.
|
||||
* @returns {module:SVGEditor.Button[]}
|
||||
*/
|
||||
function buildButtonList () {
|
||||
const buttons = [];
|
||||
// const i = 0;
|
||||
/*
|
||||
buttons.push({
|
||||
id: idPrefix + 'markers_off',
|
||||
title: 'Turn off all markers',
|
||||
type: 'context',
|
||||
events: { click: setMarkerSet },
|
||||
panel: 'marker_panel'
|
||||
});
|
||||
buttons.push({
|
||||
id: idPrefix + 'markers_dimension',
|
||||
title: 'Dimension',
|
||||
type: 'context',
|
||||
events: { click: setMarkerSet },
|
||||
panel: 'marker_panel'
|
||||
});
|
||||
buttons.push({
|
||||
id: idPrefix + 'markers_label',
|
||||
title: 'Label',
|
||||
type: 'context',
|
||||
events: { click: setMarkerSet },
|
||||
panel: 'marker_panel'
|
||||
});
|
||||
*/
|
||||
$.each(mtypes, function (k, pos) {
|
||||
const listname = pos + '_marker_list';
|
||||
let def = true;
|
||||
Object.keys(markerTypes).forEach(function (id) {
|
||||
const title = getTitle(String(id));
|
||||
buttons.push({
|
||||
id: idPrefix + pos + '_' + id,
|
||||
svgicon: id,
|
||||
icon: id + '.svg',
|
||||
title,
|
||||
type: 'context',
|
||||
events: { click: setArrowFromButton },
|
||||
panel: 'marker_panel',
|
||||
list: listname,
|
||||
isDefault: def
|
||||
});
|
||||
def = false;
|
||||
});
|
||||
});
|
||||
return buttons;
|
||||
}
|
||||
|
||||
const contextTools = [
|
||||
{
|
||||
type: 'input',
|
||||
panel: 'marker_panel',
|
||||
id: 'start_marker',
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
id: 'start_marker_list',
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'marker_panel',
|
||||
id: 'mid_marker',
|
||||
defval: '',
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
id: 'mid_marker_list',
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
}, {
|
||||
type: 'input',
|
||||
panel: 'marker_panel',
|
||||
id: 'end_marker',
|
||||
size: 3,
|
||||
events: { change: setMarker }
|
||||
}, {
|
||||
type: 'button-select',
|
||||
panel: 'marker_panel',
|
||||
id: 'end_marker_list',
|
||||
colnum: 3,
|
||||
events: { change: setArrowFromButton }
|
||||
}
|
||||
];
|
||||
|
||||
return {
|
||||
name: strings.name,
|
||||
svgicons: '',
|
||||
callback () {
|
||||
if($id("marker_panel") !== null) {
|
||||
$id("marker_panel").classList.add('toolset');
|
||||
$id("marker_panel").style.display = 'none';
|
||||
}
|
||||
},
|
||||
/* async */ addLangData ({ _importLocale, _lang }) {
|
||||
return { data: strings.langList };
|
||||
},
|
||||
selectedChanged (opts) {
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
const markerElems = [ 'line', 'path', 'polyline', 'polygon' ];
|
||||
|
||||
let i = selElems.length;
|
||||
while (i--) {
|
||||
const elem = selElems[i];
|
||||
if (elem && markerElems.includes(elem.tagName)) {
|
||||
if (opts.selectedElement && !opts.multiselected) {
|
||||
showPanel(true);
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
} else {
|
||||
showPanel(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
elementChanged (opts) {
|
||||
const elem = opts.elems[0];
|
||||
if (elem && (
|
||||
elem.getAttribute('marker-start') ||
|
||||
elem.getAttribute('marker-mid') ||
|
||||
elem.getAttribute('marker-end')
|
||||
)) {
|
||||
colorChanged(elem);
|
||||
updateReferences(elem);
|
||||
}
|
||||
// changing_flag = false; // Not apparently in use
|
||||
},
|
||||
buttons: buildButtonList(),
|
||||
context_tools: strings.contextTools.map((contextTool, i) => {
|
||||
return Object.assign(contextTools[i], contextTool);
|
||||
})
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -3,8 +3,8 @@
|
||||
[
|
||||
"@babel/env",
|
||||
{
|
||||
"useBuiltIns": "usage",
|
||||
"corejs": "3.6.5"
|
||||
"useBuiltIns": "entry",
|
||||
"corejs": "3.19"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Optimistik SAS",
|
||||
"email": "contact@optimistik.fr"
|
||||
"email": "contact@optimistik.io"
|
||||
}
|
||||
],
|
||||
"keywords": [
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,82 +1,66 @@
|
||||
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"
|
||||
<body>
|
||||
<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>
|
||||
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"
|
||||
<body>
|
||||
<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>
|
||||
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"
|
||||
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)"
|
||||
stroke="#000000"
|
||||
transform="rotate(48.8014 208.997 209.008)"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</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"
|
||||
<body>
|
||||
<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>
|
||||
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"
|
||||
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)"
|
||||
stroke="#000000"
|
||||
transform="rotate(48.8014 208.997 209.008)"
|
||||
></path>
|
||||
<image
|
||||
x="295"
|
||||
y="295"
|
||||
width="20"
|
||||
height="20"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
style="pointer-events:inherit"
|
||||
width="20"
|
||||
x="295"
|
||||
xlink:href="./images/logo.svg"
|
||||
y="295"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
@@ -87,5 +71,6 @@ exports[`use all parts of svg-edit > check tool_image #0`] = `
|
||||
></animate>
|
||||
</image>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
@@ -1,43 +1,36 @@
|
||||
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"
|
||||
<body>
|
||||
<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>
|
||||
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_circle #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<circle
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
opacity="0.5"
|
||||
style="pointer-events:inherit"
|
||||
cx="150"
|
||||
cy="150"
|
||||
r="111.80339887498948"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
opacity="0.5"
|
||||
r="111.8034"
|
||||
stroke="#000000"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
@@ -48,46 +41,37 @@ exports[`use all parts of svg-edit > check tool_circle #0`] = `
|
||||
></animate>
|
||||
</circle>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_fhellipse #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<circle
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
cx="150"
|
||||
cy="150"
|
||||
r="111.80339887498948"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
r="111.8034"
|
||||
stroke="#000000"
|
||||
></circle>
|
||||
<ellipse
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
opacity="0.5"
|
||||
style="pointer-events:inherit"
|
||||
cx="299"
|
||||
cy="169"
|
||||
fill="#FF0000"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
rx="60"
|
||||
ry="50"
|
||||
id="svg_2"
|
||||
stroke="#000000"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
@@ -98,59 +82,46 @@ exports[`use all parts of svg-edit > check tool_fhellipse #0`] = `
|
||||
></animate>
|
||||
</ellipse>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_ellipse #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<circle
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
cx="150"
|
||||
cy="150"
|
||||
r="111.80339887498948"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
r="111.8034"
|
||||
stroke="#000000"
|
||||
></circle>
|
||||
<ellipse
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
cx="299"
|
||||
cy="169"
|
||||
fill="#FF0000"
|
||||
id="svg_2"
|
||||
rx="60"
|
||||
ry="50"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
stroke="#000000"
|
||||
></ellipse>
|
||||
<ellipse
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
opacity="0.5"
|
||||
style="pointer-events:inherit"
|
||||
cx="114"
|
||||
cy="189"
|
||||
fill="#FF0000"
|
||||
id="svg_3"
|
||||
opacity="0.5"
|
||||
rx="55"
|
||||
ry="25"
|
||||
id="svg_3"
|
||||
stroke="#000000"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
@@ -161,557 +132,442 @@ exports[`use all parts of svg-edit > check tool_ellipse #0`] = `
|
||||
></animate>
|
||||
</ellipse>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_circle_change_fill_color #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<circle
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
cx="150"
|
||||
cy="150"
|
||||
r="111.80339887498948"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
r="111.8034"
|
||||
stroke="#000000"
|
||||
></circle>
|
||||
<ellipse
|
||||
fill="#ffff00"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="299"
|
||||
cy="169"
|
||||
fill="#ffff00"
|
||||
id="svg_2"
|
||||
rx="60"
|
||||
ry="50"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
stroke="#000000"
|
||||
></ellipse>
|
||||
<ellipse
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
cx="114"
|
||||
cy="189"
|
||||
fill="#FF0000"
|
||||
id="svg_3"
|
||||
rx="55"
|
||||
ry="25"
|
||||
id="svg_3"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
stroke="#000000"
|
||||
transform="matrix(1 0 0 1 0 0)"
|
||||
></ellipse>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_circle_change_opacity #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<circle
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
cx="150"
|
||||
cy="150"
|
||||
r="111.80339887498948"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
r="111.8034"
|
||||
stroke="#000000"
|
||||
></circle>
|
||||
<ellipse
|
||||
fill="#ffff00"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="299"
|
||||
cy="169"
|
||||
fill="#ffff00"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
rx="60"
|
||||
ry="50"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
></ellipse>
|
||||
<ellipse
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
cx="114"
|
||||
cy="189"
|
||||
fill="#FF0000"
|
||||
id="svg_3"
|
||||
rx="55"
|
||||
ry="25"
|
||||
id="svg_3"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
stroke="#000000"
|
||||
transform="matrix(1 0 0 1 0 0)"
|
||||
></ellipse>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_ellipse_change_rotation #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<circle
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
cx="150"
|
||||
cy="150"
|
||||
r="111.80339887498948"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
r="111.8034"
|
||||
stroke="#000000"
|
||||
></circle>
|
||||
<ellipse
|
||||
fill="#ffff00"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="299"
|
||||
cy="169"
|
||||
fill="#ffff00"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
rx="60"
|
||||
ry="50"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
transform="matrix(1 0 0 1 0 0)"
|
||||
></ellipse>
|
||||
<ellipse
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="114"
|
||||
cy="189"
|
||||
fill="#FF0000"
|
||||
id="svg_3"
|
||||
rx="55"
|
||||
ry="25"
|
||||
id="svg_3"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
stroke="#000000"
|
||||
transform="rotate(25 114 189)"
|
||||
></ellipse>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_ellipse_change_blur #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<circle
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
cx="150"
|
||||
cy="150"
|
||||
r="111.80339887498948"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
r="111.8034"
|
||||
stroke="#000000"
|
||||
></circle>
|
||||
<ellipse
|
||||
fill="#ffff00"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="299"
|
||||
cy="169"
|
||||
fill="#ffff00"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
rx="60"
|
||||
ry="50"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
transform="matrix(1 0 0 1 0 0)"
|
||||
></ellipse>
|
||||
<ellipse
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="114"
|
||||
cy="189"
|
||||
fill="#FF0000"
|
||||
filter="url(#svg_3_blur)"
|
||||
id="svg_3"
|
||||
rx="55"
|
||||
ry="25"
|
||||
id="svg_3"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
stroke="#000000"
|
||||
transform="rotate(25 114 189)"
|
||||
filter="url(#svg_3_blur)"
|
||||
></ellipse>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_3_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_3_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_ellipse_change_cx_cy_coordinate #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<circle
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
cx="150"
|
||||
cy="150"
|
||||
r="111.80339887498948"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
r="111.8034"
|
||||
stroke="#000000"
|
||||
></circle>
|
||||
<ellipse
|
||||
fill="#ffff00"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="299"
|
||||
cy="169"
|
||||
fill="#ffff00"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
rx="60"
|
||||
ry="50"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
transform="matrix(1 0 0 1 0 0)"
|
||||
></ellipse>
|
||||
<ellipse
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="139"
|
||||
cy="214"
|
||||
fill="#FF0000"
|
||||
filter="url(#svg_3_blur)"
|
||||
id="svg_3"
|
||||
rx="55"
|
||||
ry="25"
|
||||
id="svg_3"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
filter="url(#svg_3_blur)"
|
||||
stroke="#000000"
|
||||
transform="rotate(25 139 214)"
|
||||
></ellipse>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_3_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_3_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_ellipse_change_rx_ry_radius #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<circle
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
cx="150"
|
||||
cy="150"
|
||||
r="111.80339887498948"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
r="111.8034"
|
||||
stroke="#000000"
|
||||
></circle>
|
||||
<ellipse
|
||||
fill="#ffff00"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="299"
|
||||
cy="169"
|
||||
fill="#ffff00"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
rx="60"
|
||||
ry="50"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
transform="matrix(1 0 0 1 0 0)"
|
||||
></ellipse>
|
||||
<ellipse
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="139"
|
||||
cy="214"
|
||||
fill="#FF0000"
|
||||
filter="url(#svg_3_blur)"
|
||||
id="svg_3"
|
||||
rx="80"
|
||||
ry="50"
|
||||
id="svg_3"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
filter="url(#svg_3_blur)"
|
||||
stroke="#000000"
|
||||
transform="rotate(25 139 214)"
|
||||
></ellipse>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_3_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_3_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_ellipse_bring_to_back #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<ellipse
|
||||
fill="#ffff00"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="299"
|
||||
cy="169"
|
||||
fill="#ffff00"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
rx="60"
|
||||
ry="50"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
></ellipse>
|
||||
<circle
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
cx="150"
|
||||
cy="150"
|
||||
r="111.80339887498948"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
r="111.8034"
|
||||
stroke="#000000"
|
||||
></circle>
|
||||
<ellipse
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="139"
|
||||
cy="214"
|
||||
fill="#FF0000"
|
||||
filter="url(#svg_3_blur)"
|
||||
id="svg_3"
|
||||
rx="80"
|
||||
ry="50"
|
||||
id="svg_3"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
filter="url(#svg_3_blur)"
|
||||
transform="rotate(25 139 214)"
|
||||
stroke="#000000"
|
||||
transform="matrix(1 0 0 1 0 0) rotate(25 139 214)"
|
||||
></ellipse>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_3_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_3_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_ellipse_bring_to_front #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<circle
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
cx="150"
|
||||
cy="150"
|
||||
r="111.80339887498948"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
r="111.8034"
|
||||
stroke="#000000"
|
||||
></circle>
|
||||
<ellipse
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="139"
|
||||
cy="214"
|
||||
fill="#FF0000"
|
||||
filter="url(#svg_3_blur)"
|
||||
id="svg_3"
|
||||
rx="80"
|
||||
ry="50"
|
||||
id="svg_3"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
filter="url(#svg_3_blur)"
|
||||
transform="rotate(25 139 214)"
|
||||
stroke="#000000"
|
||||
transform="matrix(1 0 0 1 0 0) rotate(25 139 214)"
|
||||
></ellipse>
|
||||
<ellipse
|
||||
fill="#ffff00"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="299"
|
||||
cy="169"
|
||||
fill="#ffff00"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
rx="60"
|
||||
ry="50"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
></ellipse>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_3_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_3_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_ellipse_clone #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<circle
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
style="pointer-events:inherit"
|
||||
cx="150"
|
||||
cy="150"
|
||||
r="111.80339887498948"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
r="111.8034"
|
||||
stroke="#000000"
|
||||
></circle>
|
||||
<ellipse
|
||||
fill="#FF0000"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="139"
|
||||
cy="214"
|
||||
fill="#FF0000"
|
||||
filter="url(#svg_3_blur)"
|
||||
id="svg_3"
|
||||
rx="80"
|
||||
ry="50"
|
||||
id="svg_3"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
filter="url(#svg_3_blur)"
|
||||
transform="rotate(25 139 214)"
|
||||
stroke="#000000"
|
||||
transform="matrix(1 0 0 1 0 0) rotate(25 139 214)"
|
||||
></ellipse>
|
||||
<ellipse
|
||||
fill="#ffff00"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="299"
|
||||
cy="169"
|
||||
fill="#ffff00"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
rx="60"
|
||||
ry="50"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
></ellipse>
|
||||
<ellipse
|
||||
fill="#ffff00"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
cx="319"
|
||||
cy="189"
|
||||
fill="#ffff00"
|
||||
id="svg_4"
|
||||
opacity="0.5"
|
||||
rx="60"
|
||||
ry="50"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
opacity="0.5"
|
||||
id="svg_4"
|
||||
stroke="#000000"
|
||||
></ellipse>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_3_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_3_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
@@ -1,41 +1,34 @@
|
||||
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"
|
||||
<body>
|
||||
<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>
|
||||
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"
|
||||
<body>
|
||||
<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>
|
||||
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"
|
||||
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"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
@@ -46,113 +39,90 @@ exports[`use all parts of svg-edit > check tool_path #0`] = `
|
||||
></animate>
|
||||
</path>
|
||||
</g>
|
||||
</svg>
|
||||
</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"
|
||||
<body>
|
||||
<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>
|
||||
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"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
d="M75,75L150,100L125,200L75,75z"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
stroke="#000000"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
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"
|
||||
<body>
|
||||
<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>
|
||||
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"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
d="M75,75L150,100L125,200C235.33333,330.33333 91.66667,116.66667 75,75z"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
stroke="#000000"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
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"
|
||||
<body>
|
||||
<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>
|
||||
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"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
d="M201,246L150,100L125,200C180.16666,265.16666 297.83333,415.33333 273.625,373C249.41667,330.66667 209.33334,266.83334 201,246z"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
stroke="#000000"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</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"
|
||||
<body>
|
||||
<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>
|
||||
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"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
d="M201,246L150,100L125,200C180.16666,265.16666 297.83333,415.33333 273.625,373C249.41667,330.66667 209.33334,266.83334 201,246z"
|
||||
id="svg_1"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
stroke="#000000"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,44 +1,38 @@
|
||||
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"
|
||||
<body>
|
||||
<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>
|
||||
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_line #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_1"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
opacity="0.5"
|
||||
style="pointer-events:none"
|
||||
x1="200"
|
||||
y1="200"
|
||||
x2="450"
|
||||
y1="200"
|
||||
y2="450"
|
||||
id="svg_1"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
@@ -49,168 +43,139 @@ exports[`use all parts of svg-edit > check tool_line #0`] = `
|
||||
></animate>
|
||||
</line>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_line_change_rotation #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<line
|
||||
class="svg_1_class"
|
||||
fill="none"
|
||||
id="svg_1_id"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
x1="200"
|
||||
y1="200"
|
||||
x2="450"
|
||||
y2="450"
|
||||
id="svg_1_id"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
class="svg_1_class"
|
||||
transform="rotate(25 325 325)"
|
||||
x1="200"
|
||||
x2="450"
|
||||
y1="200"
|
||||
y2="450"
|
||||
></line>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_line_change_blur #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<line
|
||||
class="svg_1_class"
|
||||
fill="none"
|
||||
filter="url(#svg_1_id_blur)"
|
||||
id="svg_1_id"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
x1="200"
|
||||
y1="200"
|
||||
x2="450"
|
||||
y2="450"
|
||||
id="svg_1_id"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
class="svg_1_class"
|
||||
transform="rotate(25 325 325)"
|
||||
filter="url(#svg_1_id_blur)"
|
||||
x1="200"
|
||||
x2="450"
|
||||
y1="200"
|
||||
y2="450"
|
||||
></line>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_1_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_1_id_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_line_change_opacity #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<line
|
||||
class="svg_1_class"
|
||||
fill="none"
|
||||
filter="url(#svg_1_id_blur)"
|
||||
id="svg_1_id"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
x1="200"
|
||||
y1="200"
|
||||
x2="450"
|
||||
y2="450"
|
||||
id="svg_1_id"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
class="svg_1_class"
|
||||
filter="url(#svg_1_id_blur)"
|
||||
opacity="0.5"
|
||||
transform="rotate(25 325 325)"
|
||||
x1="200"
|
||||
x2="450"
|
||||
y1="200"
|
||||
y2="450"
|
||||
></line>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_1_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_1_id_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_line_delete #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_1_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_line_clone #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_2"
|
||||
opacity="0.25"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
opacity="0.25"
|
||||
style="pointer-events:none"
|
||||
x1="200"
|
||||
y1="200"
|
||||
x2="450"
|
||||
y1="200"
|
||||
y2="450"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
@@ -222,384 +187,303 @@ exports[`use all parts of svg-edit > check tool_line_clone #0`] = `
|
||||
</line>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_3"
|
||||
opacity="0.25"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
opacity="0.25"
|
||||
style="pointer-events:none"
|
||||
x1="220"
|
||||
y1="220"
|
||||
x2="470"
|
||||
y1="220"
|
||||
y2="470"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_3"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
begin="indefinite"
|
||||
dur="0.2"
|
||||
fill="freeze"
|
||||
to="0.5"
|
||||
id="svg_4"
|
||||
to="0.5"
|
||||
></animate>
|
||||
</line>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_1_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_line_bring_to_back #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
opacity="0.5"
|
||||
x1="200"
|
||||
y1="200"
|
||||
x2="450"
|
||||
y1="200"
|
||||
y2="450"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></line>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_3"
|
||||
opacity="0.25"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
opacity="0.25"
|
||||
style="pointer-events:none"
|
||||
x1="220"
|
||||
y1="220"
|
||||
x2="470"
|
||||
y1="220"
|
||||
y2="470"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_3"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
begin="indefinite"
|
||||
dur="0.2"
|
||||
fill="freeze"
|
||||
to="0.5"
|
||||
id="svg_4"
|
||||
to="0.5"
|
||||
></animate>
|
||||
</line>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_1_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_line_bring_to_front #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_3"
|
||||
opacity="0.25"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
opacity="0.25"
|
||||
style="pointer-events:none"
|
||||
x1="220"
|
||||
y1="220"
|
||||
x2="470"
|
||||
y1="220"
|
||||
y2="470"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_3"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
begin="indefinite"
|
||||
dur="0.2"
|
||||
fill="freeze"
|
||||
to="0.5"
|
||||
id="svg_4"
|
||||
to="0.5"
|
||||
></animate>
|
||||
</line>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
opacity="0.5"
|
||||
x1="200"
|
||||
y1="200"
|
||||
x2="450"
|
||||
y1="200"
|
||||
y2="450"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></line>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_1_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_line_change_x_y_coordinate #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_3"
|
||||
opacity="0.25"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
opacity="0.25"
|
||||
style="pointer-events:none"
|
||||
x1="220"
|
||||
y1="220"
|
||||
x2="470"
|
||||
y1="220"
|
||||
y2="470"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_3"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
begin="indefinite"
|
||||
dur="0.2"
|
||||
fill="freeze"
|
||||
to="0.5"
|
||||
id="svg_4"
|
||||
to="0.5"
|
||||
></animate>
|
||||
</line>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
opacity="0.5"
|
||||
x1="225"
|
||||
y1="200"
|
||||
x2="475"
|
||||
y1="175"
|
||||
y2="425"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></line>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_1_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_line_change_stroke_width #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_3"
|
||||
opacity="0.25"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
opacity="0.25"
|
||||
style="pointer-events:none"
|
||||
x1="220"
|
||||
y1="220"
|
||||
x2="470"
|
||||
y1="220"
|
||||
y2="470"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_3"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
begin="indefinite"
|
||||
dur="0.2"
|
||||
fill="freeze"
|
||||
to="0.5"
|
||||
id="svg_4"
|
||||
to="0.5"
|
||||
></animate>
|
||||
</line>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
stroke-width="15"
|
||||
opacity="0.5"
|
||||
x1="225"
|
||||
y1="200"
|
||||
x2="475"
|
||||
y1="175"
|
||||
y2="425"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></line>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_1_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_line_change_stoke_color #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_3"
|
||||
opacity="0.25"
|
||||
stroke="#bf5f00"
|
||||
stroke-width="5"
|
||||
opacity="0.25"
|
||||
x1="220"
|
||||
y1="220"
|
||||
x2="470"
|
||||
y1="220"
|
||||
y2="470"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_3"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
begin="indefinite"
|
||||
dur="0.2"
|
||||
fill="freeze"
|
||||
to="0.5"
|
||||
id="svg_4"
|
||||
to="0.5"
|
||||
></animate>
|
||||
</line>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
stroke-width="15"
|
||||
opacity="0.5"
|
||||
transform="matrix(1 0 0 1 0 0)"
|
||||
x1="225"
|
||||
y1="200"
|
||||
x2="475"
|
||||
y1="175"
|
||||
y2="425"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></line>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_1_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_line_align_to_page #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_3"
|
||||
opacity="0.25"
|
||||
stroke="#bf5f00"
|
||||
stroke-width="5"
|
||||
opacity="0.25"
|
||||
x1="220"
|
||||
y1="220"
|
||||
x2="470"
|
||||
y1="220"
|
||||
y2="470"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_3"
|
||||
>
|
||||
<animate
|
||||
attributeName="opacity"
|
||||
begin="indefinite"
|
||||
dur="0.2"
|
||||
fill="freeze"
|
||||
to="0.5"
|
||||
id="svg_4"
|
||||
to="0.5"
|
||||
></animate>
|
||||
</line>
|
||||
<line
|
||||
fill="none"
|
||||
id="svg_2"
|
||||
opacity="0.5"
|
||||
stroke="#000000"
|
||||
stroke-width="15"
|
||||
opacity="0.5"
|
||||
transform="matrix(1 0 0 1 0 0)"
|
||||
x1="225"
|
||||
y1="200"
|
||||
x2="475"
|
||||
y1="175"
|
||||
y2="425"
|
||||
id="svg_2"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></line>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_1_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
@@ -1,45 +1,38 @@
|
||||
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"
|
||||
<body>
|
||||
<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>
|
||||
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_polygon #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<svg
|
||||
width="640"
|
||||
height="480"
|
||||
id="svgcontent"
|
||||
overflow="visible"
|
||||
x="640"
|
||||
y="480"
|
||||
viewBox="0 0 640 480"
|
||||
>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
orient="x"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokewidth="5"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
>
|
||||
@@ -52,554 +45,429 @@ exports[`use all parts of svg-edit > check tool_polygon #0`] = `
|
||||
></animate>
|
||||
</polygon>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_polygon_clone #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
orient="x"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
<polygon
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
id="svg_2"
|
||||
orient="x"
|
||||
points="398.8745422363281,270 361.6481628417969,321.23773193359375 301.4145812988281,301.6666564941406 301.4145812988281,238.3333282470703 361.6481628417969,218.7622528076172 398.8745422363281,270 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="398.8745422363281,270 361.6481628417969,321.23773193359375 301.4145812988281,301.6666564941406 301.4145812988281,238.3333282470703 361.6481628417969,218.7622528076172 398.8745422363281,270 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_2"
|
||||
></polygon>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_polygon_change_rotation #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
orient="x"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
<polygon
|
||||
class="svg_2_class"
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
id="svg_2_id"
|
||||
orient="x"
|
||||
points="398.8745422363281,270 361.6481628417969,321.23773193359375 301.4145812988281,301.6666564941406 301.4145812988281,238.3333282470703 361.6481628417969,218.7622528076172 398.8745422363281,270 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="398.8745422363281,270 361.6481628417969,321.23773193359375 301.4145812988281,301.6666564941406 301.4145812988281,238.3333282470703 361.6481628417969,218.7622528076172 398.8745422363281,270 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_2_id"
|
||||
class="svg_2_class"
|
||||
transform="rotate(25 350.145 270)"
|
||||
></polygon>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_polygon_change_blur #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
orient="x"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
<polygon
|
||||
class="svg_2_class"
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
id="svg_2_id"
|
||||
orient="x"
|
||||
points="398.8745422363281,270 361.6481628417969,321.23773193359375 301.4145812988281,301.6666564941406 301.4145812988281,238.3333282470703 361.6481628417969,218.7622528076172 398.8745422363281,270 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="398.8745422363281,270 361.6481628417969,321.23773193359375 301.4145812988281,301.6666564941406 301.4145812988281,238.3333282470703 361.6481628417969,218.7622528076172 398.8745422363281,270 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_2_id"
|
||||
class="svg_2_class"
|
||||
transform="rotate(25 350.145 270)"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_2_id_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_polygon_change_opacity #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
orient="x"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
<polygon
|
||||
class="svg_2_class"
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
id="svg_2_id"
|
||||
opacity="0.5"
|
||||
orient="x"
|
||||
points="398.8745422363281,270 361.6481628417969,321.23773193359375 301.4145812988281,301.6666564941406 301.4145812988281,238.3333282470703 361.6481628417969,218.7622528076172 398.8745422363281,270 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="398.8745422363281,270 361.6481628417969,321.23773193359375 301.4145812988281,301.6666564941406 301.4145812988281,238.3333282470703 361.6481628417969,218.7622528076172 398.8745422363281,270 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_2_id"
|
||||
class="svg_2_class"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
opacity="0.5"
|
||||
transform="rotate(25 350.145 270)"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_2_id_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_polygon_bring_to_back #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
class="svg_2_class"
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
id="svg_2_id"
|
||||
opacity="0.5"
|
||||
orient="x"
|
||||
points="398.8745422363281,270 361.6481628417969,321.23773193359375 301.4145812988281,301.6666564941406 301.4145812988281,238.3333282470703 361.6481628417969,218.7622528076172 398.8745422363281,270 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="398.8745422363281,270 361.6481628417969,321.23773193359375 301.4145812988281,301.6666564941406 301.4145812988281,238.3333282470703 361.6481628417969,218.7622528076172 398.8745422363281,270 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_2_id"
|
||||
class="svg_2_class"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
opacity="0.5"
|
||||
transform="rotate(25 350.145 270)"
|
||||
></polygon>
|
||||
<polygon
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
orient="x"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_2_id_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_polygon_bring_to_front #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
orient="x"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
<polygon
|
||||
class="svg_2_class"
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
id="svg_2_id"
|
||||
opacity="0.5"
|
||||
orient="x"
|
||||
points="398.8745422363281,270 361.6481628417969,321.23773193359375 301.4145812988281,301.6666564941406 301.4145812988281,238.3333282470703 361.6481628417969,218.7622528076172 398.8745422363281,270 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="398.8745422363281,270 361.6481628417969,321.23773193359375 301.4145812988281,301.6666564941406 301.4145812988281,238.3333282470703 361.6481628417969,218.7622528076172 398.8745422363281,270 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_2_id"
|
||||
class="svg_2_class"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
opacity="0.5"
|
||||
transform="rotate(25 350.145 270)"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_2_id_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_polygon_delete #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
orient="x"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_polygon_align_to_page #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
orient="x"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_polygon_change_stroke_width #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
orient="x"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
stroke="#000000"
|
||||
stroke-width="15"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_polygon_change_stoke_fill_color #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#bf0000"
|
||||
id="svg_1"
|
||||
orient="x"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
shape="regularPoly"
|
||||
sides="5"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#bf0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 "
|
||||
stroke="#0000bf"
|
||||
stroke-width="15"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_polygon_change_sides #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="325"
|
||||
cy="250"
|
||||
edge="63.33333"
|
||||
fill="#bf0000"
|
||||
id="svg_1"
|
||||
orient="x"
|
||||
points="406.36004929315476,249.999995640346 374.69338262648813,304.8482712133604 311.3600492931548,304.8482712133604 279.69338262648813,249.999995640346 311.36004929315476,195.15172006733155 374.69338262648813,195.15172006733155 406.36004929315476,249.99999564034596 "
|
||||
shape="regularPoly"
|
||||
sides="6"
|
||||
orient="x"
|
||||
edge="63.333333333333336"
|
||||
fill="#bf0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
points="397.3124287923177,249.99999491373697 365.64576212565106,304.8482704867514 302.31242879231775,304.8482704867514 270.64576212565106,249.99999491373697 302.3124287923177,195.15171934072254 365.64576212565106,195.15171934072254 397.3124287923177,249.99999491373694 "
|
||||
stroke="#0000bf"
|
||||
stroke-width="15"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
@@ -1,48 +1,41 @@
|
||||
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"
|
||||
<body>
|
||||
<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>
|
||||
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_star #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<svg
|
||||
width="640"
|
||||
height="480"
|
||||
id="svgcontent"
|
||||
overflow="visible"
|
||||
x="640"
|
||||
y="480"
|
||||
viewBox="0 0 640 480"
|
||||
>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="300"
|
||||
cy="150"
|
||||
id="svg_1"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokewidth="5"
|
||||
starradiusmultiplier="3"
|
||||
id="svg_1"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="300,83.33333333333333 313.0618944953883,132.02184456944562 363.40376775301024,129.39886704167017 321.13458925100343,156.86704431944327 339.18568348616486,203.93446629166317 300,172.22222222222223 260.81431651383514,203.93446629166317 278.86541074899657,156.86704431944327 236.59623224698976,129.39886704167017 286.9381055046117,132.02184456944562 300,83.33333333333333 313.0618944953883,132.02184456944562 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
>
|
||||
@@ -55,605 +48,480 @@ exports[`use all parts of svg-edit > check tool_star #0`] = `
|
||||
></animate>
|
||||
</polygon>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_star_clone #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="300"
|
||||
cy="150"
|
||||
id="svg_1"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
id="svg_1"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="300,83.33333333333333 313.0618944953883,132.02184456944562 363.40376775301024,129.39886704167017 321.13458925100343,156.86704431944327 339.18568348616486,203.93446629166317 300,172.22222222222223 260.81431651383514,203.93446629166317 278.86541074899657,156.86704431944327 236.59623224698976,129.39886704167017 286.9381055046117,132.02184456944562 300,83.33333333333333 313.0618944953883,132.02184456944562 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
<polygon
|
||||
cx="300"
|
||||
cy="150"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
id="svg_2"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="320,103.33333587646484 333.0618896484375,152.0218505859375 383.4037780761719,149.39886474609375 341.13458251953125,176.86705017089844 359.1856689453125,223.93446350097656 320,192.22222900390625 280.8143310546875,223.93446350097656 298.86541748046875,176.86705017089844 256.5962371826172,149.39886474609375 306.9381103515625,152.0218505859375 320,103.33333587646484 333.0618896484375,152.0218505859375 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_2"
|
||||
></polygon>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_star_change_rotation #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="300"
|
||||
cy="150"
|
||||
id="svg_1"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
id="svg_1"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="300,83.33333333333333 313.0618944953883,132.02184456944562 363.40376775301024,129.39886704167017 321.13458925100343,156.86704431944327 339.18568348616486,203.93446629166317 300,172.22222222222223 260.81431651383514,203.93446629166317 278.86541074899657,156.86704431944327 236.59623224698976,129.39886704167017 286.9381055046117,132.02184456944562 300,83.33333333333333 313.0618944953883,132.02184456944562 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
<polygon
|
||||
class="svg_2_class"
|
||||
cx="300"
|
||||
cy="150"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
id="svg_2_id"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="320,103.33333587646484 333.0618896484375,152.0218505859375 383.4037780761719,149.39886474609375 341.13458251953125,176.86705017089844 359.1856689453125,223.93446350097656 320,192.22222900390625 280.8143310546875,223.93446350097656 298.86541748046875,176.86705017089844 256.5962371826172,149.39886474609375 306.9381103515625,152.0218505859375 320,103.33333587646484 333.0618896484375,152.0218505859375 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_2_id"
|
||||
class="svg_2_class"
|
||||
transform="rotate(25 320 163.634)"
|
||||
></polygon>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_star_change_blur #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="300"
|
||||
cy="150"
|
||||
id="svg_1"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
id="svg_1"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="300,83.33333333333333 313.0618944953883,132.02184456944562 363.40376775301024,129.39886704167017 321.13458925100343,156.86704431944327 339.18568348616486,203.93446629166317 300,172.22222222222223 260.81431651383514,203.93446629166317 278.86541074899657,156.86704431944327 236.59623224698976,129.39886704167017 286.9381055046117,132.02184456944562 300,83.33333333333333 313.0618944953883,132.02184456944562 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
<polygon
|
||||
class="svg_2_class"
|
||||
cx="300"
|
||||
cy="150"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
id="svg_2_id"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="320,103.33333587646484 333.0618896484375,152.0218505859375 383.4037780761719,149.39886474609375 341.13458251953125,176.86705017089844 359.1856689453125,223.93446350097656 320,192.22222900390625 280.8143310546875,223.93446350097656 298.86541748046875,176.86705017089844 256.5962371826172,149.39886474609375 306.9381103515625,152.0218505859375 320,103.33333587646484 333.0618896484375,152.0218505859375 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_2_id"
|
||||
class="svg_2_class"
|
||||
transform="rotate(25 320 163.634)"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_2_id_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_star_change_opacity #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="300"
|
||||
cy="150"
|
||||
id="svg_1"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
id="svg_1"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="300,83.33333333333333 313.0618944953883,132.02184456944562 363.40376775301024,129.39886704167017 321.13458925100343,156.86704431944327 339.18568348616486,203.93446629166317 300,172.22222222222223 260.81431651383514,203.93446629166317 278.86541074899657,156.86704431944327 236.59623224698976,129.39886704167017 286.9381055046117,132.02184456944562 300,83.33333333333333 313.0618944953883,132.02184456944562 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
<polygon
|
||||
class="svg_2_class"
|
||||
cx="300"
|
||||
cy="150"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
id="svg_2_id"
|
||||
opacity="0.5"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="320,103.33333587646484 333.0618896484375,152.0218505859375 383.4037780761719,149.39886474609375 341.13458251953125,176.86705017089844 359.1856689453125,223.93446350097656 320,192.22222900390625 280.8143310546875,223.93446350097656 298.86541748046875,176.86705017089844 256.5962371826172,149.39886474609375 306.9381103515625,152.0218505859375 320,103.33333587646484 333.0618896484375,152.0218505859375 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_2_id"
|
||||
class="svg_2_class"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
opacity="0.5"
|
||||
transform="rotate(25 320 163.634)"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_2_id_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_star_bring_to_back #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
class="svg_2_class"
|
||||
cx="300"
|
||||
cy="150"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
id="svg_2_id"
|
||||
opacity="0.5"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="320,103.33333587646484 333.0618896484375,152.0218505859375 383.4037780761719,149.39886474609375 341.13458251953125,176.86705017089844 359.1856689453125,223.93446350097656 320,192.22222900390625 280.8143310546875,223.93446350097656 298.86541748046875,176.86705017089844 256.5962371826172,149.39886474609375 306.9381103515625,152.0218505859375 320,103.33333587646484 333.0618896484375,152.0218505859375 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_2_id"
|
||||
class="svg_2_class"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
opacity="0.5"
|
||||
transform="rotate(25 320 163.634)"
|
||||
></polygon>
|
||||
<polygon
|
||||
cx="300"
|
||||
cy="150"
|
||||
id="svg_1"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
id="svg_1"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="300,83.33333333333333 313.0618944953883,132.02184456944562 363.40376775301024,129.39886704167017 321.13458925100343,156.86704431944327 339.18568348616486,203.93446629166317 300,172.22222222222223 260.81431651383514,203.93446629166317 278.86541074899657,156.86704431944327 236.59623224698976,129.39886704167017 286.9381055046117,132.02184456944562 300,83.33333333333333 313.0618944953883,132.02184456944562 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_2_id_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_star_bring_to_front #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="300"
|
||||
cy="150"
|
||||
id="svg_1"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
id="svg_1"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="300,83.33333333333333 313.0618944953883,132.02184456944562 363.40376775301024,129.39886704167017 321.13458925100343,156.86704431944327 339.18568348616486,203.93446629166317 300,172.22222222222223 260.81431651383514,203.93446629166317 278.86541074899657,156.86704431944327 236.59623224698976,129.39886704167017 286.9381055046117,132.02184456944562 300,83.33333333333333 313.0618944953883,132.02184456944562 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
<polygon
|
||||
class="svg_2_class"
|
||||
cx="300"
|
||||
cy="150"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
id="svg_2_id"
|
||||
opacity="0.5"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="320,103.33333587646484 333.0618896484375,152.0218505859375 383.4037780761719,149.39886474609375 341.13458251953125,176.86705017089844 359.1856689453125,223.93446350097656 320,192.22222900390625 280.8143310546875,223.93446350097656 298.86541748046875,176.86705017089844 256.5962371826172,149.39886474609375 306.9381103515625,152.0218505859375 320,103.33333587646484 333.0618896484375,152.0218505859375 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
id="svg_2_id"
|
||||
class="svg_2_class"
|
||||
filter="url(#svg_2_id_blur)"
|
||||
opacity="0.5"
|
||||
transform="rotate(25 320 163.634)"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<filter height="200%" id="svg_2_id_blur" width="200%" x="-50%" y="-50%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_star_delete #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="300"
|
||||
cy="150"
|
||||
id="svg_1"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
id="svg_1"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="300,83.33333333333333 313.0618944953883,132.02184456944562 363.40376775301024,129.39886704167017 321.13458925100343,156.86704431944327 339.18568348616486,203.93446629166317 300,172.22222222222223 260.81431651383514,203.93446629166317 278.86541074899657,156.86704431944327 236.59623224698976,129.39886704167017 286.9381055046117,132.02184456944562 300,83.33333333333333 313.0618944953883,132.02184456944562 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_star_align_to_page #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="300"
|
||||
cy="150"
|
||||
id="svg_1"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
id="svg_1"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="300,83.33333333333333 313.0618944953883,132.02184456944562 363.40376775301024,129.39886704167017 321.13458925100343,156.86704431944327 339.18568348616486,203.93446629166317 300,172.22222222222223 260.81431651383514,203.93446629166317 278.86541074899657,156.86704431944327 236.59623224698976,129.39886704167017 286.9381055046117,132.02184456944562 300,83.33333333333333 313.0618944953883,132.02184456944562 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="5"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_star_change_stroke_width #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="300"
|
||||
cy="150"
|
||||
id="svg_1"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#FF0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
id="svg_1"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="300,83.33333333333333 313.0618944953883,132.02184456944562 363.40376775301024,129.39886704167017 321.13458925100343,156.86704431944327 339.18568348616486,203.93446629166317 300,172.22222222222223 260.81431651383514,203.93446629166317 278.86541074899657,156.86704431944327 236.59623224698976,129.39886704167017 286.9381055046117,132.02184456944562 300,83.33333333333333 313.0618944953883,132.02184456944562 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#000000"
|
||||
stroke-width="15"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_star_change_stoke_fill_color #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="300"
|
||||
cy="150"
|
||||
id="svg_1"
|
||||
shape="star"
|
||||
point="5"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#bf0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
id="svg_1"
|
||||
orient="point"
|
||||
point="5"
|
||||
points="300,83.33333333333333 313.0618944953883,132.02184456944562 363.40376775301024,129.39886704167017 321.13458925100343,156.86704431944327 339.18568348616486,203.93446629166317 300,172.22222222222223 260.81431651383514,203.93446629166317 278.86541074899657,156.86704431944327 236.59623224698976,129.39886704167017 286.9381055046117,132.02184456944562 300,83.33333333333333 313.0618944953883,132.02184456944562 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#0000bf"
|
||||
stroke-width="15"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
exports[`use all parts of svg-edit > check tool_star_change_sides #0`] = `
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
<body>
|
||||
<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>
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<polygon
|
||||
cx="300"
|
||||
cy="150"
|
||||
id="svg_1"
|
||||
shape="star"
|
||||
point="6"
|
||||
r="66.66666666666667"
|
||||
radialshift="0"
|
||||
r2="22.222222222222225"
|
||||
orient="point"
|
||||
fill="#bf0000"
|
||||
strokecolor="#000000"
|
||||
strokeWidth="5"
|
||||
starRadiusMultiplier="3"
|
||||
points="301.08849207560223,76.2796007792155 312.1996031867133,123.70125847289464 358.8235189945648,109.61293411254883 323.31071429782446,142.94626744588217 358.82351899456484,176.27960077921549 312.1996031867134,162.1912764188697 301.08849207560223,209.61293411254883 289.97738096449115,162.1912764188697 243.35346515663966,176.2796007792155 278.86626985338,142.94626744588217 243.35346515663966,109.61293411254883 289.97738096449115,123.70125847289464 301.08849207560223,76.2796007792155 312.1996031867134,123.70125847289464 "
|
||||
id="svg_1"
|
||||
orient="point"
|
||||
point="6"
|
||||
points="301.8821476527623,70.14305132911319 312.99325876387337,117.56470902279233 359.61717457172483,103.47638466244652 324.1043698749845,136.80971799577986 359.6171745717249,170.14305132911318 312.9932587638734,156.0547269687674 301.8821476527623,203.47638466244655 290.7710365416512,156.0547269687674 244.1471207337997,170.14305132911323 279.65992543054006,136.80971799577986 244.1471207337997,103.47638466244652 290.7710365416512,117.56470902279233 301.8821476527623,70.14305132911319 312.9932587638734,117.56470902279233 "
|
||||
r="66.66667"
|
||||
r2="22.22222"
|
||||
radialshift="0"
|
||||
shape="star"
|
||||
starradiusmultiplier="3"
|
||||
stroke="#0000bf"
|
||||
stroke-width="15"
|
||||
fill-opacity="1"
|
||||
stroke-opacity="1"
|
||||
></polygon>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="svg_2_id_blur" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</body>
|
||||
`;
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
import {
|
||||
visitAndApproveStorage
|
||||
} from '../../support/ui-test-helper.js';
|
||||
|
||||
describe('UI - Accessibility', function () {
|
||||
beforeEach(() => {
|
||||
visitAndApproveStorage();
|
||||
cy.injectAxe();
|
||||
});
|
||||
// https://www.npmjs.com/package/cypress-axe
|
||||
it.skip('Has no detectable a11y violations on load', () => {
|
||||
// Configure aXe and test the page at initial load
|
||||
cy.configureAxe({
|
||||
// Todo: Reenable when have time to fix
|
||||
// See https://www.deque.com/axe/axe-for-web/documentation/api-documentation/#user-content-parameters-1
|
||||
rules: [ {
|
||||
id: 'meta-viewport',
|
||||
enabled: false
|
||||
} ]
|
||||
/*
|
||||
branding: {
|
||||
brand: String,
|
||||
application: String
|
||||
},
|
||||
reporter: 'option',
|
||||
checks: [Object],
|
||||
rules: [Object],
|
||||
locale: Object
|
||||
*/
|
||||
});
|
||||
cy.checkA11y(
|
||||
{},
|
||||
{
|
||||
rules: {
|
||||
'label-title-only': { enabled: false },
|
||||
'page-has-heading-one': { enabled: false },
|
||||
region: { enabled: false },
|
||||
'scrollable-region-focusable': { enabled: false }
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -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 })
|
||||
})
|
||||
})
|
||||
|
||||
35
cypress/integration/ui/issues/issue-660.js
Normal file
35
cypress/integration/ui/issues/issue-660.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import {
|
||||
visitAndApproveStorage
|
||||
} 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)
|
||||
})
|
||||
/** @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('#svg_source_textarea')
|
||||
.type('{selectall}', { force: true })
|
||||
.type(`<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<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')
|
||||
cy.get('#a_text')
|
||||
.trigger('mousedown', { which: 1, 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 })
|
||||
// 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)
|
||||
})
|
||||
})
|
||||
@@ -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,190 +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('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();
|
||||
});
|
||||
it('check tool_text_anchor_start', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#tool_text_anchor_start')
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
it('check tool_text_anchor_middle', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#tool_text_anchor_middle')
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
it('check tool_text_anchor_end', function () {
|
||||
cy.get('#svg_1').click({ force: true });
|
||||
cy.get('#tool_text_anchor_end')
|
||||
.click({ force: true });
|
||||
testSnapshot();
|
||||
});
|
||||
.find('#Ok').eq(0).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('elix-dropdown-list').eq(0).invoke('attr', 'opened', 'opened');
|
||||
cy.get('#tool_font_family').find('se-list-item').eq(6).shadow().find('elix-option').eq(0)
|
||||
.click({ force: true });
|
||||
cy.get('#svgcontent').toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_font_family').shadow().find('select').select('Serif')
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_decoration_underline', function () {
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_text_decoration_underline')
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_decoration_linethrough', function () {
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_text_decoration_linethrough')
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
it('check tool_text_decoration_overline', function () {
|
||||
cy.get('#svg_1').click({ force: true })
|
||||
cy.get('#tool_text_decoration_overline')
|
||||
.click({ force: true })
|
||||
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').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,26 +1,25 @@
|
||||
import { NS } from '../../../instrumented/common/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
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
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(
|
||||
@@ -28,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.
|
||||
@@ -54,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/common/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 []; } // eslint-disable-line class-methods-use-this
|
||||
|
||||
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/common/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/common/namespaces.js';
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
|
||||
import * as pathModule from '../../../instrumented/svgcanvas/path.js';
|
||||
import { Path, Segment } from '../../../instrumented/svgcanvas/path-method.js';
|
||||
import { init as unitsInit } from '../../../instrumented/common/units.js';
|
||||
import '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); // eslint-disable-line no-new
|
||||
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); // eslint-disable-line no-new
|
||||
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); // eslint-disable-line no-new
|
||||
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); // eslint-disable-line no-new
|
||||
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,123 +1,121 @@
|
||||
import { NS } from '../../../instrumented/common/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 () {
|
||||
// eslint-disable-next-line no-shadow
|
||||
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++); }
|
||||
};
|
||||
},
|
||||
getDataStorage() { return dataStorage; }
|
||||
getNextId () { return String(elemId++) }
|
||||
}
|
||||
);
|
||||
},
|
||||
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)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,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/common/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/common/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-connector.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,13 +1,13 @@
|
||||
/* eslint-disable max-len */
|
||||
import 'pathseg';
|
||||
import 'pathseg'
|
||||
|
||||
import { NS } from '../../../instrumented/common/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 () {
|
||||
/**
|
||||
@@ -16,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 (pth?.nodeName !== 'path') { return false }
|
||||
const tlist = pth.transform.baseVal
|
||||
const m = math.transformListToTransform(tlist).matrix
|
||||
tlist.clear()
|
||||
pth.removeAttribute('transform')
|
||||
const segList = pth.pathSegList
|
||||
|
||||
const len = segList.numberOfItems;
|
||||
const len = segList.numberOfItems
|
||||
// let lastX, lastY;
|
||||
|
||||
for (let i = 0; i < len; ++i) {
|
||||
const seg = segList.getItem(i);
|
||||
const type = seg.pathSegType;
|
||||
if (type === 1) { continue; }
|
||||
const seg = segList.getItem(i)
|
||||
const type = seg.pathSegType
|
||||
if (type === 1) { continue }
|
||||
const pts = [];
|
||||
[ '', 1, 2 ].forEach(function (n) {
|
||||
const x = seg['x' + n]; const y = seg['y' + n];
|
||||
['', 1, 2].forEach(function (n) {
|
||||
const x = seg['x' + n]; const y = seg['y' + n]
|
||||
if (x !== undefined && y !== undefined) {
|
||||
const pt = math.transformPoint(x, y, m);
|
||||
pts.splice(pts.length, 0, pt.x, pt.y);
|
||||
const pt = math.transformPoint(x, y, m)
|
||||
pts.splice(pts.length, 0, pt.x, pt.y)
|
||||
}
|
||||
});
|
||||
path.replacePathSeg(type, i, pts, pth);
|
||||
})
|
||||
path.replacePathSeg(type, i, pts, pth)
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
// path.reorientGrads(pth, m);
|
||||
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 }; // eslint-disable-line no-shadow
|
||||
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 }; // eslint-disable-line no-shadow
|
||||
tx = 10; // tx right
|
||||
ty = 10; // tx down
|
||||
txInRotatedSpace = Math.sqrt(tx * tx + ty * ty); // translate in rotated 45 space.
|
||||
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.
|
||||
@@ -456,7 +466,7 @@ describe('utilities bbox', function () {
|
||||
* @returns {Float}
|
||||
*/
|
||||
function radians (degrees) {
|
||||
return degrees * Math.PI / 180;
|
||||
return degrees * Math.PI / 180
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -466,17 +476,14 @@ describe('utilities bbox', function () {
|
||||
* @param {module:math.XYObject} origin
|
||||
* @returns {module:math.XYObject}
|
||||
*/
|
||||
function rotatePoint (point, angle, origin) { // eslint-disable-line no-shadow
|
||||
if (!origin) {
|
||||
origin = { x: 0, y: 0 };
|
||||
}
|
||||
const x = point.x - origin.x;
|
||||
const y = point.y - origin.y;
|
||||
const theta = radians(angle);
|
||||
function rotatePoint (point, angle, origin = { x: 0, y: 0 }) {
|
||||
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,22 +492,22 @@ describe('utilities bbox', function () {
|
||||
* @param {module:math.XYObject} origin
|
||||
* @returns {module:utilities.BBoxObject}
|
||||
*/
|
||||
function rotateRect (rect, angle, origin) { // eslint-disable-line no-shadow
|
||||
const tl = rotatePoint({ x: rect.x, y: rect.y }, angle, origin);
|
||||
const tr = rotatePoint({ x: rect.x + rect.width, y: rect.y }, angle, origin);
|
||||
const br = rotatePoint({ x: rect.x + rect.width, y: rect.y + rect.height }, angle, origin);
|
||||
const bl = rotatePoint({ x: rect.x, y: rect.y + rect.height }, angle, origin);
|
||||
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 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/common/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 (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,7 +1,5 @@
|
||||
/* eslint-disable max-len */
|
||||
import * as browser from '../../../instrumented/common/browser.js';
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js';
|
||||
import { NS } from '../../../instrumented/common/namespaces.js';
|
||||
import * as utilities from '../../../instrumented/svgcanvas/utilities.js'
|
||||
import { NS } from '../../../instrumented/svgcanvas/namespaces.js'
|
||||
|
||||
describe('utilities', function () {
|
||||
/**
|
||||
@@ -10,341 +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 {
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
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');
|
||||
});
|
||||
|
||||
it('Test getPathBBox', function () {
|
||||
if (browser.supportsPathBBox()) {
|
||||
return;
|
||||
}
|
||||
const doc = utilities.text2xml('<svg></svg>');
|
||||
const path = doc.createElementNS(NS.SVG, 'path');
|
||||
path.setAttribute('d', 'm0,0l5,0l0,5l-5,0l0,-5z');
|
||||
const bb = utilities.getPathBBox(path);
|
||||
assert.equal(typeof bb, 'object', 'BBox returned object');
|
||||
assert.ok(bb.x && !isNaN(bb.x));
|
||||
assert.ok(bb.y && !isNaN(bb.y));
|
||||
});
|
||||
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/;
|
||||
console.log(getPathDFromElement(elem), closeEnough);
|
||||
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,5 +1,4 @@
|
||||
/* eslint-disable max-len */
|
||||
import assertionWrapper from './assertion-wrapper.js';
|
||||
import assertionWrapper from './assertion-wrapper.js'
|
||||
|
||||
/**
|
||||
* @typedef {PlainObject} InfoObject
|
||||
@@ -22,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 }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,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 }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,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 }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,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 }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,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,23 +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';
|
||||
|
||||
/**
|
||||
* ACCESSIBILITY.
|
||||
* @see https://www.npmjs.com/package/cypress-axe
|
||||
*/
|
||||
import 'cypress-axe';
|
||||
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()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -16,21 +16,25 @@
|
||||
<div>
|
||||
[<button onclick="canvas.setMode('select')">Select</button>
|
||||
<button onclick="canvas.setMode('circle')">Circle</button>
|
||||
<button onclick="canvas.setMode('rect')">Rect</button>]
|
||||
<button onclick="canvas.setMode('rect')">Rect</button>
|
||||
<button onclick="canvas.setMode('text')">Text</button>]
|
||||
<button onclick="fill('#ff0000')">Fill Red</button>
|
||||
<button onclick="canvas.deleteSelectedElements()">Delete Selected</button>
|
||||
<button onclick="canvas.clear(); canvas.updateCanvas(width, height);">Clear All</button>
|
||||
<button onclick="alert(canvas.getSvgString())">Get SVG</button>
|
||||
</div>
|
||||
|
||||
<!-- Not visible, but useful -->
|
||||
<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 config = {
|
||||
initFill: { color: 'FFFFFF', opacity: 1 },
|
||||
@@ -40,16 +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 addListenerMulti = (element, eventNames, listener) => {
|
||||
eventNames.split(' ').forEach((eventName) => element.addEventListener(eventName, listener, false))
|
||||
}
|
||||
|
||||
addListenerMulti(hiddenTextTag, 'keyup input', (evt) => {
|
||||
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: {
|
||||
@@ -14,7 +14,6 @@ module.exports = {
|
||||
'screencasts',
|
||||
'test'
|
||||
],
|
||||
// eslint-disable-next-line max-len
|
||||
excludePattern: 'svgedit-config-*|build-html.js|rollup*|external/babel-polyfill|extensions/mathjax|imagelib/jquery.min.js|jspdf/jspdf.min.js|jspdf/underscore-min.js|jquery-ui|jquery.min.js|js-hotkeys'
|
||||
},
|
||||
sourceType: 'module',
|
||||
@@ -34,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'
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
11390
package-lock.json
generated
11390
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
112
package.json
112
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "svgedit",
|
||||
"version": "7.0.0-beta.6",
|
||||
"version": "7.1.1",
|
||||
"description": "Powerful SVG-Editor for your browser ",
|
||||
"main": "dist/Editor.js",
|
||||
"module": "dist/Editor.js",
|
||||
@@ -13,13 +13,13 @@
|
||||
"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",
|
||||
"start": "web-dev-server --app-index src/editor/index.html --open --node-resolve",
|
||||
"start:test": "web-dev-server --app-index src/editor/index.html --node-resolve",
|
||||
"start:watch": "web-dev-server --app-index src/editor/index.html --open --node-resolve --watch",
|
||||
"start:iife": "web-dev-server --app-index dist/editor/iife-index.html --esbuild-target auto --open",
|
||||
"cypress:open": "run-p start cypress:open-no-start",
|
||||
"cypress:open-no-start": "cypress open",
|
||||
"cypress:run": "rimraf \".nyc_output/*\" && cypress run -q && nyc report --reporter=text-summary",
|
||||
@@ -63,94 +63,80 @@
|
||||
},
|
||||
"homepage": "https://github.com/SVG-Edit/svgedit#readme",
|
||||
"browserslist": [
|
||||
">0%",
|
||||
"not Opera < 59",
|
||||
"not IE < 12",
|
||||
"not Chrome < 75",
|
||||
"not FireFox < 68",
|
||||
"not Safari < 11",
|
||||
"not ios_saf < 10",
|
||||
"not android < 5",
|
||||
"not op_mini all",
|
||||
"not Edge < 18",
|
||||
"not dead"
|
||||
"defaults",
|
||||
"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.20.4",
|
||||
"canvg": "3.0.7",
|
||||
"core-js": "3.16.3",
|
||||
"elix": "15.0.0",
|
||||
"html2canvas": "1.3.2",
|
||||
"i18next": "20.4.0",
|
||||
"jspdf": "2.3.1",
|
||||
"browser-fs-access": "0.23.0",
|
||||
"canvg": "3.0.9",
|
||||
"core-js": "3.20.1",
|
||||
"elix": "15.0.1",
|
||||
"html2canvas": "1.3.4",
|
||||
"i18next": "21.6.4",
|
||||
"jspdf": "2.5.0",
|
||||
"pathseg": "1.2.1",
|
||||
"regenerator-runtime": "0.13.9",
|
||||
"rollup-plugin-polyfill-node": "0.7.0",
|
||||
"svg2pdf.js": "2.1.0"
|
||||
"rollup-plugin-polyfill-node": "0.8.0",
|
||||
"svg2pdf.js": "2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.15.0",
|
||||
"@babel/preset-env": "7.15.0",
|
||||
"@babel/register": "7.15.3",
|
||||
"@babel/runtime-corejs3": "7.15.3",
|
||||
"@cypress/code-coverage": "3.9.10",
|
||||
"@cypress/fiddle": "1.19.2",
|
||||
"@fintechstudios/eslint-plugin-chai-as-promised": "3.1.0",
|
||||
"@babel/core": "7.16.7",
|
||||
"@babel/preset-env": "7.16.7",
|
||||
"@babel/register": "7.16.7",
|
||||
"@babel/runtime-corejs3": "7.16.7",
|
||||
"@cypress/code-coverage": "3.9.12",
|
||||
"@cypress/fiddle": "1.19.3",
|
||||
"@rollup/plugin-babel": "5.3.0",
|
||||
"@rollup/plugin-commonjs": "18.0.0",
|
||||
"@rollup/plugin-dynamic-import-vars": "1.4.0",
|
||||
"@rollup/plugin-node-resolve": "13.0.4",
|
||||
"@rollup/plugin-replace": "3.0.0",
|
||||
"@rollup/plugin-commonjs": "^18",
|
||||
"@rollup/plugin-dynamic-import-vars": "1.4.2",
|
||||
"@rollup/plugin-node-resolve": "13.1.1",
|
||||
"@rollup/plugin-replace": "3.0.1",
|
||||
"@rollup/plugin-url": "6.1.0",
|
||||
"@web/dev-server": "0.1.22",
|
||||
"@web/dev-server-rollup": "0.3.9",
|
||||
"axe-core": "4.3.3",
|
||||
"@web/dev-server": "0.1.29",
|
||||
"@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.16.3",
|
||||
"core-js-bundle": "3.20.1",
|
||||
"cp-cli": "2.0.0",
|
||||
"cypress": "8.3.1",
|
||||
"cypress-axe": "0.13.0",
|
||||
"cypress": "9.2.0",
|
||||
"cypress-multi-reporters": "1.5.0",
|
||||
"cypress-plugin-snapshots": "1.4.4",
|
||||
"eslint": "7.32.0",
|
||||
"eslint-config-standard": "16.0.3",
|
||||
"eslint-plugin-array-func": "3.1.7",
|
||||
"eslint-plugin-chai-expect": "2.2.0",
|
||||
"eslint-plugin-chai-expect-keywords": "2.1.0",
|
||||
"eslint-plugin-chai-friendly": "0.7.2",
|
||||
"eslint-plugin-compat": "3.13.0",
|
||||
"eslint-plugin-cypress": "2.11.3",
|
||||
"eslint-plugin-eslint-comments": "3.2.0",
|
||||
"eslint-plugin-html": "6.1.2",
|
||||
"eslint-plugin-import": "2.24.2",
|
||||
"eslint-plugin-jsdoc": "36.0.8",
|
||||
"eslint-plugin-markdown": "2.2.0",
|
||||
"eslint-plugin-no-unsanitized": "3.1.5",
|
||||
"eslint-plugin-no-use-extend-native": "0.5.0",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-promise": "5.1.0",
|
||||
"eslint-plugin-standard": "4.1.0",
|
||||
"jamilih": "0.54.0",
|
||||
"jsdoc": "3.6.7",
|
||||
"node-static": "0.7.11",
|
||||
"npm-run-all": "4.1.5",
|
||||
"nyc": "15.1.0",
|
||||
"open-cli": "7.0.0",
|
||||
"open-cli": "7.0.1",
|
||||
"promise-fs": "2.1.1",
|
||||
"qr-manipulation": "0.7.0",
|
||||
"query-result": "1.0.5",
|
||||
"remark-cli": "10.0.0",
|
||||
"remark-lint-ordered-list-marker-value": "3.0.1",
|
||||
"remark-cli": "10.0.1",
|
||||
"remark-lint-ordered-list-marker-value": "3.1.1",
|
||||
"rimraf": "3.0.2",
|
||||
"rollup": "2.56.3",
|
||||
"rollup": "2.62.0",
|
||||
"rollup-plugin-copy": "3.4.0",
|
||||
"rollup-plugin-filesize": "9.1.1",
|
||||
"rollup-plugin-html": "^0.2.1",
|
||||
"rollup-plugin-node-polyfills": "0.2.1",
|
||||
"rollup-plugin-progress": "1.1.2",
|
||||
"rollup-plugin-re": "1.0.7",
|
||||
"rollup-plugin-terser": "7.0.2",
|
||||
"start-server-and-test": "1.13.1"
|
||||
"standard": "16.0.4",
|
||||
"start-server-and-test": "1.14.0"
|
||||
}
|
||||
}
|
||||
|
||||
104
rollup.config.js
104
rollup.config.js
@@ -3,41 +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 dynamicImportVars from '@rollup/plugin-dynamic-import-vars';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
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 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((nme) => path.join(source, nme)).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')
|
||||
|
||||
/** @todo should we support systemjs? */
|
||||
const dest = [ 'dist/editor' ];
|
||||
const dest = ['dist/editor']
|
||||
|
||||
// remove existing distribution
|
||||
// eslint-disable-next-line no-console
|
||||
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',
|
||||
@@ -51,6 +52,13 @@ const config = [ {
|
||||
sourcemap: true,
|
||||
file: 'dist/editor/xdomain-Editor.js',
|
||||
intro: 'const XDOMAIN = true;'
|
||||
},
|
||||
{
|
||||
file: 'dist/editor/iife-Editor.js',
|
||||
format: 'iife',
|
||||
inlineDynamicImports: true,
|
||||
name: 'Editor',
|
||||
sourcemap: true
|
||||
}
|
||||
],
|
||||
plugins: [
|
||||
@@ -65,9 +73,19 @@ const config = [ {
|
||||
dest: 'dist/editor',
|
||||
rename: 'xdomain-index.html',
|
||||
transform: (contents) => contents.toString()
|
||||
.replace('<script type="module" src="index.js">', '<script type="module" src="xdomain-index.js">')
|
||||
.replace("import Editor from './Editor.js'", "import Editor from './xdomain-Editor.js")
|
||||
},
|
||||
{
|
||||
src: 'src/editor/index.html',
|
||||
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>')
|
||||
}
|
||||
},
|
||||
{ src: 'src/editor/images', dest },
|
||||
{ src: 'src/editor/components/jgraduate/images', dest: dest.map((d) => `${d}/components/jgraduate`) },
|
||||
{ src: 'src/editor/extensions/ext-shapes/shapelib', dest: dest.map((d) => `${d}/extensions/ext-shapes`) },
|
||||
{ src: 'src/editor/embedapi.html', dest },
|
||||
{ src: 'src/editor/embedapi.js', dest },
|
||||
@@ -76,22 +94,29 @@ const config = [ {
|
||||
{ src: 'src/editor/svgedit.css', dest }
|
||||
]
|
||||
}),
|
||||
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`,
|
||||
@@ -102,33 +127,30 @@ extensionDirs.forEach((extensionDir) => {
|
||||
inlineDynamicImports: true,
|
||||
sourcemap: true
|
||||
}
|
||||
/*
|
||||
,
|
||||
{
|
||||
format: 'system',
|
||||
dir: `dist/editor/system/extensions/${extensionName}`,
|
||||
inlineDynamicImports: true
|
||||
}
|
||||
*/
|
||||
],
|
||||
plugins: [
|
||||
url({
|
||||
include: [ '**/*.svg', '**/*.png', '**/*.jpg', '**/*.gif', '**/*.xml' ],
|
||||
include: ['**/*.svg', '**/*.xml'],
|
||||
limit: 0,
|
||||
fileName: '[name][extname]'
|
||||
}),
|
||||
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,97 +6,36 @@
|
||||
* @copyright 2010 Jeff Schiller, 2010 Alexis Deveria
|
||||
*/
|
||||
|
||||
import 'pathseg';
|
||||
const NSSVG = 'http://www.w3.org/2000/svg'
|
||||
|
||||
import { NS } from './namespaces.js';
|
||||
|
||||
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;
|
||||
|
||||
// segList functions (for FF1.5 and 2.0)
|
||||
const supportsPathReplaceItem_ = (function () {
|
||||
const path = document.createElementNS(NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 10,10');
|
||||
const seglist = path.pathSegList;
|
||||
const seg = path.createSVGPathSegLinetoAbs(5, 5);
|
||||
try {
|
||||
seglist.replaceItem(seg, 1);
|
||||
return true;
|
||||
}catch (err) {/* empty */}
|
||||
return false;
|
||||
}());
|
||||
|
||||
const supportsPathInsertItemBefore_ = (function () {
|
||||
const path = document.createElementNS(NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 10,10');
|
||||
const seglist = path.pathSegList;
|
||||
const seg = path.createSVGPathSegLinetoAbs(5, 5);
|
||||
try {
|
||||
seglist.insertItemBefore(seg, 1);
|
||||
return true;
|
||||
}catch (err) {/* empty */}
|
||||
return false;
|
||||
}());
|
||||
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(NS.SVG, 'svg');
|
||||
const svgcontent = document.createElementNS(NS.SVG, 'svg');
|
||||
document.documentElement.append(svgroot);
|
||||
svgcontent.setAttribute('x', 5);
|
||||
svgroot.append(svgcontent);
|
||||
const text = document.createElementNS(NS.SVG, '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()
|
||||
}
|
||||
}());
|
||||
|
||||
const supportsPathBBox_ = (function () {
|
||||
const svgcontent = document.createElementNS(NS.SVG, 'svg');
|
||||
document.documentElement.append(svgcontent);
|
||||
const path = document.createElementNS(NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 C0,0 10,10 10,0');
|
||||
svgcontent.append(path);
|
||||
const bbox = path.getBBox();
|
||||
svgcontent.remove();
|
||||
return (bbox.height > 4 && bbox.height < 5);
|
||||
}());
|
||||
|
||||
// Support for correct bbox sizing on groups with horizontal/vertical lines
|
||||
const supportsHVLineContainerBBox_ = (function () {
|
||||
const svgcontent = document.createElementNS(NS.SVG, 'svg');
|
||||
document.documentElement.append(svgcontent);
|
||||
const path = document.createElementNS(NS.SVG, 'path');
|
||||
path.setAttribute('d', 'M0,0 10,0');
|
||||
const path2 = document.createElementNS(NS.SVG, 'path');
|
||||
path2.setAttribute('d', 'M5,0 15,0');
|
||||
const g = document.createElementNS(NS.SVG, 'g');
|
||||
g.append(path, path2);
|
||||
svgcontent.append(g);
|
||||
const bbox = g.getBBox();
|
||||
svgcontent.remove();
|
||||
// Webkit gives 0, FF gives 10, Opera (correctly) gives 15
|
||||
return (bbox.width === 15);
|
||||
}());
|
||||
|
||||
const supportsNonScalingStroke_ = (function () {
|
||||
const rect = document.createElementNS(NS.SVG, 'rect');
|
||||
rect.setAttribute('style', 'vector-effect:non-scaling-stroke');
|
||||
return rect.style.vectorEffect === 'non-scaling-stroke';
|
||||
}());
|
||||
}())
|
||||
|
||||
// Public API
|
||||
|
||||
@@ -104,62 +43,31 @@ const supportsNonScalingStroke_ = (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_;
|
||||
|
||||
/**
|
||||
* @function module:browser.supportsPathReplaceItem
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const supportsPathReplaceItem = () => supportsPathReplaceItem_;
|
||||
|
||||
/**
|
||||
* @function module:browser.supportsPathInsertItemBefore
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const supportsPathInsertItemBefore = () => supportsPathInsertItemBefore_;
|
||||
|
||||
/**
|
||||
* @function module:browser.supportsPathBBox
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const supportsPathBBox = () => supportsPathBBox_;
|
||||
|
||||
/**
|
||||
* @function module:browser.supportsHVLineContainerBBox
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const supportsHVLineContainerBBox = () => supportsHVLineContainerBBox_;
|
||||
export const isTouch = () => isTouch_
|
||||
|
||||
/**
|
||||
* @function module:browser.supportsGoodTextCharPos
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const supportsGoodTextCharPos = () => supportsGoodTextCharPos_;
|
||||
|
||||
/**
|
||||
* @function module:browser.supportsNonScalingStroke
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const supportsNonScalingStroke = () => supportsNonScalingStroke_;
|
||||
|
||||
export const supportsGoodTextCharPos = () => supportsGoodTextCharPos_
|
||||
|
||||
@@ -6,30 +6,17 @@
|
||||
* @copyright 2010 Alexis Deveria, 2010 Jeff Schiller
|
||||
*/
|
||||
|
||||
import { NS } from './namespaces.js';
|
||||
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 ];
|
||||
// unused
|
||||
/*
|
||||
const unitNumMap = {
|
||||
'%': 2,
|
||||
em: 3,
|
||||
ex: 4,
|
||||
px: 5,
|
||||
cm: 6,
|
||||
mm: 7,
|
||||
in: 8,
|
||||
pt: 9,
|
||||
pc: 10
|
||||
};
|
||||
*/
|
||||
// Container of elements.
|
||||
let elementContainer_;
|
||||
let elementContainer_
|
||||
|
||||
// Stores mapping of unit type to user coordinates.
|
||||
let typeMap_ = {};
|
||||
let typeMap_ = {}
|
||||
|
||||
/**
|
||||
* @interface module:units.ElementContainer
|
||||
@@ -76,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(NS.SVG, 'svg');
|
||||
document.body.append(svg);
|
||||
const rect = document.createElementNS(NS.SVG, '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,
|
||||
@@ -100,8 +87,8 @@ export const init = function (elementContainer) {
|
||||
pc: inch / 6,
|
||||
px: 1,
|
||||
'%': 0
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Group: Unit conversion functions.
|
||||
@@ -111,9 +98,9 @@ export const init = function (elementContainer) {
|
||||
* @function module:units.getTypeMap
|
||||
* @returns {module:units.TypeMap} The unit object with values for each unit
|
||||
*/
|
||||
export const getTypeMap = function () {
|
||||
return typeMap_;
|
||||
};
|
||||
export const getTypeMap = () => {
|
||||
return typeMap_
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {GenericArray} module:units.CompareNumbers
|
||||
@@ -131,16 +118,16 @@ export const getTypeMap = function () {
|
||||
* @returns {Float|string} If a string/number was given, returns a Float. If an array, return a string
|
||||
* with comma-separated floats
|
||||
*/
|
||||
export const shortFloat = function (val) {
|
||||
const digits = elementContainer_.getRoundDigits();
|
||||
export const shortFloat = (val) => {
|
||||
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.
|
||||
@@ -149,13 +136,13 @@ export const shortFloat = function (val) {
|
||||
* @param {"em"|"ex"|"in"|"cm"|"mm"|"pt"|"pc"|"px"|"%"} [unit]
|
||||
* @returns {Float}
|
||||
*/
|
||||
export const convertUnit = function (val, unit) {
|
||||
unit = unit || elementContainer_.getBaseUnit();
|
||||
export const convertUnit = (val, unit) => {
|
||||
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.
|
||||
@@ -166,51 +153,20 @@ export const convertUnit = function (val, unit) {
|
||||
* @param {string} val - Attribute value to convert
|
||||
* @returns {void}
|
||||
*/
|
||||
export const setUnitAttr = function (elem, attr, val) {
|
||||
// if (!isNaN(val)) {
|
||||
// New value is a number, so check currently used unit
|
||||
// const oldVal = elem.getAttribute(attr);
|
||||
|
||||
// Enable this for alternate mode
|
||||
// if (oldVal !== null && (isNaN(oldVal) || elementContainer_.getBaseUnit() !== 'px')) {
|
||||
// // Old value was a number, so get unit, then convert
|
||||
// let unit;
|
||||
// if (oldVal.substr(-1) === '%') {
|
||||
// const res = getResolution();
|
||||
// unit = '%';
|
||||
// val *= 100;
|
||||
// if (wAttrs.includes(attr)) {
|
||||
// val = val / res.w;
|
||||
// } else if (hAttrs.includes(attr)) {
|
||||
// val = val / res.h;
|
||||
// } else {
|
||||
// return val / Math.sqrt((res.w*res.w) + (res.h*res.h))/Math.sqrt(2);
|
||||
// }
|
||||
// } else {
|
||||
// if (elementContainer_.getBaseUnit() !== 'px') {
|
||||
// unit = elementContainer_.getBaseUnit();
|
||||
// } else {
|
||||
// unit = oldVal.substr(-2);
|
||||
// }
|
||||
// val = val / typeMap_[unit];
|
||||
// }
|
||||
//
|
||||
// val += unit;
|
||||
// }
|
||||
// }
|
||||
elem.setAttribute(attr, val);
|
||||
};
|
||||
export const setUnitAttr = (elem, 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.
|
||||
@@ -218,19 +174,19 @@ const attrsToConvert = {
|
||||
* @param {Element} element - A DOM element whose attributes should be converted
|
||||
* @returns {void}
|
||||
*/
|
||||
export const convertAttrs = function (element) {
|
||||
const elName = element.tagName;
|
||||
const unit = elementContainer_.getBaseUnit();
|
||||
const attrs = attrsToConvert[elName];
|
||||
if (!attrs) { return; }
|
||||
export const convertAttrs = (element) => {
|
||||
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
|
||||
@@ -241,28 +197,28 @@ export const convertAttrs = function (element) {
|
||||
* @param {string} val - Attribute value to convert
|
||||
* @returns {Float} The converted number
|
||||
*/
|
||||
export const convertToNum = function (attr, val) {
|
||||
export const convertToNum = (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.
|
||||
@@ -272,33 +228,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,5 +1,4 @@
|
||||
// eslint-disable-next-line node/no-unpublished-import
|
||||
import { mergeDeep } from './components/jgraduate/Util.js';
|
||||
import { mergeDeep } from './components/jgraduate/Util.js'
|
||||
|
||||
/**
|
||||
* Escapes special characters in a regular expression.
|
||||
@@ -9,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
|
||||
*/
|
||||
@@ -48,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
|
||||
@@ -122,7 +121,7 @@ export default class ConfigObj {
|
||||
text: {
|
||||
stroke_width: 0,
|
||||
font_size: 24,
|
||||
font_family: 'serif'
|
||||
font_family: 'Serif'
|
||||
},
|
||||
initOpacity: 1,
|
||||
initTool: 'select',
|
||||
@@ -135,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,
|
||||
@@ -159,31 +158,31 @@ 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[]}
|
||||
*/
|
||||
this.defaultExtensions = [
|
||||
'ext-connector',
|
||||
// 'ext-connector',
|
||||
'ext-eyedropper',
|
||||
'ext-grid',
|
||||
'ext-imagelib',
|
||||
// 'ext-arrows',
|
||||
// 'ext-markers',
|
||||
'ext-overview_window',
|
||||
'ext-markers',
|
||||
// 'ext-overview_window', disabled until we fix performance issue
|
||||
'ext-panning',
|
||||
'ext-shapes',
|
||||
'ext-polystar',
|
||||
'ext-storage',
|
||||
'ext-opensave'
|
||||
];
|
||||
]
|
||||
this.curConfig = {
|
||||
// We do not put on defaultConfig to simplify object copying
|
||||
// procedures (we obtain instead from defaultExtensions)
|
||||
@@ -204,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) {
|
||||
@@ -266,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');
|
||||
if (src && src.startsWith('data:')) {
|
||||
source = src;
|
||||
const src = searchParams.get('source')
|
||||
if (src?.startsWith('data:')) {
|
||||
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
|
||||
@@ -334,7 +337,7 @@ export default class ConfigObj {
|
||||
!(/(?:^|;\s*)svgeditstore=(?:prefsAndContent|prefsOnly)/).test(document.cookie)
|
||||
)
|
||||
) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// LOAD CONTENT
|
||||
@@ -344,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]) : ''
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -403,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
|
||||
@@ -476,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 (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") {
|
||||
if (!this.editor.customExportPDF && !chrome) {
|
||||
openExportWindow();
|
||||
)
|
||||
}
|
||||
this.editor.svgCanvas.exportPDF(exportWindowName);
|
||||
const chrome = isChrome()
|
||||
if (imgType === 'PDF') {
|
||||
if (!this.editor.customExportPDF && !chrome) {
|
||||
openExportWindow()
|
||||
}
|
||||
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,149 +202,129 @@ class MainMenu {
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
clickImport() {
|
||||
/* empty fn */
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @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}
|
||||
*/
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
openHomePage() {
|
||||
window.open(homePage, "_blank");
|
||||
openHomePage () {
|
||||
window.open(homePage, '_blank')
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {module}
|
||||
*/
|
||||
init() {
|
||||
init () {
|
||||
// add Top panel
|
||||
const template = document.createElement("template");
|
||||
const { i18next } = this.editor;
|
||||
const { imgPath } = this.editor.configObj.curConfig;
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<se-menu id="main_button" label="SVG-Edit" src="${imgPath}/logo.svg" alt="logo">
|
||||
<se-menu-item id="tool_import" label="${i18next.t('tools.import_doc')}" src="${imgPath}/importImg.svg"></se-menu-item>
|
||||
<se-menu-item id="tool_export" label="${i18next.t('tools.export_img')}" src="${imgPath}/export.svg"></se-menu-item>
|
||||
<se-menu-item id="tool_docprops" label="${i18next.t('tools.docprops')}" shortcut="D" src="${imgPath}/docprop.svg"></se-menu-item>
|
||||
<se-menu-item id="tool_editor_prefs" label="${i18next.t('config.editor_prefs')}" src="${imgPath}/editPref.svg"></se-menu-item>
|
||||
<se-menu-item id="tool_editor_homepage" label="${i18next.t('tools.editor_homepage')}" src="${imgPath}/logo.svg"></se-menu-item>
|
||||
</se-menu>
|
||||
`;
|
||||
$id('tools_top').prepend(template.content.cloneNode(true));
|
||||
<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))
|
||||
|
||||
// register action to main menu entries
|
||||
/**
|
||||
* Associate all button actions as well as non-button keyboard shortcuts.
|
||||
*/
|
||||
|
||||
$id("tool_import").addEventListener("click", () => {
|
||||
this.clickImport();
|
||||
window.dispatchEvent(new CustomEvent("importImages"));
|
||||
});
|
||||
$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.js';
|
||||
import { getTypeMap } from '../common/units.js'
|
||||
import rulersTemplate from './templates/rulersTemplate.html'
|
||||
import SvgCanvas from '../svgcanvas/svgcanvas.js'
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -9,38 +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
|
||||
this.editor.$svgEditor.append(rulersTemplate.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
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,166 +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);
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
$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;
|
||||
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.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':
|
||||
// These elements don't have fill or stroke, so don't change
|
||||
// the current value
|
||||
return null;
|
||||
return null
|
||||
case 'g':
|
||||
case 'a': {
|
||||
const childs = selectedElement.getElementsByTagName('*');
|
||||
const childs = selectedElement.getElementsByTagName('*')
|
||||
|
||||
let gPaint = null;
|
||||
let gPaint = null
|
||||
for (let i = 0, len = childs.length; i < len; i++) {
|
||||
const elem = childs[i];
|
||||
const p = elem.getAttribute(type);
|
||||
const elem = childs[i]
|
||||
const p = elem.getAttribute(type)
|
||||
if (i === 0) {
|
||||
gPaint = p;
|
||||
gPaint = p
|
||||
} else if (gPaint !== p) {
|
||||
gPaint = null;
|
||||
break;
|
||||
gPaint = null
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (gPaint === null) {
|
||||
// No common color, don't update anything
|
||||
this._paintColor = null;
|
||||
return null;
|
||||
this._paintColor = null
|
||||
return null
|
||||
}
|
||||
this._paintColor = gPaint;
|
||||
this._paintOpacity = 1;
|
||||
break;
|
||||
this._paintColor = gPaint
|
||||
this._paintOpacity = 1
|
||||
break
|
||||
} default: {
|
||||
this._paintOpacity = Number.parseFloat(selectedElement.getAttribute(type + '-opacity'));
|
||||
this._paintOpacity = Number.parseFloat(selectedElement.getAttribute(type + '-opacity'))
|
||||
if (Number.isNaN(this._paintOpacity)) {
|
||||
this._paintOpacity = 1.0;
|
||||
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,12 +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 './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'
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/* eslint-disable max-len */
|
||||
/* eslint-disable no-bitwise */
|
||||
/**
|
||||
* @external Math
|
||||
*/
|
||||
@@ -10,17 +8,9 @@
|
||||
* @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`.
|
||||
* @param {any} val
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isNullish = (val) => {
|
||||
return val === null || val === undefined;
|
||||
};
|
||||
/**
|
||||
* Controls for all the input elements for the typing in color values.
|
||||
*/
|
||||
@@ -32,8 +22,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
|
||||
/**
|
||||
*
|
||||
@@ -41,95 +31,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 && ((bindedHex && e.target !== bindedHex) || !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;
|
||||
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;
|
||||
red.value = setValueInRange.call(that, (red.value << 0) - 1, 0, 255)
|
||||
color.val('r', red.value, e.target)
|
||||
return false
|
||||
}
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
green.value = setValueInRange.call(that, (green.value << 0) - 1, 0, 255)
|
||||
color.val('g', green.value, e.target)
|
||||
return false
|
||||
}
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
blue.value = setValueInRange.call(that, (blue.value << 0) - 1, 0, 255)
|
||||
color.val('b', blue.value, e.target)
|
||||
return false
|
||||
}
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
hue.value = setValueInRange.call(that, (hue.value << 0) - 1, 0, 360)
|
||||
color.val('h', hue.value, e.target)
|
||||
return false
|
||||
}
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
saturation.value = setValueInRange.call(that, (saturation.value << 0) - 1, 0, 100)
|
||||
color.val('s', saturation.value, e.target)
|
||||
return false
|
||||
}
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
value.value = setValueInRange.call(that, (value.value << 0) - 1, 0, 100)
|
||||
color.val('v', value.value, e.target)
|
||||
return false
|
||||
}
|
||||
break;
|
||||
break
|
||||
}
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
// input box key up - validate value and set color
|
||||
/**
|
||||
@@ -139,54 +129,54 @@ 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;
|
||||
((bindedHex && e.target !== bindedHex) ||
|
||||
!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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
ahex.value = ahex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 2)
|
||||
color.val('a', 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,46 +184,46 @@ export default class ColorValuePicker {
|
||||
* @returns {void}
|
||||
*/
|
||||
function blur (e) {
|
||||
if (!isNullish(color.value)) {
|
||||
if (color.value) {
|
||||
switch (e.target) {
|
||||
case red:
|
||||
color.value = 'r';
|
||||
red.value = color.value;
|
||||
break;
|
||||
color.value = 'r'
|
||||
red.value = color.value
|
||||
break
|
||||
case green:
|
||||
color.value = 'g';
|
||||
green.value = color.value;
|
||||
break;
|
||||
color.value = 'g'
|
||||
green.value = color.value
|
||||
break
|
||||
case blue:
|
||||
color.value = 'b';
|
||||
blue.value = color.value;
|
||||
break;
|
||||
color.value = 'b'
|
||||
blue.value = color.value
|
||||
break
|
||||
case alpha:
|
||||
color.value = 'a';
|
||||
alpha.value = toFixedNumeric((color.value * 100) / 255, alphaPrecision);
|
||||
break;
|
||||
color.value = 'a'
|
||||
alpha.value = toFixedNumeric((color.value * 100) / 255, alphaPrecision)
|
||||
break
|
||||
case hue:
|
||||
color.value = 'h';
|
||||
hue.value = color.value;
|
||||
break;
|
||||
color.value = 'h'
|
||||
hue.value = color.value
|
||||
break
|
||||
case saturation:
|
||||
color.value = 's';
|
||||
saturation.value = color.value;
|
||||
break;
|
||||
color.value = 's'
|
||||
saturation.value = color.value
|
||||
break
|
||||
case value:
|
||||
color.value = 'v';
|
||||
value.value = color.value;
|
||||
break;
|
||||
color.value = 'v'
|
||||
value.value = color.value
|
||||
break
|
||||
case hex:
|
||||
case bindedHex:
|
||||
color.value = 'hex';
|
||||
hex.value = color.value;
|
||||
bindedHex.value = color.value;
|
||||
break;
|
||||
color.value = 'hex'
|
||||
hex.value = color.value
|
||||
bindedHex.value = color.value
|
||||
break
|
||||
case ahex:
|
||||
color.value = 'ahex';
|
||||
ahex.value = color.value.substring(6);
|
||||
break;
|
||||
color.value = 'ahex'
|
||||
ahex.value = color.value.substring(6)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -248,12 +238,12 @@ export default class ColorValuePicker {
|
||||
case 29:
|
||||
case 37:
|
||||
case 39:
|
||||
return false;
|
||||
return false
|
||||
case 'c'.charCodeAt():
|
||||
case 'v'.charCodeAt():
|
||||
if (e.ctrlKey) return false;
|
||||
if (e.ctrlKey) return false
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,10 +254,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
|
||||
@@ -275,117 +265,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 = (all ? all.r : '')
|
||||
if (context !== green) green.value = (all ? all.g : '')
|
||||
if (context !== blue) blue.value = (all ? all.b : '')
|
||||
if (alpha && context !== alpha) alpha.value = (all ? toFixedNumeric((all.a * 100) / 255, alphaPrecision) : '')
|
||||
if (context !== hue) hue.value = (all ? all.h : '')
|
||||
if (context !== saturation) saturation.value = (all ? all.s : '')
|
||||
if (context !== value) value.value = (all ? all.v : '')
|
||||
if (context !== hex && ((bindedHex && context !== bindedHex) || !bindedHex)) hex.value = (all ? all.hex : '')
|
||||
if (bindedHex && context !== bindedHex && context !== hex) bindedHex.value = (all ? all.hex : '')
|
||||
if (ahex && context !== ahex) ahex.value = (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,13 +1,12 @@
|
||||
/* eslint-disable no-bitwise */
|
||||
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.
|
||||
@@ -19,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
|
||||
@@ -27,8 +26,8 @@ export default class Slider {
|
||||
*/
|
||||
function fireChangeEvents (context) {
|
||||
changeEvents.forEach((changeEvent) => {
|
||||
changeEvent.call(that, that, context);
|
||||
});
|
||||
changeEvent.call(that, that, context)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,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.
|
||||
@@ -55,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.
|
||||
@@ -69,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
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,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
|
||||
});
|
||||
})
|
||||
}
|
||||
/**
|
||||
*
|
||||
@@ -102,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'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,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 'x': return x
|
||||
case 'y': return y
|
||||
case 'xy':
|
||||
default: return { x, y };
|
||||
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;
|
||||
newX = (value && ((value.x && value.x | 0) || value | 0)) || 0
|
||||
break
|
||||
case 'y':
|
||||
newY = (value && ((value.y && value.y | 0) || value | 0)) || 0;
|
||||
break;
|
||||
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;
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,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 '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 };
|
||||
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;
|
||||
newMinX = (value && ((value.minX && value.minX | 0) || value | 0)) || 0
|
||||
break
|
||||
case 'maxx':
|
||||
newMaxX = (value && ((value.maxX && value.maxX | 0) || value | 0)) || 0;
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
newMinY = (value && ((value.minY && value.minY | 0) || value | 0)) || 0
|
||||
break
|
||||
case 'maxy':
|
||||
newMaxY = (value && ((value.maxY && value.maxY | 0) || value | 0)) || 0;
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
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) { // eslint-disable-line promise/prefer-await-to-callbacks
|
||||
if (typeof callback === 'function') changeEvents.push(callback);
|
||||
function bind (callback) {
|
||||
if (typeof callback === 'function') changeEvents.push(callback)
|
||||
}
|
||||
/**
|
||||
* @param {GenericCallback} callback
|
||||
* @returns {void}
|
||||
*/
|
||||
function unbind (callback) { // eslint-disable-line promise/prefer-await-to-callbacks
|
||||
if (typeof callback !== 'function') return;
|
||||
let i;
|
||||
while ((i = changeEvents.includes(callback))) changeEvents.splice(i, 1);
|
||||
function unbind (callback) {
|
||||
if (typeof callback !== 'function') return
|
||||
let i
|
||||
while ((i = changeEvents.includes(callback))) changeEvents.splice(i, 1)
|
||||
}
|
||||
/**
|
||||
*
|
||||
@@ -300,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,117 +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 = [];
|
||||
let firstChar;
|
||||
if ( selector ) {
|
||||
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
|
||||
if ( parents.length === 0 ) {
|
||||
return null;
|
||||
} else {
|
||||
return parents;
|
||||
}
|
||||
return parents.length ? parents : null
|
||||
}
|
||||
|
||||
export function getParentsUntil(elem, parent, selector) {
|
||||
const parents = [];
|
||||
let parentType;
|
||||
let selectorType;
|
||||
if ( parent ) {
|
||||
parentType = parent.charAt(0);
|
||||
}
|
||||
if ( selector ) {
|
||||
selectorType = 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
|
||||
if ( parents.length === 0 ) {
|
||||
return null;
|
||||
} else {
|
||||
return parents;
|
||||
}
|
||||
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,73 +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;
|
||||
break
|
||||
case 'solidColor':
|
||||
this.solidColor = options.copy.solidColor;
|
||||
break;
|
||||
this.solidColor = options.copy.solidColor
|
||||
break
|
||||
case 'linearGradient':
|
||||
this.linearGradient = options.copy.linearGradient.cloneNode(true);
|
||||
break;
|
||||
this.linearGradient = options.copy.linearGradient.cloneNode(true)
|
||||
break
|
||||
case 'radialGradient':
|
||||
this.radialGradient = options.copy.radialGradient.cloneNode(true);
|
||||
break;
|
||||
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;
|
||||
this.linearGradient = options.linearGradient.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)
|
||||
}
|
||||
// create linear gradient paint
|
||||
} else if (options.radialGradient) {
|
||||
this.type = 'radialGradient';
|
||||
this.solidColor = null;
|
||||
this.linearGradient = null;
|
||||
this.radialGradient = options.radialGradient.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)
|
||||
}
|
||||
// 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,5 +1,6 @@
|
||||
const template = document.createElement('template');
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
/* globals svgEditor */
|
||||
import { t } from '../locale.js'
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
:host(:hover) :not(.disabled)
|
||||
@@ -10,7 +11,7 @@ template.innerHTML = `
|
||||
{
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin: 2px 1px 4px;
|
||||
margin: 4px 1px 4px;
|
||||
padding: 3px;
|
||||
background-color: var(--icon-bg-color);
|
||||
cursor: pointer;
|
||||
@@ -38,7 +39,7 @@ template.innerHTML = `
|
||||
<div title="title">
|
||||
<img alt="icon">
|
||||
</div>
|
||||
`;
|
||||
`
|
||||
/**
|
||||
* @class ToolButton
|
||||
*/
|
||||
@@ -47,21 +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.$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
|
||||
@@ -70,53 +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', `${newValue} ${shortcut ? `[${shortcut}]` : ''}`);
|
||||
const shortcut = this.getAttribute('shortcut')
|
||||
this.$div.setAttribute('title', `${t(newValue)} ${shortcut ? `[${t(shortcut)}]` : ''}`)
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'style':
|
||||
this.$div.style = newValue;
|
||||
break;
|
||||
this.$div.style = newValue
|
||||
break
|
||||
case 'src':
|
||||
this.$img.setAttribute('src', newValue);
|
||||
break;
|
||||
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');
|
||||
this.$div.classList.remove('pressed')
|
||||
} else {
|
||||
this.$div.classList.add('pressed');
|
||||
this.$div.classList.add('pressed')
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'size':
|
||||
if (newValue === 'small') {
|
||||
this.$div.classList.add('small');
|
||||
this.$div.classList.add('small')
|
||||
} else {
|
||||
this.$div.classList.remove('small');
|
||||
this.$div.classList.remove('small')
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'disabled':
|
||||
if (newValue) {
|
||||
this.$div.classList.add('disabled');
|
||||
this.$div.classList.add('disabled')
|
||||
} else {
|
||||
this.$div.classList.remove('disabled');
|
||||
this.$div.classList.remove('disabled')
|
||||
}
|
||||
break;
|
||||
break
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get title () {
|
||||
return this.getAttribute('title');
|
||||
return this.getAttribute('title')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,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')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,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')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,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')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,7 +190,7 @@ export class ToolButton extends HTMLElement {
|
||||
* @returns {void}
|
||||
*/
|
||||
set src (value) {
|
||||
this.setAttribute('src', value);
|
||||
this.setAttribute('src', value)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,7 +198,7 @@ export class ToolButton extends HTMLElement {
|
||||
* @returns {any}
|
||||
*/
|
||||
get size () {
|
||||
return this.getAttribute('size');
|
||||
return this.getAttribute('size')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,7 +206,7 @@ export class ToolButton extends HTMLElement {
|
||||
* @returns {void}
|
||||
*/
|
||||
set size (value) {
|
||||
this.setAttribute('size', value);
|
||||
this.setAttribute('size', value)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,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 @@
|
||||
/* eslint-disable max-len */
|
||||
import { jGraduate, jGraduateMethod } from './jgraduate/jQuery.jGraduate.js';
|
||||
import PaintBox from './PaintBox.js';
|
||||
/* globals svgEditor */
|
||||
import { jGraduate, jGraduateMethod } from './jgraduate/jQuery.jGraduate.js'
|
||||
import PaintBox from './PaintBox.js'
|
||||
import { t } from '../locale.js'
|
||||
|
||||
const template = document.createElement('template');
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
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,34 +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._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', i18next.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
|
||||
@@ -690,32 +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', newValue);
|
||||
break;
|
||||
this.$logo.setAttribute('src', this.imgPath + '/' + newValue)
|
||||
break
|
||||
case 'label':
|
||||
this.setAttribute('title', newValue);
|
||||
break;
|
||||
this.setAttribute('title', t(newValue))
|
||||
break
|
||||
case 'type':
|
||||
this.$label.setAttribute('title', 'config.pick_paint_opavity');
|
||||
break;
|
||||
this.$label.setAttribute('title', 'config.pick_paint_opavity')
|
||||
break
|
||||
case 'config-change_xxx_color':
|
||||
this.$label.setAttribute('title', newValue);
|
||||
break;
|
||||
this.$label.setAttribute('title', newValue)
|
||||
break
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
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: {
|
||||
const changeEvent = new CustomEvent('change', {
|
||||
detail: {
|
||||
paint
|
||||
} });
|
||||
this.dispatchEvent(changeEvent);
|
||||
}
|
||||
})
|
||||
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 = new jGraduate.Paint(p)
|
||||
this.setPaint(paint)
|
||||
const changeEvent = new CustomEvent('change', {
|
||||
detail: {
|
||||
paint
|
||||
} });
|
||||
this.dispatchEvent(changeEvent);
|
||||
this.$color_picker.style.display = 'none';
|
||||
}
|
||||
})
|
||||
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':
|
||||
// this.$span.setAttribute('title', `${newValue} ${shortcut ? `[${shortcut}]` : ''}`);
|
||||
break;
|
||||
break
|
||||
case 'src':
|
||||
this.src = newValue;
|
||||
break;
|
||||
this.src = newValue
|
||||
break
|
||||
case 'inputsize':
|
||||
this.inputsize = newValue;
|
||||
break;
|
||||
this.inputsize = newValue
|
||||
break
|
||||
default:
|
||||
super.attributeChangedCallback(name, oldValue, newValue);
|
||||
break;
|
||||
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,5 +1,5 @@
|
||||
/* eslint-disable no-unsanitized/property */
|
||||
const template = document.createElement('template');
|
||||
/* globals svgEditor */
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
:host {
|
||||
@@ -97,7 +97,7 @@ template.innerHTML = `
|
||||
</div>
|
||||
</div>
|
||||
|
||||
`;
|
||||
`
|
||||
/**
|
||||
* @class ExplorerButton
|
||||
*/
|
||||
@@ -106,27 +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.$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
|
||||
@@ -135,57 +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}]`);
|
||||
const shortcut = this.getAttribute('shortcut')
|
||||
this.$button.setAttribute('title', `${newValue} [${shortcut}]`)
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'pressed':
|
||||
if (newValue) {
|
||||
this.$overall.classList.add('pressed');
|
||||
this.$overall.classList.add('pressed')
|
||||
} else {
|
||||
this.$overall.classList.remove('pressed');
|
||||
this.$overall.classList.remove('pressed')
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'disabled':
|
||||
if (newValue) {
|
||||
this.$overall.classList.add('disabled');
|
||||
this.$overall.classList.add('disabled')
|
||||
} else {
|
||||
this.$overall.classList.remove('disabled');
|
||||
this.$overall.classList.remove('disabled')
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'lib':
|
||||
try {
|
||||
const response = await fetch(`${newValue}index.json`);
|
||||
const json = await response.json();
|
||||
const { lib } = json;
|
||||
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]);
|
||||
)).join('')
|
||||
await this.updateLib(lib[0])
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
console.error(error)
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'src':
|
||||
this.$img.setAttribute('src', newValue);
|
||||
break;
|
||||
this.$img.setAttribute('src', this.imgPath + '/' + newValue)
|
||||
break
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
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,75 +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;
|
||||
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');
|
||||
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;
|
||||
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');
|
||||
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);
|
||||
this._shadowRoot.querySelectorAll('.menu > .pressed').forEach((b) => { b.classList.remove('pressed') })
|
||||
ev.target.classList.add('pressed')
|
||||
this.updateLib(ev.target.dataset.menu)
|
||||
}
|
||||
break;
|
||||
break
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('unknown nodeName for:', ev.target, ev.target.className);
|
||||
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) {
|
||||
// eslint-disable-next-line no-console
|
||||
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,4 +1,6 @@
|
||||
const template = document.createElement('template');
|
||||
/* globals svgEditor */
|
||||
import { t } from '../locale.js'
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
:host {
|
||||
@@ -77,7 +79,7 @@ template.innerHTML = `
|
||||
|
||||
</div>
|
||||
|
||||
`;
|
||||
`
|
||||
/**
|
||||
* @class FlyingButton
|
||||
*/
|
||||
@@ -86,27 +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.$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
|
||||
@@ -115,47 +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', `${newValue} [${shortcut}]`);
|
||||
const shortcut = this.getAttribute('shortcut')
|
||||
this.$button.setAttribute('title', `${t(newValue)} ${shortcut ? `[${t(shortcut)}]` : ''}`)
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'pressed':
|
||||
if (newValue) {
|
||||
this.$overall.classList.add('pressed');
|
||||
this.$overall.classList.add('pressed')
|
||||
} else {
|
||||
this.$overall.classList.remove('pressed');
|
||||
this.$overall.classList.remove('pressed')
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'opened':
|
||||
if (newValue) {
|
||||
this.$menu.classList.add('open');
|
||||
this.$menu.classList.add('open')
|
||||
} else {
|
||||
this.$menu.classList.remove('open');
|
||||
this.$menu.classList.remove('open')
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'disabled':
|
||||
if (newValue) {
|
||||
this.$overall.classList.add('disabled');
|
||||
this.$overall.classList.add('disabled')
|
||||
} else {
|
||||
this.$overall.classList.remove('disabled');
|
||||
this.$overall.classList.remove('disabled')
|
||||
}
|
||||
break;
|
||||
break
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get title () {
|
||||
return this.getAttribute('title');
|
||||
return this.getAttribute('title')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,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')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -180,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')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -202,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')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,61 +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 () {
|
||||
// initialize currentAction with the first slot of the list
|
||||
this.activeSlot = this.shadowRoot.querySelector('slot').assignedElements()[0];
|
||||
this.$img.setAttribute('src', 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');
|
||||
this.setAttribute('opened', 'opened')
|
||||
} else {
|
||||
// launch current action
|
||||
this.activeSlot.click();
|
||||
this.setAttribute('pressed', 'pressed');
|
||||
this.activeSlot.click()
|
||||
this.setAttribute('pressed', 'pressed')
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 'SE-BUTTON':
|
||||
// change to the current action
|
||||
this.$img.setAttribute('src', ev.target.getAttribute('src'));
|
||||
this.activeSlot = ev.target;
|
||||
this.setAttribute('pressed', 'pressed');
|
||||
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;
|
||||
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');
|
||||
this.removeAttribute('opened')
|
||||
} else {
|
||||
this.setAttribute('opened', 'opened');
|
||||
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";
|
||||
const rect = this.getBoundingClientRect()
|
||||
this.$menu.style.top = rect.top + 'px'
|
||||
}
|
||||
break;
|
||||
break
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('unkonw nodeName for:', ev.target, ev.target.className);
|
||||
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,6 +1,7 @@
|
||||
import 'elix/define/Input.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 {
|
||||
@@ -23,6 +24,7 @@ template.innerHTML = `
|
||||
elix-input {
|
||||
background-color: var(--input-color);
|
||||
border-radius: 3px;
|
||||
height: 24px;
|
||||
}
|
||||
</style>
|
||||
<div>
|
||||
@@ -30,7 +32,7 @@ template.innerHTML = `
|
||||
<span id="label">label</span>
|
||||
<elix-input></elix-input>
|
||||
</div>
|
||||
`;
|
||||
`
|
||||
|
||||
/**
|
||||
* @class SEInput
|
||||
@@ -40,23 +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.$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' ];
|
||||
return ['value', 'label', 'src', 'size', 'title']
|
||||
}
|
||||
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
* @param {string} name
|
||||
@@ -65,34 +70,53 @@ 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;
|
||||
this.$img.setAttribute('src', newValue)
|
||||
this.$label.remove()
|
||||
break
|
||||
case 'size':
|
||||
this.$input.setAttribute('size', newValue);
|
||||
break;
|
||||
this.$input.setAttribute('size', newValue)
|
||||
break
|
||||
case 'label':
|
||||
this.$label.textContent = newValue;
|
||||
this.$img.remove();
|
||||
break;
|
||||
this.$label.textContent = t(newValue)
|
||||
this.$img.remove()
|
||||
break
|
||||
case 'value':
|
||||
this.$input.value = newValue;
|
||||
break;
|
||||
this.$input.value = newValue
|
||||
break
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get title () {
|
||||
return this.getAttribute('title')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set title (value) {
|
||||
this.setAttribute('title', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get label () {
|
||||
return this.getAttribute('label');
|
||||
return this.getAttribute('label')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,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
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,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')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,7 +156,7 @@ export class SEInput extends HTMLElement {
|
||||
* @returns {void}
|
||||
*/
|
||||
set src (value) {
|
||||
this.setAttribute('src', value);
|
||||
this.setAttribute('src', value)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,7 +164,7 @@ export class SEInput extends HTMLElement {
|
||||
* @returns {any}
|
||||
*/
|
||||
get size () {
|
||||
return this.getAttribute('size');
|
||||
return this.getAttribute('size')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,7 +172,7 @@ export class SEInput extends HTMLElement {
|
||||
* @returns {void}
|
||||
*/
|
||||
set size (value) {
|
||||
this.setAttribute('size', value);
|
||||
this.setAttribute('size', value)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,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,6 +1,8 @@
|
||||
import 'elix/define/DropdownList.js';
|
||||
/* globals svgEditor */
|
||||
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 {
|
||||
@@ -11,7 +13,11 @@ elix-dropdown-list:hover {
|
||||
background-color: var(--icon-bg-color-hover);
|
||||
}
|
||||
|
||||
::part(popup-toggle) {
|
||||
elix-dropdown-list::part(value) {
|
||||
background-color: var(--main-bg-color);
|
||||
}
|
||||
|
||||
elix-dropdown-list::part(popup-toggle) {
|
||||
display: none;
|
||||
}
|
||||
::slotted(*) {
|
||||
@@ -24,7 +30,7 @@ elix-dropdown-list:hover {
|
||||
<slot></slot>
|
||||
</elix-dropdown-list>
|
||||
|
||||
`;
|
||||
`
|
||||
/**
|
||||
* @class SeList
|
||||
*/
|
||||
@@ -33,19 +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._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' ];
|
||||
return ['label', 'width', 'height', 'title', 'value']
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,29 +66,67 @@ export class SeList extends HTMLElement {
|
||||
* @returns {void}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
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 = newValue;
|
||||
break;
|
||||
this.$label.textContent = t(newValue)
|
||||
break
|
||||
case 'height':
|
||||
this.$dropdown.style.height = newValue;
|
||||
break;
|
||||
this.$dropdown.style.height = newValue
|
||||
break
|
||||
case 'width':
|
||||
this.$dropdown.style.width = newValue;
|
||||
break;
|
||||
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'))
|
||||
}
|
||||
}
|
||||
})
|
||||
break
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
break;
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get title () {
|
||||
return this.getAttribute('title')
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set title (value) {
|
||||
this.setAttribute('title', value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get label () {
|
||||
return this.getAttribute('label');
|
||||
return this.getAttribute('label')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,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')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,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')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,30 +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;
|
||||
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)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user