@seliseblocks/mailcraft 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DOCS.md +4 -3
- package/README.md +4 -1
- package/README.md.txt +4 -1
- package/dist/mailcraft-editor.bundle.js +57 -54
- package/dist/mailcraft-editor.bundle.js.map +3 -3
- package/examples/vanilla.html +19 -18
- package/package.json +1 -1
- package/src/core/brand.js +81 -0
- package/src/core/editor-core.js +41 -8
- package/src/core/export.js +8 -1
- package/src/core/i18n/ar.js +2 -2
- package/src/core/i18n/bg.js +2 -2
- package/src/core/i18n/bn.js +2 -2
- package/src/core/i18n/ca.js +2 -2
- package/src/core/i18n/cs.js +2 -2
- package/src/core/i18n/da.js +2 -2
- package/src/core/i18n/de-CH.js +2 -2
- package/src/core/i18n/de.js +2 -2
- package/src/core/i18n/dz.js +2 -2
- package/src/core/i18n/el.js +2 -2
- package/src/core/i18n/en.js +2 -2
- package/src/core/i18n/es.js +2 -2
- package/src/core/i18n/et.js +2 -2
- package/src/core/i18n/fi.js +2 -2
- package/src/core/i18n/fr.js +2 -2
- package/src/core/i18n/hr.js +2 -2
- package/src/core/i18n/hu.js +2 -2
- package/src/core/i18n/it.js +2 -2
- package/src/core/i18n/lt.js +2 -2
- package/src/core/i18n/lv.js +2 -2
- package/src/core/i18n/nb.js +2 -2
- package/src/core/i18n/nl.js +2 -2
- package/src/core/i18n/pl.js +2 -2
- package/src/core/i18n/pt.js +2 -2
- package/src/core/i18n/ro.js +2 -2
- package/src/core/i18n/ru.js +2 -2
- package/src/core/i18n/sk.js +2 -2
- package/src/core/i18n/sl.js +2 -2
- package/src/core/i18n/sv.js +2 -2
- package/src/core/i18n/tr.js +2 -2
- package/src/core/i18n/uk.js +2 -2
- package/src/core/icons.js +1 -0
- package/src/core/import-html.js +63 -9
- package/src/core/sanitize.js +34 -0
- package/src/core/theme.js +1 -1
- package/src/mailcraft-editor.js +20 -10
- package/src/render/block-body.js +12 -6
- package/src/render/canvas.js +7 -1
- package/src/render/fields.js +9 -1
- package/src/render/screenshot.js +13 -2
- package/src/render/style.js +14 -11
package/examples/vanilla.html
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<title>MailCraft — live demo</title>
|
|
7
|
-
<meta name="description" content="A host application embedding the MailCraft email editor: host-owned theme, locale, brand colour, typography and template gallery." />
|
|
8
|
-
<link rel="icon" href="
|
|
6
|
+
<title>Blocks MailCraft — live demo</title>
|
|
7
|
+
<meta name="description" content="A host application embedding the Blocks MailCraft email editor: host-owned theme, locale, brand colour, typography and template gallery." />
|
|
8
|
+
<link rel="icon" href="../assets/brand/icon.svg" media="(prefers-color-scheme: light)">
|
|
9
|
+
<link rel="icon" href="../assets/brand/icon-white.svg" media="(prefers-color-scheme: dark)">
|
|
9
10
|
<style>
|
|
10
11
|
/* The host app's brand color, as a design token -- exactly where a real
|
|
11
12
|
app keeps it. The editor is pointed at it with accent="var(--brand)".
|
|
@@ -59,8 +60,11 @@
|
|
|
59
60
|
flex: none; display: flex; align-items: center; gap: 18px; height: 56px; padding: 0 18px;
|
|
60
61
|
background: var(--surface); border-bottom: 1px solid var(--line-soft);
|
|
61
62
|
}
|
|
62
|
-
.brand { display: flex; align-items: center;
|
|
63
|
-
.brand-
|
|
63
|
+
.brand { display: flex; align-items: center; text-decoration: none; }
|
|
64
|
+
.brand-logo { width: auto; display: block; }
|
|
65
|
+
.logo-dark { display: none; }
|
|
66
|
+
[data-theme="dark"] .logo-light, .dark .logo-light { display: none; }
|
|
67
|
+
[data-theme="dark"] .logo-dark, .dark .logo-dark { display: block; }
|
|
64
68
|
.tag {
|
|
65
69
|
font-size: 10.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
|
|
66
70
|
color: var(--brand); background: var(--surface-2);
|
|
@@ -104,7 +108,7 @@
|
|
|
104
108
|
input[type="color"] { width: 34px; padding: 2px; }
|
|
105
109
|
|
|
106
110
|
@media (max-width: 780px) {
|
|
107
|
-
.tag
|
|
111
|
+
.tag { display: none; }
|
|
108
112
|
.topbar, .controls { gap: 12px; padding: 0 12px; }
|
|
109
113
|
}
|
|
110
114
|
</style>
|
|
@@ -118,21 +122,18 @@
|
|
|
118
122
|
pushed into the editor as attributes -- the editor never asks. -->
|
|
119
123
|
<header class="topbar">
|
|
120
124
|
<a class="brand" id="home-link" href="../README.md">
|
|
121
|
-
<
|
|
122
|
-
|
|
123
|
-
<rect x="7" y="9.5" width="18" height="13" rx="2.2" fill="none" stroke="#fff" stroke-width="2.2" />
|
|
124
|
-
<path d="M7 11.5 16 18l9-6.5" fill="none" stroke="#fff" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" />
|
|
125
|
-
</svg>
|
|
126
|
-
<span class="brand-name">MailCraft</span>
|
|
125
|
+
<img class="brand-logo logo-light" src="../assets/brand/blocks-mailcraft-light.svg" alt="Blocks MailCraft" height="34">
|
|
126
|
+
<img class="brand-logo logo-dark" src="../assets/brand/blocks-mailcraft-dark.svg" alt="Blocks MailCraft" height="34">
|
|
127
127
|
</a>
|
|
128
128
|
<span class="tag">Live demo</span>
|
|
129
129
|
|
|
130
|
-
<!-- Menu. The
|
|
131
|
-
|
|
132
|
-
disk,
|
|
130
|
+
<!-- Menu. The doc links are resolved at runtime (see the script at the
|
|
131
|
+
foot of the file): the .md sources when this file is opened straight
|
|
132
|
+
off disk, the Jekyll-built .html pages once the same file is served
|
|
133
|
+
from GitHub Pages. The logo is the way back to the homepage. -->
|
|
133
134
|
<nav class="menu" aria-label="Primary">
|
|
134
|
-
<a id="
|
|
135
|
-
<a id="
|
|
135
|
+
<a id="quickstart-link" href="../README.md">Quick start</a>
|
|
136
|
+
<a id="docs-link" href="../DOCS.md">Guide</a>
|
|
136
137
|
<!-- No GitHub link while the repository is private -- it 404s for anyone
|
|
137
138
|
outside the org. Restore it when the repo goes public. -->
|
|
138
139
|
<a href="https://www.npmjs.com/package/@seliseblocks/mailcraft" rel="noopener">npm</a>
|
|
@@ -1443,7 +1444,7 @@
|
|
|
1443
1444
|
// One check keeps both links live instead of picking a winner.
|
|
1444
1445
|
if (location.protocol !== 'file:') {
|
|
1445
1446
|
document.getElementById('docs-link').href = '../DOCS.html';
|
|
1446
|
-
document.getElementById('
|
|
1447
|
+
document.getElementById('quickstart-link').href = '../README.html';
|
|
1447
1448
|
document.getElementById('home-link').href = '../';
|
|
1448
1449
|
}
|
|
1449
1450
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blocks MailCraft brand artwork, inline.
|
|
3
|
+
*
|
|
4
|
+
* The editor ships as one self-contained bundle, so the logo cannot be an
|
|
5
|
+
* external file the way it is on the site -- these are the official vectors
|
|
6
|
+
* (assets/brand/) transcribed as path data. Two pieces:
|
|
7
|
+
*
|
|
8
|
+
* MARK the standalone Blocks mark, on its own 245.455 x 360 canvas
|
|
9
|
+
* LOCKUP the full "Blocks MailCraft" logo, mark plus wordmark, on the
|
|
10
|
+
* 557 x 200 canvas the official product lockups use
|
|
11
|
+
*
|
|
12
|
+
* Colour comes from --ed-logo-mark / --ed-logo-text (see render/style.js), not
|
|
13
|
+
* from currentColor: a logo must not be recoloured by the host's brand
|
|
14
|
+
* attribute the way the rest of the accent-driven chrome is.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
18
|
+
|
|
19
|
+
const MARK = [
|
|
20
|
+
'M245.455 68.1627V129.877L168.982 156.67V93.9638L245.455 68.1627Z',
|
|
21
|
+
'M240.389 62.3805L165.49 87.6573L5.30933 24.2563L85.3314 0L240.389 62.3805Z',
|
|
22
|
+
'M161.797 93.8295V156.43L81.1141 122.607V188.07L0 152.738V29.6846L161.797 93.8295Z',
|
|
23
|
+
'M76.4728 266.036L0 291.837V230.123L76.4728 203.329V266.036Z',
|
|
24
|
+
'M160.123 360L5.07178 297.619L79.964 272.343L240.145 335.744L160.123 360Z',
|
|
25
|
+
'M245.454 330.315L83.657 266.17V203.57L164.34 237.393V171.93L245.454 207.262V330.315Z',
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
const LOCKUP_MARK = [
|
|
29
|
+
'M137 38.4761V73.3121L94.3168 88.4361V53.0401L137 38.4761Z',
|
|
30
|
+
'M134.173 35.212L92.368 49.48L2.9635 13.692L47.6276 0L134.173 35.212Z',
|
|
31
|
+
'M90.3067 52.9639V88.2999L45.2737 69.2079V106.16L0 86.2159V16.7559L90.3067 52.9639Z',
|
|
32
|
+
'M42.6832 146.96L0 161.524V126.688L42.6832 111.564V146.96Z',
|
|
33
|
+
'M89.3723 200L2.83105 164.788L44.632 150.52L134.036 186.308L89.3723 200Z',
|
|
34
|
+
'M137 183.244L46.6932 147.036V111.7L91.7263 130.792V93.8398L137 113.784V183.244Z',
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
const LOCKUP_TEXT = [
|
|
38
|
+
'M198.375 79.4375H210.781C214.323 79.4375 216.896 78.7708 218.5 77.4375C220.125 76.1042 220.938 74.2188 220.938 71.7812V71.6875C220.938 70.0208 220.635 68.5938 220.031 67.4062C219.448 66.1979 218.521 65.2708 217.25 64.625C215.979 63.9792 214.344 63.6562 212.344 63.6562H198.375V58.6875H212.344C214.99 58.6875 216.979 58.0833 218.312 56.875C219.667 55.6667 220.344 53.875 220.344 51.5C220.344 49.0208 219.604 47.1667 218.125 45.9375C216.646 44.7083 214.427 44.0938 211.469 44.0938H198.375V39.0625H212.531C215.469 39.0625 217.927 39.5625 219.906 40.5625C221.885 41.5625 223.365 42.9792 224.344 44.8125C225.323 46.6458 225.812 48.8333 225.812 51.375C225.812 52.9167 225.51 54.375 224.906 55.75C224.302 57.1042 223.375 58.2708 222.125 59.25C220.896 60.2292 219.365 60.8854 217.531 61.2188C219.365 61.4896 220.948 62.1458 222.281 63.1875C223.615 64.2083 224.635 65.4896 225.344 67.0312C226.052 68.5729 226.406 70.2396 226.406 72.0312V72.125C226.406 74.5833 225.865 76.75 224.781 78.625C223.698 80.5 222.146 81.9479 220.125 82.9688C218.104 83.9896 215.75 84.5 213.062 84.5H198.375V79.4375ZM194.625 39.0625H200.062V84.5H194.625V39.0625ZM240.11 76.0312C240.11 77.1146 240.36 77.9583 240.86 78.5625C241.381 79.1458 242.1 79.4375 243.016 79.4375H246.016V84.5625H242.266C239.85 84.5625 237.975 83.8125 236.641 82.3125C235.329 80.8125 234.673 78.6979 234.673 75.9688V39.0625H240.11V76.0312ZM265.033 84.9688C262.22 84.9688 259.814 84.4167 257.814 83.3125C255.814 82.2083 254.283 80.6042 253.22 78.5C252.178 76.375 251.658 73.8229 251.658 70.8438V65.5625C251.658 62.625 252.178 60.1146 253.22 58.0312C254.283 55.9271 255.814 54.3333 257.814 53.25C259.814 52.1458 262.22 51.5938 265.033 51.5938C267.845 51.5938 270.251 52.1458 272.251 53.25C274.251 54.3333 275.772 55.9271 276.814 58.0312C277.876 60.1146 278.408 62.625 278.408 65.5625V70.9375C278.408 73.8958 277.876 76.4271 276.814 78.5312C275.772 80.6146 274.251 82.2083 272.251 83.3125C270.251 84.4167 267.845 84.9688 265.033 84.9688ZM265.033 79.8438C267.553 79.8438 269.501 79.0625 270.876 77.5C272.272 75.9375 272.97 73.75 272.97 70.9375V65.5625C272.97 62.75 272.272 60.5729 270.876 59.0312C269.501 57.4896 267.553 56.7188 265.033 56.7188C262.512 56.7188 260.553 57.4896 259.158 59.0312C257.783 60.5729 257.095 62.75 257.095 65.5625V70.9375C257.095 73.75 257.783 75.9375 259.158 77.5C260.553 79.0625 262.512 79.8438 265.033 79.8438ZM299.924 84.9688C296.882 84.9688 294.32 84.4375 292.236 83.375C290.153 82.2917 288.57 80.7083 287.486 78.625C286.424 76.5208 285.893 73.9375 285.893 70.875V65.5312C285.893 62.5104 286.424 59.9688 287.486 57.9062C288.57 55.8229 290.153 54.25 292.236 53.1875C294.32 52.125 296.882 51.5938 299.924 51.5938C301.653 51.5938 303.257 51.7917 304.736 52.1875C306.215 52.5833 307.538 53.1667 308.705 53.9375C309.872 54.6875 310.861 55.6354 311.674 56.7812L307.705 60.3125C306.705 59.125 305.549 58.2292 304.236 57.625C302.924 57.0208 301.518 56.7188 300.018 56.7188C297.184 56.7188 295.028 57.4688 293.549 58.9688C292.07 60.4479 291.33 62.6354 291.33 65.5312V70.875C291.33 73.8125 292.07 76.0417 293.549 77.5625C295.028 79.0833 297.184 79.8438 300.018 79.8438C301.58 79.8438 303.028 79.5417 304.361 78.9375C305.715 78.3125 306.903 77.4062 307.924 76.2188L311.674 79.875C310.84 80.9792 309.84 81.9167 308.674 82.6875C307.507 83.4375 306.184 84.0104 304.705 84.4062C303.247 84.7812 301.653 84.9688 299.924 84.9688ZM321.065 72.8125L338.596 52.0625H345.003L320.409 79.75L321.065 72.8125ZM318.065 39.0625H323.503V84.5H318.065V39.0625ZM329.409 66.3438L332.784 62.0938L346.596 84.5H340.409L329.409 66.3438ZM362.613 84.9688C360.779 84.9688 359.029 84.7917 357.363 84.4375C355.717 84.0625 354.165 83.5208 352.706 82.8125C351.269 82.1042 349.967 81.2396 348.8 80.2188L351.988 76.3125C353.758 77.5625 355.55 78.5208 357.363 79.1875C359.175 79.8542 360.925 80.1875 362.613 80.1875C365.425 80.1875 367.571 79.7292 369.05 78.8125C370.529 77.875 371.269 76.5312 371.269 74.7812C371.269 73.5521 370.894 72.6354 370.144 72.0312C369.394 71.4062 368.446 70.9896 367.3 70.7812C366.175 70.5729 364.592 70.3854 362.55 70.2188C362.363 70.2188 362.165 70.2188 361.956 70.2188C361.748 70.1979 361.55 70.1771 361.363 70.1562C361.279 70.1562 361.196 70.1562 361.113 70.1562C361.029 70.1354 360.946 70.125 360.863 70.125C358.738 69.9375 356.946 69.625 355.488 69.1875C354.05 68.75 352.842 67.9375 351.863 66.75C350.904 65.5625 350.425 63.8542 350.425 61.625C350.425 59.4375 350.915 57.6042 351.894 56.125C352.873 54.625 354.31 53.5 356.206 52.75C358.102 51.9792 360.435 51.5938 363.206 51.5938C364.748 51.5938 366.258 51.7396 367.738 52.0312C369.217 52.3229 370.623 52.7604 371.956 53.3438C373.31 53.9062 374.581 54.6146 375.769 55.4688L372.55 59.3438C370.967 58.3646 369.363 57.625 367.738 57.125C366.133 56.625 364.592 56.375 363.113 56.375C360.654 56.375 358.779 56.8125 357.488 57.6875C356.196 58.5625 355.55 59.8333 355.55 61.5C355.55 62.5833 355.904 63.3958 356.613 63.9375C357.342 64.4792 358.248 64.8438 359.331 65.0312C360.415 65.1979 361.935 65.3333 363.894 65.4375C363.998 65.4583 364.102 65.4688 364.206 65.4688C364.331 65.4688 364.446 65.4792 364.55 65.5C364.613 65.5 364.675 65.5 364.738 65.5C364.8 65.5 364.863 65.5104 364.925 65.5312C367.196 65.6562 369.123 65.9479 370.706 66.4062C372.31 66.8438 373.654 67.7292 374.738 69.0625C375.821 70.375 376.363 72.2812 376.363 74.7812C376.363 77.0104 375.842 78.875 374.8 80.375C373.758 81.875 372.217 83.0208 370.175 83.8125C368.133 84.5833 365.613 84.9688 362.613 84.9688Z',
|
|
39
|
+
'M194.6250 164.5000V113.3830H209.2415L222.2737 149.9422H220.4842L233.5164 113.3830H248.1109V164.5000H238.1148V125.0732L239.0389 125.2493L226.2267 159.9677H216.5312L203.6970 125.2493L204.6211 125.0732V164.5000ZM278.3938 164.5000 277.6457 159.3443V141.6330Q277.6457 138.5822 275.6693 137.1301Q273.6928 135.6780 270.4293 135.6780Q267.5470 135.6780 264.5182 136.7854Q261.4893 137.8928 259.2231 139.8289L254.5954 133.2431Q258.5264 130.1849 262.5417 128.8941Q266.5570 127.6033 271.2286 127.6033Q278.7532 127.6033 282.9738 131.3473Q287.1945 135.0912 287.1945 141.6330V164.5000ZM267.6717 165.2407Q263.7188 165.2407 260.5725 163.7593Q257.4263 162.2778 255.6222 159.5570Q253.8180 156.8361 253.8180 153.2572Q253.8180 150.1476 255.1308 147.8778Q256.4436 145.6080 258.6071 144.3832Q260.3599 143.3418 262.5857 142.8908Q264.8115 142.4397 267.3197 142.4397H278.4378V149.5463H268.7131Q267.6130 149.5463 266.5973 149.7370Q265.5816 149.9276 264.8262 150.4703Q264.1808 150.9470 263.8105 151.6621Q263.4401 152.3771 263.4401 153.2792Q263.4401 155.2153 264.9766 156.3630Q266.5130 157.5108 269.0798 157.5108Q271.4193 157.5108 273.3628 156.5024Q275.3062 155.4940 276.4760 153.7302Q277.6457 151.9664 277.6457 149.7076L280.0586 154.8634Q278.9511 158.6476 277.0187 160.9358Q275.0862 163.2239 272.6807 164.2323Q270.2752 165.2407 267.6717 165.2407ZM293.5324 164.5000V128.3441H303.1324V164.5000ZM293.3050 122.8950V113.3830H303.4111V122.8950ZM318.5276 165.2407Q314.7654 165.2407 312.2498 162.9562Q309.7343 160.6717 309.7343 155.6847V113.3830H319.2831V153.7925Q319.2831 155.2006 319.9835 155.7947Q320.6838 156.3887 321.7912 156.3887Q322.3999 156.3887 323.0270 156.2677Q323.6540 156.1467 324.3287 155.9560V164.1113Q322.7740 164.7274 321.2522 164.9840Q319.7304 165.2407 318.5276 165.2407ZM351.5828 165.6881Q344.2856 165.6881 338.7376 162.3365Q333.1895 158.9849 330.0909 152.9565Q326.9924 146.9281 326.9924 138.9048Q326.9924 130.8816 330.0909 124.8898Q333.1895 118.8981 338.7376 115.5465Q344.2856 112.1949 351.5828 112.1949Q359.7967 112.1949 365.7518 116.2909Q371.7069 120.3868 374.3031 127.5960L364.9011 130.9990Q363.3023 126.6280 359.8811 124.1858Q356.4598 121.7436 351.5828 121.7436Q347.1458 121.7436 343.8493 123.8265Q340.5527 125.9093 338.7706 129.7265Q336.9885 133.5438 336.9885 138.9048Q336.9885 144.2659 338.7706 148.1198Q340.5527 151.9737 343.8493 154.0565Q347.1458 156.1393 351.5828 156.1393Q356.4598 156.1393 359.8811 153.6862Q363.3023 151.2330 364.9011 146.8840L374.3031 150.2650Q371.7069 157.4008 365.7518 161.5445Q359.7967 165.6881 351.5828 165.6881ZM378.8149 164.5000V128.3441H388.4883V138.1788L387.0802 138.2888Q387.2856 135.1646 388.9210 132.7554Q390.5564 130.3462 393.0060 128.9748Q395.4555 127.6033 398.0003 127.6033Q399.8411 127.6033 401.5096 128.0984Q403.1780 128.5934 404.9968 129.7302L400.3765 138.3842Q399.5991 137.8928 398.3120 137.5225Q397.0249 137.1521 395.7708 137.1521Q394.3700 137.1521 393.0573 137.6581Q391.7445 138.1642 390.7361 139.2239Q389.7277 140.2836 389.1484 141.9631Q388.8037 142.9898 388.6203 144.5886Q388.4370 146.1874 388.4370 149.2016V164.5000ZM430.7987 164.5000 430.0507 159.3443V141.6330Q430.0507 138.5822 428.0742 137.1301Q426.0977 135.6780 422.8342 135.6780Q419.9520 135.6780 416.9231 136.7854Q413.8942 137.8928 411.6280 139.8289L407.0004 133.2431Q410.9313 130.1849 414.9466 128.8941Q418.9619 127.6033 423.6336 127.6033Q431.1581 127.6033 435.3788 131.3473Q439.5994 135.0912 439.5994 141.6330V164.5000ZM420.0767 165.2407Q416.1237 165.2407 412.9775 163.7593Q409.8313 162.2778 408.0271 159.5570Q406.2230 156.8361 406.2230 153.2572Q406.2230 150.1476 407.5358 147.8778Q408.8485 145.6080 411.0120 144.3832Q412.7648 143.3418 414.9906 142.8908Q417.2164 142.4397 419.7246 142.4397H430.8427V149.5463H421.1181Q420.0180 149.5463 419.0023 149.7370Q417.9865 149.9276 417.2312 150.4703Q416.5858 150.9470 416.2154 151.6621Q415.8451 152.3771 415.8451 153.2792Q415.8451 155.2153 417.3815 156.3630Q418.9179 157.5108 421.4848 157.5108Q423.8243 157.5108 425.7677 156.5024Q427.7112 155.4940 428.8809 153.7302Q430.0507 151.9664 430.0507 149.7076L432.4635 154.8634Q431.3561 158.6476 429.4236 160.9358Q427.4911 163.2239 425.0857 164.2323Q422.6802 165.2407 420.0767 165.2407ZM448.7902 164.5000V135.8027H442.3877V128.3441H448.8635V124.6772Q448.8635 119.9028 450.4403 117.2883Q452.0171 114.6738 454.6353 113.6580Q457.2535 112.6423 460.3190 112.6423Q462.6072 112.6423 464.3013 113.0603Q465.9954 113.4783 467.5429 114.2117L464.4627 121.5236Q463.7586 121.1349 462.9849 120.8782Q462.2112 120.6216 461.3898 120.6216Q459.7103 120.6216 459.0613 121.7546Q458.4123 122.8877 458.4123 124.7285V128.3441H465.9735V135.8027H458.4123V164.5000ZM483.8475 165.2407Q480.9213 165.2407 478.3435 164.1223Q475.7656 163.0039 474.2071 160.4700Q472.6487 157.9362 472.6487 153.6679V120.1522L482.3441 114.9378V150.9763Q482.3441 154.1372 483.1948 155.7617Q484.0456 157.3861 486.4877 157.3861Q487.2211 157.3861 488.1452 157.2284Q489.0693 157.0708 490.1400 156.7774V164.1333Q488.5925 164.6980 487.0341 164.9694Q485.4757 165.2407 483.8475 165.2407ZM466.1949 135.8027V128.3441H490.1400V135.8027Z',
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
function svg(viewBox, w, h) {
|
|
43
|
+
const el = document.createElementNS(SVG_NS, 'svg');
|
|
44
|
+
el.setAttribute('viewBox', viewBox);
|
|
45
|
+
el.setAttribute('width', String(Math.round(w)));
|
|
46
|
+
el.setAttribute('height', String(Math.round(h)));
|
|
47
|
+
el.setAttribute('fill', 'none');
|
|
48
|
+
el.style.display = 'block';
|
|
49
|
+
el.style.flex = 'none';
|
|
50
|
+
return el;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function fill(parent, list, paint) {
|
|
54
|
+
list.forEach((d) => {
|
|
55
|
+
const p = document.createElementNS(SVG_NS, 'path');
|
|
56
|
+
p.setAttribute('d', d);
|
|
57
|
+
p.setAttribute('fill', paint);
|
|
58
|
+
parent.appendChild(p);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The bare Blocks mark at `height` px, width from the artwork's own aspect. */
|
|
63
|
+
export function brandMark(height) {
|
|
64
|
+
const h = height || 22;
|
|
65
|
+
const el = svg('0 0 245.455 360', (h * 245.455) / 360, h);
|
|
66
|
+
el.setAttribute('role', 'img');
|
|
67
|
+
el.setAttribute('aria-label', 'Blocks');
|
|
68
|
+
fill(el, MARK, 'var(--ed-logo-mark)');
|
|
69
|
+
return el;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** The full "Blocks MailCraft" lockup at `height` px. */
|
|
73
|
+
export function brandLockup(height) {
|
|
74
|
+
const h = height || 34;
|
|
75
|
+
const el = svg('0 0 557 200', (h * 557) / 200, h);
|
|
76
|
+
el.setAttribute('role', 'img');
|
|
77
|
+
el.setAttribute('aria-label', 'Blocks MailCraft');
|
|
78
|
+
fill(el, LOCKUP_MARK, 'var(--ed-logo-mark)');
|
|
79
|
+
fill(el, LOCKUP_TEXT, 'var(--ed-logo-text)');
|
|
80
|
+
return el;
|
|
81
|
+
}
|
package/src/core/editor-core.js
CHANGED
|
@@ -3,7 +3,7 @@ import { mk, blk, mkRow, GROUPS, LAYOUTS, migrateDoc, normalizeDoc, blankDoc } f
|
|
|
3
3
|
import { binder, decorate, group } from './binder.js';
|
|
4
4
|
import { ALL_FOLDER_ID, normalizeAsset, resolveLimits, providerProblems } from './storage.js';
|
|
5
5
|
import { validateFiles, limitsProblem } from './storage-limits.js';
|
|
6
|
-
import { migrateTokens, cleanHtml, escHtml } from './sanitize.js';
|
|
6
|
+
import { migrateTokens, cleanHtml, escHtml, linkHref } from './sanitize.js';
|
|
7
7
|
import { buildHtml as buildHtmlFn } from './export.js';
|
|
8
8
|
import { htmlToDoc } from './import-html.js';
|
|
9
9
|
import { boxCss } from './layout-style.js';
|
|
@@ -490,11 +490,16 @@ export class EditorCore {
|
|
|
490
490
|
|
|
491
491
|
applyLink = (b) => {
|
|
492
492
|
const d = this.state.linkDraft; if (!d) return;
|
|
493
|
-
|
|
493
|
+
// Normalized here rather than at render: inline links live inside the
|
|
494
|
+
// block's own HTML, which nothing re-templates, so a bare `selise.ch`
|
|
495
|
+
// typed in this dialog would be stored -- and shipped -- as a relative
|
|
496
|
+
// URL that resolves against the mail client instead of the site.
|
|
497
|
+
const href = linkHref(d.href);
|
|
498
|
+
this.exec('createLink', href);
|
|
494
499
|
const elNode = this.editEl;
|
|
495
500
|
if (elNode) {
|
|
496
501
|
elNode.querySelectorAll('a').forEach((a) => {
|
|
497
|
-
if (a.getAttribute('href') !==
|
|
502
|
+
if (a.getAttribute('href') !== href) return;
|
|
498
503
|
if (d.blank) { a.setAttribute('target', '_blank'); a.setAttribute('rel', 'noopener'); }
|
|
499
504
|
else { a.removeAttribute('target'); a.removeAttribute('rel'); }
|
|
500
505
|
});
|
|
@@ -827,17 +832,39 @@ export class EditorCore {
|
|
|
827
832
|
};
|
|
828
833
|
}
|
|
829
834
|
|
|
830
|
-
|
|
835
|
+
/**
|
|
836
|
+
* The element whose children are the row slots, given whatever the drag
|
|
837
|
+
* listener was attached to. The row slots are children of the sheet, but the
|
|
838
|
+
* canvas's own listeners sit on the page wrapper around it, so that a drag
|
|
839
|
+
* held over the page's padding still counts as aimed at the template
|
|
840
|
+
* (canvas.js). Reading the page's children finds no slots at all, so an
|
|
841
|
+
* index derived from it came back 0 and every section landed at the top no
|
|
842
|
+
* matter where the drop line was shown. The canvas now passes its index
|
|
843
|
+
* outright; this keeps the derived path right for any other host wiring.
|
|
844
|
+
*/
|
|
845
|
+
rowSlotHost(target) {
|
|
846
|
+
if (!target || !target.getAttribute) return target || null;
|
|
847
|
+
if (target.getAttribute('data-mc-sheet') === '1') return target;
|
|
848
|
+
return (target.querySelector && target.querySelector('[data-mc-sheet="1"]')) || target;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
canvasDragOver = (e, index) => {
|
|
831
852
|
const d = this.drag; if (!d) return;
|
|
832
853
|
e.preventDefault();
|
|
833
|
-
const
|
|
834
|
-
if (this.state.rowDrop !==
|
|
854
|
+
const at = typeof index === 'number' ? index : this.indexFromPoint(this.rowSlotHost(e.currentTarget), e.clientY);
|
|
855
|
+
if (this.state.rowDrop !== at) this.setState({ rowDrop: at, drop: null });
|
|
835
856
|
};
|
|
836
857
|
|
|
837
|
-
|
|
858
|
+
/**
|
|
859
|
+
* `index` is the slot the caller already highlighted. The canvas passes it
|
|
860
|
+
* so the drop lands where the line was drawn -- one measurement, not two of
|
|
861
|
+
* them racing. Omitted (a host wiring these onto its own element), the
|
|
862
|
+
* index is derived here instead.
|
|
863
|
+
*/
|
|
864
|
+
canvasDrop = (e, index) => {
|
|
838
865
|
const d = this.drag; if (!d) return;
|
|
839
866
|
e.preventDefault();
|
|
840
|
-
|
|
867
|
+
index = typeof index === 'number' ? index : this.indexFromPoint(this.rowSlotHost(e.currentTarget), e.clientY);
|
|
841
868
|
if (d.kind === 'row') this.insertRow(d.spans, index, d.html);
|
|
842
869
|
else if (d.kind === 'move-row') this.moveRow(d.id, index);
|
|
843
870
|
else if (d.kind === 'block') this.insertBlock(d.type, null, 0, index);
|
|
@@ -1501,6 +1528,12 @@ export class EditorCore {
|
|
|
1501
1528
|
B.color('Content area background color', 'contentBg', { transparent: true, solid: '#ffffff' }),
|
|
1502
1529
|
B.range('Corner radius', 'radius', 0, 48, 1, 'px'),
|
|
1503
1530
|
B.range('Border thickness', 'borderW', 0, 12, 1, 'px'),
|
|
1531
|
+
B.sel('Drop shadow', 'shadow', [
|
|
1532
|
+
{ value: '', label: 'None' },
|
|
1533
|
+
{ value: '0 2px 8px rgba(23,32,51,0.08)', label: 'Soft' },
|
|
1534
|
+
{ value: '0 8px 28px rgba(23,32,51,0.14)', label: 'Medium' },
|
|
1535
|
+
{ value: '0 18px 48px rgba(23,32,51,0.22)', label: 'Deep' },
|
|
1536
|
+
]),
|
|
1504
1537
|
].concat(this.state.doc.theme.borderW ? [
|
|
1505
1538
|
B.sel('Border style', 'borderStyle', BORDER_STYLES),
|
|
1506
1539
|
B.color('Border color', 'borderColor'),
|
package/src/core/export.js
CHANGED
|
@@ -93,6 +93,10 @@ export function buildHtml(state, root, boxCss) {
|
|
|
93
93
|
if (!el) return '';
|
|
94
94
|
return el.outerHTML
|
|
95
95
|
.replace(/\scontenteditable="[^"]*"/g, '')
|
|
96
|
+
// Editor bookkeeping (caret restoration): a fresh random id every
|
|
97
|
+
// import, so leaving it in shipped mail also made export -> import ->
|
|
98
|
+
// export never converge byte-for-byte.
|
|
99
|
+
.replace(/\sdata-focus-key="[^"]*"/g, '')
|
|
96
100
|
.replace(/\sdata-mc-[a-z-]+="[^"]*"/g, '')
|
|
97
101
|
.replace(/\sspellcheck="[^"]*"/g, '')
|
|
98
102
|
.replace(/\sdata-(?:gramm|gramm_editor|enable-grammarly|lt-active)="[^"]*"/g, '')
|
|
@@ -157,6 +161,9 @@ export function buildHtml(state, root, boxCss) {
|
|
|
157
161
|
// `overflow:hidden` is what actually clips a row's own background to the
|
|
158
162
|
// rounded corner; without it the first and last rows paint square over it.
|
|
159
163
|
const contentShape = (t.radius ? 'border-radius:' + t.radius + 'px;overflow:hidden;' : '')
|
|
160
|
-
+ (t.borderW ? 'border:' + t.borderW + 'px ' + (t.borderStyle || 'solid') + ' ' + (t.borderColor || '#e2e2e5') + ';' : '')
|
|
164
|
+
+ (t.borderW ? 'border:' + t.borderW + 'px ' + (t.borderStyle || 'solid') + ' ' + (t.borderColor || '#e2e2e5') + ';' : '')
|
|
165
|
+
// Patchy in mail clients (Outlook drops it), but honest: what the user
|
|
166
|
+
// styled ships, and capable clients render it.
|
|
167
|
+
+ (t.shadow ? 'box-shadow:' + t.shadow + ';' : '');
|
|
161
168
|
return '<!doctype html>\n<html lang="en">\n<head>\n<meta charset="utf-8">\n<meta name="viewport" content="width=device-width,initial-scale=1">\n<meta name="color-scheme" content="light dark">\n<title>' + 'Email' + '</title>\n</head>\n<body style="margin:0;padding:0;background:' + pageBg + ';font-family:' + t.font.replace(/"/g, "'") + ';color:' + t.text + ';-webkit-font-smoothing:antialiased;">\n<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="background:' + pageBg + ';">\n <tr><td align="center" style="padding:' + pagePad + ';">\n <table role="presentation" width="' + t.width + '" cellpadding="0" cellspacing="0" border="0" style="width:' + t.width + 'px;max-width:100%;background:' + (t.contentBg || 'transparent') + ';' + contentShape + '">\n' + rows + '\n </table>\n </td></tr>\n</table>\n</body>\n</html>';
|
|
162
169
|
}
|
package/src/core/i18n/ar.js
CHANGED
|
@@ -81,7 +81,7 @@ export const AR = {
|
|
|
81
81
|
'rows.hintStack': 'تكديس حر: بدون تخطيطات — كل كتلة تسحبها تصبح قسمًا مستقلًا بعرض كامل، مرتبة بالتسلسل.',
|
|
82
82
|
|
|
83
83
|
'files.libraryCount': 'المكتبة — {count} ملفات',
|
|
84
|
-
'files.openManager': 'فتح
|
|
84
|
+
'files.openManager': 'فتح مكتبة الوسائط',
|
|
85
85
|
'files.dragToCanvas': 'اسحب أي ملف مباشرة إلى اللوحة لوضعه كصورة.',
|
|
86
86
|
|
|
87
87
|
'layers.structure': 'البنية',
|
|
@@ -100,7 +100,7 @@ export const AR = {
|
|
|
100
100
|
'vars.noneDeclared': 'لم يُعرِّف تطبيقك أي متغيرات بعد.',
|
|
101
101
|
'vars.rteHint': 'أثناء تحرير النص يمكنك أيضًا اختيار متغير من القائمة المنسدلة في شريط الأدوات المضمّن.',
|
|
102
102
|
|
|
103
|
-
'modal.fileManager': '
|
|
103
|
+
'modal.fileManager': 'مكتبة الوسائط',
|
|
104
104
|
'modal.assetsTitle': 'الأصول',
|
|
105
105
|
'modal.replaceImage': 'استبدال الصورة',
|
|
106
106
|
'library.searchPlaceholder': 'بحث في الملفات…',
|
package/src/core/i18n/bg.js
CHANGED
|
@@ -66,7 +66,7 @@ export const BG = {
|
|
|
66
66
|
'Базирано на секции: първо пуснете оформление, после блокове в неговите колони — всяка секция има собствен фон, рамка, flex или grid настройки.',
|
|
67
67
|
'rows.hintStack': 'Свободно подреждане: без оформления — всеки пуснат блок става собствена секция на цялата ширина, подредена по ред.',
|
|
68
68
|
'files.libraryCount': 'Библиотека — {count} файла',
|
|
69
|
-
'files.openManager': 'Отваряне на
|
|
69
|
+
'files.openManager': 'Отваряне на медийната библиотека',
|
|
70
70
|
'files.dragToCanvas': 'Плъзнете произволен файл директно върху платното, за да го поставите като блок с изображение.',
|
|
71
71
|
'layers.structure': 'Структура',
|
|
72
72
|
'layers.sectionSingle': 'Секция',
|
|
@@ -82,7 +82,7 @@ export const BG = {
|
|
|
82
82
|
'vars.noMatch': 'Няма променлива, отговаряща на този филтър.',
|
|
83
83
|
'vars.noneDeclared': 'Вашето приложение все още не е декларирало променливи.',
|
|
84
84
|
'vars.rteHint': 'При редактиране на текст можете да изберете променлива и директно от падащото меню на вградената лента с инструменти.',
|
|
85
|
-
'modal.fileManager': '
|
|
85
|
+
'modal.fileManager': 'Медийна библиотека',
|
|
86
86
|
'modal.assetsTitle': 'Ресурси',
|
|
87
87
|
'modal.replaceImage': 'Замяна на изображение',
|
|
88
88
|
'library.searchPlaceholder': 'Търсене на файлове…',
|
package/src/core/i18n/bn.js
CHANGED
|
@@ -80,7 +80,7 @@ export const BN = {
|
|
|
80
80
|
'rows.hintStack': 'ফ্রি স্ট্যাক: লেআউট ছাড়াই — আপনি যে ব্লকই রাখুন না কেন তা নিজেই একটি পূর্ণ-প্রস্থ সেকশন হয়ে ক্রমানুসারে সাজে।',
|
|
81
81
|
|
|
82
82
|
'files.libraryCount': 'লাইব্রেরি — {count}টি ফাইল',
|
|
83
|
-
'files.openManager': '
|
|
83
|
+
'files.openManager': 'মিডিয়া লাইব্রেরি খুলুন',
|
|
84
84
|
'files.dragToCanvas': 'একটি ইমেজ ব্লক হিসেবে বসাতে যেকোনো ফাইল সরাসরি ক্যানভাসে টেনে আনুন।',
|
|
85
85
|
|
|
86
86
|
'layers.structure': 'কাঠামো',
|
|
@@ -99,7 +99,7 @@ export const BN = {
|
|
|
99
99
|
'vars.noneDeclared': 'আপনার অ্যাপ্লিকেশন এখনো কোনো ভেরিয়েবল ঘোষণা করেনি।',
|
|
100
100
|
'vars.rteHint': 'টেক্সট সম্পাদনার সময় আপনি ইনলাইন টুলবারের ড্রপডাউন থেকেও ভেরিয়েবল বেছে নিতে পারেন।',
|
|
101
101
|
|
|
102
|
-
'modal.fileManager': '
|
|
102
|
+
'modal.fileManager': 'মিডিয়া লাইব্রেরি',
|
|
103
103
|
'modal.assetsTitle': 'অ্যাসেট',
|
|
104
104
|
'modal.replaceImage': 'ইমেজ প্রতিস্থাপন করুন',
|
|
105
105
|
'library.searchPlaceholder': 'ফাইল খুঁজুন…',
|
package/src/core/i18n/ca.js
CHANGED
|
@@ -66,7 +66,7 @@ export const CA = {
|
|
|
66
66
|
'Basat en seccions: primer deixeu anar un disseny, després blocs a les seves columnes — cada secció té el seu propi fons, vora, configuració flex o de graella.',
|
|
67
67
|
'rows.hintStack': 'Pila lliure: sense dissenys — cada bloc que deixeu anar esdevé la seva pròpia secció d’amplada completa, apilada en ordre.',
|
|
68
68
|
'files.libraryCount': 'Biblioteca — {count} fitxers',
|
|
69
|
-
'files.openManager': 'Obre
|
|
69
|
+
'files.openManager': 'Obre la biblioteca multimèdia',
|
|
70
70
|
'files.dragToCanvas': 'Arrossegueu qualsevol fitxer directament al llenç per col·locar-lo com a bloc d’imatge.',
|
|
71
71
|
'layers.structure': 'Estructura',
|
|
72
72
|
'layers.sectionSingle': 'Secció',
|
|
@@ -82,7 +82,7 @@ export const CA = {
|
|
|
82
82
|
'vars.noMatch': 'Cap variable coincideix amb aquest filtre.',
|
|
83
83
|
'vars.noneDeclared': 'La vostra aplicació encara no ha declarat cap variable.',
|
|
84
84
|
'vars.rteHint': 'Mentre editeu text, també podeu triar una variable directament des del menú desplegable de la barra d’eines en línia.',
|
|
85
|
-
'modal.fileManager': '
|
|
85
|
+
'modal.fileManager': 'Biblioteca multimèdia',
|
|
86
86
|
'modal.assetsTitle': 'Recursos',
|
|
87
87
|
'modal.replaceImage': 'Substitueix la imatge',
|
|
88
88
|
'library.searchPlaceholder': 'Cerca fitxers…',
|
package/src/core/i18n/cs.js
CHANGED
|
@@ -66,7 +66,7 @@ export const CS = {
|
|
|
66
66
|
'Založeno na sekcích: nejprve umístěte rozvržení, poté bloky do jeho sloupců — každá sekce má vlastní pozadí, ohraničení, nastavení flex nebo mřížky.',
|
|
67
67
|
'rows.hintStack': 'Volný zásobník: bez rozvržení — každý umístěný blok se stane vlastní sekcí na celou šířku, seřazenou postupně.',
|
|
68
68
|
'files.libraryCount': 'Knihovna — {count} souborů',
|
|
69
|
-
'files.openManager': 'Otevřít
|
|
69
|
+
'files.openManager': 'Otevřít knihovnu médií',
|
|
70
70
|
'files.dragToCanvas': 'Přetáhněte libovolný soubor přímo na plátno a umístěte jej jako obrazový blok.',
|
|
71
71
|
'layers.structure': 'Struktura',
|
|
72
72
|
'layers.sectionSingle': 'Sekce',
|
|
@@ -82,7 +82,7 @@ export const CS = {
|
|
|
82
82
|
'vars.noMatch': 'Žádná proměnná neodpovídá tomuto filtru.',
|
|
83
83
|
'vars.noneDeclared': 'Vaše aplikace zatím nedeklarovala žádné proměnné.',
|
|
84
84
|
'vars.rteHint': 'Při úpravě textu můžete proměnnou vybrat i přímo z rozbalovací nabídky vloženého panelu nástrojů.',
|
|
85
|
-
'modal.fileManager': '
|
|
85
|
+
'modal.fileManager': 'Knihovna médií',
|
|
86
86
|
'modal.assetsTitle': 'Zdroje',
|
|
87
87
|
'modal.replaceImage': 'Nahradit obrázek',
|
|
88
88
|
'library.searchPlaceholder': 'Hledat soubory…',
|
package/src/core/i18n/da.js
CHANGED
|
@@ -66,7 +66,7 @@ export const DA = {
|
|
|
66
66
|
'Sektionsbaseret: slip et layout først, derefter blokke i dets kolonner — hver sektion har sin egen baggrund, kant, flex- eller gitterindstillinger.',
|
|
67
67
|
'rows.hintStack': 'Fri stak: uden layouts — hver blok, du slipper, bliver sin egen fuldbredde-sektion, stablet i rækkefølge.',
|
|
68
68
|
'files.libraryCount': 'Bibliotek — {count} filer',
|
|
69
|
-
'files.openManager': 'Åbn
|
|
69
|
+
'files.openManager': 'Åbn mediebibliotek',
|
|
70
70
|
'files.dragToCanvas': 'Træk en vilkårlig fil direkte til lærredet for at placere den som en billedblok.',
|
|
71
71
|
'layers.structure': 'Struktur',
|
|
72
72
|
'layers.sectionSingle': 'Sektion',
|
|
@@ -82,7 +82,7 @@ export const DA = {
|
|
|
82
82
|
'vars.noMatch': 'Ingen variabel matcher det filter.',
|
|
83
83
|
'vars.noneDeclared': 'Din applikation har endnu ikke erklæret nogen variabler.',
|
|
84
84
|
'vars.rteHint': 'Når du redigerer tekst, kan du også vælge en variabel direkte fra rullemenuen i den indlejrede værktøjslinje.',
|
|
85
|
-
'modal.fileManager': '
|
|
85
|
+
'modal.fileManager': 'Mediebibliotek',
|
|
86
86
|
'modal.assetsTitle': 'Ressourcer',
|
|
87
87
|
'modal.replaceImage': 'Erstat billede',
|
|
88
88
|
'library.searchPlaceholder': 'Søg i filer…',
|
package/src/core/i18n/de-CH.js
CHANGED
|
@@ -66,7 +66,7 @@ export const DE_CH = {
|
|
|
66
66
|
'Abschnittsbasiert: Zuerst ein Layout ablegen, dann Blöcke in seine Spalten ziehen — jeder Abschnitt hat eigene Hintergrund-, Rahmen-, Flex- oder Grid-Einstellungen.',
|
|
67
67
|
'rows.hintStack': 'Freier Stapel: Ohne Layouts — jeder abgelegte Block wird zu einem eigenen, vollbreiten Abschnitt, der Reihe nach gestapelt.',
|
|
68
68
|
'files.libraryCount': 'Bibliothek — {count} Dateien',
|
|
69
|
-
'files.openManager': '
|
|
69
|
+
'files.openManager': 'Medienbibliothek öffnen',
|
|
70
70
|
'files.dragToCanvas': 'Ziehe eine beliebige Datei direkt auf die Canvas, um sie als Bildblock einzufügen.',
|
|
71
71
|
'layers.structure': 'Struktur',
|
|
72
72
|
'layers.sectionSingle': 'Abschnitt',
|
|
@@ -82,7 +82,7 @@ export const DE_CH = {
|
|
|
82
82
|
'vars.noMatch': 'Keine Variable entspricht diesem Filter.',
|
|
83
83
|
'vars.noneDeclared': 'Deine Anwendung hat noch keine Variablen deklariert.',
|
|
84
84
|
'vars.rteHint': 'Beim Bearbeiten von Text kannst du eine Variable auch direkt aus dem Dropdown der Inline-Symbolleiste auswählen.',
|
|
85
|
-
'modal.fileManager': '
|
|
85
|
+
'modal.fileManager': 'Medienbibliothek',
|
|
86
86
|
'modal.assetsTitle': 'Assets',
|
|
87
87
|
'modal.replaceImage': 'Bild ersetzen',
|
|
88
88
|
'library.searchPlaceholder': 'Dateien suchen…',
|
package/src/core/i18n/de.js
CHANGED
|
@@ -66,7 +66,7 @@ export const DE = {
|
|
|
66
66
|
'Abschnittsbasiert: Zuerst ein Layout ablegen, dann Blöcke in seine Spalten ziehen — jeder Abschnitt hat eigene Hintergrund-, Rahmen-, Flex- oder Grid-Einstellungen.',
|
|
67
67
|
'rows.hintStack': 'Freier Stapel: Ohne Layouts — jeder abgelegte Block wird zu einem eigenen, vollbreiten Abschnitt, der Reihe nach gestapelt.',
|
|
68
68
|
'files.libraryCount': 'Bibliothek — {count} Dateien',
|
|
69
|
-
'files.openManager': '
|
|
69
|
+
'files.openManager': 'Medienbibliothek öffnen',
|
|
70
70
|
'files.dragToCanvas': 'Ziehe eine beliebige Datei direkt auf die Canvas, um sie als Bildblock einzufügen.',
|
|
71
71
|
'layers.structure': 'Struktur',
|
|
72
72
|
'layers.sectionSingle': 'Abschnitt',
|
|
@@ -82,7 +82,7 @@ export const DE = {
|
|
|
82
82
|
'vars.noMatch': 'Keine Variable entspricht diesem Filter.',
|
|
83
83
|
'vars.noneDeclared': 'Deine Anwendung hat noch keine Variablen deklariert.',
|
|
84
84
|
'vars.rteHint': 'Beim Bearbeiten von Text kannst du eine Variable auch direkt aus dem Dropdown der Inline-Symbolleiste auswählen.',
|
|
85
|
-
'modal.fileManager': '
|
|
85
|
+
'modal.fileManager': 'Medienbibliothek',
|
|
86
86
|
'modal.assetsTitle': 'Assets',
|
|
87
87
|
'modal.replaceImage': 'Bild ersetzen',
|
|
88
88
|
'library.searchPlaceholder': 'Dateien suchen…',
|
package/src/core/i18n/dz.js
CHANGED
|
@@ -83,7 +83,7 @@ export const DZ = {
|
|
|
83
83
|
'rows.hintStack': 'རང་མོས་སྤུང་ཚུལ: བཀོད་པ་མེད་པར — ཁྱོད་ཀྱིས་འདྲུད་དེ་བཙུགས་པའི་སྡེབ་ཚན་རེ་རེ་རང་སོའི་རྒྱ་ཚད་ཧྲིལ་བུའི་དབྱེ་ཚན་ཅིག་ལུ་གྱུར་ཏེ་གོ་རིམ་བཞིན་སྤུངས།',
|
|
84
84
|
|
|
85
85
|
'files.libraryCount': 'དཔེ་མཛོད — ཡིག་སྣོད་ {count}',
|
|
86
|
-
'files.openManager': '
|
|
86
|
+
'files.openManager': 'བརྡ་བརྒྱུད་དཔེ་མྫོད་ཁ་ཕྱེ',
|
|
87
87
|
'files.dragToCanvas': 'གཟུགས་བརྙན་སྡེབ་ཚན་ཅིག་སྦེ་བཙུགས་ནིའི་དོན་ལུ་ཡིག་སྣོད་ག་ནི་འབད་རུང་ཐིག་ཁྲམ་ལུ་ཐད་ཀར་འདྲུད།',
|
|
88
88
|
|
|
89
89
|
'layers.structure': 'བཀོད་པ',
|
|
@@ -102,7 +102,7 @@ export const DZ = {
|
|
|
102
102
|
'vars.noneDeclared': 'ཁྱོད་ཀྱི་ལག་ཆས་ཀྱིས་ད་ལྟོ་ཚུན་འགྱུར་ཚད་ག་ནི་ཡང་གསལ་བཀོད་མ་འབད',
|
|
103
103
|
'vars.rteHint': 'ཡི་གུ་བཟོ་བཅོས་སྐབས་ལག་ཆས་ཕྲ་མོའི་ཐོ་ཡིག་ནང་ལས་ཡང་འགྱུར་ཚད་ཅིག་འཐུ་བཏུབ།',
|
|
104
104
|
|
|
105
|
-
'modal.fileManager': '
|
|
105
|
+
'modal.fileManager': 'བརྡ་བརྒྱུད་དཔེ་མྫོད',
|
|
106
106
|
'modal.assetsTitle': 'དངོས་རིགས',
|
|
107
107
|
'modal.replaceImage': 'གཟུགས་བརྙན་ཚབ་བཙུགས',
|
|
108
108
|
'library.searchPlaceholder': 'ཡིག་སྣོད་འཚོལ…',
|
package/src/core/i18n/el.js
CHANGED
|
@@ -66,7 +66,7 @@ export const EL = {
|
|
|
66
66
|
'Βάσει ενοτήτων: αποθέστε πρώτα μια διάταξη, μετά μπλοκ στις στήλες της — κάθε ενότητα έχει το δικό της φόντο, περίγραμμα, ρυθμίσεις flex ή πλέγματος.',
|
|
67
67
|
'rows.hintStack': 'Ελεύθερη στοίβα: χωρίς διατάξεις — κάθε μπλοκ που αποθέτετε γίνεται δική του ενότητα πλήρους πλάτους, στοιβαγμένη με τη σειρά.',
|
|
68
68
|
'files.libraryCount': 'Βιβλιοθήκη — {count} αρχεία',
|
|
69
|
-
'files.openManager': 'Άνοιγμα
|
|
69
|
+
'files.openManager': 'Άνοιγμα βιβλιοθήκης πολυμέσων',
|
|
70
70
|
'files.dragToCanvas': 'Σύρετε οποιοδήποτε αρχείο απευθείας στον καμβά για να το τοποθετήσετε ως μπλοκ εικόνας.',
|
|
71
71
|
'layers.structure': 'Δομή',
|
|
72
72
|
'layers.sectionSingle': 'Ενότητα',
|
|
@@ -82,7 +82,7 @@ export const EL = {
|
|
|
82
82
|
'vars.noMatch': 'Καμία μεταβλητή δεν ταιριάζει με αυτό το φίλτρο.',
|
|
83
83
|
'vars.noneDeclared': 'Η εφαρμογή σας δεν έχει δηλώσει ακόμη μεταβλητές.',
|
|
84
84
|
'vars.rteHint': 'Κατά την επεξεργασία κειμένου, μπορείτε επίσης να επιλέξετε μια μεταβλητή απευθείας από το αναπτυσσόμενο μενού της ενσωματωμένης γραμμής εργαλείων.',
|
|
85
|
-
'modal.fileManager': '
|
|
85
|
+
'modal.fileManager': 'Βιβλιοθήκη πολυμέσων',
|
|
86
86
|
'modal.assetsTitle': 'Πόροι',
|
|
87
87
|
'modal.replaceImage': 'Αντικατάσταση εικόνας',
|
|
88
88
|
'library.searchPlaceholder': 'Αναζήτηση αρχείων…',
|
package/src/core/i18n/en.js
CHANGED
|
@@ -100,7 +100,7 @@ export const EN = {
|
|
|
100
100
|
|
|
101
101
|
// Files tab (sidebar)
|
|
102
102
|
'files.libraryCount': 'Library — {count} files',
|
|
103
|
-
'files.openManager': 'Open
|
|
103
|
+
'files.openManager': 'Open media library',
|
|
104
104
|
'files.dragToCanvas': 'Drag any file straight onto the canvas to place it as an image block.',
|
|
105
105
|
|
|
106
106
|
// Layers (Tree) tab
|
|
@@ -122,7 +122,7 @@ export const EN = {
|
|
|
122
122
|
'vars.rteHint': 'While editing text you can also pick a variable straight from the inline toolbar’s dropdown.',
|
|
123
123
|
|
|
124
124
|
// Library modal
|
|
125
|
-
'modal.fileManager': '
|
|
125
|
+
'modal.fileManager': 'Media library',
|
|
126
126
|
'modal.assetsTitle': 'Assets',
|
|
127
127
|
'modal.replaceImage': 'Replace image',
|
|
128
128
|
'library.searchPlaceholder': 'Search files…',
|
package/src/core/i18n/es.js
CHANGED
|
@@ -66,7 +66,7 @@ export const ES = {
|
|
|
66
66
|
'Basado en secciones: primero suelta un diseño, luego suelta bloques en sus columnas — cada sección tiene su propio fondo, borde, ajustes flex o de cuadrícula.',
|
|
67
67
|
'rows.hintStack': 'Pila libre: sin diseños — cada bloque que sueltas se convierte en su propia sección de ancho completo, apilada en orden.',
|
|
68
68
|
'files.libraryCount': 'Biblioteca — {count} archivos',
|
|
69
|
-
'files.openManager': 'Abrir
|
|
69
|
+
'files.openManager': 'Abrir biblioteca multimedia',
|
|
70
70
|
'files.dragToCanvas': 'Arrastra cualquier archivo directamente al lienzo para colocarlo como bloque de imagen.',
|
|
71
71
|
'layers.structure': 'Estructura',
|
|
72
72
|
'layers.sectionSingle': 'Sección',
|
|
@@ -82,7 +82,7 @@ export const ES = {
|
|
|
82
82
|
'vars.noMatch': 'Ninguna variable coincide con ese filtro.',
|
|
83
83
|
'vars.noneDeclared': 'Tu aplicación aún no ha declarado ninguna variable.',
|
|
84
84
|
'vars.rteHint': 'Al editar texto también puedes elegir una variable directamente desde el menú de la barra de herramientas en línea.',
|
|
85
|
-
'modal.fileManager': '
|
|
85
|
+
'modal.fileManager': 'Biblioteca multimedia',
|
|
86
86
|
'modal.assetsTitle': 'Recursos',
|
|
87
87
|
'modal.replaceImage': 'Reemplazar imagen',
|
|
88
88
|
'library.searchPlaceholder': 'Buscar archivos…',
|
package/src/core/i18n/et.js
CHANGED
|
@@ -66,7 +66,7 @@ export const ET = {
|
|
|
66
66
|
'Sektsioonidel põhinev: aseta esmalt paigutus, seejärel plokid selle veergudesse — igal sektsioonil on oma taust, äär, flex- või ruudustiku seaded.',
|
|
67
67
|
'rows.hintStack': 'Vaba virn: ilma paigutusteta — iga asetatud plokk saab oma täislaiuses sektsiooniks, virnastatuna järjekorras.',
|
|
68
68
|
'files.libraryCount': 'Teek — {count} faili',
|
|
69
|
-
'files.openManager': 'Ava
|
|
69
|
+
'files.openManager': 'Ava meediateek',
|
|
70
70
|
'files.dragToCanvas': 'Lohista mistahes fail otse lõuendile, et paigutada see pildiplokina.',
|
|
71
71
|
'layers.structure': 'Struktuur',
|
|
72
72
|
'layers.sectionSingle': 'Sektsioon',
|
|
@@ -82,7 +82,7 @@ export const ET = {
|
|
|
82
82
|
'vars.noMatch': 'Ükski muutuja ei vasta sellele filtrile.',
|
|
83
83
|
'vars.noneDeclared': 'Sinu rakendus pole veel muutujaid deklareerinud.',
|
|
84
84
|
'vars.rteHint': 'Teksti muutmisel saad valida muutuja ka otse sisseehitatud tööriistariba rippmenüüst.',
|
|
85
|
-
'modal.fileManager': '
|
|
85
|
+
'modal.fileManager': 'Meediateek',
|
|
86
86
|
'modal.assetsTitle': 'Ressursid',
|
|
87
87
|
'modal.replaceImage': 'Asenda pilt',
|
|
88
88
|
'library.searchPlaceholder': 'Otsi faile…',
|
package/src/core/i18n/fi.js
CHANGED
|
@@ -66,7 +66,7 @@ export const FI = {
|
|
|
66
66
|
'Osioihin perustuva: pudota ensin asettelu, sitten lohkoja sen sarakkeisiin — jokaisella osiolla on oma tausta, reunus, flex- tai ruudukkoasetukset.',
|
|
67
67
|
'rows.hintStack': 'Vapaa pino: ilman asetteluja — jokaisesta pudottamastasi lohkosta tulee oma täysleveä osio, pinottuna järjestyksessä.',
|
|
68
68
|
'files.libraryCount': 'Kirjasto — {count} tiedostoa',
|
|
69
|
-
'files.openManager': 'Avaa
|
|
69
|
+
'files.openManager': 'Avaa mediakirjasto',
|
|
70
70
|
'files.dragToCanvas': 'Vedä mikä tahansa tiedosto suoraan kankaalle asettaaksesi sen kuvalohkona.',
|
|
71
71
|
'layers.structure': 'Rakenne',
|
|
72
72
|
'layers.sectionSingle': 'Osio',
|
|
@@ -82,7 +82,7 @@ export const FI = {
|
|
|
82
82
|
'vars.noMatch': 'Yksikään muuttuja ei vastaa tätä suodatinta.',
|
|
83
83
|
'vars.noneDeclared': 'Sovelluksesi ei ole vielä määritellyt muuttujia.',
|
|
84
84
|
'vars.rteHint': 'Tekstiä muokatessasi voit myös valita muuttujan suoraan sisäisen työkalurivin pudotusvalikosta.',
|
|
85
|
-
'modal.fileManager': '
|
|
85
|
+
'modal.fileManager': 'Mediakirjasto',
|
|
86
86
|
'modal.assetsTitle': 'Resurssit',
|
|
87
87
|
'modal.replaceImage': 'Korvaa kuva',
|
|
88
88
|
'library.searchPlaceholder': 'Etsi tiedostoja…',
|
package/src/core/i18n/fr.js
CHANGED
|
@@ -66,7 +66,7 @@ export const FR = {
|
|
|
66
66
|
'Basé sur les sections : déposez d’abord une mise en page, puis des blocs dans ses colonnes — chaque section a son propre arrière-plan, sa bordure, ses réglages flex ou grille.',
|
|
67
67
|
'rows.hintStack': 'Pile libre : sans mise en page — chaque bloc déposé devient sa propre section pleine largeur, empilée dans l’ordre.',
|
|
68
68
|
'files.libraryCount': 'Bibliothèque — {count} fichiers',
|
|
69
|
-
'files.openManager': 'Ouvrir
|
|
69
|
+
'files.openManager': 'Ouvrir la médiathèque',
|
|
70
70
|
'files.dragToCanvas': 'Glissez un fichier directement sur le canevas pour le placer comme bloc image.',
|
|
71
71
|
'layers.structure': 'Structure',
|
|
72
72
|
'layers.sectionSingle': 'Section',
|
|
@@ -82,7 +82,7 @@ export const FR = {
|
|
|
82
82
|
'vars.noMatch': 'Aucune variable ne correspond à ce filtre.',
|
|
83
83
|
'vars.noneDeclared': 'Votre application n’a encore déclaré aucune variable.',
|
|
84
84
|
'vars.rteHint': 'En modifiant du texte, vous pouvez aussi choisir une variable directement dans le menu de la barre d’outils.',
|
|
85
|
-
'modal.fileManager': '
|
|
85
|
+
'modal.fileManager': 'Médiathèque',
|
|
86
86
|
'modal.assetsTitle': 'Ressources',
|
|
87
87
|
'modal.replaceImage': 'Remplacer l’image',
|
|
88
88
|
'library.searchPlaceholder': 'Rechercher des fichiers…',
|
package/src/core/i18n/hr.js
CHANGED
|
@@ -66,7 +66,7 @@ export const HR = {
|
|
|
66
66
|
'Temeljeno na odjeljcima: prvo ispustite raspored, zatim blokove u njegove stupce — svaki odjeljak ima vlastitu pozadinu, obrub, flex ili grid postavke.',
|
|
67
67
|
'rows.hintStack': 'Slobodni stog: bez rasporeda — svaki ispušteni blok postaje vlastiti odjeljak preko cijele širine, poslagan redom.',
|
|
68
68
|
'files.libraryCount': 'Knjižnica — {count} datoteka',
|
|
69
|
-
'files.openManager': 'Otvori
|
|
69
|
+
'files.openManager': 'Otvori medijsku knjižnicu',
|
|
70
70
|
'files.dragToCanvas': 'Povucite bilo koju datoteku izravno na platno da je postavite kao slikovni blok.',
|
|
71
71
|
'layers.structure': 'Struktura',
|
|
72
72
|
'layers.sectionSingle': 'Odjeljak',
|
|
@@ -82,7 +82,7 @@ export const HR = {
|
|
|
82
82
|
'vars.noMatch': 'Nijedna varijabla ne odgovara ovom filtru.',
|
|
83
83
|
'vars.noneDeclared': 'Vaša aplikacija još nije deklarirala nijednu varijablu.',
|
|
84
84
|
'vars.rteHint': 'Tijekom uređivanja teksta varijablu možete odabrati i izravno iz padajućeg izbornika ugrađene alatne trake.',
|
|
85
|
-
'modal.fileManager': '
|
|
85
|
+
'modal.fileManager': 'Medijska knjižnica',
|
|
86
86
|
'modal.assetsTitle': 'Resursi',
|
|
87
87
|
'modal.replaceImage': 'Zamijeni sliku',
|
|
88
88
|
'library.searchPlaceholder': 'Pretraži datoteke…',
|