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 @@
-
+
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 @@
-
\ No newline at end of file
+
\ 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`] = `
+
+`;
+
+exports[`use various parts of svg-edit > check tool_text_decoration_overline #0`] = `
+
+`;
+
+exports[`use various parts of svg-edit > check tool_text_decoration_linethrough #0`] = `
+
`;
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 @@
+
+
+
+
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 @@
+
+
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