From 35e6de97efd1d023d76f43e95fb6a2e9adaee110 Mon Sep 17 00:00:00 2001 From: Timo Dittmann Date: Tue, 19 Jan 2021 00:35:24 +0100 Subject: [PATCH] - Added text decoration options (underline, overline, line-through) (#469) - Added german translations to extensions Co-authored-by: Timo Dittmann --- badges/coverage-badge.svg | 2 +- badges/tests-badge.svg | 2 +- .../ui/__snapshots__/scenario.js.snap | 427 +++++++++--------- cypress/integration/ui/scenario.js | 54 ++- src/editor/extensions/ext-arrows/locale/de.js | 19 + .../extensions/ext-closepath/locale/de.js | 11 + .../extensions/ext-connector/locale/de.js | 11 + .../extensions/ext-eyedropper/locale/de.js | 9 + .../extensions/ext-foreignobject/locale/de.js | 25 + src/editor/extensions/ext-grid/locale/de.js | 8 + .../extensions/ext-helloworld/locale/de.js | 9 + .../extensions/ext-imagelib/locale/de.js | 18 +- .../extensions/ext-markers/locale/de.js | 46 ++ .../extensions/ext-mathjax/locale/de.js | 8 + .../extensions/ext-panning/locale/de.js | 8 + .../extensions/ext-placemark/locale/de.js | 40 ++ .../extensions/ext-polygon/locale/de.js | 14 + .../ext-server_moinsave/locale/de.js | 4 + .../ext-server_opensave/locale/de.js | 4 + src/editor/extensions/ext-shapes/locale/de.js | 24 + src/editor/extensions/ext-star/locale/de.js | 22 + .../extensions/ext-storage/locale/de.js | 14 +- .../extensions/ext-webappfind/locale/de.js | 8 + src/editor/images/svg_edit_icons.svg | 7 + src/editor/index.html | 21 +- src/editor/svgedit.css | 27 +- src/editor/svgedit.js | 52 +-- src/svgcanvas/elem-get-set.js | 60 +++ src/svgcanvas/sanitize.js | 2 +- src/svgcanvas/svgcanvas.js | 27 +- 30 files changed, 684 insertions(+), 299 deletions(-) create mode 100644 src/editor/extensions/ext-arrows/locale/de.js create mode 100644 src/editor/extensions/ext-closepath/locale/de.js create mode 100644 src/editor/extensions/ext-connector/locale/de.js create mode 100644 src/editor/extensions/ext-eyedropper/locale/de.js create mode 100644 src/editor/extensions/ext-foreignobject/locale/de.js create mode 100644 src/editor/extensions/ext-grid/locale/de.js create mode 100644 src/editor/extensions/ext-helloworld/locale/de.js create mode 100644 src/editor/extensions/ext-markers/locale/de.js create mode 100644 src/editor/extensions/ext-mathjax/locale/de.js create mode 100644 src/editor/extensions/ext-panning/locale/de.js create mode 100644 src/editor/extensions/ext-placemark/locale/de.js create mode 100644 src/editor/extensions/ext-polygon/locale/de.js create mode 100644 src/editor/extensions/ext-server_moinsave/locale/de.js create mode 100644 src/editor/extensions/ext-server_opensave/locale/de.js create mode 100644 src/editor/extensions/ext-shapes/locale/de.js create mode 100644 src/editor/extensions/ext-star/locale/de.js create mode 100644 src/editor/extensions/ext-webappfind/locale/de.js diff --git a/badges/coverage-badge.svg b/badges/coverage-badge.svg index c3f8392e..cc106eca 100644 --- a/badges/coverage-badge.svg +++ b/badges/coverage-badge.svg @@ -1 +1 @@ -Statements 52.95%Statements 52.95%Branches 41.89%Branches 41.89%Lines 53.76%Lines 53.76%Functions 60.47%Functions 60.47% +Statements 53.05%Statements 53.05%Branches 41.79%Branches 41.79%Lines 53.87%Lines 53.87%Functions 60.57%Functions 60.57% diff --git a/badges/tests-badge.svg b/badges/tests-badge.svg index 515cd6b9..c4904976 100644 --- a/badges/tests-badge.svg +++ b/badges/tests-badge.svg @@ -1 +1 @@ -TestsTests144/144144/144 \ No newline at end of file +TestsTests147/147147/147 \ No newline at end of file diff --git a/cypress/integration/ui/__snapshots__/scenario.js.snap b/cypress/integration/ui/__snapshots__/scenario.js.snap index 99c631c3..bb8ccc0a 100644 --- a/cypress/integration/ui/__snapshots__/scenario.js.snap +++ b/cypress/integration/ui/__snapshots__/scenario.js.snap @@ -486,12 +486,13 @@ exports[`use various parts of svg-edit > check tool_star #0`] = ` id="svg_1" font-size="24" font-family="serif" - text-anchor="middle" + text-anchor="end" xml:space="preserve" fill-opacity="1" stroke-opacity="1" font-style="italic" font-weight="bold" + text-decoration=" underline overline line-through" > B @@ -522,7 +523,7 @@ exports[`use various parts of svg-edit > check tool_star #0`] = ` radialshift="" r2="5.333333333333334" orient="point" - fill="#000000" + fill="#ffff00" strokecolor="#000000" strokeWidth="0" points="407,31.666666666666664 410.1348546788932,40.68524269666695 419.68075355060205,40.87977340833403 412.0723014202408,46.64809063666639 414.83713669723295,55.78689325833263 407,50.333333333333336 399.16286330276705,55.78689325833263 401.9276985797592,46.64809063666639 394.31924644939795,40.87977340833404 403.8651453211068,40.68524269666695 407,31.666666666666664 410.1348546788932,40.68524269666695 " @@ -577,12 +578,13 @@ exports[`use various parts of svg-edit > check tool_polygon #0`] = ` id="svg_1" font-size="24" font-family="serif" - text-anchor="middle" + text-anchor="end" xml:space="preserve" fill-opacity="1" stroke-opacity="1" font-style="italic" font-weight="bold" + text-decoration=" underline overline line-through" > B @@ -613,7 +615,7 @@ exports[`use various parts of svg-edit > check tool_polygon #0`] = ` radialshift="" r2="5.333333333333334" orient="point" - fill="#000000" + fill="#ffff00" strokecolor="#000000" strokeWidth="0" points="407,31.666666666666664 410.1348546788932,40.68524269666695 419.68075355060205,40.87977340833403 412.0723014202408,46.64809063666639 414.83713669723295,55.78689325833263 407,50.333333333333336 399.16286330276705,55.78689325833263 401.9276985797592,46.64809063666639 394.31924644939795,40.87977340833404 403.8651453211068,40.68524269666695 407,31.666666666666664 410.1348546788932,40.68524269666695 " @@ -631,7 +633,7 @@ exports[`use various parts of svg-edit > check tool_polygon #0`] = ` sides="5" orient="x" edge="6.666666666666667" - fill="#000000" + fill="#ffff00" strokecolor="#000000" strokeWidth="5" points="462.6710053890136,95 458.7524370403971,100.39344662916632 452.4120602650961,98.33333333333333 452.4120602650961,91.66666666666667 458.7524370403971,89.60655337083368 462.6710053890136,95 " @@ -685,7 +687,7 @@ exports[`use various parts of svg-edit > check tool_text_anchor_start #0`] = ` id="svg_1" font-size="24" font-family="serif" - text-anchor="middle" + text-anchor="start" xml:space="preserve" fill-opacity="1" stroke-opacity="1" @@ -711,62 +713,6 @@ exports[`use various parts of svg-edit > check tool_text_anchor_start #0`] = ` > B - - - - - `; @@ -832,77 +778,6 @@ exports[`use various parts of svg-edit > check tool_text_anchor_middle #0`] = ` > B - - - - - - `; @@ -942,7 +817,7 @@ exports[`use various parts of svg-edit > check tool_text_anchor_end #0`] = ` id="svg_1" font-size="24" font-family="serif" - text-anchor="middle" + text-anchor="end" xml:space="preserve" fill-opacity="1" stroke-opacity="1" @@ -968,92 +843,204 @@ exports[`use various parts of svg-edit > check tool_text_anchor_end #0`] = ` > B - - - - - - - + + +`; + +exports[`use various parts of svg-edit > check tool_text_decoration_underline #0`] = ` + + + Layer 1 + + + B + + + B + + + +`; + +exports[`use various parts of svg-edit > check tool_text_decoration_overline #0`] = ` + + + Layer 1 + + + B + + + B + + + +`; + +exports[`use various parts of svg-edit > check tool_text_decoration_linethrough #0`] = ` + + + Layer 1 + + + B + + + B + `; diff --git a/cypress/integration/ui/scenario.js b/cypress/integration/ui/scenario.js index bdd23209..d69e0716 100644 --- a/cypress/integration/ui/scenario.js +++ b/cypress/integration/ui/scenario.js @@ -70,24 +70,6 @@ describe('use various parts of svg-edit', function () { .click({force: true}); testSnapshot(); }); - it('check tool_star', function () { - cy.get('#tool_star') - .click({force: true}); - cy.get('#svgcontent') - .trigger('mousedown', {which: 1, pageX: 600, pageY: 150, force: true}) - .trigger('mousemove', {which: 1, pageX: 600, pageY: 170, force: true}) - .trigger('mouseup', {force: true}); - cy.get('#svgcontent').toMatchSnapshot(); - }); - it('check tool_polygon', function () { - cy.get('#tool_polygon') - .click({force: true}); - cy.get('#svgcontent') - .trigger('mousedown', {which: 1, pageX: 650, pageY: 200, force: true}) - .trigger('mousemove', {which: 1, pageX: 650, pageY: 210, force: true}) - .trigger('mouseup', {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') @@ -106,4 +88,40 @@ describe('use various parts of svg-edit', function () { .click({force: true}); 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_overline', function () { + cy.get('#svg_1').click({force: true}); + cy.get('#tool_text_decoration_overline') + .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_star', function () { + cy.get('#tool_star') + .click({force: true}); + cy.get('#svgcontent') + .trigger('mousedown', {which: 1, pageX: 600, pageY: 150, force: true}) + .trigger('mousemove', {which: 1, pageX: 600, pageY: 170, force: true}) + .trigger('mouseup', {force: true}); + cy.get('#svgcontent').toMatchSnapshot(); + }); + it('check tool_polygon', function () { + cy.get('#tool_polygon') + .click({force: true}); + cy.get('#svgcontent') + .trigger('mousedown', {which: 1, pageX: 650, pageY: 200, force: true}) + .trigger('mousemove', {which: 1, pageX: 650, pageY: 210, force: true}) + .trigger('mouseup', {force: true}); + cy.get('#svgcontent').toMatchSnapshot(); + }); }); diff --git a/src/editor/extensions/ext-arrows/locale/de.js b/src/editor/extensions/ext-arrows/locale/de.js new file mode 100644 index 00000000..cd9fefad --- /dev/null +++ b/src/editor/extensions/ext-arrows/locale/de.js @@ -0,0 +1,19 @@ +export default { + name: 'Arrows', + langList: [ + {id: 'arrow_none', textContent: 'Kein Pfeil'} + ], + contextTools: [ + { + title: 'Pfeiltyp auswählen', + options: { + none: 'Kein Pfeil', + end: '---->', + start: '<----', + both: '<--->', + mid: '-->--', + mid_bk: '--<--' + } + } + ] +}; diff --git a/src/editor/extensions/ext-closepath/locale/de.js b/src/editor/extensions/ext-closepath/locale/de.js new file mode 100644 index 00000000..7406aa63 --- /dev/null +++ b/src/editor/extensions/ext-closepath/locale/de.js @@ -0,0 +1,11 @@ +export default { + name: 'ClosePath', + buttons: [ + { + title: 'Pfad öffnen' + }, + { + title: 'Pfad schließen' + } + ] +}; diff --git a/src/editor/extensions/ext-connector/locale/de.js b/src/editor/extensions/ext-connector/locale/de.js new file mode 100644 index 00000000..91b3adc7 --- /dev/null +++ b/src/editor/extensions/ext-connector/locale/de.js @@ -0,0 +1,11 @@ +export default { + name: 'Connector', + langList: [ + {id: 'mode_connect', title: 'Zwei Objekte verbinden'} + ], + buttons: [ + { + title: 'Zwei Objekte verbinden' + } + ] +}; diff --git a/src/editor/extensions/ext-eyedropper/locale/de.js b/src/editor/extensions/ext-eyedropper/locale/de.js new file mode 100644 index 00000000..46c7b5bb --- /dev/null +++ b/src/editor/extensions/ext-eyedropper/locale/de.js @@ -0,0 +1,9 @@ +export default { + name: 'eyedropper', + buttons: [ + { + title: 'Pipetten Werkzeug', + key: 'I' + } + ] +}; diff --git a/src/editor/extensions/ext-foreignobject/locale/de.js b/src/editor/extensions/ext-foreignobject/locale/de.js new file mode 100644 index 00000000..9fdac4f3 --- /dev/null +++ b/src/editor/extensions/ext-foreignobject/locale/de.js @@ -0,0 +1,25 @@ +export default { + name: 'foreignObject', + buttons: [ + { + title: 'Foreign Object Werkzeug' + }, + { + title: 'Inhalt des ForeignObject bearbeiten' + } + ], + contextTools: [ + { + title: 'Breite des ForeignObject ändern', + label: 'w' + }, + { + title: 'Höhe des ForeignObject ändern', + label: 'h' + }, + { + title: 'Schriftgröße des ForeignObject ändern', + label: 'Schriftgröße' + } + ] +}; diff --git a/src/editor/extensions/ext-grid/locale/de.js b/src/editor/extensions/ext-grid/locale/de.js new file mode 100644 index 00000000..23d80db0 --- /dev/null +++ b/src/editor/extensions/ext-grid/locale/de.js @@ -0,0 +1,8 @@ +export default { + name: 'Raster anzeigen', + buttons: [ + { + title: 'Raster anzeigen/verbergen' + } + ] +}; diff --git a/src/editor/extensions/ext-helloworld/locale/de.js b/src/editor/extensions/ext-helloworld/locale/de.js new file mode 100644 index 00000000..82bb91bf --- /dev/null +++ b/src/editor/extensions/ext-helloworld/locale/de.js @@ -0,0 +1,9 @@ +export default { + name: 'Hello World', + text: 'Hello World!\n\nSie haben hier geklickt: {x}, {y}', + buttons: [ + { + title: "Sage 'Hello World'" + } + ] +}; diff --git a/src/editor/extensions/ext-imagelib/locale/de.js b/src/editor/extensions/ext-imagelib/locale/de.js index 2a14ec96..8814a5a2 100644 --- a/src/editor/extensions/ext-imagelib/locale/de.js +++ b/src/editor/extensions/ext-imagelib/locale/de.js @@ -1,9 +1,9 @@ export default { - select_lib: 'Select an image library', - show_list: 'Show library list', - import_single: 'Import single', - import_multi: 'Import multiple', - open: 'Open as new document', + select_lib: 'Bilder Bibliothek auswählen', + show_list: 'Liste aller Bibliotheken anzeigen', + import_single: 'Einzelne importieren', + import_multi: 'Mehrere importieren', + open: 'Öffnen als neues Dokument', buttons: [ { title: 'Bilder-Bibliothek' @@ -11,14 +11,14 @@ export default { ], imgLibs: [ { - name: 'Demo library (local)', + name: 'Demo Bibliothek (lokal)', url: 'extensions/ext-imagelib/index.html', - description: 'Demonstration library for SVG-edit on this server' + description: 'Demo Bibltiothek für svg-edit auf diesem Server' }, { - name: 'IAN Symbol Libraries', + name: 'IAN Symbol Bibliothek', url: 'https://ian.umces.edu/symbols/catalog/svgedit/album_chooser.php?svgedit=3', - description: 'Free library of illustrations' + description: 'Kostenlose Bibliothek mit Illustrationen' } /* // See message in "en" locale for further details diff --git a/src/editor/extensions/ext-markers/locale/de.js b/src/editor/extensions/ext-markers/locale/de.js new file mode 100644 index 00000000..80d1841b --- /dev/null +++ b/src/editor/extensions/ext-markers/locale/de.js @@ -0,0 +1,46 @@ +export default { + name: 'Markers', + langList: [ + {id: 'nomarker', title: 'Keine Markierung'}, + {id: 'leftarrow', title: 'Pfeil links'}, + {id: 'rightarrow', title: 'Pfeil rechts'}, + {id: 'textmarker', title: 'Text Marker'}, + {id: 'forwardslash', title: 'Schrägstrich'}, + {id: 'reverseslash', title: 'Umgekehrter Schrägstrich'}, + {id: 'verticalslash', title: 'Vertikaler Strich'}, + {id: 'box', title: 'Box'}, + {id: 'star', title: 'Stern'}, + {id: 'xmark', title: 'X'}, + {id: 'triangle', title: 'Dreieck'}, + {id: 'mcircle', title: 'Kreis'}, + {id: 'leftarrow_o', title: 'Offener Pfeil links'}, + {id: 'rightarrow_o', title: 'Offener Pfeil rechts'}, + {id: 'box_o', title: 'Offene Box'}, + {id: 'star_o', title: 'Offener Stern'}, + {id: 'triangle_o', title: 'Offenes Dreieck'}, + {id: 'mcircle_o', title: 'Offener Kreis'} + ], + contextTools: [ + { + title: 'Start-Markierung', + label: 's' + }, + { + title: 'Start-Markierung auswählen' + }, + { + title: 'Mitte-Markierung', + label: 'm' + }, + { + title: 'Mitte-Markierung auswählen' + }, + { + title: 'End-Markierung', + label: 'e' + }, + { + title: 'End-Markierung auswählen' + } + ] +}; diff --git a/src/editor/extensions/ext-mathjax/locale/de.js b/src/editor/extensions/ext-mathjax/locale/de.js new file mode 100644 index 00000000..5ba092a3 --- /dev/null +++ b/src/editor/extensions/ext-mathjax/locale/de.js @@ -0,0 +1,8 @@ +export default { + name: 'MathJax', + buttons: [ + { + title: 'Mathematik hinzufügen' + } + ] +}; diff --git a/src/editor/extensions/ext-panning/locale/de.js b/src/editor/extensions/ext-panning/locale/de.js new file mode 100644 index 00000000..fb7fe849 --- /dev/null +++ b/src/editor/extensions/ext-panning/locale/de.js @@ -0,0 +1,8 @@ +export default { + name: 'Extension Panning', + buttons: [ + { + title: 'Fenster verschieben' + } + ] +}; diff --git a/src/editor/extensions/ext-placemark/locale/de.js b/src/editor/extensions/ext-placemark/locale/de.js new file mode 100644 index 00000000..b850aa79 --- /dev/null +++ b/src/editor/extensions/ext-placemark/locale/de.js @@ -0,0 +1,40 @@ +export default { + name: 'placemark', + langList: [ + {id: 'nomarker', title: 'Keine Markierung'}, + {id: 'leftarrow', title: 'Pfeil links'}, + {id: 'rightarrow', title: 'Pfeil rechts'}, + {id: 'forwardslash', title: 'Schrägstrich'}, + {id: 'reverseslash', title: 'Umgekehrter Schrägstrich'}, + {id: 'verticalslash', title: 'Vertikaler Strich'}, + {id: 'box', title: 'Box'}, + {id: 'star', title: 'Stern'}, + {id: 'xmark', title: 'X'}, + {id: 'triangle', title: 'Dreieck'}, + {id: 'mcircle', title: 'Kreis'}, + {id: 'leftarrow_o', title: 'Offener Pfeil links'}, + {id: 'rightarrow_o', title: 'Offener Pfeil rechts'}, + {id: 'box_o', title: 'Offene Box'}, + {id: 'star_o', title: 'Offener Stern'}, + {id: 'triangle_o', title: 'Offenes Dreieck'}, + {id: 'mcircle_o', title: 'Offener Kreis'} + ], + buttons: [ + { + title: 'Placemark Werkzeug' + } + ], + contextTools: [ + { + title: 'Typ der Placemark auswählen' + }, + { + title: 'Text (mehrere Texte mit Semikolon getrennt)', + label: 'Text' + }, + { + title: 'Schriftart für den Text', + label: '' + } + ] +}; diff --git a/src/editor/extensions/ext-polygon/locale/de.js b/src/editor/extensions/ext-polygon/locale/de.js new file mode 100644 index 00000000..f6b16865 --- /dev/null +++ b/src/editor/extensions/ext-polygon/locale/de.js @@ -0,0 +1,14 @@ +export default { + name: 'polygon', + buttons: [ + { + title: 'Polygon Werkzeug' + } + ], + contextTools: [ + { + title: 'Anzahl der Seiten', + label: 'Seiten' + } + ] +}; diff --git a/src/editor/extensions/ext-server_moinsave/locale/de.js b/src/editor/extensions/ext-server_moinsave/locale/de.js new file mode 100644 index 00000000..9152e7a9 --- /dev/null +++ b/src/editor/extensions/ext-server_moinsave/locale/de.js @@ -0,0 +1,4 @@ +export default { + saved: 'Gespeichert! Zurück zur Artikelansicht!', + hiddenframe: 'Moinsave frame um verdeckte Werte zu speichern' +}; diff --git a/src/editor/extensions/ext-server_opensave/locale/de.js b/src/editor/extensions/ext-server_opensave/locale/de.js new file mode 100644 index 00000000..993977ac --- /dev/null +++ b/src/editor/extensions/ext-server_opensave/locale/de.js @@ -0,0 +1,4 @@ +export default { + uploading: 'Hochladen...', + hiddenframe: 'Opensave frame um versteckte Werte zu speichern' +}; diff --git a/src/editor/extensions/ext-shapes/locale/de.js b/src/editor/extensions/ext-shapes/locale/de.js new file mode 100644 index 00000000..1f689cbc --- /dev/null +++ b/src/editor/extensions/ext-shapes/locale/de.js @@ -0,0 +1,24 @@ +export default { + loading: 'Lädt...', + categories: { + basic: 'Basis', + object: 'Objekte', + symbol: 'Symbole', + arrow: 'Pfeile', + flowchart: 'Flussdiagramm', + animal: 'Tiere', + game: 'Karten & Schach', + dialog_balloon: 'Sprechblasen', + electronics: 'Elektronik', + math: 'Mathematik', + music: 'Musik', + misc: 'Verschiedenes', + raphael_1: 'raphaeljs.com set 1', + raphael_2: 'raphaeljs.com set 2' + }, + buttons: [ + { + title: 'Form-Bibliothek' + } + ] +}; diff --git a/src/editor/extensions/ext-star/locale/de.js b/src/editor/extensions/ext-star/locale/de.js new file mode 100644 index 00000000..48f97b70 --- /dev/null +++ b/src/editor/extensions/ext-star/locale/de.js @@ -0,0 +1,22 @@ +export default { + name: 'star', + buttons: [ + { + title: 'Stern Werkzeug' + } + ], + contextTools: [ + { + title: 'Anzahl der Ecken', + label: 'Ecken' + }, + { + title: 'Schärfe', + label: 'Schärfe' + }, + { + title: 'Dreht den Stern', + label: 'Radialverschiebung' + } + ] +}; diff --git a/src/editor/extensions/ext-storage/locale/de.js b/src/editor/extensions/ext-storage/locale/de.js index d3160369..40540f00 100644 --- a/src/editor/extensions/ext-storage/locale/de.js +++ b/src/editor/extensions/ext-storage/locale/de.js @@ -4,11 +4,11 @@ export default { 'nicht jedes Mal die SVG neu laden. Falls Sie aus Datenschutzgründen ' + 'dies nicht wollen, ' + 'können Sie die Standardeinstellung im Folgenden ändern.', - storagePrefsAndContent: 'Store preferences and SVG content locally', - storagePrefsOnly: 'Only store preferences locally', - storagePrefs: 'Store preferences locally', - storageNoPrefsOrContent: 'Do not store my preferences or SVG content locally', - storageNoPrefs: 'Do not store my preferences locally', - rememberLabel: 'Remember this choice?', - rememberTooltip: 'If you choose to opt out of storage while remembering this choice, the URL will change so as to avoid asking again.' + storagePrefsAndContent: 'Voreinstellungen und SVG-Inhalte lokal speichern', + storagePrefsOnly: 'Nur Voreinstellungen lokal speichern', + storagePrefs: 'Einstellungen lokal speichern', + storageNoPrefsOrContent: 'Meine Einstellungen oder SVG-Inhalte nicht lokal speichern', + storageNoPrefs: 'Meine Einstellungen nicht lokal speichern', + rememberLabel: 'Ihre Einstellungen merken?', + rememberTooltip: 'Wenn Sie die Speicherung deaktivieren, aber die Einstellungen merken, wird die URL geändert, damit Sie nicht erneut gefragt werden.' }; diff --git a/src/editor/extensions/ext-webappfind/locale/de.js b/src/editor/extensions/ext-webappfind/locale/de.js new file mode 100644 index 00000000..b98f977d --- /dev/null +++ b/src/editor/extensions/ext-webappfind/locale/de.js @@ -0,0 +1,8 @@ +export default { + name: 'WebAppFind', + buttons: [ + { + title: 'Bild auf der Festplatte speichern' + } + ] +}; diff --git a/src/editor/images/svg_edit_icons.svg b/src/editor/images/svg_edit_icons.svg index 3eb60792..45f178f2 100644 --- a/src/editor/images/svg_edit_icons.svg +++ b/src/editor/images/svg_edit_icons.svg @@ -1069,6 +1069,13 @@ + + + ab + + + + diff --git a/src/editor/index.html b/src/editor/index.html index ad1b99e6..fb3792d0 100644 --- a/src/editor/index.html +++ b/src/editor/index.html @@ -319,12 +319,17 @@
-
-
-
B
i
+ +
diff --git a/src/editor/svgedit.css b/src/editor/svgedit.css index 355e28b0..e51a4d9e 100644 --- a/src/editor/svgedit.css +++ b/src/editor/svgedit.css @@ -776,8 +776,10 @@ span.zoom_tool { padding-right: 5px; } -#tool_bold, #tool_italic { - font: bold 2.1em/1.1em serif; +#tool_bold, +#tool_italic, +#text_decoration_opts li { + font: 2.1em/1.1em serif; text-align: center; padding-left: 2px; position: relative; @@ -788,7 +790,9 @@ span.zoom_tool { left: -9999px; } -#tool_bold span, #tool_italic span { +#tool_bold span, +#tool_italic span, +#text_decoration_opts li span{ position: absolute; width: 100%; height: 100%; @@ -797,11 +801,26 @@ span.zoom_tool { opacity: 0; } +#tool_bold { + font-weight: bold; +} + #tool_italic { - font-weight: normal; font-style: italic; } +#tool_text_decoration_underline { + text-decoration-line: underline; +} + +#tool_text_decoration_overline { + text-decoration-line: overline; +} + +#tool_text_decoration_linethrough { + text-decoration-line: line-through; +} + #url_notice { padding-top: 4px; display: none; diff --git a/src/editor/svgedit.js b/src/editor/svgedit.js index 59e81bab..88b95b2a 100644 --- a/src/editor/svgedit.js +++ b/src/editor/svgedit.js @@ -1201,6 +1201,8 @@ editor.init = () => { '#group_opacityLabel': 'opacity', '#blurLabel': 'blur', '#font_sizeLabel': 'fontsize', + '#text_anchor_icon': 'anchor_middle', + '#text_decoration_icon': 'textdecoration', '.flyout_arrow_horiz': 'arrow_right', '.dropdown button, #main_button .dropdown': 'arrow_down', @@ -2312,26 +2314,6 @@ editor.init = () => { } else { $('#tool_bold').removeClass('push_button_pressed').addClass('tool_button'); } - const textAnchorStart = $('#tool_text_anchor_start'); - const textAnchorMiddle = $('#tool_text_anchor_middle'); - const textAnchorEnd = $('#tool_text_anchor_end'); - switch (elem.getAttribute('text-anchor')) { - case 'start': - textAnchorStart.addClass('push_button_pressed').removeClass('tool_button'); - textAnchorMiddle.removeClass('push_button_pressed').addClass('tool_button'); - textAnchorEnd.removeClass('push_button_pressed').addClass('tool_button'); - break; - case 'middle': - textAnchorStart.removeClass('push_button_pressed').addClass('tool_button'); - textAnchorMiddle.addClass('push_button_pressed').removeClass('tool_button'); - textAnchorEnd.removeClass('push_button_pressed').addClass('tool_button'); - break; - case 'end': - textAnchorStart.removeClass('push_button_pressed').addClass('tool_button'); - textAnchorMiddle.removeClass('push_button_pressed').addClass('tool_button'); - textAnchorEnd.addClass('push_button_pressed').removeClass('tool_button'); - break; - } $('#font_family').val(elem.getAttribute('font-family')); $('#font_size').val(elem.getAttribute('font-size')); $('#text').val(elem.textContent); @@ -3917,6 +3899,22 @@ editor.init = () => { svgCanvas.alignSelectedElements(letter, 'page'); }, {multiclick: true}); + addAltDropDown('#tool_text_decoration', '#text_decoration_opts', function () { + const selectedTextDecoration = $(this).data('value'); + + if (svgCanvas.hasTextDecoration(selectedTextDecoration)) { + svgCanvas.removeTextDecoration(selectedTextDecoration); + } else { + svgCanvas.addTextDecoration(selectedTextDecoration); + } + }, {multiclick: true}); + + addAltDropDown('#tool_text_anchor', '#text_anchor_opts', function () { + const selectedTextAnchor = $(this).data('value'); + svgCanvas.setTextAnchor(selectedTextAnchor); + updateContextPanel(); + }, {}); + /* When a flyout icon is selected @@ -4345,17 +4343,6 @@ editor.init = () => { return false; }; - /** - * - * @param {string} value "start","end" or "middle" - * @returns {false} - */ - const clickTextAnchor = function (value) { - svgCanvas.setTextAnchor(value); - updateContextPanel(); - return false; - }; - /** * * @returns {void} @@ -5540,9 +5527,6 @@ editor.init = () => { // {sel: '#tools_ellipse_show', fn: clickEllipse, evt: 'click'}, {sel: '#tool_bold', fn: clickBold, evt: 'mousedown'}, {sel: '#tool_italic', fn: clickItalic, evt: 'mousedown'}, - {sel: '#tool_text_anchor_start', fn () { clickTextAnchor('start'); }, evt: 'mousedown'}, - {sel: '#tool_text_anchor_middle', fn () { clickTextAnchor('middle'); }, evt: 'mousedown'}, - {sel: '#tool_text_anchor_end', fn () { clickTextAnchor('end'); }, evt: 'mousedown'}, {sel: '#sidepanel_handle', fn: toggleSidePanel, key: ['X']}, {sel: '#copy_save_done', fn: cancelOverlays, evt: 'click'}, diff --git a/src/svgcanvas/elem-get-set.js b/src/svgcanvas/elem-get-set.js index 354e3355..3d08ccc7 100644 --- a/src/svgcanvas/elem-get-set.js +++ b/src/svgcanvas/elem-get-set.js @@ -607,6 +607,66 @@ isNullish(selectedElements[1])) { } }; +/** + * Checks whether the selected element has the given text decoration value or not + * @function module:svgcanvas.SvgCanvas#hasTextDecoration + * @param {string} value - The value that should be checked + * @returns {boolean} Indicates whether or not element has the text decoration value + */ +export const hasTextDecorationMethod = function (value) { + const selectedElements = elemContext_.getSelectedElements(); + const selected = selectedElements[0]; + + if (!isNullish(selected) && selected.tagName === 'text' && isNullish(selectedElements[1])) { + const attribute = selected.getAttribute('text-decoration'); + if (attribute) { + return attribute.includes(value); + } + } + + return false; +}; + +/** + * Adds the given value to the text decoration + * @function module:svgcanvas.SvgCanvas#addTextDecoration + * @param {string} value - The value that should be added + * @returns {void} + */ +export const addTextDecorationMethod = function (value) { + const selectedElements = elemContext_.getSelectedElements(); + const selected = selectedElements[0]; + + if (!isNullish(selected) && selected.tagName === 'text' && isNullish(selectedElements[1])) { + const oldValue = selected.getAttribute('text-decoration') || ''; + elemContext_.getCanvas().changeSelectedAttribute('text-decoration', oldValue + ' ' + value); + } + + if (!selectedElements[0].textContent) { + elemContext_.getCanvas().textActions.setCursor(); + } +}; + +/** + * Removes the given value from the text decoration + * @function module:svgcanvas.SvgCanvas#removeTextDecoration + * @param {string} value - The value that should be removed + * @returns {void} + */ +export const removeTextDecorationMethod = function (value) { + const selectedElements = elemContext_.getSelectedElements(); + const selected = selectedElements[0]; + + if (!isNullish(selected) && selected.tagName === 'text' && isNullish(selectedElements[1])) { + const actualValues = selected.getAttribute('text-decoration'); + elemContext_.getCanvas().changeSelectedAttribute('text-decoration', actualValues.replace(value, '')); + } + + if (!selectedElements[0].textContent) { + elemContext_.getCanvas().textActions.setCursor(); + } +}; + /** * Set the new text anchor * @function module:svgcanvas.SvgCanvas#setTextAnchor diff --git a/src/svgcanvas/sanitize.js b/src/svgcanvas/sanitize.js index 4adc68c8..94412698 100644 --- a/src/svgcanvas/sanitize.js +++ b/src/svgcanvas/sanitize.js @@ -49,7 +49,7 @@ const svgWhiteList_ = { svg: ['class', 'clip-path', 'clip-rule', 'filter', 'id', 'height', 'mask', 'preserveAspectRatio', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xmlns', 'xmlns:se', 'xmlns:xlink', 'y'], switch: ['class', 'id', 'requiredFeatures', 'systemLanguage'], symbol: ['class', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'opacity', 'preserveAspectRatio', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'viewBox'], - text: ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'transform', 'x', 'xml:space', 'y', 'display'], + text: ['class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-decoration', 'style', 'systemLanguage', 'text-anchor', 'transform', 'x', 'xml:space', 'y', 'display'], textPath: ['class', 'id', 'method', 'requiredFeatures', 'spacing', 'startOffset', 'style', 'systemLanguage', 'transform', 'xlink:href', 'display'], title: [], tspan: ['class', 'clip-path', 'clip-rule', 'dx', 'dy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'rotate', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'textLength', 'transform', 'x', 'xml:space', 'y', 'display'], diff --git a/src/svgcanvas/svgcanvas.js b/src/svgcanvas/svgcanvas.js index f8f67472..50a22900 100644 --- a/src/svgcanvas/svgcanvas.js +++ b/src/svgcanvas/svgcanvas.js @@ -57,7 +57,8 @@ import { setDocumentTitleMethod, setResolutionMethod, getEditorNSMethod, setBBoxZoomMethod, setZoomMethod, setColorMethod, setGradientMethod, findDuplicateGradient, setPaintMethod, setStrokeWidthMethod, setStrokeAttrMethod, getBoldMethod, setBoldMethod, getItalicMethod, - setItalicMethod, setTextAnchorMethod, getFontFamilyMethod, setFontFamilyMethod, setFontColorMethod, getFontColorMethod, + setItalicMethod, hasTextDecorationMethod, addTextDecorationMethod, removeTextDecorationMethod, + setTextAnchorMethod, getFontFamilyMethod, setFontFamilyMethod, setFontColorMethod, getFontColorMethod, getFontSizeMethod, setFontSizeMethod, getTextMethod, setTextContentMethod, setImageURLMethod, setLinkURLMethod, setRectRadiusMethod, makeHyperlinkMethod, removeHyperlinkMethod, setSegTypeMethod, setBackgroundMethod @@ -2215,6 +2216,30 @@ class SvgCanvas { */ this.setItalic = setItalicMethod; + /** + * Check whether selected element has the given text decoration or not. + * @function module:svgcanvas.SvgCanvas#hasTextDecoration + * @param {string} value - The value that should be checked + * @returns {boolean} Indicates whether the element has the given text decoration + */ + this.hasTextDecoration = hasTextDecorationMethod; + + /** + * Adds the given value to the text decoration. + * @function module:svgcanvas.SvgCanvas#addTextDecoration + * @param {string} value - The value that should be added + * @returns {void} + */ + this.addTextDecoration = addTextDecorationMethod; + + /** + * Removes the given value from the text decoration. + * @function module:svgcanvas.SvgCanvas#removeTextDecoration + * @param {string} value - The value that should be removed + * @returns {void} + */ + this.removeTextDecoration = removeTextDecorationMethod; + /** * Set the new text anchor. * @function module:svgcanvas.SvgCanvas#setTextAnchor