mail-editor-pancake 0.0.8 → 0.0.9
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/README.md +126 -4
- package/package.json +1 -1
- package/packages/blocks/dist/index.d.ts +12 -0
- package/packages/blocks/dist/index.js +175 -136
- package/packages/blocks/dist/index.js.map +1 -1
- package/packages/blocks/src/index.ts +2 -0
- package/packages/blocks/src/social.ts +8 -11
- package/packages/blocks/src/socialGroup.ts +8 -11
- package/packages/blocks/src/socialShared.ts +52 -0
- package/packages/core/dist/index.d.ts +56 -3
- package/packages/core/dist/index.js +1134 -942
- package/packages/core/dist/index.js.map +1 -1
- package/packages/core/dist/style.css +1 -1
- package/packages/core/src/editor/Canvas.ts +9 -0
- package/packages/core/src/editor/Editor.ts +217 -50
- package/packages/core/src/editor/InlineEditor.ts +10 -0
- package/packages/core/src/editor/styles.css +49 -8
- package/packages/core/src/index.ts +11 -0
- package/packages/core/src/types.ts +2 -0
- package/packages/core/src/utils/richHtmlInsert.ts +16 -0
- package/packages/core/src/variables/index.ts +91 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import { EditorView as
|
|
7
|
-
import { html as
|
|
8
|
-
import { EditorState as
|
|
9
|
-
class
|
|
1
|
+
var Qt = Object.defineProperty;
|
|
2
|
+
var Zt = (o, t, e) => t in o ? Qt(o, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[t] = e;
|
|
3
|
+
var _ = (o, t, e) => Zt(o, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
import te from "mjml-browser";
|
|
5
|
+
import nt from "sortablejs";
|
|
6
|
+
import { EditorView as rt, basicSetup as lt } from "codemirror";
|
|
7
|
+
import { html as ct } from "@codemirror/lang-html";
|
|
8
|
+
import { EditorState as U } from "@codemirror/state";
|
|
9
|
+
class ee {
|
|
10
10
|
constructor() {
|
|
11
|
-
|
|
11
|
+
_(this, "map", /* @__PURE__ */ new Map());
|
|
12
12
|
}
|
|
13
13
|
register(t) {
|
|
14
14
|
return this.map.has(t.type) && console.warn(`[simple-mail] block type 重复注册: ${t.type},后注册的会覆盖前者`), this.map.set(t.type, t), this;
|
|
@@ -32,20 +32,20 @@ class Xt {
|
|
|
32
32
|
createBlock(t) {
|
|
33
33
|
const e = this.require(t);
|
|
34
34
|
return {
|
|
35
|
-
id:
|
|
35
|
+
id: se(),
|
|
36
36
|
type: t,
|
|
37
37
|
props: structuredClone(e.defaultProps)
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
function
|
|
41
|
+
function se() {
|
|
42
42
|
const o = Date.now().toString(36).slice(-4), t = Math.floor(Math.random() * 36 ** 4).toString(36).padStart(4, "0");
|
|
43
43
|
return `blk_${o}${t}`;
|
|
44
44
|
}
|
|
45
|
-
function
|
|
45
|
+
function $s(o) {
|
|
46
46
|
return o;
|
|
47
47
|
}
|
|
48
|
-
function
|
|
48
|
+
function Wt(o) {
|
|
49
49
|
if (o == null || o === "") return;
|
|
50
50
|
if (typeof o == "number" && Number.isFinite(o)) {
|
|
51
51
|
const e = Math.round(o);
|
|
@@ -58,28 +58,28 @@ function jt(o) {
|
|
|
58
58
|
if (/^\d+(\.\d+)?$/.test(t)) return `${t}px`;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
function
|
|
62
|
-
return
|
|
61
|
+
function zt(o) {
|
|
62
|
+
return Wt(o) ?? "600px";
|
|
63
63
|
}
|
|
64
|
-
function
|
|
64
|
+
function ne(o) {
|
|
65
65
|
const t = o.trim();
|
|
66
66
|
return t ? /^\d+(\.\d+)?%$/.test(t) ? t : /^\d+(\.\d+)?px$/i.test(t) ? t.replace(/PX$/i, "px") : /^\d+$/.test(t) ? Number(t) : /^\d+\.\d+$/.test(t) ? `${t}px` : t : 600;
|
|
67
67
|
}
|
|
68
|
-
function
|
|
68
|
+
function ie(o) {
|
|
69
69
|
return o == null ? "600" : (typeof o == "number" && Number.isFinite(o), String(o));
|
|
70
70
|
}
|
|
71
|
-
function
|
|
71
|
+
function Ct(o) {
|
|
72
72
|
if (o == null) return;
|
|
73
73
|
const t = String(o).trim();
|
|
74
74
|
if (!(!t || t.toLowerCase() === "auto"))
|
|
75
|
-
return
|
|
75
|
+
return Wt(t);
|
|
76
76
|
}
|
|
77
|
-
function
|
|
77
|
+
function oe(o) {
|
|
78
78
|
const t = o.trim();
|
|
79
79
|
if (t)
|
|
80
80
|
return /^\d+(\.\d+)?%$/.test(t) ? t : /^\d+(\.\d+)?px$/i.test(t) ? t.replace(/PX$/i, "px") : /^\d+$/.test(t) ? Number(t) : /^\d+\.\d+$/.test(t) ? `${t}px` : t;
|
|
81
81
|
}
|
|
82
|
-
function
|
|
82
|
+
function re(o) {
|
|
83
83
|
return o == null || o === "" ? "" : (typeof o == "number" && Number.isFinite(o), String(o));
|
|
84
84
|
}
|
|
85
85
|
function r(o, t = {}, e = []) {
|
|
@@ -90,19 +90,19 @@ function r(o, t = {}, e = []) {
|
|
|
90
90
|
n == null || n === !1 || s.appendChild(typeof n == "string" ? document.createTextNode(n) : n);
|
|
91
91
|
return s;
|
|
92
92
|
}
|
|
93
|
-
function
|
|
93
|
+
function R(o) {
|
|
94
94
|
for (; o.firstChild; ) o.removeChild(o.firstChild);
|
|
95
95
|
}
|
|
96
|
-
function
|
|
96
|
+
function tt(o) {
|
|
97
97
|
return o.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
98
98
|
}
|
|
99
99
|
function $(o) {
|
|
100
|
-
return
|
|
100
|
+
return tt(o);
|
|
101
101
|
}
|
|
102
|
-
const
|
|
102
|
+
const le = ["300", "400", "500", "600", "700"], it = le.map(
|
|
103
103
|
(o) => ({ label: o, value: o })
|
|
104
104
|
);
|
|
105
|
-
function
|
|
105
|
+
function j(o) {
|
|
106
106
|
const t = String(o ?? "400").trim().toLowerCase();
|
|
107
107
|
if (t === "" || t === "normal" || t === "regular") return "400";
|
|
108
108
|
if (t === "bold" || t === "bolder") return "700";
|
|
@@ -119,28 +119,28 @@ function H(o) {
|
|
|
119
119
|
}
|
|
120
120
|
return "400";
|
|
121
121
|
}
|
|
122
|
-
function
|
|
122
|
+
function ce(o) {
|
|
123
123
|
return {
|
|
124
124
|
fontSize: (o.fontSize || "16px").trim(),
|
|
125
125
|
lineHeight: (o.lineHeight || "1.25").trim(),
|
|
126
126
|
color: (o.color || "#433f3f").trim(),
|
|
127
127
|
fontFamily: (o.fontFamily || "sans-serif").trim(),
|
|
128
|
-
fontWeight:
|
|
128
|
+
fontWeight: j(o.fontWeight)
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
|
-
function
|
|
131
|
+
function K(o) {
|
|
132
132
|
return o.replace(/"/g, "'").replace(/\s+/g, " ").trim();
|
|
133
133
|
}
|
|
134
|
-
function
|
|
135
|
-
const e =
|
|
134
|
+
function ae(o, t) {
|
|
135
|
+
const e = K(t.fontSize), s = K(t.lineHeight), n = K(t.color), i = K(t.fontFamily), l = K(t.fontWeight);
|
|
136
136
|
return `padding:${o};font-size:${e};line-height:${s};color:${n};font-family:${i};font-weight:${l}`;
|
|
137
137
|
}
|
|
138
|
-
function
|
|
138
|
+
function qt(o, t, e) {
|
|
139
139
|
return `<mj-raw>
|
|
140
140
|
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
|
141
141
|
<tbody>
|
|
142
142
|
<tr>
|
|
143
|
-
<td style="${
|
|
143
|
+
<td style="${ae(o, e)}">
|
|
144
144
|
${t}
|
|
145
145
|
</td>
|
|
146
146
|
</tr>
|
|
@@ -148,29 +148,29 @@ function Wt(o, t, e) {
|
|
|
148
148
|
</table>
|
|
149
149
|
</mj-raw>`;
|
|
150
150
|
}
|
|
151
|
-
function
|
|
151
|
+
function de(o, t) {
|
|
152
152
|
const e = o.trimStart();
|
|
153
153
|
if (!e) return "<mj-raw><!-- empty --></mj-raw>";
|
|
154
154
|
if (/^<mj-/i.test(e)) return o;
|
|
155
155
|
const s = o.trim();
|
|
156
|
-
return
|
|
156
|
+
return qt("0", s, t);
|
|
157
157
|
}
|
|
158
|
-
function
|
|
158
|
+
function ue(o, t, e) {
|
|
159
159
|
const s = o.trim(), n = s.match(/^<mj-raw\b[^>]*>([\s\S]*)<\/mj-raw\s*>$/i);
|
|
160
160
|
if (!n) return o;
|
|
161
161
|
let i = n[1].trim();
|
|
162
162
|
const l = i.match(/^\s*<div\b[^>]*style="[^"]*"[^>]*>([\s\S]*)<\/div>\s*$/i);
|
|
163
|
-
return l && (i = l[1].trim()), /^\s*<table\b/i.test(i) ? s :
|
|
163
|
+
return l && (i = l[1].trim()), /^\s*<table\b/i.test(i) ? s : qt(t, i, e);
|
|
164
164
|
}
|
|
165
|
-
function
|
|
165
|
+
function he(o, t) {
|
|
166
166
|
const e = o.trim(), s = e.match(/^<mj-raw\b[^>]*>([\s\S]*)<\/mj-raw\s*>$/i), n = `${t.top}px ${t.right}px ${t.bottom}px ${t.left}px`;
|
|
167
167
|
if (s)
|
|
168
168
|
return s[1].trim() || `<div style="padding:${n};color:#9ca3af;font-size:13px;">(无内容)</div>`;
|
|
169
169
|
const i = e;
|
|
170
170
|
return i ? `<div style="padding:${n}">${i}</div>` : `<div style="padding:${n};color:#9ca3af;font-size:13px;">(无内容)</div>`;
|
|
171
171
|
}
|
|
172
|
-
function
|
|
173
|
-
const e = { doc: o, engine: "mjml" }, s = o.styles, n = o.sections.map((i) =>
|
|
172
|
+
function pe(o, t) {
|
|
173
|
+
const e = { doc: o, engine: "mjml" }, s = o.styles, n = o.sections.map((i) => fe(i, t, e)).join(`
|
|
174
174
|
`);
|
|
175
175
|
return `<mjml>
|
|
176
176
|
<mj-head>
|
|
@@ -178,84 +178,84 @@ function le(o, t) {
|
|
|
178
178
|
${o.meta.preheader ? `<mj-preview>${$(o.meta.preheader)}</mj-preview>` : ""}
|
|
179
179
|
<mj-attributes>
|
|
180
180
|
<mj-all font-family="${$(s.fontFamily)}" />
|
|
181
|
-
<mj-text font-size="${$(s.fontSize)}" font-weight="${$(
|
|
181
|
+
<mj-text font-size="${$(s.fontSize)}" font-weight="${$(j(s.fontWeight))}" color="${$(s.color)}" line-height="${$(s.lineHeight ?? "1.25")}" />
|
|
182
182
|
<mj-class name="link" color="${$(s.linkColor)}" />
|
|
183
183
|
</mj-attributes>
|
|
184
184
|
<mj-style>
|
|
185
185
|
a { color: ${$(s.linkColor)}; }
|
|
186
|
-
${
|
|
186
|
+
${me(o)}
|
|
187
187
|
</mj-style>
|
|
188
188
|
</mj-head>
|
|
189
|
-
<mj-body background-color="${$(s.backgroundColor)}" width="${$(
|
|
189
|
+
<mj-body background-color="${$(s.backgroundColor)}" width="${$(zt(o.meta.width))}">
|
|
190
190
|
${n}
|
|
191
191
|
</mj-body>
|
|
192
192
|
</mjml>`;
|
|
193
193
|
}
|
|
194
|
-
function
|
|
194
|
+
function Ot(o) {
|
|
195
195
|
return `sm-sec-${o.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
|
|
196
196
|
}
|
|
197
|
-
function
|
|
197
|
+
function me(o) {
|
|
198
198
|
return o.sections.map((t) => {
|
|
199
|
-
const e =
|
|
200
|
-
return e ? ` .${
|
|
199
|
+
const e = Ct(t.attrs.width);
|
|
200
|
+
return e ? ` .${Ot(t.id)} { max-width: ${e} !important; width: 100% !important; margin-left: auto !important; margin-right: auto !important; }` : "";
|
|
201
201
|
}).filter(Boolean).join(`
|
|
202
202
|
`);
|
|
203
203
|
}
|
|
204
|
-
function
|
|
205
|
-
const s = o.attrs, n = [s.paddingTop, s.paddingRight, s.paddingBottom, s.paddingLeft].map((
|
|
206
|
-
(
|
|
204
|
+
function fe(o, t, e) {
|
|
205
|
+
const s = o.attrs, n = [s.paddingTop, s.paddingRight, s.paddingBottom, s.paddingLeft].map((m) => `${m ?? 0}px`).join(" "), i = s.backgroundColor ? ` background-color="${$(s.backgroundColor)}"` : "", c = Ct(s.width) ? ` css-class="${$(Ot(o.id))}"` : "", a = be(o.layout), p = Math.max(0, o.attrs.columnGap ?? 0), g = o.columns.map(
|
|
206
|
+
(m, f) => ge(m, a[f], f, o.columns.length, p, t, e)
|
|
207
207
|
).join(`
|
|
208
208
|
`), u = o.columns.length > 1 && o.attrs.preserveColumnsOnMobile === !0 ? ` <mj-group>
|
|
209
|
-
${
|
|
210
|
-
</mj-group>` :
|
|
209
|
+
${yt(g, 2)}
|
|
210
|
+
</mj-group>` : g;
|
|
211
211
|
return ` <mj-section padding="${n}"${i}${c}>
|
|
212
212
|
${u}
|
|
213
213
|
</mj-section>`;
|
|
214
214
|
}
|
|
215
|
-
function
|
|
215
|
+
function ge(o, t, e, s, n, i, l) {
|
|
216
216
|
const c = o.attrs, a = c.verticalAlign ? ` vertical-align="${c.verticalAlign}"` : "", p = c.backgroundColor ? ` background-color="${$(c.backgroundColor)}"` : "";
|
|
217
|
-
let
|
|
217
|
+
let g = "";
|
|
218
218
|
if (s > 1 && n > 0) {
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
const d =
|
|
223
|
-
if (
|
|
224
|
-
let
|
|
225
|
-
if (
|
|
226
|
-
const
|
|
227
|
-
|
|
219
|
+
const m = n / 2, f = e > 0 ? `${m}px` : "0px";
|
|
220
|
+
g = ` padding="0px ${e < s - 1 ? `${m}px` : "0px"} 0px ${f}"`;
|
|
221
|
+
}
|
|
222
|
+
const d = ce(l.doc.styles), u = o.blocks.map((m) => {
|
|
223
|
+
if (m.lockedMjml) {
|
|
224
|
+
let b = de(m.lockedMjml, d);
|
|
225
|
+
if (m.type === "html") {
|
|
226
|
+
const y = m.props, h = `${Number(y.paddingTop ?? 8)}px ${Number(y.paddingRight ?? 0)}px ${Number(y.paddingBottom ?? 8)}px ${Number(y.paddingLeft ?? 0)}px`;
|
|
227
|
+
b = ue(b, h, d);
|
|
228
228
|
}
|
|
229
|
-
return
|
|
229
|
+
return yt(b, 8);
|
|
230
230
|
}
|
|
231
|
-
const
|
|
232
|
-
return
|
|
231
|
+
const f = i.require(m.type);
|
|
232
|
+
return yt(f.toMjml(m.props, l), 8);
|
|
233
233
|
}).join(`
|
|
234
234
|
`);
|
|
235
|
-
return ` <mj-column width="${t}"${a}${p}${
|
|
235
|
+
return ` <mj-column width="${t}"${a}${p}${g}>
|
|
236
236
|
${u || " <!-- empty column -->"}
|
|
237
237
|
</mj-column>`;
|
|
238
238
|
}
|
|
239
|
-
function
|
|
239
|
+
function be(o) {
|
|
240
240
|
const t = o.split("-").map(Number), e = t.reduce((s, n) => s + n, 0);
|
|
241
241
|
return t.map((s) => `${(s / e * 100).toFixed(2)}%`);
|
|
242
242
|
}
|
|
243
|
-
function
|
|
243
|
+
function yt(o, t) {
|
|
244
244
|
const e = " ".repeat(t);
|
|
245
245
|
return o.split(`
|
|
246
246
|
`).map((s) => s && e + s).join(`
|
|
247
247
|
`);
|
|
248
248
|
}
|
|
249
|
-
function
|
|
249
|
+
function at(o, t, e = {}) {
|
|
250
250
|
const s = e.engine ?? "mjml";
|
|
251
251
|
if (s !== "mjml")
|
|
252
252
|
throw new Error(`渲染引擎暂未实现: ${s}`);
|
|
253
|
-
const n =
|
|
253
|
+
const n = pe(o, t), i = te(n, {
|
|
254
254
|
validationLevel: "soft",
|
|
255
255
|
keepComments: !1
|
|
256
256
|
});
|
|
257
257
|
let l = i.html;
|
|
258
|
-
return e.withSampleVariables && (l =
|
|
258
|
+
return e.withSampleVariables && (l = ye(l, o.variables)), {
|
|
259
259
|
mjml: n,
|
|
260
260
|
html: l,
|
|
261
261
|
errors: (i.errors || []).map((c) => ({
|
|
@@ -263,27 +263,27 @@ function lt(o, t, e = {}) {
|
|
|
263
263
|
}))
|
|
264
264
|
};
|
|
265
265
|
}
|
|
266
|
-
function
|
|
266
|
+
function ye(o, t) {
|
|
267
267
|
return t.length ? o.replace(/\{\{\s*([^}\s]+)\s*\}\}/g, (e, s) => {
|
|
268
268
|
const n = t.find((i) => i.key === s);
|
|
269
269
|
return n && n.sample != null ? n.sample : e;
|
|
270
270
|
}) : o;
|
|
271
271
|
}
|
|
272
|
-
let
|
|
273
|
-
function
|
|
274
|
-
|
|
272
|
+
let Mt = 0;
|
|
273
|
+
function _t(o = "id") {
|
|
274
|
+
Mt += 1;
|
|
275
275
|
const t = Date.now().toString(36).slice(-4), e = Math.floor(Math.random() * 36 ** 3).toString(36).padStart(3, "0");
|
|
276
|
-
return `${o}_${t}${e}${
|
|
276
|
+
return `${o}_${t}${e}${Mt.toString(36)}`;
|
|
277
277
|
}
|
|
278
|
-
class
|
|
278
|
+
class _e {
|
|
279
279
|
constructor(t) {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
280
|
+
_(this, "_doc");
|
|
281
|
+
_(this, "_selection", null);
|
|
282
|
+
_(this, "_listeners", /* @__PURE__ */ new Set());
|
|
283
|
+
_(this, "_selectionListeners", /* @__PURE__ */ new Set());
|
|
284
|
+
_(this, "_past", []);
|
|
285
|
+
_(this, "_future", []);
|
|
286
|
+
_(this, "_historyLimit", 100);
|
|
287
287
|
this._doc = t;
|
|
288
288
|
}
|
|
289
289
|
get doc() {
|
|
@@ -332,7 +332,7 @@ class pe {
|
|
|
332
332
|
this._listeners.forEach((s) => s(e));
|
|
333
333
|
}
|
|
334
334
|
}
|
|
335
|
-
function
|
|
335
|
+
function H(o, t) {
|
|
336
336
|
return o.sections.find((e) => e.id === t);
|
|
337
337
|
}
|
|
338
338
|
function L(o, t) {
|
|
@@ -342,20 +342,20 @@ function L(o, t) {
|
|
|
342
342
|
if (i) return { section: e, columnIndex: s, block: i };
|
|
343
343
|
}
|
|
344
344
|
}
|
|
345
|
-
function
|
|
345
|
+
function et(o, t) {
|
|
346
346
|
const e = o.sections.find((n) => n.id === t);
|
|
347
347
|
!e || e.columns.length > 1 || !e.columns.every((n) => n.blocks.length === 0) || (o.sections = o.sections.filter((n) => n.id !== t));
|
|
348
348
|
}
|
|
349
|
-
function
|
|
349
|
+
function As(o) {
|
|
350
350
|
o.sections = o.sections.filter(
|
|
351
351
|
(t) => t.columns.some((e) => e.blocks.length > 0)
|
|
352
352
|
);
|
|
353
353
|
}
|
|
354
|
-
const
|
|
355
|
-
function
|
|
354
|
+
const Bs = ["1-1", "1-2", "2-1"];
|
|
355
|
+
function ve(o) {
|
|
356
356
|
return o === "1-1" || o === "1-2" || o === "2-1";
|
|
357
357
|
}
|
|
358
|
-
function
|
|
358
|
+
function ke(o, t) {
|
|
359
359
|
const e = t.split("-").length, s = o.columns.length;
|
|
360
360
|
if (e === s) {
|
|
361
361
|
o.layout = t;
|
|
@@ -363,7 +363,7 @@ function fe(o, t) {
|
|
|
363
363
|
}
|
|
364
364
|
if (e > s)
|
|
365
365
|
for (let n = s; n < e; n++)
|
|
366
|
-
o.columns.push({ id:
|
|
366
|
+
o.columns.push({ id: _t("col"), attrs: {}, blocks: [] });
|
|
367
367
|
else {
|
|
368
368
|
const n = o.columns.splice(e), i = o.columns[e - 1];
|
|
369
369
|
if (i)
|
|
@@ -371,14 +371,14 @@ function fe(o, t) {
|
|
|
371
371
|
}
|
|
372
372
|
o.layout = t;
|
|
373
373
|
}
|
|
374
|
-
function
|
|
374
|
+
function W(o) {
|
|
375
375
|
const t = o.split("-").length, e = Array.from({ length: t }, () => ({
|
|
376
|
-
id:
|
|
376
|
+
id: _t("col"),
|
|
377
377
|
attrs: {},
|
|
378
378
|
blocks: []
|
|
379
379
|
}));
|
|
380
380
|
return {
|
|
381
|
-
id:
|
|
381
|
+
id: _t("sec"),
|
|
382
382
|
type: "section",
|
|
383
383
|
layout: o,
|
|
384
384
|
attrs: {
|
|
@@ -391,18 +391,79 @@ function U(o) {
|
|
|
391
391
|
columns: e
|
|
392
392
|
};
|
|
393
393
|
}
|
|
394
|
-
|
|
394
|
+
function Ut(o) {
|
|
395
|
+
const t = String(o || "").trim(), e = t.match(/^\{\{\s*([^}]+?)\s*\}\}$/);
|
|
396
|
+
return ((e == null ? void 0 : e[1]) || t.replace(/^\{\{\s*/, "").replace(/\s*\}\}$/, "")).trim();
|
|
397
|
+
}
|
|
398
|
+
function q(o) {
|
|
399
|
+
return `{{${o}}}`;
|
|
400
|
+
}
|
|
401
|
+
function we(o) {
|
|
402
|
+
var t;
|
|
403
|
+
return o.sample != null && String(o.sample).trim() !== "" ? String(o.sample) : o.kind === "image" ? "https://via.placeholder.com/120x80/e8e8e8/666666?text=Image" : o.kind === "link" ? "#" : ((t = o.label) == null ? void 0 : t.trim()) || o.key;
|
|
404
|
+
}
|
|
405
|
+
function O(o) {
|
|
406
|
+
var s;
|
|
407
|
+
const t = ((s = o.key) == null ? void 0 : s.trim()) || Ut(String(o.key)), e = o.kind ?? "text";
|
|
408
|
+
return {
|
|
409
|
+
...o,
|
|
410
|
+
key: t,
|
|
411
|
+
kind: e,
|
|
412
|
+
sample: we({ ...o, key: t, kind: e })
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
function Gt(o, t) {
|
|
416
|
+
const e = o.replace(/"/g, """), s = o.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
417
|
+
return `<a href="${e}" style="color:${t} !important;text-decoration:underline;">${s}</a>`;
|
|
418
|
+
}
|
|
419
|
+
function Kt(o) {
|
|
420
|
+
const t = O(o);
|
|
421
|
+
return { content: q(t.key), asHtml: !1 };
|
|
422
|
+
}
|
|
423
|
+
function Ce(o, t) {
|
|
424
|
+
var i, l;
|
|
425
|
+
const e = O(o), s = ((i = t == null ? void 0 : t.token) == null ? void 0 : i.trim()) || q(e.key), n = ((l = t == null ? void 0 : t.linkColor) == null ? void 0 : l.trim()) || "#ff5a00";
|
|
426
|
+
if (e.kind === "link")
|
|
427
|
+
return {
|
|
428
|
+
content: Gt(s, n),
|
|
429
|
+
asHtml: !0
|
|
430
|
+
};
|
|
431
|
+
if (e.kind === "image") {
|
|
432
|
+
const c = Ut(s);
|
|
433
|
+
return {
|
|
434
|
+
content: `<img src="${s.replace(/"/g, """)}" alt="${c.replace(/"/g, """)}" width="100" style="max-width:100%;height:auto;display:block;border:0;" />`,
|
|
435
|
+
asHtml: !0
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
return Kt(e);
|
|
439
|
+
}
|
|
440
|
+
function Is(o, t) {
|
|
441
|
+
const e = O(o);
|
|
442
|
+
return e.kind === "link" || e.kind === "image" ? Ce(e, t) : Kt(e);
|
|
443
|
+
}
|
|
444
|
+
function $t(o, t) {
|
|
445
|
+
const e = String(o ?? "").trim();
|
|
446
|
+
if (!t) return e;
|
|
447
|
+
if (!e) return `<p style="margin:0;">${t}</p>`;
|
|
448
|
+
const s = e.match(/<\/(p|div|h[1-6]|li)>\s*$/i);
|
|
449
|
+
if (s && s.index != null) {
|
|
450
|
+
const n = s.index;
|
|
451
|
+
return e.slice(0, n) + t + e.slice(n);
|
|
452
|
+
}
|
|
453
|
+
return e + t;
|
|
454
|
+
}
|
|
455
|
+
const Se = {
|
|
395
456
|
1: "一列",
|
|
396
457
|
"1-1": "两列",
|
|
397
458
|
"1-2": "1:2",
|
|
398
459
|
"2-1": "2:1",
|
|
399
460
|
"1-1-1": "三列"
|
|
400
461
|
};
|
|
401
|
-
function
|
|
402
|
-
return
|
|
462
|
+
function vt(o) {
|
|
463
|
+
return Se[o] ?? o;
|
|
403
464
|
}
|
|
404
|
-
function
|
|
405
|
-
var p,
|
|
465
|
+
function Xt(o, t = " ") {
|
|
466
|
+
var p, g;
|
|
406
467
|
if (!o) return "";
|
|
407
468
|
const e = /* @__PURE__ */ new Set([
|
|
408
469
|
"area",
|
|
@@ -423,9 +484,9 @@ function zt(o, t = " ") {
|
|
|
423
484
|
let i = 0, l = [];
|
|
424
485
|
const c = [], a = (d) => t.repeat(Math.max(0, d));
|
|
425
486
|
for (const d of n) {
|
|
426
|
-
const u = d,
|
|
487
|
+
const u = d, m = l.length > 0;
|
|
427
488
|
if (u.startsWith("<!--") || u.startsWith("<![")) {
|
|
428
|
-
|
|
489
|
+
m ? c.push(u) : c.push(a(i) + u.trim());
|
|
429
490
|
continue;
|
|
430
491
|
}
|
|
431
492
|
if (u.startsWith("<!")) {
|
|
@@ -433,8 +494,8 @@ function zt(o, t = " ") {
|
|
|
433
494
|
continue;
|
|
434
495
|
}
|
|
435
496
|
if (u.startsWith("</")) {
|
|
436
|
-
const
|
|
437
|
-
if (l[l.length - 1] ===
|
|
497
|
+
const f = (p = (u.match(/^<\/([\w-]+)/) ?? [])[1]) == null ? void 0 : p.toLowerCase();
|
|
498
|
+
if (l[l.length - 1] === f) {
|
|
438
499
|
l.pop(), c.push(u);
|
|
439
500
|
continue;
|
|
440
501
|
}
|
|
@@ -442,34 +503,34 @@ function zt(o, t = " ") {
|
|
|
442
503
|
continue;
|
|
443
504
|
}
|
|
444
505
|
if (u.startsWith("<")) {
|
|
445
|
-
const
|
|
446
|
-
if (
|
|
447
|
-
c.push(u),
|
|
506
|
+
const f = (g = (u.match(/^<([\w-]+)/) ?? [])[1]) == null ? void 0 : g.toLowerCase(), b = u.endsWith("/>") || f && e.has(f);
|
|
507
|
+
if (m) {
|
|
508
|
+
c.push(u), f && s.has(f) && !b && l.push(f);
|
|
448
509
|
continue;
|
|
449
510
|
}
|
|
450
|
-
c.push(a(i) + u.trim()),
|
|
511
|
+
c.push(a(i) + u.trim()), f && !b && (s.has(f) ? l.push(f) : i += 1);
|
|
451
512
|
continue;
|
|
452
513
|
}
|
|
453
|
-
if (
|
|
514
|
+
if (m)
|
|
454
515
|
c.push(u);
|
|
455
516
|
else {
|
|
456
|
-
const
|
|
457
|
-
|
|
517
|
+
const f = u.replace(/\s+/g, " ").trim();
|
|
518
|
+
f && c.push(a(i) + f);
|
|
458
519
|
}
|
|
459
520
|
}
|
|
460
521
|
return c.join(`
|
|
461
522
|
`);
|
|
462
523
|
}
|
|
463
|
-
class
|
|
524
|
+
class dt {
|
|
464
525
|
constructor(t) {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
526
|
+
_(this, "el");
|
|
527
|
+
_(this, "mask");
|
|
528
|
+
_(this, "card");
|
|
529
|
+
_(this, "headerEl");
|
|
530
|
+
_(this, "bodyEl");
|
|
531
|
+
_(this, "footerEl");
|
|
532
|
+
_(this, "opts");
|
|
533
|
+
_(this, "keydownHandler");
|
|
473
534
|
this.opts = t, this.mask = r("div", {
|
|
474
535
|
class: "sm-modal__mask",
|
|
475
536
|
onclick: (e) => {
|
|
@@ -521,7 +582,7 @@ class ct {
|
|
|
521
582
|
title: "关闭 Esc",
|
|
522
583
|
onclick: () => this._handleClose()
|
|
523
584
|
},
|
|
524
|
-
[
|
|
585
|
+
[Ee()]
|
|
525
586
|
);
|
|
526
587
|
this.headerEl.append(t, e, s);
|
|
527
588
|
}
|
|
@@ -530,18 +591,18 @@ class ct {
|
|
|
530
591
|
this.keydownHandler && document.removeEventListener("keydown", this.keydownHandler), this.el.classList.remove("is-open"), setTimeout(() => this.el.remove(), 180), (e = (t = this.opts).onClose) == null || e.call(t);
|
|
531
592
|
}
|
|
532
593
|
}
|
|
533
|
-
function
|
|
594
|
+
function Ee() {
|
|
534
595
|
const o = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
535
596
|
return o.setAttribute("width", "16"), o.setAttribute("height", "16"), o.setAttribute("viewBox", "0 0 20 20"), o.innerHTML = '<path d="M5 5l10 10M15 5L5 15" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>', o;
|
|
536
597
|
}
|
|
537
|
-
class
|
|
598
|
+
class xe {
|
|
538
599
|
constructor(t) {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
this.opts = t, this.modal = new
|
|
600
|
+
_(this, "opts");
|
|
601
|
+
_(this, "modal");
|
|
602
|
+
_(this, "editorHost");
|
|
603
|
+
_(this, "cm", null);
|
|
604
|
+
_(this, "blockId", null);
|
|
605
|
+
this.opts = t, this.modal = new dt({
|
|
545
606
|
title: "编辑组件代码",
|
|
546
607
|
className: "sm-modal--block-code",
|
|
547
608
|
width: "min(720px, 92vw)",
|
|
@@ -568,11 +629,11 @@ class ye {
|
|
|
568
629
|
if (!n) return;
|
|
569
630
|
this._destroyCm(), this.blockId = t;
|
|
570
631
|
const i = n.block, l = this.opts.registry.get(i.type), c = i.lockedMjml ?? (l ? l.toMjml(i.props, { doc: s, engine: "mjml" }) : "");
|
|
571
|
-
this.modal.setTitle(`编辑组件代码 · ${e}`), this.cm = new
|
|
632
|
+
this.modal.setTitle(`编辑组件代码 · ${e}`), this.cm = new rt({
|
|
572
633
|
parent: this.editorHost,
|
|
573
|
-
state:
|
|
634
|
+
state: U.create({
|
|
574
635
|
doc: c,
|
|
575
|
-
extensions: [
|
|
636
|
+
extensions: [lt, ct()]
|
|
576
637
|
})
|
|
577
638
|
}), this.modal.open(this.opts.mountParent);
|
|
578
639
|
}
|
|
@@ -581,7 +642,7 @@ class ye {
|
|
|
581
642
|
}
|
|
582
643
|
_beautify() {
|
|
583
644
|
if (!this.cm) return;
|
|
584
|
-
const t =
|
|
645
|
+
const t = Xt(this.cm.state.doc.toString());
|
|
585
646
|
this.cm.dispatch({
|
|
586
647
|
changes: { from: 0, to: this.cm.state.doc.length, insert: t }
|
|
587
648
|
});
|
|
@@ -598,17 +659,17 @@ class ye {
|
|
|
598
659
|
this.cm && (this.cm.destroy(), this.cm = null), this.blockId = null;
|
|
599
660
|
}
|
|
600
661
|
}
|
|
601
|
-
function
|
|
662
|
+
function St(o = document) {
|
|
602
663
|
return o;
|
|
603
664
|
}
|
|
604
|
-
function
|
|
605
|
-
return
|
|
665
|
+
function T(o, t = !1, e, s = document) {
|
|
666
|
+
return St(s).execCommand(o, t, e);
|
|
606
667
|
}
|
|
607
|
-
function
|
|
608
|
-
return
|
|
668
|
+
function P(o, t = document) {
|
|
669
|
+
return St(t).queryCommandState(o);
|
|
609
670
|
}
|
|
610
|
-
function
|
|
611
|
-
return
|
|
671
|
+
function Fe(o, t = document) {
|
|
672
|
+
return St(t).queryCommandValue(o);
|
|
612
673
|
}
|
|
613
674
|
function A(o) {
|
|
614
675
|
const t = o.trim();
|
|
@@ -616,19 +677,19 @@ function A(o) {
|
|
|
616
677
|
const e = t.replace(/^#/, "");
|
|
617
678
|
return /^[0-9a-fA-F]{3}$/.test(e) ? `#${(e[0] + e[0] + e[1] + e[1] + e[2] + e[2]).toUpperCase()}` : /^[0-9a-fA-F]{6}$/.test(e) ? `#${e.toUpperCase()}` : null;
|
|
618
679
|
}
|
|
619
|
-
function
|
|
680
|
+
function Le(o) {
|
|
620
681
|
const t = o.trim().match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)/);
|
|
621
682
|
if (!t) return null;
|
|
622
683
|
const e = (s) => Number(s).toString(16).padStart(2, "0");
|
|
623
684
|
return `#${e(t[1])}${e(t[2])}${e(t[3])}`;
|
|
624
685
|
}
|
|
625
|
-
function
|
|
686
|
+
function Me(o, t) {
|
|
626
687
|
const e = A(o);
|
|
627
688
|
if (!e) return t ? "rgba(129, 140, 248, 0.18)" : "rgba(79, 70, 229, 0.12)";
|
|
628
689
|
const s = parseInt(e.slice(1, 3), 16), n = parseInt(e.slice(3, 5), 16), i = parseInt(e.slice(5, 7), 16);
|
|
629
690
|
return `rgba(${s},${n},${i},${t ? 0.22 : 0.14})`;
|
|
630
691
|
}
|
|
631
|
-
const
|
|
692
|
+
const $e = [
|
|
632
693
|
"#FFFFFF",
|
|
633
694
|
"#F5F6F8",
|
|
634
695
|
"#E6E8EC",
|
|
@@ -654,21 +715,21 @@ const we = [
|
|
|
654
715
|
"#EEF2FF",
|
|
655
716
|
"#F3E8FF"
|
|
656
717
|
];
|
|
657
|
-
let
|
|
658
|
-
function
|
|
659
|
-
return
|
|
718
|
+
let z = null;
|
|
719
|
+
function At() {
|
|
720
|
+
return z !== null;
|
|
660
721
|
}
|
|
661
|
-
function
|
|
662
|
-
|
|
722
|
+
function Ae() {
|
|
723
|
+
z == null || z(), z = null;
|
|
663
724
|
}
|
|
664
|
-
function
|
|
725
|
+
function Be(o, t, e) {
|
|
665
726
|
const s = t.getBoundingClientRect(), n = e.getBoundingClientRect();
|
|
666
727
|
o.style.top = `${s.bottom - n.top + 4}px`, o.style.left = `${Math.max(4, s.left - n.left)}px`, requestAnimationFrame(() => {
|
|
667
728
|
const i = o.getBoundingClientRect();
|
|
668
729
|
i.right > n.right - 8 && (o.style.left = `${Math.max(4, parseFloat(o.style.left) - (i.right - n.right + 8))}px`), i.bottom > window.innerHeight - 8 && (o.style.top = `${s.top - n.top - i.height - 4}px`);
|
|
669
730
|
});
|
|
670
731
|
}
|
|
671
|
-
function
|
|
732
|
+
function Ie(o) {
|
|
672
733
|
o.addEventListener(
|
|
673
734
|
"mousedown",
|
|
674
735
|
(t) => {
|
|
@@ -677,13 +738,13 @@ function Ee(o) {
|
|
|
677
738
|
!0
|
|
678
739
|
);
|
|
679
740
|
}
|
|
680
|
-
function
|
|
741
|
+
function Bt(o, t) {
|
|
681
742
|
const e = A(t);
|
|
682
743
|
e && (o.value = e);
|
|
683
744
|
}
|
|
684
|
-
function
|
|
685
|
-
var
|
|
686
|
-
|
|
745
|
+
function Te(o) {
|
|
746
|
+
var y;
|
|
747
|
+
Ae(), (y = o.onBeforeOpen) == null || y.call(o);
|
|
687
748
|
const t = A(o.value);
|
|
688
749
|
let e = t ?? "#4F46E5", s = !1;
|
|
689
750
|
const n = r("div", {
|
|
@@ -713,23 +774,23 @@ function xe(o) {
|
|
|
713
774
|
class: "sm-input sm-color-picker__hex",
|
|
714
775
|
type: "text",
|
|
715
776
|
placeholder: o.placeholder ?? "#RRGGBB"
|
|
716
|
-
}),
|
|
777
|
+
}), g = (h, v) => {
|
|
717
778
|
var w;
|
|
718
779
|
const k = A(h);
|
|
719
|
-
k && (e = k,
|
|
780
|
+
k && (e = k, Bt(a, k), p.value = k, (w = o.onPreview) == null || w.call(o, k), (v || o.liveCommit) && o.onCommit(k));
|
|
720
781
|
};
|
|
721
|
-
|
|
782
|
+
Bt(a, e), p.value = t ?? "";
|
|
722
783
|
const d = (h) => {
|
|
723
784
|
var v;
|
|
724
785
|
if (!s) {
|
|
725
|
-
if (s = !0,
|
|
786
|
+
if (s = !0, z = null, document.removeEventListener("keydown", f, !0), document.removeEventListener("mousedown", b, !0), n.remove(), h && !o.liveCommit) {
|
|
726
787
|
const k = A(e);
|
|
727
788
|
k && o.onCommit(k);
|
|
728
789
|
}
|
|
729
790
|
(v = o.onClosed) == null || v.call(o);
|
|
730
791
|
}
|
|
731
792
|
}, u = r("div", { class: "sm-color-picker__swatches" });
|
|
732
|
-
for (const h of
|
|
793
|
+
for (const h of $e) {
|
|
733
794
|
const v = r("button", {
|
|
734
795
|
class: "sm-color-picker__swatch",
|
|
735
796
|
type: "button",
|
|
@@ -737,23 +798,23 @@ function xe(o) {
|
|
|
737
798
|
style: `background:${h}`,
|
|
738
799
|
"aria-label": h
|
|
739
800
|
});
|
|
740
|
-
v.addEventListener("click", () =>
|
|
741
|
-
k.preventDefault(),
|
|
801
|
+
v.addEventListener("click", () => g(h, !1)), v.addEventListener("dblclick", (k) => {
|
|
802
|
+
k.preventDefault(), g(h, !0), d(!0);
|
|
742
803
|
}), u.append(v);
|
|
743
804
|
}
|
|
744
|
-
a.addEventListener("input", () =>
|
|
805
|
+
a.addEventListener("input", () => g(a.value, !1)), p.addEventListener("input", () => {
|
|
745
806
|
const h = A(p.value);
|
|
746
|
-
h &&
|
|
807
|
+
h && g(h, !1);
|
|
747
808
|
}), p.addEventListener("keydown", (h) => {
|
|
748
809
|
const v = h;
|
|
749
810
|
if (v.key === "Enter") {
|
|
750
811
|
v.preventDefault();
|
|
751
812
|
const k = A(p.value);
|
|
752
|
-
k && (
|
|
813
|
+
k && (g(k, !0), d(!0));
|
|
753
814
|
}
|
|
754
815
|
});
|
|
755
|
-
const
|
|
756
|
-
o.allowClear &&
|
|
816
|
+
const m = [];
|
|
817
|
+
o.allowClear && m.push(
|
|
757
818
|
r(
|
|
758
819
|
"button",
|
|
759
820
|
{
|
|
@@ -766,19 +827,19 @@ function xe(o) {
|
|
|
766
827
|
},
|
|
767
828
|
["清除"]
|
|
768
829
|
)
|
|
769
|
-
), i.append(c, u, a, p),
|
|
830
|
+
), i.append(c, u, a, p), m.length && i.append(r("div", { class: "sm-color-picker__foot" }, m)), n.append(i), Ie(n), o.layerRoot.append(n), Be(n, o.anchor, o.layerRoot), l.addEventListener("click", (h) => {
|
|
770
831
|
h.preventDefault(), d(!0);
|
|
771
832
|
});
|
|
772
|
-
const
|
|
833
|
+
const f = (h) => {
|
|
773
834
|
var v;
|
|
774
835
|
h.key === "Escape" && (h.preventDefault(), h.stopPropagation(), t && ((v = o.onPreview) == null || v.call(o, t)), d(!1));
|
|
775
|
-
},
|
|
836
|
+
}, b = (h) => {
|
|
776
837
|
const v = h.target;
|
|
777
838
|
n.contains(v) || o.anchor.contains(v) || d(!0);
|
|
778
839
|
};
|
|
779
|
-
document.addEventListener("keydown",
|
|
840
|
+
document.addEventListener("keydown", f, !0), setTimeout(() => document.addEventListener("mousedown", b, !0), 0), z = () => d(!0), o.autoFocusHex !== !1 && p.focus();
|
|
780
841
|
}
|
|
781
|
-
function
|
|
842
|
+
function X(o, t) {
|
|
782
843
|
o.title || (o.title = "点击打开色板;预设色块可双击快速确认"), o.addEventListener("mousedown", (e) => {
|
|
783
844
|
var s;
|
|
784
845
|
e.preventDefault(), (s = t.onBeforeOpen) == null || s.call(t);
|
|
@@ -786,7 +847,7 @@ function G(o, t) {
|
|
|
786
847
|
var i;
|
|
787
848
|
e.preventDefault(), e.stopPropagation();
|
|
788
849
|
const s = t.layerRoot ?? o.closest(".sm-root") ?? document.body, n = ((i = t.getValue) == null ? void 0 : i.call(t)) ?? o.value;
|
|
789
|
-
|
|
850
|
+
Te({
|
|
790
851
|
...t,
|
|
791
852
|
anchor: o,
|
|
792
853
|
layerRoot: s,
|
|
@@ -794,26 +855,26 @@ function G(o, t) {
|
|
|
794
855
|
});
|
|
795
856
|
});
|
|
796
857
|
}
|
|
797
|
-
class
|
|
858
|
+
class Re {
|
|
798
859
|
constructor(t) {
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
860
|
+
_(this, "opts");
|
|
861
|
+
_(this, "el");
|
|
862
|
+
_(this, "listeners", []);
|
|
863
|
+
_(this, "committed", !1);
|
|
864
|
+
_(this, "originalContent");
|
|
804
865
|
/** 防止 selectionchange 在我们 destroy 之后还回调 */
|
|
805
|
-
|
|
866
|
+
_(this, "alive", !0);
|
|
806
867
|
/**
|
|
807
868
|
* 上一次"用户在编辑区内"时的有效选区。
|
|
808
869
|
* 当用户去工具条点 select / input 时焦点会离开 contenteditable,
|
|
809
870
|
* execCommand 在那种状态下会哑火——必须先 focus 回来,再恢复选区,再执行命令。
|
|
810
871
|
*/
|
|
811
|
-
|
|
872
|
+
_(this, "savedRange", null);
|
|
812
873
|
/** 富文本工具条控件会抢走焦点,此时 getSelection 已不在编辑区内;保留上一帧状态避免工具条整栏收起。 */
|
|
813
|
-
|
|
874
|
+
_(this, "lastSelectionState", null);
|
|
814
875
|
/** hiliteColor 在输入前不写 DOM;记录「待输入背景色 + 锚点」以便 bar 即时同步,移开光标后清除 */
|
|
815
|
-
|
|
816
|
-
|
|
876
|
+
_(this, "pendingHiliteColor", null);
|
|
877
|
+
_(this, "pendingHiliteAnchor", null);
|
|
817
878
|
this.opts = t, this.el = t.el, this.originalContent = this.el.innerHTML, this._mount();
|
|
818
879
|
}
|
|
819
880
|
/** 立即提交并销毁。 */
|
|
@@ -821,7 +882,7 @@ class Fe {
|
|
|
821
882
|
if (this.committed) return;
|
|
822
883
|
this.committed = !0;
|
|
823
884
|
const t = this.opts.mode === "plain" ? (this.el.textContent ?? "").replace(/\s+\n/g, `
|
|
824
|
-
`).trim() : this.opts.mode === "html" ? this.el.innerHTML :
|
|
885
|
+
`).trim() : this.opts.mode === "html" ? this.el.innerHTML : Oe(this.el.innerHTML);
|
|
825
886
|
this.opts.onCommit(t), this.destroy(!1);
|
|
826
887
|
}
|
|
827
888
|
/** 放弃编辑、还原 DOM 并销毁。 */
|
|
@@ -846,7 +907,7 @@ class Fe {
|
|
|
846
907
|
this._ensureFocus(), this._restoreSelection();
|
|
847
908
|
const s = window.getSelection();
|
|
848
909
|
let n = null;
|
|
849
|
-
t === "hiliteColor" && (s != null && s.rangeCount) && (n =
|
|
910
|
+
t === "hiliteColor" && (s != null && s.rangeCount) && (n = pt(s.getRangeAt(0))), T("styleWithCSS", !1, t === "insertOrderedList" || t === "insertUnorderedList" ? "false" : "true"), T(t, !1, e), t === "hiliteColor" && (this.pendingHiliteColor = e ?? null, this.pendingHiliteAnchor = n), this.saveSelection(), this._emitSelection();
|
|
850
911
|
}
|
|
851
912
|
/**
|
|
852
913
|
* 设置或移除超链接:已有 <a> 则改 href;否则 createLink。
|
|
@@ -856,17 +917,21 @@ class Fe {
|
|
|
856
917
|
this._ensureFocus(), this._restoreSelection();
|
|
857
918
|
const e = t.trim();
|
|
858
919
|
if (!e) {
|
|
859
|
-
|
|
920
|
+
T("unlink"), this.saveSelection(), this._emitSelection();
|
|
860
921
|
return;
|
|
861
922
|
}
|
|
862
923
|
const s = /^https?:|^mailto:|^tel:|^\{\{/i.test(e) ? e : `https://${e}`, n = window.getSelection();
|
|
863
924
|
if (!n || n.rangeCount === 0) return;
|
|
864
|
-
const i =
|
|
865
|
-
i ? (i.setAttribute("href", s), i.getAttribute("rel") || i.setAttribute("rel", "noopener")) : (
|
|
925
|
+
const i = It(n.anchorNode, this.el);
|
|
926
|
+
i ? (i.setAttribute("href", s), i.getAttribute("rel") || i.setAttribute("rel", "noopener")) : (T("styleWithCSS", !1, "true"), T("createLink", !1, s)), this.saveSelection(), this._emitSelection();
|
|
866
927
|
}
|
|
867
928
|
/** 在当前光标处插入纯文本(供"插入变量"使用)。 */
|
|
868
929
|
insertText(t) {
|
|
869
|
-
this._ensureFocus(), this._restoreSelection(),
|
|
930
|
+
this._ensureFocus(), this._restoreSelection(), T("insertText", !1, t), this.saveSelection();
|
|
931
|
+
}
|
|
932
|
+
/** 在当前光标处插入 HTML 片段(供链接类变量使用)。 */
|
|
933
|
+
insertHtml(t) {
|
|
934
|
+
this._ensureFocus(), this._restoreSelection(), T("insertHTML", !1, t), this.saveSelection();
|
|
870
935
|
}
|
|
871
936
|
/** Toolbar 关闭某个面板/控件后调用,把选区还给编辑区,方便用户继续输入。 */
|
|
872
937
|
refocus() {
|
|
@@ -874,7 +939,7 @@ class Fe {
|
|
|
874
939
|
}
|
|
875
940
|
/** 字号:走原生 fontSize 命令(styleWithCSS 下浏览器会写 span),与 foreColor 同类 */
|
|
876
941
|
applyFontSize(t) {
|
|
877
|
-
this.exec("fontSize",
|
|
942
|
+
this.exec("fontSize", ze(t));
|
|
878
943
|
}
|
|
879
944
|
/**
|
|
880
945
|
* 字重:浏览器只有 bold 命令,没有 font-weight:500/600 的原生 API,需包 span。
|
|
@@ -917,69 +982,69 @@ class Fe {
|
|
|
917
982
|
/* -------------------------------- 内部 ---------------------------------- */
|
|
918
983
|
_mount() {
|
|
919
984
|
const { el: t, mode: e, multiline: s, placeholder: n } = this.opts;
|
|
920
|
-
t.setAttribute("contenteditable", "true"), t.classList.add("sm-inline-editing"), n && t.setAttribute("data-placeholder", n), this.opts.initialValue && (t.innerHTML = e === "plain" ?
|
|
921
|
-
t.focus(),
|
|
985
|
+
t.setAttribute("contenteditable", "true"), t.classList.add("sm-inline-editing"), n && t.setAttribute("data-placeholder", n), this.opts.initialValue && (t.innerHTML = e === "plain" ? qe(this.opts.initialValue) : this.opts.initialValue), requestAnimationFrame(() => {
|
|
986
|
+
t.focus(), Ne(t);
|
|
922
987
|
});
|
|
923
988
|
let i = !1, l = !1;
|
|
924
989
|
const c = () => {
|
|
925
990
|
i = !0;
|
|
926
991
|
}, a = () => {
|
|
927
992
|
i = !1, l = !0;
|
|
928
|
-
}, p = (
|
|
929
|
-
if (
|
|
930
|
-
|
|
993
|
+
}, p = (b) => {
|
|
994
|
+
if (b.key === "Escape") {
|
|
995
|
+
b.preventDefault(), this.cancel();
|
|
931
996
|
return;
|
|
932
997
|
}
|
|
933
|
-
if (
|
|
934
|
-
if (
|
|
998
|
+
if (b.key === "Enter") {
|
|
999
|
+
if (b.isComposing || i || b.keyCode === 229) return;
|
|
935
1000
|
if (l) {
|
|
936
1001
|
l = !1;
|
|
937
1002
|
return;
|
|
938
1003
|
}
|
|
939
1004
|
if (!s) {
|
|
940
|
-
|
|
1005
|
+
b.preventDefault(), this.commit();
|
|
941
1006
|
return;
|
|
942
1007
|
}
|
|
943
|
-
|
|
1008
|
+
b.preventDefault(), T("insertLineBreak");
|
|
944
1009
|
}
|
|
945
|
-
},
|
|
1010
|
+
}, g = (b) => {
|
|
946
1011
|
setTimeout(() => {
|
|
947
|
-
var v, k, w, E, C, B,
|
|
1012
|
+
var v, k, w, E, C, B, I, N, D;
|
|
948
1013
|
if (!this.alive) return;
|
|
949
|
-
const
|
|
950
|
-
if (
|
|
951
|
-
const h =
|
|
952
|
-
(
|
|
1014
|
+
const y = document.activeElement;
|
|
1015
|
+
if (y && (y === t || t.contains(y)) || At() || (v = y == null ? void 0 : y.closest) != null && v.call(y, ".sm-floating-toolbar, .sm-color-picker, .sm-color-picker-layer") || (k = y == null ? void 0 : y.closest) != null && k.call(y, ".sm-topbar, .sm-popover") || (w = y == null ? void 0 : y.closest) != null && w.call(y, ".sm-panel--left") || (E = y == null ? void 0 : y.closest) != null && E.call(y, ".sm-block__handle, .sm-section__handle")) return;
|
|
1016
|
+
const h = b.relatedTarget;
|
|
1017
|
+
(C = h == null ? void 0 : h.closest) != null && C.call(h, ".sm-panel--left") || (B = h == null ? void 0 : h.closest) != null && B.call(h, ".sm-block-card") || (I = h == null ? void 0 : h.closest) != null && I.call(h, ".sm-block__handle, .sm-section__handle") || (N = h == null ? void 0 : h.closest) != null && N.call(h, ".sm-color-picker, .sm-color-picker-layer") || (D = h == null ? void 0 : h.closest) != null && D.call(h, ".sm-topbar, .sm-popover") || document.querySelector(".sm-root .sm-drag, .sm-root .sm-chosen") || this.commit();
|
|
953
1018
|
}, 0);
|
|
954
|
-
}, d = (
|
|
1019
|
+
}, d = (b) => {
|
|
955
1020
|
var v;
|
|
956
1021
|
if (e !== "plain") return;
|
|
957
|
-
|
|
958
|
-
const
|
|
959
|
-
|
|
1022
|
+
b.preventDefault();
|
|
1023
|
+
const y = ((v = b.clipboardData) == null ? void 0 : v.getData("text/plain")) ?? "", h = s ? y : y.replace(/\r?\n/g, " ");
|
|
1024
|
+
T("insertText", !1, h);
|
|
960
1025
|
}, u = () => {
|
|
961
1026
|
this.alive && (this._syncPendingHiliteAnchor(), this.saveSelection(), this._emitSelection());
|
|
962
|
-
},
|
|
963
|
-
if (!(
|
|
964
|
-
const
|
|
965
|
-
if (!
|
|
966
|
-
const h =
|
|
967
|
-
return h == null || h === "" || h === "#" ? null :
|
|
968
|
-
},
|
|
969
|
-
e !== "rich" && e !== "html" ||
|
|
1027
|
+
}, m = (b) => {
|
|
1028
|
+
if (!(b instanceof Element)) return null;
|
|
1029
|
+
const y = b.closest("a");
|
|
1030
|
+
if (!y || !t.contains(y)) return null;
|
|
1031
|
+
const h = y.getAttribute("href");
|
|
1032
|
+
return h == null || h === "" || h === "#" ? null : y;
|
|
1033
|
+
}, f = (b) => {
|
|
1034
|
+
e !== "rich" && e !== "html" || m(b.target) && b.preventDefault();
|
|
970
1035
|
};
|
|
971
|
-
t.addEventListener("keydown", p), t.addEventListener("compositionstart", c), t.addEventListener("compositionend", a), t.addEventListener("blur",
|
|
1036
|
+
t.addEventListener("keydown", p), t.addEventListener("compositionstart", c), t.addEventListener("compositionend", a), t.addEventListener("blur", g), t.addEventListener("paste", d), document.addEventListener("selectionchange", u), t.addEventListener("input", u), t.addEventListener("mouseup", u), (e === "rich" || e === "html") && (t.addEventListener("click", f, !0), t.addEventListener("auxclick", f, !0)), this.listeners.push(
|
|
972
1037
|
() => t.removeEventListener("keydown", p),
|
|
973
1038
|
() => t.removeEventListener("compositionstart", c),
|
|
974
1039
|
() => t.removeEventListener("compositionend", a),
|
|
975
|
-
() => t.removeEventListener("blur",
|
|
1040
|
+
() => t.removeEventListener("blur", g),
|
|
976
1041
|
() => t.removeEventListener("paste", d),
|
|
977
1042
|
() => document.removeEventListener("selectionchange", u),
|
|
978
1043
|
() => t.removeEventListener("input", u),
|
|
979
1044
|
() => t.removeEventListener("mouseup", u),
|
|
980
1045
|
...e === "rich" || e === "html" ? [
|
|
981
|
-
() => t.removeEventListener("click",
|
|
982
|
-
() => t.removeEventListener("auxclick",
|
|
1046
|
+
() => t.removeEventListener("click", f, !0),
|
|
1047
|
+
() => t.removeEventListener("auxclick", f, !0)
|
|
983
1048
|
] : []
|
|
984
1049
|
);
|
|
985
1050
|
}
|
|
@@ -993,7 +1058,7 @@ class Fe {
|
|
|
993
1058
|
this._clearPendingHilite();
|
|
994
1059
|
return;
|
|
995
1060
|
}
|
|
996
|
-
|
|
1061
|
+
pt(t.getRangeAt(0)) !== this.pendingHiliteAnchor && this._clearPendingHilite();
|
|
997
1062
|
}
|
|
998
1063
|
_clearPendingHilite() {
|
|
999
1064
|
this.pendingHiliteColor = null, this.pendingHiliteAnchor = null;
|
|
@@ -1013,27 +1078,27 @@ class Fe {
|
|
|
1013
1078
|
this._emitSelectionOrKeepToolbar(null);
|
|
1014
1079
|
return;
|
|
1015
1080
|
}
|
|
1016
|
-
const e = t.getRangeAt(0), s = t.isCollapsed ? this._caretRect(e) : e.getBoundingClientRect(), n =
|
|
1017
|
-
const
|
|
1018
|
-
return (
|
|
1019
|
-
})(), l =
|
|
1020
|
-
let c = l.foreColor ??
|
|
1021
|
-
!a && e.collapsed && this.pendingHiliteColor && this.pendingHiliteAnchor ===
|
|
1081
|
+
const e = t.getRangeAt(0), s = t.isCollapsed ? this._caretRect(e) : e.getBoundingClientRect(), n = P("justifyCenter") ? "center" : P("justifyRight") ? "right" : P("justifyFull") ? "justify" : "left", i = (() => {
|
|
1082
|
+
const g = It(t.anchorNode, this.el);
|
|
1083
|
+
return (g == null ? void 0 : g.getAttribute("href")) ?? null;
|
|
1084
|
+
})(), l = Pe(this.el, t);
|
|
1085
|
+
let c = l.foreColor ?? Tt("foreColor"), a = l.backColor;
|
|
1086
|
+
!a && e.collapsed && this.pendingHiliteColor && this.pendingHiliteAnchor === pt(e) && (a = this.pendingHiliteColor), l.backColor && this._clearPendingHilite();
|
|
1022
1087
|
const p = {
|
|
1023
1088
|
hasSelection: !0,
|
|
1024
1089
|
rect: s,
|
|
1025
1090
|
formats: {
|
|
1026
|
-
bold:
|
|
1027
|
-
italic:
|
|
1028
|
-
underline:
|
|
1029
|
-
strikethrough:
|
|
1030
|
-
unorderedList:
|
|
1031
|
-
orderedList:
|
|
1091
|
+
bold: P("bold"),
|
|
1092
|
+
italic: P("italic"),
|
|
1093
|
+
underline: P("underline"),
|
|
1094
|
+
strikethrough: P("strikeThrough"),
|
|
1095
|
+
unorderedList: P("insertUnorderedList"),
|
|
1096
|
+
orderedList: P("insertOrderedList"),
|
|
1032
1097
|
align: n,
|
|
1033
1098
|
link: i,
|
|
1034
1099
|
foreColor: c,
|
|
1035
1100
|
fontSize: l.fontSize,
|
|
1036
|
-
fontName:
|
|
1101
|
+
fontName: Tt("fontName"),
|
|
1037
1102
|
fontWeight: l.fontWeight,
|
|
1038
1103
|
backColor: a
|
|
1039
1104
|
}
|
|
@@ -1043,7 +1108,7 @@ class Fe {
|
|
|
1043
1108
|
/** 焦点在浮动工具条上时沿用上一帧选区,避免点开链接框 / 颜色等控件后工具条消失。 */
|
|
1044
1109
|
_emitSelectionOrKeepToolbar(t) {
|
|
1045
1110
|
var e, s, n, i, l, c;
|
|
1046
|
-
if (t === null && this.lastSelectionState &&
|
|
1111
|
+
if (t === null && this.lastSelectionState && At() || (s = (e = document.activeElement) == null ? void 0 : e.closest) != null && s.call(
|
|
1047
1112
|
e,
|
|
1048
1113
|
".sm-floating-toolbar, .sm-color-picker, .sm-color-picker-layer"
|
|
1049
1114
|
)) {
|
|
@@ -1063,7 +1128,7 @@ class Fe {
|
|
|
1063
1128
|
return n.remove(), i;
|
|
1064
1129
|
}
|
|
1065
1130
|
}
|
|
1066
|
-
function
|
|
1131
|
+
function It(o, t) {
|
|
1067
1132
|
for (; o && o !== t; ) {
|
|
1068
1133
|
if (o.nodeType === 1 && o.tagName === "A")
|
|
1069
1134
|
return o;
|
|
@@ -1071,71 +1136,71 @@ function $t(o, t) {
|
|
|
1071
1136
|
}
|
|
1072
1137
|
return null;
|
|
1073
1138
|
}
|
|
1074
|
-
function
|
|
1139
|
+
function Ne(o) {
|
|
1075
1140
|
const t = document.createRange();
|
|
1076
1141
|
t.selectNodeContents(o), t.collapse(!1);
|
|
1077
1142
|
const e = window.getSelection();
|
|
1078
1143
|
e && (e.removeAllRanges(), e.addRange(t));
|
|
1079
1144
|
}
|
|
1080
|
-
function
|
|
1145
|
+
function Tt(o) {
|
|
1081
1146
|
try {
|
|
1082
|
-
const t =
|
|
1147
|
+
const t = Fe(o);
|
|
1083
1148
|
return t || null;
|
|
1084
1149
|
} catch {
|
|
1085
1150
|
return null;
|
|
1086
1151
|
}
|
|
1087
1152
|
}
|
|
1088
|
-
function
|
|
1089
|
-
const e =
|
|
1153
|
+
function Pe(o, t) {
|
|
1154
|
+
const e = We(t, o);
|
|
1090
1155
|
if (!e) return { fontSize: null, fontWeight: null, foreColor: null, backColor: null };
|
|
1091
1156
|
let s = null;
|
|
1092
1157
|
for (let c = e; c && o.contains(c) && c !== o; c = c.parentElement)
|
|
1093
1158
|
c.style.fontWeight && (s = c.style.fontWeight);
|
|
1094
|
-
const n =
|
|
1095
|
-
return s ? s =
|
|
1159
|
+
const n = He(o, e), i = De(o, e), l = window.getComputedStyle(e).fontSize;
|
|
1160
|
+
return s ? s = j(s) : s = P("bold") ? "700" : j(window.getComputedStyle(e).fontWeight), { fontSize: l, fontWeight: s, foreColor: n, backColor: i };
|
|
1096
1161
|
}
|
|
1097
|
-
function
|
|
1162
|
+
function He(o, t) {
|
|
1098
1163
|
var s;
|
|
1099
1164
|
for (let n = t; n && o.contains(n) && n !== o; n = n.parentElement) {
|
|
1100
1165
|
const i = (s = n.style.color) == null ? void 0 : s.trim();
|
|
1101
1166
|
if (i) return i;
|
|
1102
|
-
const l =
|
|
1167
|
+
const l = je(n.getAttribute("style"));
|
|
1103
1168
|
if (l) return l;
|
|
1104
1169
|
}
|
|
1105
1170
|
return window.getComputedStyle(t).color || null;
|
|
1106
1171
|
}
|
|
1107
|
-
function
|
|
1172
|
+
function je(o) {
|
|
1108
1173
|
if (!o) return null;
|
|
1109
1174
|
const t = o.match(/(?:^|;)\s*color\s*:\s*([^;]+)/i);
|
|
1110
1175
|
return t && t[1].trim() || null;
|
|
1111
1176
|
}
|
|
1112
|
-
function
|
|
1177
|
+
function De(o, t) {
|
|
1113
1178
|
var e;
|
|
1114
1179
|
for (let s = t; s && o.contains(s) && s !== o; s = s.parentElement) {
|
|
1115
1180
|
const n = (e = s.style.backgroundColor) == null ? void 0 : e.trim();
|
|
1116
|
-
if (n && !
|
|
1117
|
-
const i =
|
|
1181
|
+
if (n && !kt(n)) return n;
|
|
1182
|
+
const i = Ve(s.getAttribute("style"));
|
|
1118
1183
|
if (i) return i;
|
|
1119
1184
|
const l = window.getComputedStyle(s).backgroundColor;
|
|
1120
|
-
if (l && !
|
|
1185
|
+
if (l && !kt(l)) return l;
|
|
1121
1186
|
}
|
|
1122
1187
|
return null;
|
|
1123
1188
|
}
|
|
1124
|
-
function
|
|
1189
|
+
function Ve(o) {
|
|
1125
1190
|
if (!o) return null;
|
|
1126
1191
|
const t = o.match(/background(?:-color)?\s*:\s*([^;]+)/i);
|
|
1127
1192
|
if (!t) return null;
|
|
1128
1193
|
const e = t[1].trim();
|
|
1129
|
-
return e && !
|
|
1194
|
+
return e && !kt(e) ? e : null;
|
|
1130
1195
|
}
|
|
1131
|
-
function
|
|
1196
|
+
function We(o, t) {
|
|
1132
1197
|
const e = o.anchorNode;
|
|
1133
1198
|
return !e || !t.contains(e) ? null : e.nodeType === Node.TEXT_NODE ? e.parentElement : e;
|
|
1134
1199
|
}
|
|
1135
|
-
function
|
|
1200
|
+
function pt(o) {
|
|
1136
1201
|
return `${o.startContainer.nodeType}:${o.startOffset}:${o.endContainer.nodeType}:${o.endOffset}`;
|
|
1137
1202
|
}
|
|
1138
|
-
function
|
|
1203
|
+
function ze(o) {
|
|
1139
1204
|
const t = {
|
|
1140
1205
|
"10px": "1",
|
|
1141
1206
|
"12px": "2",
|
|
@@ -1168,29 +1233,29 @@ function Re(o) {
|
|
|
1168
1233
|
}
|
|
1169
1234
|
return i;
|
|
1170
1235
|
}
|
|
1171
|
-
function
|
|
1236
|
+
function kt(o) {
|
|
1172
1237
|
const t = o.trim().toLowerCase();
|
|
1173
1238
|
if (t === "transparent" || t === "inherit" || t === "initial" || t === "unset" || t === "rgba(0, 0, 0, 0)" || t === "rgba(0,0,0,0)") return !0;
|
|
1174
1239
|
const e = t.match(/^rgba?\(\s*(\d+)[,\s]+(\d+)[,\s]+(\d+)(?:[,\s/]+([\d.]+))?\s*\)$/);
|
|
1175
1240
|
return e ? (e[4] !== void 0 ? parseFloat(e[4]) : 1) === 0 : !1;
|
|
1176
1241
|
}
|
|
1177
|
-
function
|
|
1242
|
+
function qe(o) {
|
|
1178
1243
|
return o.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1179
1244
|
}
|
|
1180
|
-
function
|
|
1245
|
+
function Oe(o) {
|
|
1181
1246
|
const t = document.createElement("template");
|
|
1182
1247
|
return t.innerHTML = o, e(t.content), t.innerHTML.replace(/\u200b/g, "");
|
|
1183
1248
|
function e(s) {
|
|
1184
1249
|
const n = [];
|
|
1185
1250
|
s.querySelectorAll("*").forEach((l) => {
|
|
1186
|
-
var
|
|
1251
|
+
var g;
|
|
1187
1252
|
const c = l.tagName.toLowerCase();
|
|
1188
1253
|
if (c === "font") {
|
|
1189
|
-
const d = document.createElement("span"), u = l.getAttribute("color"),
|
|
1190
|
-
u &&
|
|
1191
|
-
const
|
|
1192
|
-
for (
|
|
1193
|
-
(
|
|
1254
|
+
const d = document.createElement("span"), u = l.getAttribute("color"), m = l.getAttribute("size"), f = l.getAttribute("face"), b = [l.getAttribute("style") ?? ""];
|
|
1255
|
+
u && b.push(`color:${u}`), m && b.push(`font-size:${Ue(m)}`), f && b.push(`font-family:${f}`);
|
|
1256
|
+
const y = b.filter(Boolean).join(";");
|
|
1257
|
+
for (y && d.setAttribute("style", y); l.firstChild; ) d.appendChild(l.firstChild);
|
|
1258
|
+
(g = l.parentNode) == null || g.replaceChild(d, l);
|
|
1194
1259
|
return;
|
|
1195
1260
|
}
|
|
1196
1261
|
if (![
|
|
@@ -1233,7 +1298,7 @@ function Pe(o) {
|
|
|
1233
1298
|
});
|
|
1234
1299
|
}
|
|
1235
1300
|
}
|
|
1236
|
-
function
|
|
1301
|
+
function Ue(o) {
|
|
1237
1302
|
return {
|
|
1238
1303
|
1: "10px",
|
|
1239
1304
|
2: "12px",
|
|
@@ -1244,22 +1309,22 @@ function He(o) {
|
|
|
1244
1309
|
7: "32px"
|
|
1245
1310
|
}[o] ?? o;
|
|
1246
1311
|
}
|
|
1247
|
-
class
|
|
1312
|
+
class Ge {
|
|
1248
1313
|
constructor(t) {
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1314
|
+
_(this, "el");
|
|
1315
|
+
_(this, "inner");
|
|
1316
|
+
_(this, "addBar");
|
|
1317
|
+
_(this, "opts");
|
|
1318
|
+
_(this, "sortableRefs", []);
|
|
1254
1319
|
/** 正在内联编辑的 block id;进入时画布不会被 store 触发的重渲染干扰它 */
|
|
1255
|
-
|
|
1256
|
-
|
|
1320
|
+
_(this, "editingBlockId", null);
|
|
1321
|
+
_(this, "inlineEditor", null);
|
|
1257
1322
|
/** 当 store 在编辑期间触发了 change(外部调用之类),延迟到编辑结束再重渲染 */
|
|
1258
|
-
|
|
1323
|
+
_(this, "pendingRender", !1);
|
|
1259
1324
|
/** 设计模式下禁用画布内超链接导航(预览弹框 iframe 不在此 DOM 内,不受影响) */
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
this.opts = t, this.el = r("div", { class: "sm-canvas-wrap" }), this.inner = r("div", { class: "sm-canvas" }), this.addBar = this._renderAddBar(), this.el.append(this.inner, this.addBar), this.blockCodeModal = new
|
|
1325
|
+
_(this, "linkNavSuppression", new AbortController());
|
|
1326
|
+
_(this, "blockCodeModal");
|
|
1327
|
+
this.opts = t, this.el = r("div", { class: "sm-canvas-wrap" }), this.inner = r("div", { class: "sm-canvas" }), this.addBar = this._renderAddBar(), this.el.append(this.inner, this.addBar), this.blockCodeModal = new xe({
|
|
1263
1328
|
store: t.store,
|
|
1264
1329
|
registry: t.registry,
|
|
1265
1330
|
mountParent: t.layerRoot
|
|
@@ -1285,6 +1350,14 @@ class je {
|
|
|
1285
1350
|
var t;
|
|
1286
1351
|
(t = this.inlineEditor) == null || t.commit();
|
|
1287
1352
|
}
|
|
1353
|
+
/** 强制重绘(内联编辑中会延迟到 commit 后) */
|
|
1354
|
+
refresh() {
|
|
1355
|
+
if (this.editingBlockId) {
|
|
1356
|
+
this.pendingRender = !0;
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1359
|
+
this._render();
|
|
1360
|
+
}
|
|
1288
1361
|
destroy() {
|
|
1289
1362
|
this.linkNavSuppression.abort(), this._exitEditing(!1), this._destroySortables(), this.blockCodeModal.destroy();
|
|
1290
1363
|
}
|
|
@@ -1329,9 +1402,9 @@ class je {
|
|
|
1329
1402
|
}
|
|
1330
1403
|
/* -------------------------------- 渲染 ---------------------------------- */
|
|
1331
1404
|
_render() {
|
|
1332
|
-
this._destroySortables(),
|
|
1405
|
+
this._destroySortables(), R(this.inner);
|
|
1333
1406
|
const { doc: t } = this.opts.store;
|
|
1334
|
-
if (this.inner.style.maxWidth =
|
|
1407
|
+
if (this.inner.style.maxWidth = zt(t.meta.width), this.inner.style.background = t.styles.contentBackgroundColor, this.inner.style.fontFamily = t.styles.fontFamily, this.inner.style.fontSize = t.styles.fontSize, this.inner.style.fontWeight = j(t.styles.fontWeight), this.inner.style.color = t.styles.color, this.inner.style.lineHeight = t.styles.lineHeight ?? "1.25", this.inner.style.setProperty("--sm-editor-link-color", t.styles.linkColor), !t.sections.length)
|
|
1335
1408
|
this.inner.append(
|
|
1336
1409
|
r("div", { class: "sm-empty-doc" }, [
|
|
1337
1410
|
"从左侧拖入布局开始,或直接双击开始 ✦"
|
|
@@ -1340,7 +1413,7 @@ class je {
|
|
|
1340
1413
|
else
|
|
1341
1414
|
for (let n = 0; n < t.sections.length; n++)
|
|
1342
1415
|
this.inner.append(this._renderSection(t.sections[n], t, n));
|
|
1343
|
-
const e = this.opts.autoWrapSection ? ["sections", "blocks"] : ["sections"], s =
|
|
1416
|
+
const e = this.opts.autoWrapSection ? ["sections", "blocks"] : ["sections"], s = nt.create(this.inner, {
|
|
1344
1417
|
group: { name: "sections", pull: !1, put: e },
|
|
1345
1418
|
animation: 150,
|
|
1346
1419
|
handle: ".sm-section__handle",
|
|
@@ -1354,7 +1427,7 @@ class je {
|
|
|
1354
1427
|
this.sortableRefs.push(s), this._syncSelection();
|
|
1355
1428
|
}
|
|
1356
1429
|
_renderSection(t, e, s) {
|
|
1357
|
-
const n = t.attrs, i = `${n.paddingTop ?? 0}px ${n.paddingRight ?? 0}px ${n.paddingBottom ?? 0}px ${n.paddingLeft ?? 0}px`, l =
|
|
1430
|
+
const n = t.attrs, i = `${n.paddingTop ?? 0}px ${n.paddingRight ?? 0}px ${n.paddingBottom ?? 0}px ${n.paddingLeft ?? 0}px`, l = vt(t.layout), c = `区块 ${s + 1} · ${l}`, a = Ct(n.width), p = a != null ? `max-width:${a};width:100%;margin-left:auto;margin-right:auto;box-sizing:border-box;` : "", g = r("div", {
|
|
1358
1431
|
class: "sm-section-host",
|
|
1359
1432
|
"data-id": t.id
|
|
1360
1433
|
}), d = r("div", {
|
|
@@ -1371,7 +1444,7 @@ class je {
|
|
|
1371
1444
|
type: "button",
|
|
1372
1445
|
title: "拖拽排序"
|
|
1373
1446
|
},
|
|
1374
|
-
[
|
|
1447
|
+
[Rt()]
|
|
1375
1448
|
),
|
|
1376
1449
|
r(
|
|
1377
1450
|
"button",
|
|
@@ -1379,11 +1452,11 @@ class je {
|
|
|
1379
1452
|
class: "sm-tool-btn",
|
|
1380
1453
|
type: "button",
|
|
1381
1454
|
title: "复制",
|
|
1382
|
-
onclick: (
|
|
1383
|
-
|
|
1455
|
+
onclick: (f) => {
|
|
1456
|
+
f.stopPropagation(), this._duplicateSection(t.id);
|
|
1384
1457
|
}
|
|
1385
1458
|
},
|
|
1386
|
-
[
|
|
1459
|
+
[Nt()]
|
|
1387
1460
|
),
|
|
1388
1461
|
r(
|
|
1389
1462
|
"button",
|
|
@@ -1391,36 +1464,36 @@ class je {
|
|
|
1391
1464
|
class: "sm-tool-btn sm-tool-btn--danger",
|
|
1392
1465
|
type: "button",
|
|
1393
1466
|
title: "删除",
|
|
1394
|
-
onclick: (
|
|
1395
|
-
|
|
1467
|
+
onclick: (f) => {
|
|
1468
|
+
f.stopPropagation(), this._removeSection(t.id);
|
|
1396
1469
|
}
|
|
1397
1470
|
},
|
|
1398
|
-
[
|
|
1471
|
+
[Pt()]
|
|
1399
1472
|
)
|
|
1400
1473
|
])
|
|
1401
|
-
]),
|
|
1474
|
+
]), m = r("div", {
|
|
1402
1475
|
class: "sm-section__columns",
|
|
1403
|
-
style:
|
|
1476
|
+
style: Ke(t.layout, t.attrs.columnGap)
|
|
1404
1477
|
});
|
|
1405
|
-
return t.columns.forEach((
|
|
1406
|
-
|
|
1407
|
-
}), d.append(
|
|
1408
|
-
|
|
1409
|
-
}),
|
|
1478
|
+
return t.columns.forEach((f, b) => {
|
|
1479
|
+
m.append(this._renderColumn(t, f, b, e));
|
|
1480
|
+
}), d.append(m), g.append(d, u), g.addEventListener("click", (f) => {
|
|
1481
|
+
f.target.closest(".sm-block") || !f.altKey && this._shouldSuppressSectionSelectFromTextInteraction() || (f.stopPropagation(), this.opts.store.setSelection({ kind: "section", sectionId: t.id }));
|
|
1482
|
+
}), g;
|
|
1410
1483
|
}
|
|
1411
1484
|
_renderColumn(t, e, s, n) {
|
|
1412
1485
|
const i = e.blocks.length === 0, l = r("div", {
|
|
1413
1486
|
class: `sm-column ${i ? "is-empty" : ""}`,
|
|
1414
1487
|
"data-section-id": t.id,
|
|
1415
1488
|
"data-column-index": String(s),
|
|
1416
|
-
style: `flex:${
|
|
1489
|
+
style: `flex:${Xe(t.layout, s)};${e.attrs.backgroundColor ? `background:${e.attrs.backgroundColor};` : ""}${e.attrs.verticalAlign ? `align-self:${Ye(e.attrs.verticalAlign)};` : ""}`
|
|
1417
1490
|
});
|
|
1418
1491
|
for (const a of e.blocks)
|
|
1419
1492
|
l.append(this._renderBlock(t, s, a, n));
|
|
1420
1493
|
i && l.addEventListener("dblclick", (a) => {
|
|
1421
1494
|
a.target.closest(".sm-block") || (a.preventDefault(), a.stopPropagation(), this._insertEmptyTextAndEdit(t.id, s));
|
|
1422
1495
|
});
|
|
1423
|
-
const c =
|
|
1496
|
+
const c = nt.create(l, {
|
|
1424
1497
|
group: { name: "blocks", put: ["blocks"] },
|
|
1425
1498
|
animation: 150,
|
|
1426
1499
|
draggable: ".sm-block",
|
|
@@ -1441,25 +1514,25 @@ class je {
|
|
|
1441
1514
|
if (s.lockedMjml)
|
|
1442
1515
|
if (s.type === "html") {
|
|
1443
1516
|
const u = s.props;
|
|
1444
|
-
c = `<div class="sm-html-content">${
|
|
1517
|
+
c = `<div class="sm-html-content">${he(s.lockedMjml, {
|
|
1445
1518
|
top: Number(u.paddingTop ?? 8),
|
|
1446
1519
|
right: Number(u.paddingRight ?? 0),
|
|
1447
1520
|
bottom: Number(u.paddingBottom ?? 8),
|
|
1448
1521
|
left: Number(u.paddingLeft ?? 0)
|
|
1449
1522
|
})}</div>`;
|
|
1450
1523
|
} else
|
|
1451
|
-
c = `<div style="padding:8px;color:#92400e;background:#fffbeb;border:1px dashed #f59e0b;font-family:monospace;font-size:11px;white-space:pre-wrap;">${
|
|
1524
|
+
c = `<div style="padding:8px;color:#92400e;background:#fffbeb;border:1px dashed #f59e0b;font-family:monospace;font-size:11px;white-space:pre-wrap;">${tt(
|
|
1452
1525
|
s.lockedMjml
|
|
1453
1526
|
)}</div>`;
|
|
1454
|
-
else l != null && l.renderPreview ? c = l.renderPreview(s.props, i) : l ? c = `<div style="padding:16px;color:#6b7280;background:#f9fafb;border:1px dashed #d1d5db;text-align:center;">${
|
|
1527
|
+
else l != null && l.renderPreview ? c = l.renderPreview(s.props, i) : l ? c = `<div style="padding:16px;color:#6b7280;background:#f9fafb;border:1px dashed #d1d5db;text-align:center;">${tt(
|
|
1455
1528
|
l.name
|
|
1456
|
-
)}</div>` : c = `<div style="padding:8px;color:#dc2626;">未知组件: ${
|
|
1529
|
+
)}</div>` : c = `<div style="padding:8px;color:#dc2626;">未知组件: ${tt(s.type)}</div>`;
|
|
1457
1530
|
const a = (l == null ? void 0 : l.name) ?? s.type, p = r("div", {
|
|
1458
1531
|
class: `sm-block ${s.lockedMjml ? "is-locked" : ""}`,
|
|
1459
1532
|
"data-id": s.id,
|
|
1460
1533
|
"data-section-id": t.id,
|
|
1461
1534
|
"data-column-index": String(e)
|
|
1462
|
-
}),
|
|
1535
|
+
}), g = r("div", { class: "sm-block__content", html: c }), d = r("div", { class: "sm-block__toolbar" }, [
|
|
1463
1536
|
r("span", { class: "sm-block__toolbar-name", title: a }, [a]),
|
|
1464
1537
|
r("div", { class: "sm-block__toolbar-actions" }, [
|
|
1465
1538
|
r(
|
|
@@ -1470,7 +1543,7 @@ class je {
|
|
|
1470
1543
|
title: "拖拽排序",
|
|
1471
1544
|
onclick: (u) => u.stopPropagation()
|
|
1472
1545
|
},
|
|
1473
|
-
[
|
|
1546
|
+
[Rt()]
|
|
1474
1547
|
),
|
|
1475
1548
|
l != null && l.inlineEditable && !s.lockedMjml ? r(
|
|
1476
1549
|
"button",
|
|
@@ -1482,7 +1555,7 @@ class je {
|
|
|
1482
1555
|
u.stopPropagation(), this._enterEditing(s);
|
|
1483
1556
|
}
|
|
1484
1557
|
},
|
|
1485
|
-
[
|
|
1558
|
+
[Je()]
|
|
1486
1559
|
) : null,
|
|
1487
1560
|
r(
|
|
1488
1561
|
"button",
|
|
@@ -1494,7 +1567,7 @@ class je {
|
|
|
1494
1567
|
u.stopPropagation(), this.blockCodeModal.open(s.id, a);
|
|
1495
1568
|
}
|
|
1496
1569
|
},
|
|
1497
|
-
[
|
|
1570
|
+
[Qe()]
|
|
1498
1571
|
),
|
|
1499
1572
|
r(
|
|
1500
1573
|
"button",
|
|
@@ -1506,7 +1579,7 @@ class je {
|
|
|
1506
1579
|
u.stopPropagation(), this._duplicateBlock(s.id);
|
|
1507
1580
|
}
|
|
1508
1581
|
},
|
|
1509
|
-
[
|
|
1582
|
+
[Nt()]
|
|
1510
1583
|
),
|
|
1511
1584
|
r(
|
|
1512
1585
|
"button",
|
|
@@ -1518,11 +1591,11 @@ class je {
|
|
|
1518
1591
|
u.stopPropagation(), this._removeBlock(s.id);
|
|
1519
1592
|
}
|
|
1520
1593
|
},
|
|
1521
|
-
[
|
|
1594
|
+
[Pt()]
|
|
1522
1595
|
)
|
|
1523
1596
|
])
|
|
1524
1597
|
]);
|
|
1525
|
-
return p.append(d,
|
|
1598
|
+
return p.append(d, g), p.addEventListener("click", (u) => {
|
|
1526
1599
|
if (this.editingBlockId !== s.id) {
|
|
1527
1600
|
if (u.altKey) {
|
|
1528
1601
|
u.stopPropagation(), this.opts.store.setSelection({ kind: "section", sectionId: t.id });
|
|
@@ -1553,7 +1626,7 @@ class je {
|
|
|
1553
1626
|
class: "sm-add-section-bar__btn",
|
|
1554
1627
|
type: "button",
|
|
1555
1628
|
onclick: () => this.opts.store.update((n) => {
|
|
1556
|
-
n.sections.push(
|
|
1629
|
+
n.sections.push(W(s.layout));
|
|
1557
1630
|
})
|
|
1558
1631
|
},
|
|
1559
1632
|
[s.label]
|
|
@@ -1577,7 +1650,7 @@ class je {
|
|
|
1577
1650
|
if (c.sections.length > 0) return;
|
|
1578
1651
|
const a = t.createBlock("text");
|
|
1579
1652
|
a.props.content = "";
|
|
1580
|
-
const p =
|
|
1653
|
+
const p = W("1");
|
|
1581
1654
|
p.columns[0].blocks.push(a), c.sections.push(p);
|
|
1582
1655
|
});
|
|
1583
1656
|
const s = (l = (i = this.opts.store.doc.sections[0]) == null ? void 0 : i.columns[0]) == null ? void 0 : l.blocks[0];
|
|
@@ -1593,7 +1666,7 @@ class je {
|
|
|
1593
1666
|
if (!((i = s.get("text")) != null && i.inlineEditable)) return;
|
|
1594
1667
|
const n = s.createBlock("text");
|
|
1595
1668
|
n.props.content = "", this.opts.store.update((l) => {
|
|
1596
|
-
const c =
|
|
1669
|
+
const c = H(l, t);
|
|
1597
1670
|
if (!c) return;
|
|
1598
1671
|
const a = c.columns[e];
|
|
1599
1672
|
!a || a.blocks.length > 0 || a.blocks.push(n);
|
|
@@ -1608,14 +1681,14 @@ class je {
|
|
|
1608
1681
|
const e = this.opts.registry.get(t.type);
|
|
1609
1682
|
if (!(e != null && e.inlineEditable)) return;
|
|
1610
1683
|
const s = this.inner.querySelector(
|
|
1611
|
-
`.sm-block[data-id="${
|
|
1684
|
+
`.sm-block[data-id="${Z(t.id)}"]`
|
|
1612
1685
|
), n = s == null ? void 0 : s.querySelector(".sm-block__content");
|
|
1613
1686
|
if (!n) return;
|
|
1614
1687
|
const i = e.inlineEditable.selector ? n.querySelector(e.inlineEditable.selector) : n.firstElementChild;
|
|
1615
1688
|
if (!i) return;
|
|
1616
1689
|
this.editingBlockId = t.id, s == null || s.classList.add("is-editing");
|
|
1617
1690
|
const l = (e.inlineEditable.mode === "plain", String(t.props[e.inlineEditable.propKey] ?? ""));
|
|
1618
|
-
this.inlineEditor = new
|
|
1691
|
+
this.inlineEditor = new Re({
|
|
1619
1692
|
el: i,
|
|
1620
1693
|
initialValue: l,
|
|
1621
1694
|
mode: e.inlineEditable.mode,
|
|
@@ -1623,8 +1696,8 @@ class je {
|
|
|
1623
1696
|
placeholder: e.inlineEditable.placeholder,
|
|
1624
1697
|
onCommit: (c) => {
|
|
1625
1698
|
const a = e.inlineEditable.propKey, p = t.id;
|
|
1626
|
-
this._exitEditing(!1), this.opts.store.update((
|
|
1627
|
-
const d = L(
|
|
1699
|
+
this._exitEditing(!1), this.opts.store.update((g) => {
|
|
1700
|
+
const d = L(g, p);
|
|
1628
1701
|
d && (d.block.props[a] = c);
|
|
1629
1702
|
});
|
|
1630
1703
|
},
|
|
@@ -1645,7 +1718,7 @@ class je {
|
|
|
1645
1718
|
const e = this.editingBlockId;
|
|
1646
1719
|
this.editingBlockId = null, this.inlineEditor && (this.inlineEditor.destroy(t), this.inlineEditor = null), this.opts.toolbar.detach();
|
|
1647
1720
|
const s = this.inner.querySelector(
|
|
1648
|
-
`.sm-block[data-id="${
|
|
1721
|
+
`.sm-block[data-id="${Z(e)}"]`
|
|
1649
1722
|
);
|
|
1650
1723
|
s == null || s.classList.remove("is-editing"), this.pendingRender && (this.pendingRender = !1, this._render());
|
|
1651
1724
|
}
|
|
@@ -1659,40 +1732,40 @@ class je {
|
|
|
1659
1732
|
return e != null && e.expandPaletteDrop ? e.expandPaletteDrop((s) => this.opts.registry.createBlock(s)) : [this.opts.registry.createBlock(t)];
|
|
1660
1733
|
}
|
|
1661
1734
|
_handleSectionAdd(t) {
|
|
1662
|
-
var a, p,
|
|
1735
|
+
var a, p, g;
|
|
1663
1736
|
this._commitEditingBeforeStructureChange();
|
|
1664
1737
|
const e = t.item, s = e.getAttribute("data-layout"), n = e.getAttribute("data-block-type"), i = e.getAttribute("data-id"), l = e.getAttribute("data-source-group"), c = t.newIndex ?? 0;
|
|
1665
1738
|
if (s) {
|
|
1666
1739
|
(a = e.parentElement) == null || a.removeChild(e), this.opts.store.update((d) => {
|
|
1667
|
-
d.sections.splice(c, 0,
|
|
1740
|
+
d.sections.splice(c, 0, W(s));
|
|
1668
1741
|
});
|
|
1669
1742
|
return;
|
|
1670
1743
|
}
|
|
1671
1744
|
if (l === "blocks" && n) {
|
|
1672
1745
|
(p = e.parentElement) == null || p.removeChild(e);
|
|
1673
|
-
const d = this._blocksFromPaletteDrop(n), u =
|
|
1674
|
-
u.columns[0].blocks.splice(c, 0, ...d), this.opts.store.update((
|
|
1675
|
-
|
|
1746
|
+
const d = this._blocksFromPaletteDrop(n), u = W("1");
|
|
1747
|
+
u.columns[0].blocks.splice(c, 0, ...d), this.opts.store.update((f) => {
|
|
1748
|
+
f.sections.splice(c, 0, u);
|
|
1676
1749
|
});
|
|
1677
|
-
const
|
|
1678
|
-
|
|
1750
|
+
const m = d[0];
|
|
1751
|
+
m && this.opts.store.setSelection({
|
|
1679
1752
|
kind: "block",
|
|
1680
1753
|
sectionId: u.id,
|
|
1681
1754
|
columnIndex: 0,
|
|
1682
|
-
blockId:
|
|
1755
|
+
blockId: m.id
|
|
1683
1756
|
});
|
|
1684
1757
|
return;
|
|
1685
1758
|
}
|
|
1686
1759
|
if (i) {
|
|
1687
|
-
(
|
|
1688
|
-
const d =
|
|
1760
|
+
(g = e.parentElement) == null || g.removeChild(e);
|
|
1761
|
+
const d = W("1");
|
|
1689
1762
|
this.opts.store.update((u) => {
|
|
1690
|
-
const
|
|
1691
|
-
if (!
|
|
1692
|
-
const
|
|
1693
|
-
if (
|
|
1694
|
-
const [
|
|
1695
|
-
d.columns[0].blocks.push(
|
|
1763
|
+
const m = L(u, i);
|
|
1764
|
+
if (!m) return;
|
|
1765
|
+
const f = m.section.columns[m.columnIndex], b = f.blocks.findIndex((h) => h.id === i);
|
|
1766
|
+
if (b < 0) return;
|
|
1767
|
+
const [y] = f.blocks.splice(b, 1);
|
|
1768
|
+
d.columns[0].blocks.push(y), u.sections.splice(c, 0, d), et(u, m.section.id);
|
|
1696
1769
|
}), this.opts.store.setSelection({
|
|
1697
1770
|
kind: "block",
|
|
1698
1771
|
sectionId: d.id,
|
|
@@ -1715,13 +1788,13 @@ class je {
|
|
|
1715
1788
|
const n = t.item, i = t.newIndex ?? 0, l = n.getAttribute("data-source-group"), c = n.getAttribute("data-block-type"), a = n.getAttribute("data-id");
|
|
1716
1789
|
if (l === "blocks" && c) {
|
|
1717
1790
|
(p = n.parentElement) == null || p.removeChild(n);
|
|
1718
|
-
const
|
|
1791
|
+
const g = this._blocksFromPaletteDrop(c);
|
|
1719
1792
|
this.opts.store.update((u) => {
|
|
1720
|
-
var
|
|
1721
|
-
const
|
|
1722
|
-
|
|
1793
|
+
var f;
|
|
1794
|
+
const m = u.sections.find((b) => b.id === e);
|
|
1795
|
+
m && ((f = m.columns[s]) == null || f.blocks.splice(i, 0, ...g));
|
|
1723
1796
|
});
|
|
1724
|
-
const d =
|
|
1797
|
+
const d = g[0];
|
|
1725
1798
|
d && this.opts.store.setSelection({
|
|
1726
1799
|
kind: "block",
|
|
1727
1800
|
sectionId: e,
|
|
@@ -1730,21 +1803,21 @@ class je {
|
|
|
1730
1803
|
});
|
|
1731
1804
|
return;
|
|
1732
1805
|
}
|
|
1733
|
-
a && this.opts.store.update((
|
|
1734
|
-
var
|
|
1735
|
-
const d = L(
|
|
1806
|
+
a && this.opts.store.update((g) => {
|
|
1807
|
+
var y;
|
|
1808
|
+
const d = L(g, a);
|
|
1736
1809
|
if (!d) return;
|
|
1737
|
-
const u = d.section.columns[d.columnIndex],
|
|
1738
|
-
if (
|
|
1739
|
-
const [
|
|
1740
|
-
(
|
|
1810
|
+
const u = d.section.columns[d.columnIndex], m = u.blocks.findIndex((h) => h.id === a);
|
|
1811
|
+
if (m < 0) return;
|
|
1812
|
+
const [f] = u.blocks.splice(m, 1), b = g.sections.find((h) => h.id === e);
|
|
1813
|
+
(y = b == null ? void 0 : b.columns[s]) == null || y.blocks.splice(i, 0, f), et(g, d.section.id);
|
|
1741
1814
|
});
|
|
1742
1815
|
}
|
|
1743
1816
|
_handleBlockMove(t, e, s) {
|
|
1744
1817
|
this._commitEditingBeforeStructureChange();
|
|
1745
1818
|
const n = t.oldIndex ?? 0, i = t.newIndex ?? 0;
|
|
1746
1819
|
n !== i && this.opts.store.update((l) => {
|
|
1747
|
-
const c = l.sections.find((
|
|
1820
|
+
const c = l.sections.find((g) => g.id === e), a = c == null ? void 0 : c.columns[s];
|
|
1748
1821
|
if (!a) return;
|
|
1749
1822
|
const [p] = a.blocks.splice(n, 1);
|
|
1750
1823
|
a.blocks.splice(i, 0, p);
|
|
@@ -1773,7 +1846,7 @@ class je {
|
|
|
1773
1846
|
const s = L(e, t);
|
|
1774
1847
|
if (!s) return;
|
|
1775
1848
|
const n = s.section.columns[s.columnIndex];
|
|
1776
|
-
n.blocks = n.blocks.filter((i) => i.id !== t),
|
|
1849
|
+
n.blocks = n.blocks.filter((i) => i.id !== t), et(e, s.section.id);
|
|
1777
1850
|
}), this.opts.store.setSelection(null);
|
|
1778
1851
|
}
|
|
1779
1852
|
_duplicateBlock(t) {
|
|
@@ -1806,62 +1879,62 @@ class je {
|
|
|
1806
1879
|
_syncSelection() {
|
|
1807
1880
|
var e, s;
|
|
1808
1881
|
const t = this.opts.store.selection;
|
|
1809
|
-
this.inner.querySelectorAll(".is-selected").forEach((n) => n.classList.remove("is-selected")), t && (t.kind === "section" ? (e = this.inner.querySelector(`.sm-section-host[data-id="${
|
|
1882
|
+
this.inner.querySelectorAll(".is-selected").forEach((n) => n.classList.remove("is-selected")), t && (t.kind === "section" ? (e = this.inner.querySelector(`.sm-section-host[data-id="${Z(t.sectionId)}"]`)) == null || e.classList.add("is-selected") : (s = this.inner.querySelector(`.sm-block[data-id="${Z(t.blockId)}"]`)) == null || s.classList.add("is-selected"));
|
|
1810
1883
|
}
|
|
1811
1884
|
_destroySortables() {
|
|
1812
1885
|
for (const t of this.sortableRefs) t.destroy();
|
|
1813
1886
|
this.sortableRefs = [];
|
|
1814
1887
|
}
|
|
1815
1888
|
}
|
|
1816
|
-
function
|
|
1889
|
+
function Ke(o, t) {
|
|
1817
1890
|
return `display:flex;flex-wrap:nowrap;width:100%;${t != null && t > 0 ? `gap:${Math.min(t, 200)}px;` : ""}`;
|
|
1818
1891
|
}
|
|
1819
|
-
function
|
|
1892
|
+
function Xe(o, t) {
|
|
1820
1893
|
const e = o.split("-").map(Number), s = e.reduce((i, l) => i + l, 0), n = e[t] ?? 1;
|
|
1821
1894
|
return `${n} 1 0;min-width:0;width:${(n / s * 100).toFixed(2)}%`;
|
|
1822
1895
|
}
|
|
1823
|
-
function
|
|
1896
|
+
function Ye(o) {
|
|
1824
1897
|
return o === "top" ? "flex-start" : o === "bottom" ? "flex-end" : "center";
|
|
1825
1898
|
}
|
|
1826
|
-
function
|
|
1899
|
+
function Z(o) {
|
|
1827
1900
|
return typeof CSS < "u" && CSS.escape ? CSS.escape(o) : o.replace(/[^\w-]/g, "\\$&");
|
|
1828
1901
|
}
|
|
1829
|
-
function
|
|
1902
|
+
function Y(o) {
|
|
1830
1903
|
const t = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
1831
1904
|
return t.setAttribute("width", "12"), t.setAttribute("height", "12"), t.setAttribute("viewBox", "0 0 20 20"), t.innerHTML = o, t;
|
|
1832
1905
|
}
|
|
1833
|
-
function
|
|
1834
|
-
return
|
|
1906
|
+
function Rt() {
|
|
1907
|
+
return Y(
|
|
1835
1908
|
'<circle cx="7" cy="5" r="1.4" fill="currentColor"/><circle cx="13" cy="5" r="1.4" fill="currentColor"/><circle cx="7" cy="10" r="1.4" fill="currentColor"/><circle cx="13" cy="10" r="1.4" fill="currentColor"/><circle cx="7" cy="15" r="1.4" fill="currentColor"/><circle cx="13" cy="15" r="1.4" fill="currentColor"/>'
|
|
1836
1909
|
);
|
|
1837
1910
|
}
|
|
1838
|
-
function
|
|
1839
|
-
return
|
|
1911
|
+
function Nt() {
|
|
1912
|
+
return Y(
|
|
1840
1913
|
'<rect x="6" y="6" width="10" height="10" rx="1.5" stroke="currentColor" stroke-width="1.4" fill="none"/><path d="M4 12V5a1 1 0 011-1h7" stroke="currentColor" stroke-width="1.4" fill="none"/>'
|
|
1841
1914
|
);
|
|
1842
1915
|
}
|
|
1843
|
-
function
|
|
1844
|
-
return
|
|
1916
|
+
function Pt() {
|
|
1917
|
+
return Y(
|
|
1845
1918
|
'<path d="M5 6h10M8 6V4h4v2M6 6l1 10h6l1-10" stroke="currentColor" stroke-width="1.4" fill="none" stroke-linejoin="round"/>'
|
|
1846
1919
|
);
|
|
1847
1920
|
}
|
|
1848
|
-
function
|
|
1849
|
-
return
|
|
1921
|
+
function Je() {
|
|
1922
|
+
return Y(
|
|
1850
1923
|
'<path d="M4 14l8-8 2 2-8 8H4v-2z" stroke="currentColor" stroke-width="1.4" fill="none" stroke-linejoin="round"/>'
|
|
1851
1924
|
);
|
|
1852
1925
|
}
|
|
1853
|
-
function
|
|
1854
|
-
return
|
|
1926
|
+
function Qe() {
|
|
1927
|
+
return Y(
|
|
1855
1928
|
'<path d="M7 7l-3 3 3 3M13 7l3 3-3 3" stroke="currentColor" stroke-width="1.4" fill="none" stroke-linecap="round" stroke-linejoin="round"/>'
|
|
1856
1929
|
);
|
|
1857
1930
|
}
|
|
1858
|
-
class
|
|
1931
|
+
class Ze {
|
|
1859
1932
|
constructor(t) {
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
this.opts = t, this.modal = new
|
|
1933
|
+
_(this, "opts");
|
|
1934
|
+
_(this, "modal");
|
|
1935
|
+
_(this, "cm", null);
|
|
1936
|
+
_(this, "current", "");
|
|
1937
|
+
this.opts = t, this.modal = new dt({
|
|
1865
1938
|
title: "导出 HTML",
|
|
1866
1939
|
className: "sm-modal--export",
|
|
1867
1940
|
width: "min(960px, 96vw)",
|
|
@@ -1887,11 +1960,11 @@ class qe {
|
|
|
1887
1960
|
},
|
|
1888
1961
|
["下载 .html"]
|
|
1889
1962
|
);
|
|
1890
|
-
this.modal.footer.append(s, n, i), this.cm = new
|
|
1963
|
+
this.modal.footer.append(s, n, i), this.cm = new rt({
|
|
1891
1964
|
parent: e,
|
|
1892
|
-
state:
|
|
1965
|
+
state: U.create({
|
|
1893
1966
|
doc: "",
|
|
1894
|
-
extensions: [
|
|
1967
|
+
extensions: [lt, ct(), U.readOnly.of(!0)]
|
|
1895
1968
|
})
|
|
1896
1969
|
});
|
|
1897
1970
|
}
|
|
@@ -1899,7 +1972,7 @@ class qe {
|
|
|
1899
1972
|
this._compile(), this.modal.open(t);
|
|
1900
1973
|
}
|
|
1901
1974
|
_compile() {
|
|
1902
|
-
const t =
|
|
1975
|
+
const t = at(this.opts.store.doc, this.opts.registry, {
|
|
1903
1976
|
withSampleVariables: this.opts.withSampleVariables ?? !0
|
|
1904
1977
|
});
|
|
1905
1978
|
this.current = t.html, this._setText(t.html);
|
|
@@ -1914,11 +1987,11 @@ class qe {
|
|
|
1914
1987
|
await navigator.clipboard.writeText(this.current), this._toast("已复制到剪贴板");
|
|
1915
1988
|
} catch {
|
|
1916
1989
|
const t = document.createElement("textarea");
|
|
1917
|
-
t.value = this.current, document.body.appendChild(t), t.select(),
|
|
1990
|
+
t.value = this.current, document.body.appendChild(t), t.select(), T("copy"), document.body.removeChild(t), this._toast("已复制");
|
|
1918
1991
|
}
|
|
1919
1992
|
}
|
|
1920
1993
|
_beautify() {
|
|
1921
|
-
this.current =
|
|
1994
|
+
this.current = Xt(this.current), this._setText(this.current);
|
|
1922
1995
|
}
|
|
1923
1996
|
_download() {
|
|
1924
1997
|
const t = new Blob([this.current], { type: "text/html;charset=utf-8" }), e = URL.createObjectURL(t), s = document.createElement("a");
|
|
@@ -1935,29 +2008,29 @@ class qe {
|
|
|
1935
2008
|
(t = this.cm) == null || t.destroy(), this.cm = null;
|
|
1936
2009
|
}
|
|
1937
2010
|
}
|
|
1938
|
-
const
|
|
1939
|
-
{ layout: "1", name: "一列", icon:
|
|
2011
|
+
const ts = [
|
|
2012
|
+
{ layout: "1", name: "一列", icon: mt([1]) },
|
|
1940
2013
|
/** 默认 1:1;1:2 / 2:1 在选中 Section 后于右栏「列比例」切换 */
|
|
1941
|
-
{ layout: "1-1", name: "两列", icon:
|
|
1942
|
-
{ layout: "1-1-1", name: "三列", icon:
|
|
2014
|
+
{ layout: "1-1", name: "两列", icon: mt([1, 1]) },
|
|
2015
|
+
{ layout: "1-1-1", name: "三列", icon: mt([1, 1, 1]) }
|
|
1943
2016
|
];
|
|
1944
|
-
class
|
|
2017
|
+
class es {
|
|
1945
2018
|
constructor(t) {
|
|
1946
|
-
|
|
1947
|
-
|
|
2019
|
+
_(this, "el");
|
|
2020
|
+
_(this, "opts");
|
|
1948
2021
|
this.opts = t, this.el = r("aside", { class: "sm-panel sm-panel--left" }), this._render();
|
|
1949
2022
|
}
|
|
1950
2023
|
refresh() {
|
|
1951
2024
|
this._render();
|
|
1952
2025
|
}
|
|
1953
2026
|
_render() {
|
|
1954
|
-
|
|
2027
|
+
R(this.el);
|
|
1955
2028
|
const t = this.opts.registry.byCategory("content"), e = this.opts.registry.byCategory("custom"), s = r("div", { class: "sm-blocks" });
|
|
1956
2029
|
s.append(this._renderLayoutGroup()), t.length && s.append(this._renderBlockGroup("内容", t)), e.length && s.append(this._renderBlockGroup("自定义", e)), this.el.append(s);
|
|
1957
2030
|
}
|
|
1958
2031
|
_renderLayoutGroup() {
|
|
1959
2032
|
const t = r("div", { class: "sm-blocks__grid" });
|
|
1960
|
-
for (const e of
|
|
2033
|
+
for (const e of ts)
|
|
1961
2034
|
t.append(
|
|
1962
2035
|
r(
|
|
1963
2036
|
"div",
|
|
@@ -1973,7 +2046,7 @@ class Ge {
|
|
|
1973
2046
|
]
|
|
1974
2047
|
)
|
|
1975
2048
|
);
|
|
1976
|
-
return
|
|
2049
|
+
return nt.create(t, {
|
|
1977
2050
|
group: { name: "sections", pull: "clone", put: !1 },
|
|
1978
2051
|
sort: !1,
|
|
1979
2052
|
animation: 120,
|
|
@@ -2003,7 +2076,7 @@ class Ge {
|
|
|
2003
2076
|
]
|
|
2004
2077
|
)
|
|
2005
2078
|
);
|
|
2006
|
-
return
|
|
2079
|
+
return nt.create(s, {
|
|
2007
2080
|
group: { name: "blocks", pull: "clone", put: !1 },
|
|
2008
2081
|
sort: !1,
|
|
2009
2082
|
animation: 120,
|
|
@@ -2016,7 +2089,7 @@ class Ge {
|
|
|
2016
2089
|
]);
|
|
2017
2090
|
}
|
|
2018
2091
|
}
|
|
2019
|
-
function
|
|
2092
|
+
function mt(o) {
|
|
2020
2093
|
const t = o.reduce((c, a) => c + a, 0), e = 24, s = 1, n = e - s * (o.length - 1);
|
|
2021
2094
|
let i = 0;
|
|
2022
2095
|
return `<svg width="24" height="24" viewBox="0 0 24 24">${o.map((c) => {
|
|
@@ -2026,22 +2099,22 @@ function ht(o) {
|
|
|
2026
2099
|
return i += a + s, p;
|
|
2027
2100
|
}).join("")}</svg>`;
|
|
2028
2101
|
}
|
|
2029
|
-
const
|
|
2102
|
+
const Ht = {
|
|
2030
2103
|
pc: { width: 800, label: "PC" },
|
|
2031
2104
|
pad: { width: 640, label: "Pad" },
|
|
2032
2105
|
phone: { width: 375, label: "Phone" }
|
|
2033
|
-
},
|
|
2106
|
+
}, ot = class ot {
|
|
2034
2107
|
constructor(t) {
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
this.opts = t, this.modal = new
|
|
2108
|
+
_(this, "opts");
|
|
2109
|
+
_(this, "modal");
|
|
2110
|
+
_(this, "device", "pc");
|
|
2111
|
+
_(this, "iframe");
|
|
2112
|
+
_(this, "viewport");
|
|
2113
|
+
_(this, "deviceBtns", {});
|
|
2114
|
+
_(this, "iframeRo");
|
|
2115
|
+
_(this, "layoutRaf", null);
|
|
2116
|
+
_(this, "onWinResize");
|
|
2117
|
+
this.opts = t, this.modal = new dt({
|
|
2045
2118
|
title: "预览邮件",
|
|
2046
2119
|
className: "sm-modal--preview",
|
|
2047
2120
|
width: "min(960px, calc(100vw - 32px))",
|
|
@@ -2063,7 +2136,7 @@ const Rt = {
|
|
|
2063
2136
|
type: "button",
|
|
2064
2137
|
onclick: () => this.setDevice(s)
|
|
2065
2138
|
},
|
|
2066
|
-
[
|
|
2139
|
+
[ss(s), Ht[s].label]
|
|
2067
2140
|
);
|
|
2068
2141
|
this.deviceBtns[s] = n, e.append(n);
|
|
2069
2142
|
}), this.modal.appendHeaderTool(e);
|
|
@@ -2073,7 +2146,7 @@ const Rt = {
|
|
|
2073
2146
|
}
|
|
2074
2147
|
setDevice(t) {
|
|
2075
2148
|
this.device = t;
|
|
2076
|
-
const e =
|
|
2149
|
+
const e = Ht[t];
|
|
2077
2150
|
this.viewport.style.setProperty("--sm-preview-w", `${e.width}px`);
|
|
2078
2151
|
for (const s of Object.keys(this.deviceBtns))
|
|
2079
2152
|
this.deviceBtns[s].classList.toggle("sm-segmented__item--active", s === t);
|
|
@@ -2082,7 +2155,7 @@ const Rt = {
|
|
|
2082
2155
|
);
|
|
2083
2156
|
}
|
|
2084
2157
|
_render() {
|
|
2085
|
-
const t =
|
|
2158
|
+
const t = at(this.opts.store.doc, this.opts.registry, {
|
|
2086
2159
|
withSampleVariables: !0
|
|
2087
2160
|
});
|
|
2088
2161
|
this.iframe.srcdoc = t.html;
|
|
@@ -2099,7 +2172,7 @@ const Rt = {
|
|
|
2099
2172
|
if (!e || !s) return;
|
|
2100
2173
|
const n = Math.max(e.scrollHeight, s.scrollHeight), i = Math.max(
|
|
2101
2174
|
240,
|
|
2102
|
-
window.innerHeight -
|
|
2175
|
+
window.innerHeight - ot.VIEWPORT_RESERVED_Y
|
|
2103
2176
|
), c = Math.min(Math.max(Math.ceil(n), 200), i);
|
|
2104
2177
|
this.viewport.style.height = `${c}px`;
|
|
2105
2178
|
} catch {
|
|
@@ -2123,13 +2196,13 @@ const Rt = {
|
|
|
2123
2196
|
}
|
|
2124
2197
|
};
|
|
2125
2198
|
/** 标题栏 + body 上下 padding + 与视口的小间距 */
|
|
2126
|
-
|
|
2127
|
-
let
|
|
2128
|
-
function
|
|
2199
|
+
_(ot, "VIEWPORT_RESERVED_Y", 112);
|
|
2200
|
+
let wt = ot;
|
|
2201
|
+
function ss(o) {
|
|
2129
2202
|
const t = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
2130
2203
|
return t.setAttribute("width", "14"), t.setAttribute("height", "14"), t.setAttribute("viewBox", "0 0 20 20"), o === "pc" ? t.innerHTML = '<rect x="2" y="4" width="16" height="11" rx="1.5" stroke="currentColor" stroke-width="1.4" fill="none"/><path d="M7 18h6" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/>' : o === "pad" ? t.innerHTML = '<rect x="4" y="2" width="12" height="16" rx="2" stroke="currentColor" stroke-width="1.4" fill="none"/><circle cx="10" cy="16" r="0.6" fill="currentColor"/>' : t.innerHTML = '<rect x="6" y="2" width="8" height="16" rx="1.5" stroke="currentColor" stroke-width="1.4" fill="none"/><circle cx="10" cy="16" r="0.6" fill="currentColor"/>', t;
|
|
2131
2204
|
}
|
|
2132
|
-
const
|
|
2205
|
+
const Yt = [
|
|
2133
2206
|
{ label: "默认", value: "" },
|
|
2134
2207
|
{ label: "Inter", value: "Inter, -apple-system, BlinkMacSystemFont, sans-serif" },
|
|
2135
2208
|
{ label: "苹方/PingFang", value: '"PingFang SC", "Helvetica Neue", Arial, sans-serif' },
|
|
@@ -2139,22 +2212,22 @@ const Ot = [
|
|
|
2139
2212
|
{ label: "Arial", value: "Arial, sans-serif" },
|
|
2140
2213
|
{ label: "Georgia", value: "Georgia, serif" },
|
|
2141
2214
|
{ label: "Courier", value: '"Courier New", monospace' }
|
|
2142
|
-
],
|
|
2143
|
-
class
|
|
2215
|
+
], st = ["12px", "13px", "14px", "15px", "16px", "18px", "20px", "24px", "28px", "32px"];
|
|
2216
|
+
class ns {
|
|
2144
2217
|
constructor(t) {
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2218
|
+
_(this, "el");
|
|
2219
|
+
_(this, "opts");
|
|
2220
|
+
_(this, "editor", null);
|
|
2221
|
+
_(this, "btns", {});
|
|
2222
|
+
_(this, "selectFontFamily");
|
|
2223
|
+
_(this, "selectFontSize");
|
|
2224
|
+
_(this, "selectFontWeight");
|
|
2225
|
+
_(this, "inputColor");
|
|
2226
|
+
_(this, "inputBgColor");
|
|
2227
|
+
_(this, "inputLink");
|
|
2228
|
+
_(this, "linkPanel");
|
|
2156
2229
|
/** 最近一次选区推断出的链接,供打开面板时预填 */
|
|
2157
|
-
|
|
2230
|
+
_(this, "lastLinkHref", null);
|
|
2158
2231
|
this.opts = t, this.el = r("div", { class: "sm-floating-toolbar", role: "toolbar" }), this._build(), this.hide(), t.positionRoot.append(this.el), this.el.addEventListener(
|
|
2159
2232
|
"mousedown",
|
|
2160
2233
|
() => {
|
|
@@ -2187,10 +2260,10 @@ class Xe {
|
|
|
2187
2260
|
this._setActive("bold", e.bold), this._setActive("italic", e.italic), this._setActive("underline", e.underline), this._setActive("strikethrough", e.strikethrough), this._setActive("ul", e.unorderedList), this._setActive("ol", e.orderedList), this._setActive("alignLeft", e.align === "left"), this._setActive("alignCenter", e.align === "center"), this._setActive("alignRight", e.align === "right");
|
|
2188
2261
|
const s = !!e.link;
|
|
2189
2262
|
if (this.lastLinkHref = e.link, this.btns.unlink.style.display = s ? "" : "none", e.foreColor) {
|
|
2190
|
-
const i =
|
|
2263
|
+
const i = jt(e.foreColor);
|
|
2191
2264
|
i && (this.inputColor.value = i);
|
|
2192
2265
|
}
|
|
2193
|
-
this.inputBgColor.value = e.backColor ?
|
|
2266
|
+
this.inputBgColor.value = e.backColor ? jt(e.backColor) ?? "#ffffff" : "#ffffff", e.fontName && (this.selectFontFamily.value = is(e.fontName)), this.selectFontSize.value = os(e.fontSize), this.selectFontWeight.value = rs(e.fontWeight);
|
|
2194
2267
|
const n = this.editor;
|
|
2195
2268
|
requestAnimationFrame(() => {
|
|
2196
2269
|
!this.editor || n !== this.editor || !this.el.classList.contains("is-visible") || this._positionForAnchor(n.getAnchorRect());
|
|
@@ -2210,31 +2283,31 @@ class Xe {
|
|
|
2210
2283
|
}), this.btns.strikethrough = this._btn("S", "删除线", e("strikeThrough"), {
|
|
2211
2284
|
textDecoration: "line-through"
|
|
2212
2285
|
}), this.btns.alignLeft = this._iconBtn(
|
|
2213
|
-
|
|
2286
|
+
V(
|
|
2214
2287
|
'<path d="M3 5h14M3 9h10M3 13h14M3 17h10" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>'
|
|
2215
2288
|
),
|
|
2216
2289
|
"左对齐",
|
|
2217
2290
|
e("justifyLeft")
|
|
2218
2291
|
), this.btns.alignCenter = this._iconBtn(
|
|
2219
|
-
|
|
2292
|
+
V(
|
|
2220
2293
|
'<path d="M3 5h14M5 9h10M3 13h14M5 17h10" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>'
|
|
2221
2294
|
),
|
|
2222
2295
|
"居中",
|
|
2223
2296
|
e("justifyCenter")
|
|
2224
2297
|
), this.btns.alignRight = this._iconBtn(
|
|
2225
|
-
|
|
2298
|
+
V(
|
|
2226
2299
|
'<path d="M3 5h14M7 9h10M3 13h14M7 17h10" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>'
|
|
2227
2300
|
),
|
|
2228
2301
|
"右对齐",
|
|
2229
2302
|
e("justifyRight")
|
|
2230
2303
|
), this.btns.ul = this._iconBtn(
|
|
2231
|
-
|
|
2304
|
+
V(
|
|
2232
2305
|
'<circle cx="4" cy="6" r="1.2" fill="currentColor"/><circle cx="4" cy="10" r="1.2" fill="currentColor"/><circle cx="4" cy="14" r="1.2" fill="currentColor"/><path d="M8 6h9M8 10h9M8 14h9" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>'
|
|
2233
2306
|
),
|
|
2234
2307
|
"无序列表",
|
|
2235
2308
|
e("insertUnorderedList")
|
|
2236
2309
|
), this.btns.ol = this._iconBtn(
|
|
2237
|
-
|
|
2310
|
+
V(
|
|
2238
2311
|
'<text x="2" y="8" font-size="6" font-weight="600" fill="currentColor">1</text><text x="2" y="14" font-size="6" font-weight="600" fill="currentColor">2</text><path d="M8 6h9M8 12h9" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>'
|
|
2239
2312
|
),
|
|
2240
2313
|
"有序列表",
|
|
@@ -2248,7 +2321,7 @@ class Xe {
|
|
|
2248
2321
|
i ? (l = this.editor) == null || l.exec("fontName", i) : (c = this.editor) == null || c.exec("removeFormat");
|
|
2249
2322
|
}
|
|
2250
2323
|
});
|
|
2251
|
-
for (const n of
|
|
2324
|
+
for (const n of Yt) {
|
|
2252
2325
|
const i = document.createElement("option");
|
|
2253
2326
|
i.value = n.value, i.textContent = n.label, this.selectFontFamily.append(i);
|
|
2254
2327
|
}
|
|
@@ -2265,7 +2338,7 @@ class Xe {
|
|
|
2265
2338
|
const n = document.createElement("option");
|
|
2266
2339
|
n.value = "", n.textContent = "字号", this.selectFontSize.append(n);
|
|
2267
2340
|
}
|
|
2268
|
-
for (const n of
|
|
2341
|
+
for (const n of st) {
|
|
2269
2342
|
const i = document.createElement("option");
|
|
2270
2343
|
i.value = n, i.textContent = n, this.selectFontSize.append(i);
|
|
2271
2344
|
}
|
|
@@ -2282,7 +2355,7 @@ class Xe {
|
|
|
2282
2355
|
const n = document.createElement("option");
|
|
2283
2356
|
n.value = "", n.textContent = "字重", this.selectFontWeight.append(n);
|
|
2284
2357
|
}
|
|
2285
|
-
for (const n of
|
|
2358
|
+
for (const n of it) {
|
|
2286
2359
|
const i = document.createElement("option");
|
|
2287
2360
|
i.value = n.value, i.textContent = n.label, this.selectFontWeight.append(i);
|
|
2288
2361
|
}
|
|
@@ -2291,7 +2364,7 @@ class Xe {
|
|
|
2291
2364
|
type: "color",
|
|
2292
2365
|
title: "文字颜色",
|
|
2293
2366
|
value: "#433f3f"
|
|
2294
|
-
}),
|
|
2367
|
+
}), X(this.inputColor, {
|
|
2295
2368
|
layerRoot: this.opts.positionRoot,
|
|
2296
2369
|
liveCommit: !0,
|
|
2297
2370
|
autoFocusHex: !1,
|
|
@@ -2312,7 +2385,7 @@ class Xe {
|
|
|
2312
2385
|
type: "color",
|
|
2313
2386
|
title: "文字背景色",
|
|
2314
2387
|
value: "#fff7e6"
|
|
2315
|
-
}),
|
|
2388
|
+
}), X(this.inputBgColor, {
|
|
2316
2389
|
layerRoot: this.opts.positionRoot,
|
|
2317
2390
|
liveCommit: !0,
|
|
2318
2391
|
autoFocusHex: !1,
|
|
@@ -2329,19 +2402,19 @@ class Xe {
|
|
|
2329
2402
|
return (n = this.editor) == null ? void 0 : n.refocus();
|
|
2330
2403
|
}
|
|
2331
2404
|
}), this.btns.link = this._iconBtn(
|
|
2332
|
-
|
|
2405
|
+
V(
|
|
2333
2406
|
'<path d="M9 11.5l1.5 1.5a3.5 3.5 0 005-5l-2-2a3.5 3.5 0 00-5 0M11 8.5L9.5 7a3.5 3.5 0 00-5 5l2 2a3.5 3.5 0 005 0" stroke="currentColor" stroke-width="1.6" fill="none" stroke-linecap="round" stroke-linejoin="round"/>'
|
|
2334
2407
|
),
|
|
2335
2408
|
"插入或编辑链接",
|
|
2336
2409
|
() => this._toggleLinkPanel()
|
|
2337
2410
|
), this.btns.unlink = this._iconBtn(
|
|
2338
|
-
|
|
2411
|
+
V(
|
|
2339
2412
|
'<path d="M9 11.5l1.5 1.5a3.5 3.5 0 005-5l-2-2" stroke="currentColor" stroke-width="1.6" fill="none" stroke-linecap="round"/><path d="M3 3l14 14" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>'
|
|
2340
2413
|
),
|
|
2341
2414
|
"取消链接",
|
|
2342
2415
|
e("unlink")
|
|
2343
2416
|
), this.btns.clear = this._iconBtn(
|
|
2344
|
-
|
|
2417
|
+
V(
|
|
2345
2418
|
'<text x="2" y="14" font-size="11" font-weight="700" fill="currentColor">T</text><text x="11" y="9" font-size="7" font-weight="700" fill="currentColor">x</text><path d="M11 11l5 5M16 11l-5 5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/>'
|
|
2346
2419
|
),
|
|
2347
2420
|
"清除格式",
|
|
@@ -2443,37 +2516,37 @@ class Xe {
|
|
|
2443
2516
|
return r("div", { class: "sm-floating-toolbar__group" }, t);
|
|
2444
2517
|
}
|
|
2445
2518
|
}
|
|
2446
|
-
function
|
|
2519
|
+
function V(o) {
|
|
2447
2520
|
const t = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
2448
2521
|
return t.setAttribute("width", "14"), t.setAttribute("height", "14"), t.setAttribute("viewBox", "0 0 20 20"), t.innerHTML = o, t;
|
|
2449
2522
|
}
|
|
2450
|
-
function
|
|
2523
|
+
function is(o) {
|
|
2451
2524
|
const t = o.toLowerCase().replace(/['"]/g, "").split(",")[0].trim();
|
|
2452
|
-
for (const e of
|
|
2525
|
+
for (const e of Yt)
|
|
2453
2526
|
if (e.value && e.value.toLowerCase().includes(t))
|
|
2454
2527
|
return e.value;
|
|
2455
2528
|
return "";
|
|
2456
2529
|
}
|
|
2457
|
-
function
|
|
2530
|
+
function os(o) {
|
|
2458
2531
|
if (!o) return "";
|
|
2459
2532
|
const t = o.trim().match(/^(\d+(?:\.\d+)?)px$/i);
|
|
2460
2533
|
if (!t) return "";
|
|
2461
2534
|
const e = `${Math.round(parseFloat(t[1]))}px`;
|
|
2462
|
-
if (
|
|
2535
|
+
if (st.includes(e)) return e;
|
|
2463
2536
|
const s = parseFloat(e);
|
|
2464
|
-
let n =
|
|
2465
|
-
for (const l of
|
|
2537
|
+
let n = st[0], i = 1 / 0;
|
|
2538
|
+
for (const l of st) {
|
|
2466
2539
|
const c = Math.abs(parseFloat(l) - s);
|
|
2467
2540
|
c < i && (i = c, n = l);
|
|
2468
2541
|
}
|
|
2469
2542
|
return n;
|
|
2470
2543
|
}
|
|
2471
|
-
function
|
|
2544
|
+
function rs(o) {
|
|
2472
2545
|
if (!o) return "";
|
|
2473
|
-
const t =
|
|
2474
|
-
return
|
|
2546
|
+
const t = j(o);
|
|
2547
|
+
return it.some((e) => e.value === t) ? t : "";
|
|
2475
2548
|
}
|
|
2476
|
-
function
|
|
2549
|
+
function jt(o) {
|
|
2477
2550
|
const t = o.trim();
|
|
2478
2551
|
if (!t) return null;
|
|
2479
2552
|
if (t.startsWith("#")) {
|
|
@@ -2488,7 +2561,7 @@ function Nt(o) {
|
|
|
2488
2561
|
const s = (n) => Number(n).toString(16).padStart(2, "0");
|
|
2489
2562
|
return `#${s(e[1])}${s(e[2])}${s(e[3])}`;
|
|
2490
2563
|
}
|
|
2491
|
-
function
|
|
2564
|
+
function ls(o) {
|
|
2492
2565
|
return {
|
|
2493
2566
|
wechat: "#1AAD19",
|
|
2494
2567
|
weibo: "#E6162D",
|
|
@@ -2505,10 +2578,10 @@ function Qe(o) {
|
|
|
2505
2578
|
web: "#6b7280"
|
|
2506
2579
|
}[o] ?? "#6b7280";
|
|
2507
2580
|
}
|
|
2508
|
-
class
|
|
2581
|
+
class cs {
|
|
2509
2582
|
constructor(t) {
|
|
2510
|
-
|
|
2511
|
-
|
|
2583
|
+
_(this, "el");
|
|
2584
|
+
_(this, "opts");
|
|
2512
2585
|
this.opts = t, this.el = r("nav", {
|
|
2513
2586
|
class: "sm-focus-crumb",
|
|
2514
2587
|
"aria-label": "当前选中"
|
|
@@ -2518,7 +2591,7 @@ class ts {
|
|
|
2518
2591
|
this.el.hidden = !t;
|
|
2519
2592
|
}
|
|
2520
2593
|
sync() {
|
|
2521
|
-
|
|
2594
|
+
R(this.el);
|
|
2522
2595
|
const t = this._buildItems();
|
|
2523
2596
|
if (!t.length) {
|
|
2524
2597
|
this.el.hidden = !0;
|
|
@@ -2554,59 +2627,59 @@ class ts {
|
|
|
2554
2627
|
if (!l)
|
|
2555
2628
|
return [{ label: s, current: !0 }];
|
|
2556
2629
|
if (l.kind === "section") {
|
|
2557
|
-
const u =
|
|
2630
|
+
const u = H(c, l.sectionId);
|
|
2558
2631
|
return u ? [
|
|
2559
2632
|
{ label: s, current: !1, onClick: n },
|
|
2560
|
-
{ label:
|
|
2633
|
+
{ label: vt(u.layout), current: !0 }
|
|
2561
2634
|
] : [{ label: s, current: !0 }];
|
|
2562
2635
|
}
|
|
2563
|
-
const a =
|
|
2636
|
+
const a = H(c, l.sectionId), p = L(c, l.blockId);
|
|
2564
2637
|
if (!a || !p)
|
|
2565
2638
|
return [{ label: s, current: !0 }];
|
|
2566
|
-
const
|
|
2639
|
+
const g = ((d = e.get(p.block.type)) == null ? void 0 : d.name) ?? p.block.type;
|
|
2567
2640
|
return [
|
|
2568
2641
|
{
|
|
2569
|
-
label:
|
|
2642
|
+
label: vt(a.layout),
|
|
2570
2643
|
current: !1,
|
|
2571
2644
|
onClick: () => i(l.sectionId)
|
|
2572
2645
|
},
|
|
2573
|
-
{ label:
|
|
2646
|
+
{ label: g, current: !0 }
|
|
2574
2647
|
];
|
|
2575
2648
|
}
|
|
2576
2649
|
}
|
|
2577
|
-
function
|
|
2578
|
-
const { adapter: t, onPick: e, parent: s = document.body, onClose: n } = o, i = new
|
|
2650
|
+
function as(o) {
|
|
2651
|
+
const { adapter: t, onPick: e, parent: s = document.body, onClose: n } = o, i = new dt({
|
|
2579
2652
|
title: "图库",
|
|
2580
2653
|
width: "min(760px, 94vw)",
|
|
2581
2654
|
height: "min(580px, 88vh)",
|
|
2582
2655
|
className: "sm-modal--gallery",
|
|
2583
2656
|
onClose: n
|
|
2584
2657
|
}), l = r("div", { class: "sm-gallery-modal" });
|
|
2585
|
-
let c = "", a = 0, p = !1,
|
|
2658
|
+
let c = "", a = 0, p = !1, g = !1, d = null;
|
|
2586
2659
|
const u = r("div", {
|
|
2587
2660
|
class: "sm-gallery-modal__error",
|
|
2588
2661
|
style: "display:none",
|
|
2589
2662
|
role: "alert"
|
|
2590
|
-
}),
|
|
2663
|
+
}), m = r("input", {
|
|
2591
2664
|
class: "sm-input sm-gallery-modal__search",
|
|
2592
2665
|
type: "search",
|
|
2593
2666
|
placeholder: "搜索…",
|
|
2594
2667
|
"aria-label": "搜索图片"
|
|
2595
2668
|
});
|
|
2596
|
-
let
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
c =
|
|
2669
|
+
let f = null;
|
|
2670
|
+
m.addEventListener("input", () => {
|
|
2671
|
+
f && clearTimeout(f), f = setTimeout(() => {
|
|
2672
|
+
c = m.value, C();
|
|
2600
2673
|
}, 320);
|
|
2601
2674
|
});
|
|
2602
|
-
const
|
|
2675
|
+
const b = r("div", { class: "sm-gallery-modal__grid" }), y = r(
|
|
2603
2676
|
"button",
|
|
2604
2677
|
{
|
|
2605
2678
|
class: "sm-btn sm-btn--secondary sm-gallery-modal__loadmore",
|
|
2606
2679
|
type: "button",
|
|
2607
2680
|
style: "display:none",
|
|
2608
2681
|
onclick: () => {
|
|
2609
|
-
!p ||
|
|
2682
|
+
!p || g || E(a + 1, !0);
|
|
2610
2683
|
}
|
|
2611
2684
|
},
|
|
2612
2685
|
["加载更多"]
|
|
@@ -2624,23 +2697,23 @@ function es(o) {
|
|
|
2624
2697
|
x ? (u.textContent = x, u.style.display = "") : (u.textContent = "", u.style.display = "none");
|
|
2625
2698
|
}
|
|
2626
2699
|
function k() {
|
|
2627
|
-
|
|
2700
|
+
b.querySelectorAll(".sm-gallery-modal__cell").forEach((M) => {
|
|
2628
2701
|
const S = M.dataset.id;
|
|
2629
2702
|
M.classList.toggle("is-selected", !!d && S === d.id);
|
|
2630
2703
|
});
|
|
2631
2704
|
}
|
|
2632
2705
|
function w(x, M) {
|
|
2633
2706
|
var S;
|
|
2634
|
-
if (M ||
|
|
2635
|
-
|
|
2707
|
+
if (M || R(b), x.length === 0 && !M) {
|
|
2708
|
+
b.append(
|
|
2636
2709
|
r("div", { class: "sm-gallery-modal__empty" }, [
|
|
2637
2710
|
"暂无图片,可上传、添加链接或更换搜索条件"
|
|
2638
2711
|
])
|
|
2639
|
-
),
|
|
2712
|
+
), y.style.display = p ? "" : "none";
|
|
2640
2713
|
return;
|
|
2641
2714
|
}
|
|
2642
2715
|
for (const F of x) {
|
|
2643
|
-
const
|
|
2716
|
+
const J = F.thumbnailUrl || F.url, ut = r("div", { class: "sm-gallery-modal__cell-wrap" }), xt = r(
|
|
2644
2717
|
"button",
|
|
2645
2718
|
{
|
|
2646
2719
|
type: "button",
|
|
@@ -2650,69 +2723,69 @@ function es(o) {
|
|
|
2650
2723
|
onclick: () => {
|
|
2651
2724
|
d = F, k(), h.disabled = !1;
|
|
2652
2725
|
},
|
|
2653
|
-
ondblclick: (
|
|
2654
|
-
|
|
2726
|
+
ondblclick: (ht) => {
|
|
2727
|
+
ht.preventDefault(), d = F, B();
|
|
2655
2728
|
}
|
|
2656
2729
|
},
|
|
2657
2730
|
[]
|
|
2658
|
-
),
|
|
2731
|
+
), Q = r("img", {
|
|
2659
2732
|
class: "sm-gallery-modal__thumb",
|
|
2660
2733
|
alt: "",
|
|
2661
2734
|
loading: "lazy",
|
|
2662
2735
|
decoding: "async"
|
|
2663
2736
|
});
|
|
2664
|
-
|
|
2665
|
-
|
|
2737
|
+
Q.src = J, Q.onerror = () => {
|
|
2738
|
+
Q.style.opacity = "0.72";
|
|
2666
2739
|
};
|
|
2667
|
-
const
|
|
2740
|
+
const Jt = r("div", { class: "sm-gallery-modal__caption" }, [
|
|
2668
2741
|
(S = F.title) != null && S.trim() ? F.title : "图片"
|
|
2669
2742
|
]);
|
|
2670
|
-
if (
|
|
2671
|
-
const
|
|
2743
|
+
if (xt.append(Q, Jt), ut.append(xt), t.deleteItem) {
|
|
2744
|
+
const ht = r(
|
|
2672
2745
|
"button",
|
|
2673
2746
|
{
|
|
2674
2747
|
type: "button",
|
|
2675
2748
|
class: "sm-gallery-modal__cell-delete",
|
|
2676
2749
|
title: "从图库删除",
|
|
2677
|
-
onclick: async (
|
|
2678
|
-
if (
|
|
2750
|
+
onclick: async (Ft) => {
|
|
2751
|
+
if (Ft.preventDefault(), Ft.stopPropagation(), !!window.confirm("确定从图库中删除这张图片?"))
|
|
2679
2752
|
try {
|
|
2680
2753
|
await t.deleteItem(F.id), (d == null ? void 0 : d.id) === F.id && (d = null, h.disabled = !0), await C();
|
|
2681
|
-
} catch (
|
|
2682
|
-
v(
|
|
2754
|
+
} catch (Lt) {
|
|
2755
|
+
v(Lt instanceof Error ? Lt.message : "删除失败");
|
|
2683
2756
|
}
|
|
2684
2757
|
}
|
|
2685
2758
|
},
|
|
2686
2759
|
["×"]
|
|
2687
2760
|
);
|
|
2688
|
-
|
|
2761
|
+
ut.append(ht);
|
|
2689
2762
|
}
|
|
2690
|
-
|
|
2763
|
+
b.append(ut);
|
|
2691
2764
|
}
|
|
2692
|
-
|
|
2765
|
+
y.style.display = p ? "" : "none";
|
|
2693
2766
|
}
|
|
2694
2767
|
async function E(x, M) {
|
|
2695
|
-
if (!
|
|
2696
|
-
|
|
2768
|
+
if (!g) {
|
|
2769
|
+
g = !0, y.disabled = !0, v(null);
|
|
2697
2770
|
try {
|
|
2698
2771
|
const S = await t.listItems({ query: c, page: x });
|
|
2699
2772
|
p = S.hasMore, a = x, w(S.items, M);
|
|
2700
2773
|
} catch (S) {
|
|
2701
2774
|
v(S instanceof Error ? S.message : "加载失败");
|
|
2702
2775
|
} finally {
|
|
2703
|
-
|
|
2776
|
+
g = !1, y.disabled = !1;
|
|
2704
2777
|
}
|
|
2705
2778
|
}
|
|
2706
2779
|
}
|
|
2707
2780
|
async function C() {
|
|
2708
|
-
a = 0, d = null, h.disabled = !0,
|
|
2781
|
+
a = 0, d = null, h.disabled = !0, R(b), await E(0, !1), k();
|
|
2709
2782
|
}
|
|
2710
2783
|
function B() {
|
|
2711
2784
|
var x;
|
|
2712
2785
|
(x = d == null ? void 0 : d.url) != null && x.trim() && (e(d.url.trim()), i.close());
|
|
2713
2786
|
}
|
|
2714
|
-
const
|
|
2715
|
-
if (
|
|
2787
|
+
const I = r("div", { class: "sm-gallery-modal__toolbar" }), N = r("div", { class: "sm-gallery-modal__toolbar-row" });
|
|
2788
|
+
if (N.append(m), t.addByUrl) {
|
|
2716
2789
|
const x = r("input", {
|
|
2717
2790
|
class: "sm-input sm-gallery-modal__addurl-input",
|
|
2718
2791
|
type: "url",
|
|
@@ -2734,7 +2807,7 @@ function es(o) {
|
|
|
2734
2807
|
},
|
|
2735
2808
|
["添加"]
|
|
2736
2809
|
);
|
|
2737
|
-
|
|
2810
|
+
N.append(x, M);
|
|
2738
2811
|
}
|
|
2739
2812
|
if (t.uploadFile) {
|
|
2740
2813
|
const x = r("input", {
|
|
@@ -2748,8 +2821,8 @@ function es(o) {
|
|
|
2748
2821
|
if (x.value = "", !!S)
|
|
2749
2822
|
try {
|
|
2750
2823
|
await t.uploadFile(S), await C();
|
|
2751
|
-
} catch (
|
|
2752
|
-
v(
|
|
2824
|
+
} catch (J) {
|
|
2825
|
+
v(J instanceof Error ? J.message : "上传失败");
|
|
2753
2826
|
}
|
|
2754
2827
|
});
|
|
2755
2828
|
const M = r(
|
|
@@ -2761,11 +2834,11 @@ function es(o) {
|
|
|
2761
2834
|
},
|
|
2762
2835
|
["上传"]
|
|
2763
2836
|
);
|
|
2764
|
-
|
|
2837
|
+
N.append(M, x);
|
|
2765
2838
|
}
|
|
2766
|
-
|
|
2767
|
-
const
|
|
2768
|
-
l.append(
|
|
2839
|
+
I.append(N);
|
|
2840
|
+
const D = r("div", { class: "sm-gallery-modal__scroll" }, [b, y]);
|
|
2841
|
+
l.append(I, u, D), i.body.append(l), i.footer.append(
|
|
2769
2842
|
r(
|
|
2770
2843
|
"button",
|
|
2771
2844
|
{
|
|
@@ -2778,26 +2851,26 @@ function es(o) {
|
|
|
2778
2851
|
h
|
|
2779
2852
|
), i.open(s), C();
|
|
2780
2853
|
}
|
|
2781
|
-
function
|
|
2854
|
+
function ds(o) {
|
|
2782
2855
|
const t = (o ?? "").trim();
|
|
2783
2856
|
return !t || t.toLowerCase() === "auto" ? "auto" : /^\d+(\.\d+)?%$/.test(t) ? "%" : /^\d+(\.\d+)?px$/i.test(t) || /^\d+(\.\d+)?$/.test(t) ? "px" : "custom";
|
|
2784
2857
|
}
|
|
2785
|
-
function
|
|
2858
|
+
function ft(o, t) {
|
|
2786
2859
|
const e = (o ?? "").trim();
|
|
2787
2860
|
if (!e) return t === "%" ? 100 : 280;
|
|
2788
2861
|
const s = e.match(/^(\d+(\.\d+)?)/), n = s ? parseFloat(s[1]) : t === "%" ? 100 : 280;
|
|
2789
2862
|
return Math.min(t === "%" ? 100 : 1200, Math.max(1, Math.round(n)));
|
|
2790
2863
|
}
|
|
2791
|
-
class
|
|
2864
|
+
class us {
|
|
2792
2865
|
constructor(t) {
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
this.opts = t, this.el = r("aside", { class: "sm-panel sm-panel--right" }), this.focusCrumb = new
|
|
2866
|
+
_(this, "el");
|
|
2867
|
+
_(this, "opts");
|
|
2868
|
+
_(this, "headEl");
|
|
2869
|
+
_(this, "contentEl");
|
|
2870
|
+
_(this, "focusCrumb");
|
|
2871
|
+
_(this, "currentTab", "props");
|
|
2872
|
+
_(this, "codeView", null);
|
|
2873
|
+
this.opts = t, this.el = r("aside", { class: "sm-panel sm-panel--right" }), this.focusCrumb = new cs({
|
|
2801
2874
|
store: t.store,
|
|
2802
2875
|
registry: t.registry,
|
|
2803
2876
|
docRootLabel: t.docRootLabel ?? "邮件",
|
|
@@ -2855,14 +2928,14 @@ class ns {
|
|
|
2855
2928
|
return null;
|
|
2856
2929
|
}
|
|
2857
2930
|
_render() {
|
|
2858
|
-
this._destroyCodeView(),
|
|
2931
|
+
this._destroyCodeView(), R(this.contentEl);
|
|
2859
2932
|
const t = this.opts.store.selection, e = this.opts.store.doc;
|
|
2860
2933
|
if (!t) {
|
|
2861
2934
|
this.contentEl.append(this._renderDocForm(e));
|
|
2862
2935
|
return;
|
|
2863
2936
|
}
|
|
2864
2937
|
if (t.kind === "section") {
|
|
2865
|
-
const l =
|
|
2938
|
+
const l = H(e, t.sectionId);
|
|
2866
2939
|
if (!l) return;
|
|
2867
2940
|
this.contentEl.append(this._renderSectionForm(l));
|
|
2868
2941
|
return;
|
|
@@ -2945,9 +3018,9 @@ class ns {
|
|
|
2945
3018
|
), s.push(
|
|
2946
3019
|
this._textField(
|
|
2947
3020
|
"内容宽度",
|
|
2948
|
-
|
|
3021
|
+
ie(t.meta.width),
|
|
2949
3022
|
(n) => this.opts.store.update((i) => {
|
|
2950
|
-
i.meta.width =
|
|
3023
|
+
i.meta.width = ne(n);
|
|
2951
3024
|
}),
|
|
2952
3025
|
"如 600、600px、100%",
|
|
2953
3026
|
"doc:meta.width"
|
|
@@ -3024,12 +3097,12 @@ class ns {
|
|
|
3024
3097
|
const e = t.attrs;
|
|
3025
3098
|
return r("form", { class: "sm-form", onsubmit: (s) => s.preventDefault() }, [
|
|
3026
3099
|
r("div", { class: "sm-panel__title" }, ["Section 设置"]),
|
|
3027
|
-
...
|
|
3100
|
+
...ve(t.layout) ? [
|
|
3028
3101
|
this._twoColumnRatioField(
|
|
3029
3102
|
t.layout,
|
|
3030
3103
|
(s) => this.opts.store.update((n) => {
|
|
3031
|
-
const i =
|
|
3032
|
-
i &&
|
|
3104
|
+
const i = H(n, t.id);
|
|
3105
|
+
i && ke(i, s);
|
|
3033
3106
|
}),
|
|
3034
3107
|
`section:${t.id}:layout`
|
|
3035
3108
|
)
|
|
@@ -3038,7 +3111,7 @@ class ns {
|
|
|
3038
3111
|
"背景色",
|
|
3039
3112
|
e.backgroundColor ?? "",
|
|
3040
3113
|
(s) => this.opts.store.update((n) => {
|
|
3041
|
-
const i =
|
|
3114
|
+
const i = H(n, t.id);
|
|
3042
3115
|
i && (i.attrs.backgroundColor = s || void 0);
|
|
3043
3116
|
}),
|
|
3044
3117
|
`section:${t.id}:attrs.bg`,
|
|
@@ -3046,10 +3119,10 @@ class ns {
|
|
|
3046
3119
|
),
|
|
3047
3120
|
this._layoutWidthField(
|
|
3048
3121
|
"区域宽度",
|
|
3049
|
-
|
|
3122
|
+
re(e.width),
|
|
3050
3123
|
(s) => this.opts.store.update((n) => {
|
|
3051
|
-
const i =
|
|
3052
|
-
i && (i.attrs.width =
|
|
3124
|
+
const i = H(n, t.id);
|
|
3125
|
+
i && (i.attrs.width = oe(s));
|
|
3053
3126
|
}),
|
|
3054
3127
|
`section:${t.id}:attrs.width`,
|
|
3055
3128
|
"留空=与邮件同宽;自适应等价于清空宽度"
|
|
@@ -3058,7 +3131,7 @@ class ns {
|
|
|
3058
3131
|
"内边距",
|
|
3059
3132
|
[e.paddingTop, e.paddingRight, e.paddingBottom, e.paddingLeft],
|
|
3060
3133
|
(s) => this.opts.store.update((n) => {
|
|
3061
|
-
const i =
|
|
3134
|
+
const i = H(n, t.id);
|
|
3062
3135
|
i && ([i.attrs.paddingTop, i.attrs.paddingRight, i.attrs.paddingBottom, i.attrs.paddingLeft] = s);
|
|
3063
3136
|
}),
|
|
3064
3137
|
`section:${t.id}:attrs.pad`,
|
|
@@ -3072,7 +3145,7 @@ class ns {
|
|
|
3072
3145
|
(s) => {
|
|
3073
3146
|
const n = Math.max(0, Math.min(64, Math.round(s)));
|
|
3074
3147
|
this.opts.store.update((i) => {
|
|
3075
|
-
const l =
|
|
3148
|
+
const l = H(i, t.id);
|
|
3076
3149
|
l && (l.attrs.columnGap = n > 0 ? n : void 0);
|
|
3077
3150
|
});
|
|
3078
3151
|
},
|
|
@@ -3083,7 +3156,7 @@ class ns {
|
|
|
3083
3156
|
"小屏仍并排显示多列(可能字很窄)",
|
|
3084
3157
|
!!e.preserveColumnsOnMobile,
|
|
3085
3158
|
(s) => this.opts.store.update((n) => {
|
|
3086
|
-
const i =
|
|
3159
|
+
const i = H(n, t.id);
|
|
3087
3160
|
i && (i.attrs.preserveColumnsOnMobile = s || void 0);
|
|
3088
3161
|
}),
|
|
3089
3162
|
"开启后 MJML 会生成 mj-group,移动端预览/导出与默认「小屏堆叠列」行为不同。",
|
|
@@ -3105,7 +3178,7 @@ class ns {
|
|
|
3105
3178
|
});
|
|
3106
3179
|
}
|
|
3107
3180
|
_field(t, e) {
|
|
3108
|
-
var
|
|
3181
|
+
var g;
|
|
3109
3182
|
const s = e.id, n = `block:${s}:${t.key}`, i = this.opts.registry.get(e.type), l = i == null ? void 0 : i.defaultProps, c = e.props[t.key], a = c ?? (l == null ? void 0 : l[t.key]), p = (d) => this._updateBlock(s, t.key, d);
|
|
3110
3183
|
switch (t.type) {
|
|
3111
3184
|
case "textarea":
|
|
@@ -3125,31 +3198,31 @@ class ns {
|
|
|
3125
3198
|
return this._colorField(
|
|
3126
3199
|
t.label,
|
|
3127
3200
|
u,
|
|
3128
|
-
(
|
|
3201
|
+
(m) => p(m.trim()),
|
|
3129
3202
|
n,
|
|
3130
3203
|
t.placeholder ?? ""
|
|
3131
3204
|
);
|
|
3132
3205
|
}
|
|
3133
3206
|
case "select": {
|
|
3134
|
-
const d = t.key === "fontWeight" || t.key === "labelFontWeight", u = (
|
|
3207
|
+
const d = t.key === "fontWeight" || t.key === "labelFontWeight", u = (g = t.options) != null && g.length ? t.options : d ? it : [];
|
|
3135
3208
|
if (d && t.inheritGlobal) {
|
|
3136
|
-
const
|
|
3209
|
+
const f = c != null ? String(c).trim() : "";
|
|
3137
3210
|
return this._fontWeightInheritField(
|
|
3138
3211
|
t.label,
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
(
|
|
3212
|
+
f,
|
|
3213
|
+
j(this.opts.store.doc.styles.fontWeight),
|
|
3214
|
+
(b) => p(b),
|
|
3142
3215
|
n,
|
|
3143
3216
|
u,
|
|
3144
3217
|
t.help
|
|
3145
3218
|
);
|
|
3146
3219
|
}
|
|
3147
|
-
const
|
|
3220
|
+
const m = d ? j(String(a ?? "")) : String(a ?? "");
|
|
3148
3221
|
if (d || t.selectVariant === "segmented") {
|
|
3149
|
-
const
|
|
3150
|
-
return t.help &&
|
|
3222
|
+
const f = this._segmentedSelectField(t.label, m, u, p, n);
|
|
3223
|
+
return t.help && f.append(r("div", { class: "sm-field__help" }, [t.help])), f;
|
|
3151
3224
|
}
|
|
3152
|
-
return this._selectField(t.label,
|
|
3225
|
+
return this._selectField(t.label, m, u, p, n);
|
|
3153
3226
|
}
|
|
3154
3227
|
case "switch":
|
|
3155
3228
|
return this._switchField(t.label, !!a, p, t.help, n);
|
|
@@ -3177,7 +3250,7 @@ class ns {
|
|
|
3177
3250
|
return this._fontSizeSliderField(
|
|
3178
3251
|
t.label,
|
|
3179
3252
|
u,
|
|
3180
|
-
(
|
|
3253
|
+
(m) => p(m.trim()),
|
|
3181
3254
|
n,
|
|
3182
3255
|
t.help,
|
|
3183
3256
|
this.opts.store.doc.styles.fontSize
|
|
@@ -3198,20 +3271,20 @@ class ns {
|
|
|
3198
3271
|
Number(d.paddingRight ?? 0),
|
|
3199
3272
|
Number(d.paddingBottom ?? 0),
|
|
3200
3273
|
Number(d.paddingLeft ?? 0)
|
|
3201
|
-
],
|
|
3202
|
-
Number((
|
|
3203
|
-
Number((
|
|
3204
|
-
Number((
|
|
3205
|
-
Number((
|
|
3274
|
+
], m = this.opts.registry.get(e.type), f = m == null ? void 0 : m.defaultProps, b = [
|
|
3275
|
+
Number((f == null ? void 0 : f.paddingTop) ?? 0),
|
|
3276
|
+
Number((f == null ? void 0 : f.paddingRight) ?? 0),
|
|
3277
|
+
Number((f == null ? void 0 : f.paddingBottom) ?? 0),
|
|
3278
|
+
Number((f == null ? void 0 : f.paddingLeft) ?? 0)
|
|
3206
3279
|
];
|
|
3207
|
-
return this._spacingField(t.label, u, (
|
|
3280
|
+
return this._spacingField(t.label, u, (y) => {
|
|
3208
3281
|
this.opts.store.update((h) => {
|
|
3209
3282
|
const v = L(h, s);
|
|
3210
3283
|
if (!v) return;
|
|
3211
3284
|
const k = v.block.props;
|
|
3212
|
-
[k.paddingTop, k.paddingRight, k.paddingBottom, k.paddingLeft] =
|
|
3285
|
+
[k.paddingTop, k.paddingRight, k.paddingBottom, k.paddingLeft] = y;
|
|
3213
3286
|
});
|
|
3214
|
-
}, `${n}:pad`,
|
|
3287
|
+
}, `${n}:pad`, b);
|
|
3215
3288
|
}
|
|
3216
3289
|
case "socialLinkList": {
|
|
3217
3290
|
const d = Array.isArray(a) ? a : Array.isArray(l == null ? void 0 : l[t.key]) ? l[t.key] : [];
|
|
@@ -3235,10 +3308,10 @@ class ns {
|
|
|
3235
3308
|
* 读取当前 props 再合并,禁止依赖闭包里的 items 快照(否则改一行会覆盖其它行已编辑未重绘的数据)。
|
|
3236
3309
|
*/
|
|
3237
3310
|
_socialLinkListField(t, e, s, n, i, l, c) {
|
|
3238
|
-
var
|
|
3239
|
-
const a = ((
|
|
3311
|
+
var b, y;
|
|
3312
|
+
const a = ((b = s[0]) == null ? void 0 : b.value) ?? "weibo", p = r("div", { class: "sm-field" });
|
|
3240
3313
|
p.append(r("label", { class: "sm-field__label" }, [t]));
|
|
3241
|
-
const
|
|
3314
|
+
const g = r("div", { class: "sm-social-link-list" }), d = (h) => {
|
|
3242
3315
|
this.opts.store.update((v) => {
|
|
3243
3316
|
const k = L(v, n);
|
|
3244
3317
|
if (!k) return;
|
|
@@ -3249,7 +3322,7 @@ class ns {
|
|
|
3249
3322
|
d(
|
|
3250
3323
|
(k) => k.map((w, E) => E === h ? { ...w, ...v } : w)
|
|
3251
3324
|
);
|
|
3252
|
-
},
|
|
3325
|
+
}, m = (h) => {
|
|
3253
3326
|
d((v) => v.filter((k, w) => w !== h));
|
|
3254
3327
|
};
|
|
3255
3328
|
for (let h = 0; h < e.length; h++) {
|
|
@@ -3279,13 +3352,13 @@ class ns {
|
|
|
3279
3352
|
class: "sm-social-link-list__remove",
|
|
3280
3353
|
type: "button",
|
|
3281
3354
|
title: "删除",
|
|
3282
|
-
onclick: () =>
|
|
3355
|
+
onclick: () => m(h)
|
|
3283
3356
|
},
|
|
3284
3357
|
["×"]
|
|
3285
3358
|
);
|
|
3286
3359
|
w.append(E, C, B), k.append(w);
|
|
3287
|
-
const
|
|
3288
|
-
|
|
3360
|
+
const I = r("div", { class: "sm-social-link-list__row-extras" }), N = ls(v.network), D = (y = v.backgroundColor) == null ? void 0 : y.trim(), x = D && D.startsWith("#") ? D : N;
|
|
3361
|
+
I.append(
|
|
3289
3362
|
r("input", {
|
|
3290
3363
|
class: "sm-input sm-social-link-list__label",
|
|
3291
3364
|
type: "text",
|
|
@@ -3306,15 +3379,15 @@ class ns {
|
|
|
3306
3379
|
const M = r("input", {
|
|
3307
3380
|
class: "sm-social-link-list__color sm-social-link-list__color--compact",
|
|
3308
3381
|
type: "color",
|
|
3309
|
-
value: x.length >= 4 ? x :
|
|
3382
|
+
value: x.length >= 4 ? x : N,
|
|
3310
3383
|
...c ? { "data-sm-focus": `${c}:row:${h}:bg` } : {}
|
|
3311
3384
|
});
|
|
3312
|
-
|
|
3385
|
+
X(M, {
|
|
3313
3386
|
liveCommit: !0,
|
|
3314
3387
|
onCommit: (S) => u(h, { backgroundColor: S })
|
|
3315
|
-
}),
|
|
3388
|
+
}), I.append(M), k.append(I), g.append(k);
|
|
3316
3389
|
}
|
|
3317
|
-
const
|
|
3390
|
+
const f = r(
|
|
3318
3391
|
"button",
|
|
3319
3392
|
{
|
|
3320
3393
|
class: "sm-btn sm-social-link-list__add",
|
|
@@ -3331,7 +3404,7 @@ class ns {
|
|
|
3331
3404
|
},
|
|
3332
3405
|
["+ 添加社交链接"]
|
|
3333
3406
|
);
|
|
3334
|
-
return p.append(
|
|
3407
|
+
return p.append(g, f), l && p.append(r("div", { class: "sm-field__help" }, [l])), p;
|
|
3335
3408
|
}
|
|
3336
3409
|
/* --------------------------------- 控件 --------------------------------- */
|
|
3337
3410
|
_textField(t, e, s, n = "", i) {
|
|
@@ -3349,23 +3422,23 @@ class ns {
|
|
|
3349
3422
|
}
|
|
3350
3423
|
/** `type: 'image'`:URL 输入 + 可选上传、图床(由 `imageAssets` 注入) */
|
|
3351
3424
|
_imageField(t, e, s, n, i, l) {
|
|
3352
|
-
const c = this.opts.imageAssets, a = !!(c != null && c.uploadImage) && c.showUpload !== !1, p = (c == null ? void 0 : c.showGallery) === !0 && (!!c.imageGallery || !!c.pickImageFromGallery),
|
|
3425
|
+
const c = this.opts.imageAssets, a = !!(c != null && c.uploadImage) && c.showUpload !== !1, p = (c == null ? void 0 : c.showGallery) === !0 && (!!c.imageGallery || !!c.pickImageFromGallery), g = !!(c != null && c.uploadImage || c != null && c.pickImageFromGallery || c != null && c.imageGallery), d = a || p, u = r("div", { class: "sm-image-field__row" }), m = r("input", {
|
|
3353
3426
|
class: "sm-input sm-image-field__url",
|
|
3354
3427
|
type: "url",
|
|
3355
3428
|
value: e,
|
|
3356
3429
|
placeholder: n,
|
|
3357
3430
|
...i ? { "data-sm-focus": i } : {},
|
|
3358
3431
|
oninput: (v) => s(v.target.value)
|
|
3359
|
-
}),
|
|
3432
|
+
}), f = () => ({
|
|
3360
3433
|
blockId: l.blockId,
|
|
3361
3434
|
propKey: l.propKey,
|
|
3362
|
-
currentUrl:
|
|
3435
|
+
currentUrl: m.value
|
|
3363
3436
|
});
|
|
3364
|
-
u.append(
|
|
3365
|
-
const
|
|
3437
|
+
u.append(m);
|
|
3438
|
+
const b = (v) => {
|
|
3366
3439
|
const k = v.trim();
|
|
3367
|
-
k && (s(k),
|
|
3368
|
-
},
|
|
3440
|
+
k && (s(k), m.value = k);
|
|
3441
|
+
}, y = (v, k) => {
|
|
3369
3442
|
v.catch((w) => {
|
|
3370
3443
|
console.error(`[simple-mail] ${k}`, w);
|
|
3371
3444
|
});
|
|
@@ -3378,8 +3451,8 @@ class ns {
|
|
|
3378
3451
|
onchange: (k) => {
|
|
3379
3452
|
var C;
|
|
3380
3453
|
const w = k.target, E = (C = w.files) == null ? void 0 : C[0];
|
|
3381
|
-
w.value = "", E &&
|
|
3382
|
-
c.uploadImage(E,
|
|
3454
|
+
w.value = "", E && y(
|
|
3455
|
+
c.uploadImage(E, f()).then((B) => b(String(B))),
|
|
3383
3456
|
"uploadImage"
|
|
3384
3457
|
);
|
|
3385
3458
|
}
|
|
@@ -3406,15 +3479,15 @@ class ns {
|
|
|
3406
3479
|
title: "从图库选择",
|
|
3407
3480
|
onclick: () => {
|
|
3408
3481
|
if (c.imageGallery) {
|
|
3409
|
-
|
|
3482
|
+
as({
|
|
3410
3483
|
adapter: c.imageGallery,
|
|
3411
|
-
onPick: (v) =>
|
|
3484
|
+
onPick: (v) => b(v)
|
|
3412
3485
|
});
|
|
3413
3486
|
return;
|
|
3414
3487
|
}
|
|
3415
|
-
c.pickImageFromGallery &&
|
|
3416
|
-
c.pickImageFromGallery(
|
|
3417
|
-
v != null && String(v).trim() &&
|
|
3488
|
+
c.pickImageFromGallery && y(
|
|
3489
|
+
c.pickImageFromGallery(f()).then((v) => {
|
|
3490
|
+
v != null && String(v).trim() && b(String(v));
|
|
3418
3491
|
}),
|
|
3419
3492
|
"pickImageFromGallery"
|
|
3420
3493
|
);
|
|
@@ -3427,7 +3500,7 @@ class ns {
|
|
|
3427
3500
|
if (d) {
|
|
3428
3501
|
const v = ["可手输 URL"];
|
|
3429
3502
|
a && v.push("或使用「上传」"), p && v.push("或使用「图床」"), h = `${v.join(";")}。`;
|
|
3430
|
-
} else
|
|
3503
|
+
} else g ? h = "已传入 imageAssets:上传默认显示(提供 uploadImage 且未设 showUpload:false);图库需 showGallery:true,可使用内置 imageGallery 或自管 pickImageFromGallery。仍可手输 URL。" : h = "在 MailEditor 的 imageAssets 中配置 uploadImage、内置 imageGallery 或 pickImageFromGallery 等;未配置时仅支持手输 URL。";
|
|
3431
3504
|
return r("div", { class: "sm-field" }, [
|
|
3432
3505
|
r("label", { class: "sm-field__label" }, [t]),
|
|
3433
3506
|
u,
|
|
@@ -3451,14 +3524,14 @@ class ns {
|
|
|
3451
3524
|
);
|
|
3452
3525
|
}
|
|
3453
3526
|
_numberField(t, e, s, n, i, l = 1, c) {
|
|
3454
|
-
const a = (
|
|
3455
|
-
const
|
|
3456
|
-
if (!l || l <= 0) return
|
|
3457
|
-
const
|
|
3458
|
-
return Number((s +
|
|
3527
|
+
const a = (m) => {
|
|
3528
|
+
const f = Math.min(n, Math.max(s, m));
|
|
3529
|
+
if (!l || l <= 0) return f;
|
|
3530
|
+
const b = Math.round((f - s) / l);
|
|
3531
|
+
return Number((s + b * l).toPrecision(12));
|
|
3459
3532
|
};
|
|
3460
3533
|
if (!this._preferSliderControls()) {
|
|
3461
|
-
const
|
|
3534
|
+
const m = r("input", {
|
|
3462
3535
|
class: "sm-input",
|
|
3463
3536
|
type: "number",
|
|
3464
3537
|
value: String(e),
|
|
@@ -3466,30 +3539,30 @@ class ns {
|
|
|
3466
3539
|
max: n,
|
|
3467
3540
|
step: l,
|
|
3468
3541
|
...c ? { "data-sm-focus": c } : {}
|
|
3469
|
-
}),
|
|
3470
|
-
const
|
|
3471
|
-
if (
|
|
3472
|
-
|
|
3542
|
+
}), f = () => {
|
|
3543
|
+
const b = m.value.trim(), y = a(e);
|
|
3544
|
+
if (b === "") {
|
|
3545
|
+
m.value = String(y), i(y);
|
|
3473
3546
|
return;
|
|
3474
3547
|
}
|
|
3475
|
-
const h = Number(
|
|
3476
|
-
|
|
3548
|
+
const h = Number(b), v = a(Number.isNaN(h) ? y : h);
|
|
3549
|
+
m.value = String(v), i(v);
|
|
3477
3550
|
};
|
|
3478
|
-
return s > 0 ? (
|
|
3479
|
-
|
|
3480
|
-
})) : (
|
|
3481
|
-
const
|
|
3482
|
-
if (
|
|
3483
|
-
const
|
|
3484
|
-
Number.isNaN(
|
|
3485
|
-
}),
|
|
3486
|
-
|
|
3551
|
+
return s > 0 ? (m.addEventListener("blur", f), m.addEventListener("keydown", (b) => {
|
|
3552
|
+
b.key === "Enter" && m.blur();
|
|
3553
|
+
})) : (m.addEventListener("input", () => {
|
|
3554
|
+
const b = m.value.trim();
|
|
3555
|
+
if (b === "") return;
|
|
3556
|
+
const y = Number(b);
|
|
3557
|
+
Number.isNaN(y) || i(a(y));
|
|
3558
|
+
}), m.addEventListener("blur", f), m.addEventListener("keydown", (b) => {
|
|
3559
|
+
b.key === "Enter" && f();
|
|
3487
3560
|
})), r("div", { class: "sm-field" }, [
|
|
3488
3561
|
r("label", { class: "sm-field__label" }, [t]),
|
|
3489
|
-
|
|
3562
|
+
m
|
|
3490
3563
|
]);
|
|
3491
3564
|
}
|
|
3492
|
-
const p = a(e),
|
|
3565
|
+
const p = a(e), g = r("input", {
|
|
3493
3566
|
type: "range",
|
|
3494
3567
|
min: s,
|
|
3495
3568
|
max: n,
|
|
@@ -3503,34 +3576,34 @@ class ns {
|
|
|
3503
3576
|
step: l,
|
|
3504
3577
|
value: String(p),
|
|
3505
3578
|
...c ? { "data-sm-focus": c } : {}
|
|
3506
|
-
}), u = (
|
|
3507
|
-
const
|
|
3508
|
-
|
|
3579
|
+
}), u = (m) => {
|
|
3580
|
+
const f = a(m);
|
|
3581
|
+
g.value = String(f), d.value = String(f), i(f);
|
|
3509
3582
|
};
|
|
3510
|
-
return
|
|
3511
|
-
u(Number(
|
|
3583
|
+
return g.addEventListener("input", () => {
|
|
3584
|
+
u(Number(g.value));
|
|
3512
3585
|
}), d.addEventListener("input", () => {
|
|
3513
|
-
const
|
|
3514
|
-
if (
|
|
3515
|
-
const
|
|
3516
|
-
Number.isNaN(
|
|
3586
|
+
const m = d.value.trim();
|
|
3587
|
+
if (m === "") return;
|
|
3588
|
+
const f = Number(m);
|
|
3589
|
+
Number.isNaN(f) || (g.value = String(a(f)));
|
|
3517
3590
|
}), d.addEventListener("blur", () => {
|
|
3518
|
-
const
|
|
3519
|
-
if (
|
|
3520
|
-
u(
|
|
3591
|
+
const m = d.value.trim(), f = a(Number(g.value));
|
|
3592
|
+
if (m === "") {
|
|
3593
|
+
u(f);
|
|
3521
3594
|
return;
|
|
3522
3595
|
}
|
|
3523
|
-
const
|
|
3524
|
-
if (Number.isNaN(
|
|
3525
|
-
u(
|
|
3596
|
+
const b = Number(m);
|
|
3597
|
+
if (Number.isNaN(b)) {
|
|
3598
|
+
u(f);
|
|
3526
3599
|
return;
|
|
3527
3600
|
}
|
|
3528
|
-
u(
|
|
3529
|
-
}), d.addEventListener("keydown", (
|
|
3530
|
-
|
|
3601
|
+
u(b);
|
|
3602
|
+
}), d.addEventListener("keydown", (m) => {
|
|
3603
|
+
m.key === "Enter" && d.blur();
|
|
3531
3604
|
}), r("div", { class: "sm-field" }, [
|
|
3532
3605
|
r("label", { class: "sm-field__label" }, [t]),
|
|
3533
|
-
r("div", { class: "sm-field__slider-row" }, [
|
|
3606
|
+
r("div", { class: "sm-field__slider-row" }, [g, d])
|
|
3534
3607
|
]);
|
|
3535
3608
|
}
|
|
3536
3609
|
_colorField(t, e, s, n, i = "#ffffff") {
|
|
@@ -3543,45 +3616,45 @@ class ns {
|
|
|
3543
3616
|
placeholder: i,
|
|
3544
3617
|
...c ? { "data-sm-focus": c } : {}
|
|
3545
3618
|
});
|
|
3546
|
-
let
|
|
3619
|
+
let g = e.trim();
|
|
3547
3620
|
const d = () => {
|
|
3548
3621
|
a.value = "#808080", a.classList.add("sm-color-row__pick--inherit"), a.title = i || "未设置";
|
|
3549
|
-
}, u = (
|
|
3550
|
-
const
|
|
3551
|
-
p.value =
|
|
3552
|
-
const h = A(
|
|
3622
|
+
}, u = (b) => {
|
|
3623
|
+
const y = b.trim();
|
|
3624
|
+
p.value = y;
|
|
3625
|
+
const h = A(y);
|
|
3553
3626
|
h ? (a.value = h, a.classList.remove("sm-color-row__pick--inherit"), a.title = "") : d();
|
|
3554
3627
|
};
|
|
3555
3628
|
u(e);
|
|
3556
|
-
const
|
|
3557
|
-
p.value =
|
|
3629
|
+
const m = (b) => {
|
|
3630
|
+
p.value = b, a.value = b, a.classList.remove("sm-color-row__pick--inherit"), a.title = "", g = b;
|
|
3558
3631
|
};
|
|
3559
|
-
return
|
|
3632
|
+
return X(a, {
|
|
3560
3633
|
getValue: () => p.value.trim() || a.value,
|
|
3561
3634
|
placeholder: i,
|
|
3562
3635
|
allowClear: !0,
|
|
3563
|
-
onPreview:
|
|
3564
|
-
onCommit: (
|
|
3565
|
-
|
|
3636
|
+
onPreview: m,
|
|
3637
|
+
onCommit: (b) => {
|
|
3638
|
+
m(b), s(b);
|
|
3566
3639
|
},
|
|
3567
3640
|
onClear: () => {
|
|
3568
|
-
u(""),
|
|
3641
|
+
u(""), g = "", s("");
|
|
3569
3642
|
}
|
|
3570
3643
|
}), p.addEventListener("input", () => {
|
|
3571
|
-
const
|
|
3572
|
-
|
|
3644
|
+
const b = p.value, y = A(b);
|
|
3645
|
+
y ? (a.value = y, a.classList.remove("sm-color-row__pick--inherit"), a.title = "", g = y) : b.trim() || (d(), g = ""), s(b);
|
|
3573
3646
|
}), p.addEventListener("blur", () => {
|
|
3574
|
-
const
|
|
3575
|
-
if (!
|
|
3576
|
-
u(""),
|
|
3647
|
+
const b = p.value.trim();
|
|
3648
|
+
if (!b) {
|
|
3649
|
+
u(""), g = "", s("");
|
|
3577
3650
|
return;
|
|
3578
3651
|
}
|
|
3579
|
-
const
|
|
3580
|
-
if (
|
|
3581
|
-
u(
|
|
3652
|
+
const y = A(b);
|
|
3653
|
+
if (y) {
|
|
3654
|
+
u(y), g = y, y !== b && s(y);
|
|
3582
3655
|
return;
|
|
3583
3656
|
}
|
|
3584
|
-
u(
|
|
3657
|
+
u(g), s(g);
|
|
3585
3658
|
}), r("div", { class: "sm-field" }, [
|
|
3586
3659
|
r("label", { class: "sm-field__label" }, [t]),
|
|
3587
3660
|
r("div", { class: "sm-color-row" }, [a, p])
|
|
@@ -3650,49 +3723,49 @@ class ns {
|
|
|
3650
3723
|
]) : l;
|
|
3651
3724
|
}
|
|
3652
3725
|
_spacingField(t, [e, s, n, i], l, c, a) {
|
|
3653
|
-
const p = ["上", "右", "下", "左"],
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
], u = () => l([...d]),
|
|
3726
|
+
const p = ["上", "右", "下", "左"], g = (b) => Math.max(0, Math.min(200, Math.round(b))), d = [
|
|
3727
|
+
g(Number(e ?? 0)),
|
|
3728
|
+
g(Number(s ?? 0)),
|
|
3729
|
+
g(Number(n ?? 0)),
|
|
3730
|
+
g(Number(i ?? 0))
|
|
3731
|
+
], u = () => l([...d]), m = (b, y) => {
|
|
3659
3732
|
const h = r("input", {
|
|
3660
3733
|
class: "sm-input",
|
|
3661
3734
|
type: "number",
|
|
3662
3735
|
min: 0,
|
|
3663
3736
|
max: 200,
|
|
3664
|
-
value: String(
|
|
3665
|
-
title: p[
|
|
3666
|
-
...c ? { "data-sm-focus": `${c}:${
|
|
3737
|
+
value: String(b ?? 0),
|
|
3738
|
+
title: p[y],
|
|
3739
|
+
...c ? { "data-sm-focus": `${c}:${y}` } : {}
|
|
3667
3740
|
});
|
|
3668
3741
|
return h.addEventListener("input", () => {
|
|
3669
3742
|
const v = h.value.trim();
|
|
3670
3743
|
if (v === "") return;
|
|
3671
3744
|
const k = Number(v);
|
|
3672
|
-
Number.isNaN(k) || (d[
|
|
3745
|
+
Number.isNaN(k) || (d[y] = g(k), u());
|
|
3673
3746
|
}), h.addEventListener("blur", () => {
|
|
3674
3747
|
const v = h.value.trim();
|
|
3675
3748
|
if (v === "") {
|
|
3676
|
-
h.value = String(d[
|
|
3749
|
+
h.value = String(d[y]);
|
|
3677
3750
|
return;
|
|
3678
3751
|
}
|
|
3679
|
-
const k = Number(v), w =
|
|
3680
|
-
h.value = String(w), d[
|
|
3752
|
+
const k = Number(v), w = g(Number.isNaN(k) ? d[y] : k);
|
|
3753
|
+
h.value = String(w), d[y] = w, u();
|
|
3681
3754
|
}), h.addEventListener("keydown", (v) => {
|
|
3682
3755
|
v.key === "Enter" && h.blur();
|
|
3683
3756
|
}), h;
|
|
3684
|
-
},
|
|
3685
|
-
const h =
|
|
3757
|
+
}, f = (b, y) => {
|
|
3758
|
+
const h = g(b ?? 0), v = r("input", {
|
|
3686
3759
|
type: "range",
|
|
3687
3760
|
min: 0,
|
|
3688
3761
|
max: 200,
|
|
3689
3762
|
step: 1,
|
|
3690
3763
|
value: String(h),
|
|
3691
|
-
title: p[
|
|
3764
|
+
title: p[y]
|
|
3692
3765
|
});
|
|
3693
3766
|
v.addEventListener("input", () => {
|
|
3694
|
-
const w =
|
|
3695
|
-
d[
|
|
3767
|
+
const w = g(Number(v.value));
|
|
3768
|
+
d[y] = w, k.value = String(w), u();
|
|
3696
3769
|
});
|
|
3697
3770
|
const k = r("input", {
|
|
3698
3771
|
class: "sm-input",
|
|
@@ -3700,28 +3773,28 @@ class ns {
|
|
|
3700
3773
|
min: 0,
|
|
3701
3774
|
max: 200,
|
|
3702
3775
|
value: String(h),
|
|
3703
|
-
title: p[
|
|
3704
|
-
...c ? { "data-sm-focus": `${c}:${
|
|
3776
|
+
title: p[y],
|
|
3777
|
+
...c ? { "data-sm-focus": `${c}:${y}` } : {}
|
|
3705
3778
|
});
|
|
3706
3779
|
return k.addEventListener("input", () => {
|
|
3707
3780
|
const w = k.value.trim();
|
|
3708
3781
|
if (w === "") return;
|
|
3709
3782
|
const E = Number(w);
|
|
3710
3783
|
if (Number.isNaN(E)) return;
|
|
3711
|
-
const C =
|
|
3712
|
-
v.value = String(C), d[
|
|
3784
|
+
const C = g(E);
|
|
3785
|
+
v.value = String(C), d[y] = C, u();
|
|
3713
3786
|
}), k.addEventListener("blur", () => {
|
|
3714
3787
|
const w = k.value.trim();
|
|
3715
3788
|
if (w === "") {
|
|
3716
|
-
k.value = String(d[
|
|
3789
|
+
k.value = String(d[y]), v.value = String(d[y]);
|
|
3717
3790
|
return;
|
|
3718
3791
|
}
|
|
3719
|
-
const E = Number(w), C =
|
|
3720
|
-
k.value = String(C), v.value = String(C), d[
|
|
3792
|
+
const E = Number(w), C = g(Number.isNaN(E) ? d[y] : E);
|
|
3793
|
+
k.value = String(C), v.value = String(C), d[y] = C, u();
|
|
3721
3794
|
}), k.addEventListener("keydown", (w) => {
|
|
3722
3795
|
w.key === "Enter" && k.blur();
|
|
3723
3796
|
}), r("div", { class: "sm-spacing-row" }, [
|
|
3724
|
-
r("span", { class: "sm-spacing-row__axis" }, [p[
|
|
3797
|
+
r("span", { class: "sm-spacing-row__axis" }, [p[y]]),
|
|
3725
3798
|
v,
|
|
3726
3799
|
k
|
|
3727
3800
|
]);
|
|
@@ -3735,8 +3808,8 @@ class ns {
|
|
|
3735
3808
|
type: "button",
|
|
3736
3809
|
class: "sm-btn sm-btn--ghost sm-spacing-field__reset",
|
|
3737
3810
|
onclick: () => {
|
|
3738
|
-
const
|
|
3739
|
-
for (let
|
|
3811
|
+
const b = a.map((y) => g(Number(y)));
|
|
3812
|
+
for (let y = 0; y < 4; y++) d[y] = b[y];
|
|
3740
3813
|
l([...d]);
|
|
3741
3814
|
}
|
|
3742
3815
|
},
|
|
@@ -3746,11 +3819,11 @@ class ns {
|
|
|
3746
3819
|
this._preferSliderControls() ? r(
|
|
3747
3820
|
"div",
|
|
3748
3821
|
{ class: "sm-spacing-rows" },
|
|
3749
|
-
[0, 1, 2, 3].map((
|
|
3822
|
+
[0, 1, 2, 3].map((b) => f([e, s, n, i][b], b))
|
|
3750
3823
|
) : r(
|
|
3751
3824
|
"div",
|
|
3752
3825
|
{ class: "sm-spacing-grid" },
|
|
3753
|
-
[0, 1, 2, 3].map((
|
|
3826
|
+
[0, 1, 2, 3].map((b) => m([e, s, n, i][b], b))
|
|
3754
3827
|
)
|
|
3755
3828
|
]);
|
|
3756
3829
|
}
|
|
@@ -3772,8 +3845,8 @@ class ns {
|
|
|
3772
3845
|
]),
|
|
3773
3846
|
l
|
|
3774
3847
|
]);
|
|
3775
|
-
return i.addEventListener("change", () => s(i.checked)), { el: c, setInherit: (p,
|
|
3776
|
-
i.checked = p,
|
|
3848
|
+
return i.addEventListener("change", () => s(i.checked)), { el: c, setInherit: (p, g) => {
|
|
3849
|
+
i.checked = p, g !== void 0 && (l.textContent = g), l.hidden = !p;
|
|
3777
3850
|
} };
|
|
3778
3851
|
}
|
|
3779
3852
|
_fontWeightInheritField(t, e, s, n, i, l, c) {
|
|
@@ -3782,42 +3855,42 @@ class ns {
|
|
|
3782
3855
|
class: "sm-segmented sm-segmented--fill",
|
|
3783
3856
|
role: "group",
|
|
3784
3857
|
"aria-label": t
|
|
3785
|
-
}),
|
|
3858
|
+
}), g = () => {
|
|
3786
3859
|
p.classList.toggle("sm-segmented--disabled", a);
|
|
3787
|
-
const
|
|
3788
|
-
|
|
3789
|
-
for (const
|
|
3790
|
-
const
|
|
3860
|
+
const m = a ? "" : j(e || s);
|
|
3861
|
+
R(p);
|
|
3862
|
+
for (const f of l) {
|
|
3863
|
+
const b = !a && f.value === m;
|
|
3791
3864
|
p.append(
|
|
3792
3865
|
r(
|
|
3793
3866
|
"button",
|
|
3794
3867
|
{
|
|
3795
3868
|
type: "button",
|
|
3796
|
-
class: `sm-segmented__item${
|
|
3797
|
-
"aria-pressed":
|
|
3798
|
-
title:
|
|
3799
|
-
...i ? { "data-sm-focus": `${i}:${
|
|
3869
|
+
class: `sm-segmented__item${b ? " sm-segmented__item--active" : ""}`,
|
|
3870
|
+
"aria-pressed": b ? "true" : "false",
|
|
3871
|
+
title: f.label,
|
|
3872
|
+
...i ? { "data-sm-focus": `${i}:${f.value}` } : {},
|
|
3800
3873
|
onclick: () => {
|
|
3801
|
-
a = !1, e =
|
|
3874
|
+
a = !1, e = f.value, d.setInherit(!1), g(), n(f.value);
|
|
3802
3875
|
}
|
|
3803
3876
|
},
|
|
3804
|
-
[
|
|
3877
|
+
[f.label]
|
|
3805
3878
|
)
|
|
3806
3879
|
);
|
|
3807
3880
|
}
|
|
3808
3881
|
}, d = this._globalInheritSwitch(
|
|
3809
3882
|
a,
|
|
3810
3883
|
s,
|
|
3811
|
-
(
|
|
3812
|
-
if (
|
|
3813
|
-
a = !0, e = "", d.setInherit(!0, s),
|
|
3884
|
+
(m) => {
|
|
3885
|
+
if (m) {
|
|
3886
|
+
a = !0, e = "", d.setInherit(!0, s), g(), n("");
|
|
3814
3887
|
return;
|
|
3815
3888
|
}
|
|
3816
|
-
a = !1, e = s, d.setInherit(!1),
|
|
3889
|
+
a = !1, e = s, d.setInherit(!1), g(), n(s);
|
|
3817
3890
|
},
|
|
3818
3891
|
`${i}:inherit`
|
|
3819
3892
|
);
|
|
3820
|
-
|
|
3893
|
+
g();
|
|
3821
3894
|
const u = r("div", { class: "sm-field" }, [
|
|
3822
3895
|
r("label", { class: "sm-field__label" }, [t]),
|
|
3823
3896
|
d.el,
|
|
@@ -3832,21 +3905,21 @@ class ns {
|
|
|
3832
3905
|
class: "sm-input",
|
|
3833
3906
|
type: "text",
|
|
3834
3907
|
...n ? { "data-sm-focus": n } : {}
|
|
3835
|
-
}),
|
|
3908
|
+
}), g = () => {
|
|
3836
3909
|
p.disabled = a, p.value = a ? "" : e, p.placeholder = a ? "" : "如 16px", p.classList.toggle("sm-input--inherit-disabled", a);
|
|
3837
3910
|
}, d = this._globalInheritSwitch(
|
|
3838
3911
|
a,
|
|
3839
3912
|
`${c}px`,
|
|
3840
|
-
(
|
|
3841
|
-
if (
|
|
3842
|
-
a = !0, e = "", d.setInherit(!0, `${c}px`),
|
|
3913
|
+
(m) => {
|
|
3914
|
+
if (m) {
|
|
3915
|
+
a = !0, e = "", d.setInherit(!0, `${c}px`), g(), s("");
|
|
3843
3916
|
return;
|
|
3844
3917
|
}
|
|
3845
|
-
a = !1, e = `${c}px`, d.setInherit(!1),
|
|
3918
|
+
a = !1, e = `${c}px`, d.setInherit(!1), g(), s(e);
|
|
3846
3919
|
},
|
|
3847
3920
|
`${n}:inherit`
|
|
3848
3921
|
);
|
|
3849
|
-
|
|
3922
|
+
g(), p.addEventListener("input", () => {
|
|
3850
3923
|
a || (e = p.value, s(e));
|
|
3851
3924
|
}), p.addEventListener("blur", () => {
|
|
3852
3925
|
if (a) return;
|
|
@@ -3874,65 +3947,65 @@ class ns {
|
|
|
3874
3947
|
l,
|
|
3875
3948
|
i
|
|
3876
3949
|
) : this._textField(t, e ?? "", s, "", n);
|
|
3877
|
-
const a = 10, p = 48,
|
|
3878
|
-
let
|
|
3879
|
-
const
|
|
3950
|
+
const a = 10, p = 48, g = 1, d = (C) => Math.min(p, Math.max(a, Math.round(C))), u = d(this._snapFontSizeToPx(l ?? e ?? "16px"));
|
|
3951
|
+
let m = e.trim(), f = c && !m;
|
|
3952
|
+
const b = r("div", { class: "sm-field__slider-row" }), y = r("input", {
|
|
3880
3953
|
type: "range",
|
|
3881
3954
|
min: a,
|
|
3882
3955
|
max: p,
|
|
3883
|
-
step:
|
|
3956
|
+
step: g
|
|
3884
3957
|
}), h = r("input", {
|
|
3885
3958
|
class: "sm-input",
|
|
3886
3959
|
type: "number",
|
|
3887
3960
|
min: a,
|
|
3888
3961
|
max: p,
|
|
3889
|
-
step:
|
|
3962
|
+
step: g,
|
|
3890
3963
|
"data-sm-focus": n
|
|
3891
3964
|
});
|
|
3892
|
-
|
|
3965
|
+
b.append(y, h);
|
|
3893
3966
|
const v = () => {
|
|
3894
|
-
if (
|
|
3895
|
-
|
|
3967
|
+
if (b.classList.toggle("sm-field__slider-row--inherit", f), h.disabled = f, f)
|
|
3968
|
+
y.value = String(u), h.value = "";
|
|
3896
3969
|
else {
|
|
3897
|
-
const C = d(this._snapFontSizeToPx(
|
|
3898
|
-
|
|
3970
|
+
const C = d(this._snapFontSizeToPx(m || `${u}px`));
|
|
3971
|
+
y.value = String(C), h.value = String(C);
|
|
3899
3972
|
}
|
|
3900
3973
|
};
|
|
3901
3974
|
let k = null;
|
|
3902
3975
|
c && (k = this._globalInheritSwitch(
|
|
3903
|
-
|
|
3976
|
+
f,
|
|
3904
3977
|
`${u}px`,
|
|
3905
3978
|
(C) => {
|
|
3906
3979
|
if (C) {
|
|
3907
|
-
|
|
3980
|
+
f = !0, m = "", k.setInherit(!0, `${u}px`), v(), s("");
|
|
3908
3981
|
return;
|
|
3909
3982
|
}
|
|
3910
|
-
|
|
3983
|
+
f = !1, m = `${u}px`, k.setInherit(!1), v(), s(m);
|
|
3911
3984
|
},
|
|
3912
3985
|
`${n}:inherit`
|
|
3913
3986
|
)), v();
|
|
3914
3987
|
const w = () => {
|
|
3915
|
-
|
|
3988
|
+
f && (f = !1, k == null || k.setInherit(!1), v());
|
|
3916
3989
|
};
|
|
3917
|
-
|
|
3990
|
+
y.addEventListener("input", () => {
|
|
3918
3991
|
w();
|
|
3919
|
-
const C = d(Number(
|
|
3920
|
-
h.value = String(C),
|
|
3992
|
+
const C = d(Number(y.value));
|
|
3993
|
+
h.value = String(C), m = `${C}px`, s(m);
|
|
3921
3994
|
}), h.addEventListener("input", () => {
|
|
3922
|
-
if (
|
|
3995
|
+
if (f) return;
|
|
3923
3996
|
const C = Number(h.value);
|
|
3924
|
-
Number.isNaN(C) || (
|
|
3997
|
+
Number.isNaN(C) || (y.value = String(d(C)));
|
|
3925
3998
|
}), h.addEventListener("blur", () => {
|
|
3926
|
-
if (
|
|
3927
|
-
const C = h.value.trim(), B = d(Number(
|
|
3928
|
-
|
|
3999
|
+
if (f) return;
|
|
4000
|
+
const C = h.value.trim(), B = d(Number(y.value)), I = d(C === "" || Number.isNaN(Number(C)) ? B : Number(C));
|
|
4001
|
+
m = `${I}px`, h.value = String(I), y.value = String(I), s(m);
|
|
3929
4002
|
}), h.addEventListener("keydown", (C) => {
|
|
3930
4003
|
C.key === "Enter" && h.blur();
|
|
3931
4004
|
});
|
|
3932
4005
|
const E = r("div", { class: "sm-field" }, [
|
|
3933
4006
|
r("label", { class: "sm-field__label" }, [t]),
|
|
3934
4007
|
...k ? [k.el] : [],
|
|
3935
|
-
|
|
4008
|
+
b
|
|
3936
4009
|
]);
|
|
3937
4010
|
return i && E.append(r("div", { class: "sm-field__help" }, [i])), E;
|
|
3938
4011
|
}
|
|
@@ -3950,7 +4023,7 @@ class ns {
|
|
|
3950
4023
|
const k = this._textField(t, e, s, "", n);
|
|
3951
4024
|
return i && k.append(r("div", { class: "sm-field__help" }, [i])), k;
|
|
3952
4025
|
}
|
|
3953
|
-
const l =
|
|
4026
|
+
const l = ds(e);
|
|
3954
4027
|
if (l === "custom") {
|
|
3955
4028
|
const k = r("div", { class: "sm-field" });
|
|
3956
4029
|
return k.append(r("label", { class: "sm-field__label" }, [t])), k.append(
|
|
@@ -3968,59 +4041,59 @@ class ns {
|
|
|
3968
4041
|
})
|
|
3969
4042
|
), i && k.append(r("div", { class: "sm-field__help" }, [i])), k;
|
|
3970
4043
|
}
|
|
3971
|
-
const c = l, a = c === "%" ? 100 : 1200, p = 1,
|
|
4044
|
+
const c = l, a = c === "%" ? 100 : 1200, p = 1, g = c === "auto" ? 280 : ft(e, c === "%" ? "%" : "px"), d = (k) => Math.max(p, Math.min(a, Math.round(k))), u = r("input", {
|
|
3972
4045
|
type: "range",
|
|
3973
4046
|
min: p,
|
|
3974
4047
|
max: a,
|
|
3975
4048
|
step: 1,
|
|
3976
|
-
value: String(
|
|
4049
|
+
value: String(g),
|
|
3977
4050
|
disabled: c === "auto"
|
|
3978
|
-
}),
|
|
4051
|
+
}), m = r("input", {
|
|
3979
4052
|
class: "sm-input",
|
|
3980
4053
|
type: "number",
|
|
3981
4054
|
min: p,
|
|
3982
4055
|
max: a,
|
|
3983
4056
|
step: 1,
|
|
3984
|
-
value: String(
|
|
4057
|
+
value: String(g),
|
|
3985
4058
|
disabled: c === "auto",
|
|
3986
4059
|
...n ? { "data-sm-focus": n } : {}
|
|
3987
|
-
}),
|
|
4060
|
+
}), f = (k) => {
|
|
3988
4061
|
const w = d(k);
|
|
3989
|
-
u.value = String(w),
|
|
4062
|
+
u.value = String(w), m.value = String(w), s(c === "%" ? `${w}%` : `${w}px`);
|
|
3990
4063
|
};
|
|
3991
4064
|
u.addEventListener("input", () => {
|
|
3992
|
-
c !== "auto" &&
|
|
3993
|
-
}),
|
|
4065
|
+
c !== "auto" && f(Number(u.value));
|
|
4066
|
+
}), m.addEventListener("input", () => {
|
|
3994
4067
|
if (c === "auto") return;
|
|
3995
|
-
const k =
|
|
4068
|
+
const k = m.value.trim();
|
|
3996
4069
|
if (k === "") return;
|
|
3997
4070
|
const w = Number(k);
|
|
3998
4071
|
Number.isNaN(w) || (u.value = String(d(w)));
|
|
3999
|
-
}),
|
|
4072
|
+
}), m.addEventListener("blur", () => {
|
|
4000
4073
|
if (c === "auto") return;
|
|
4001
|
-
const k =
|
|
4074
|
+
const k = m.value.trim(), w = d(Number(u.value));
|
|
4002
4075
|
if (k === "") {
|
|
4003
|
-
|
|
4076
|
+
f(w);
|
|
4004
4077
|
return;
|
|
4005
4078
|
}
|
|
4006
4079
|
const E = Number(k);
|
|
4007
|
-
|
|
4008
|
-
}),
|
|
4009
|
-
c !== "auto" && k.key === "Enter" &&
|
|
4080
|
+
f(Number.isNaN(E) ? w : E);
|
|
4081
|
+
}), m.addEventListener("keydown", (k) => {
|
|
4082
|
+
c !== "auto" && k.key === "Enter" && m.blur();
|
|
4010
4083
|
});
|
|
4011
|
-
const
|
|
4084
|
+
const b = r(
|
|
4012
4085
|
"div",
|
|
4013
4086
|
{ class: `sm-width-field__slider-row ${c === "auto" ? "is-disabled" : ""}` },
|
|
4014
|
-
[u,
|
|
4015
|
-
),
|
|
4016
|
-
|
|
4087
|
+
[u, m]
|
|
4088
|
+
), y = r("div", { class: "sm-segmented sm-segmented--wrap sm-width-field__modes" }), h = (k, w) => {
|
|
4089
|
+
y.append(
|
|
4017
4090
|
r(
|
|
4018
4091
|
"button",
|
|
4019
4092
|
{
|
|
4020
4093
|
type: "button",
|
|
4021
4094
|
class: `sm-segmented__item ${c === k ? "sm-segmented__item--active" : ""}`,
|
|
4022
4095
|
onclick: () => {
|
|
4023
|
-
s(k === "auto" ? "" : k === "px" ? `${
|
|
4096
|
+
s(k === "auto" ? "" : k === "px" ? `${ft(e, "px")}px` : `${ft(e, "%")}%`);
|
|
4024
4097
|
}
|
|
4025
4098
|
},
|
|
4026
4099
|
[w]
|
|
@@ -4030,14 +4103,14 @@ class ns {
|
|
|
4030
4103
|
h("auto", "自适应"), h("px", "px"), h("%", "%");
|
|
4031
4104
|
const v = r("div", { class: "sm-field" }, [
|
|
4032
4105
|
r("label", { class: "sm-field__label" }, [t]),
|
|
4033
|
-
|
|
4034
|
-
|
|
4106
|
+
y,
|
|
4107
|
+
b
|
|
4035
4108
|
]);
|
|
4036
4109
|
return i && v.append(r("div", { class: "sm-field__help" }, [i])), v;
|
|
4037
4110
|
}
|
|
4038
4111
|
_docFontWeightField(t, e, s) {
|
|
4039
|
-
const n =
|
|
4040
|
-
return this._segmentedSelectField("字重", n,
|
|
4112
|
+
const n = j(t);
|
|
4113
|
+
return this._segmentedSelectField("字重", n, it, e, s);
|
|
4041
4114
|
}
|
|
4042
4115
|
_twoColumnRatioField(t, e, s) {
|
|
4043
4116
|
return this._segmentedSelectField(
|
|
@@ -4055,11 +4128,11 @@ class ns {
|
|
|
4055
4128
|
_renderBlockCodeView(t) {
|
|
4056
4129
|
const e = this.opts.registry.get(t.type), s = t.lockedMjml ?? (e ? e.toMjml(t.props, { doc: this.opts.store.doc, engine: "mjml" }) : ""), n = r("div", { class: "sm-code-pane" }), i = r("div", { class: "sm-code-pane__header" }, [
|
|
4057
4130
|
r("div", { class: "sm-code-pane__title" }, ["编辑组件 MJML 源码"])
|
|
4058
|
-
]), l = r("div", { class: "sm-code" }), c = new
|
|
4131
|
+
]), l = r("div", { class: "sm-code" }), c = new rt({
|
|
4059
4132
|
parent: l,
|
|
4060
|
-
state:
|
|
4133
|
+
state: U.create({
|
|
4061
4134
|
doc: s,
|
|
4062
|
-
extensions: [
|
|
4135
|
+
extensions: [lt, ct()]
|
|
4063
4136
|
})
|
|
4064
4137
|
});
|
|
4065
4138
|
this.codeView = c;
|
|
@@ -4071,8 +4144,8 @@ class ns {
|
|
|
4071
4144
|
type: "button",
|
|
4072
4145
|
onclick: () => {
|
|
4073
4146
|
this.opts.store.update((p) => {
|
|
4074
|
-
const
|
|
4075
|
-
|
|
4147
|
+
const g = L(p, t.id);
|
|
4148
|
+
g && delete g.block.lockedMjml;
|
|
4076
4149
|
});
|
|
4077
4150
|
}
|
|
4078
4151
|
},
|
|
@@ -4085,8 +4158,8 @@ class ns {
|
|
|
4085
4158
|
type: "button",
|
|
4086
4159
|
onclick: () => {
|
|
4087
4160
|
const p = c.state.doc.toString();
|
|
4088
|
-
this.opts.store.update((
|
|
4089
|
-
const d = L(
|
|
4161
|
+
this.opts.store.update((g) => {
|
|
4162
|
+
const d = L(g, t.id);
|
|
4090
4163
|
d && (d.block.lockedMjml = p);
|
|
4091
4164
|
});
|
|
4092
4165
|
}
|
|
@@ -4107,13 +4180,13 @@ class ns {
|
|
|
4107
4180
|
this.codeView && (this.codeView.destroy(), this.codeView = null);
|
|
4108
4181
|
}
|
|
4109
4182
|
}
|
|
4110
|
-
class
|
|
4183
|
+
class hs {
|
|
4111
4184
|
constructor(t) {
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4185
|
+
_(this, "el");
|
|
4186
|
+
_(this, "opts");
|
|
4187
|
+
_(this, "currentTab", "mjml");
|
|
4188
|
+
_(this, "body");
|
|
4189
|
+
_(this, "cm", null);
|
|
4117
4190
|
this.opts = t, this.el = r("div", { class: "sm-doc-source" }), this.body = r("div", { class: "sm-doc-source__body" }), this._render(), t.store.subscribe(() => {
|
|
4118
4191
|
this._isVisible() && this._renderEditor();
|
|
4119
4192
|
});
|
|
@@ -4130,7 +4203,7 @@ class is {
|
|
|
4130
4203
|
return this.el.isConnected && (this.el.offsetParent !== null || this.el.getClientRects().length > 0);
|
|
4131
4204
|
}
|
|
4132
4205
|
_render() {
|
|
4133
|
-
|
|
4206
|
+
R(this.el);
|
|
4134
4207
|
const t = r("div", { class: "sm-doc-source__bar" }, [
|
|
4135
4208
|
this._tabBtn("mjml", "MJML"),
|
|
4136
4209
|
this._tabBtn("html", "HTML(编译产物)"),
|
|
@@ -4161,15 +4234,15 @@ class is {
|
|
|
4161
4234
|
);
|
|
4162
4235
|
}
|
|
4163
4236
|
_renderEditor() {
|
|
4164
|
-
this._destroyCm(),
|
|
4165
|
-
const t =
|
|
4237
|
+
this._destroyCm(), R(this.body);
|
|
4238
|
+
const t = at(this.opts.store.doc, this.opts.registry, {
|
|
4166
4239
|
withSampleVariables: !1
|
|
4167
4240
|
}), e = this.currentTab === "mjml" ? t.mjml : t.html;
|
|
4168
|
-
this.cm = new
|
|
4241
|
+
this.cm = new rt({
|
|
4169
4242
|
parent: this.body,
|
|
4170
|
-
state:
|
|
4243
|
+
state: U.create({
|
|
4171
4244
|
doc: e,
|
|
4172
|
-
extensions: [
|
|
4245
|
+
extensions: [lt, ct(), U.readOnly.of(!0)]
|
|
4173
4246
|
})
|
|
4174
4247
|
});
|
|
4175
4248
|
}
|
|
@@ -4180,7 +4253,7 @@ class is {
|
|
|
4180
4253
|
await navigator.clipboard.writeText(t);
|
|
4181
4254
|
} catch {
|
|
4182
4255
|
const e = document.createElement("textarea");
|
|
4183
|
-
e.value = t, document.body.appendChild(e), e.select(),
|
|
4256
|
+
e.value = t, document.body.appendChild(e), e.select(), T("copy"), document.body.removeChild(e);
|
|
4184
4257
|
}
|
|
4185
4258
|
}
|
|
4186
4259
|
_destroyCm() {
|
|
@@ -4190,17 +4263,17 @@ class is {
|
|
|
4190
4263
|
this._destroyCm();
|
|
4191
4264
|
}
|
|
4192
4265
|
}
|
|
4193
|
-
class
|
|
4266
|
+
class ps {
|
|
4194
4267
|
constructor(t) {
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4268
|
+
_(this, "el");
|
|
4269
|
+
_(this, "opts");
|
|
4270
|
+
_(this, "undoBtn");
|
|
4271
|
+
_(this, "redoBtn");
|
|
4272
|
+
_(this, "themeButtons");
|
|
4273
|
+
_(this, "modeButtons", {});
|
|
4274
|
+
_(this, "accentInput");
|
|
4275
|
+
_(this, "fullscreenBtn");
|
|
4276
|
+
_(this, "layoutBordersBtn");
|
|
4204
4277
|
this.opts = t, this.el = r("header", { class: "sm-topbar" }), this._render(), t.store.subscribe(() => this._sync()), this._sync();
|
|
4205
4278
|
}
|
|
4206
4279
|
setMode(t) {
|
|
@@ -4218,7 +4291,7 @@ class os {
|
|
|
4218
4291
|
/** 根据 `.sm-root` 上计算后的 `--sm-primary` 更新拾取器显示(无拾取器或未挂 root 时忽略) */
|
|
4219
4292
|
syncAccentPicker() {
|
|
4220
4293
|
if (!this.accentInput || !this.opts.accentPickerRoot) return;
|
|
4221
|
-
const t = getComputedStyle(this.opts.accentPickerRoot).getPropertyValue("--sm-primary").trim(), e = A(t) ||
|
|
4294
|
+
const t = getComputedStyle(this.opts.accentPickerRoot).getPropertyValue("--sm-primary").trim(), e = A(t) || Le(t);
|
|
4222
4295
|
if (!e) return;
|
|
4223
4296
|
const s = A(e);
|
|
4224
4297
|
if (!s) return;
|
|
@@ -4228,7 +4301,7 @@ class os {
|
|
|
4228
4301
|
/** 与 document fullscreen 状态同步图标与 aria(按钮不存在时忽略) */
|
|
4229
4302
|
setFullscreenActive(t) {
|
|
4230
4303
|
const e = this.fullscreenBtn;
|
|
4231
|
-
e && (e.replaceChildren(t ?
|
|
4304
|
+
e && (e.replaceChildren(t ? ys() : Dt()), e.title = t ? "退出全屏" : "全屏", e.setAttribute("aria-label", t ? "退出全屏" : "全屏"), e.setAttribute("aria-pressed", t ? "true" : "false"));
|
|
4232
4305
|
}
|
|
4233
4306
|
/** 与画布布局边框开关同步按钮高亮(按钮不存在时忽略) */
|
|
4234
4307
|
setLayoutBordersActive(t) {
|
|
@@ -4236,7 +4309,7 @@ class os {
|
|
|
4236
4309
|
e && (e.setAttribute("aria-pressed", t ? "true" : "false"), e.title = t ? "隐藏 Section / Block 边框" : "显示 Section / Block 边框", e.setAttribute("aria-label", t ? "隐藏 Section / Block 边框" : "显示 Section / Block 边框"));
|
|
4237
4310
|
}
|
|
4238
4311
|
_render() {
|
|
4239
|
-
|
|
4312
|
+
R(this.el);
|
|
4240
4313
|
const t = r("div", { class: "sm-segmented" }), e = r(
|
|
4241
4314
|
"button",
|
|
4242
4315
|
{
|
|
@@ -4271,9 +4344,9 @@ class os {
|
|
|
4271
4344
|
[w]
|
|
4272
4345
|
);
|
|
4273
4346
|
this.themeButtons = {
|
|
4274
|
-
light: i("light", "浅色",
|
|
4275
|
-
dark: i("dark", "深色",
|
|
4276
|
-
system: i("system", "跟随系统",
|
|
4347
|
+
light: i("light", "浅色", _s()),
|
|
4348
|
+
dark: i("dark", "深色", vs()),
|
|
4349
|
+
system: i("system", "跟随系统", ks())
|
|
4277
4350
|
}, n.append(this.themeButtons.light, this.themeButtons.dark, this.themeButtons.system);
|
|
4278
4351
|
const l = [n];
|
|
4279
4352
|
if (this.opts.showAccentColorPicker && this.opts.onAccentChange) {
|
|
@@ -4284,7 +4357,7 @@ class os {
|
|
|
4284
4357
|
title: "主题色",
|
|
4285
4358
|
value: "#4f46e5"
|
|
4286
4359
|
});
|
|
4287
|
-
|
|
4360
|
+
X(v, {
|
|
4288
4361
|
layerRoot: this.opts.accentPickerRoot,
|
|
4289
4362
|
liveCommit: !0,
|
|
4290
4363
|
onCommit: (k) => this.opts.onAccentChange(k)
|
|
@@ -4299,7 +4372,7 @@ class os {
|
|
|
4299
4372
|
title: "撤销 ⌘Z",
|
|
4300
4373
|
onclick: this.opts.onUndo
|
|
4301
4374
|
},
|
|
4302
|
-
[
|
|
4375
|
+
[ms(), "撤销"]
|
|
4303
4376
|
), this.redoBtn = r(
|
|
4304
4377
|
"button",
|
|
4305
4378
|
{
|
|
@@ -4308,7 +4381,7 @@ class os {
|
|
|
4308
4381
|
title: "重做 ⌘⇧Z",
|
|
4309
4382
|
onclick: this.opts.onRedo
|
|
4310
4383
|
},
|
|
4311
|
-
[
|
|
4384
|
+
[fs(), "重做"]
|
|
4312
4385
|
);
|
|
4313
4386
|
const c = [];
|
|
4314
4387
|
this.opts.showClearCanvasButton !== !1 && typeof this.opts.onClearCanvas == "function" && c.push(
|
|
@@ -4342,16 +4415,16 @@ class os {
|
|
|
4342
4415
|
onclick: (v) => this.opts.onInsertVariable(v.currentTarget)
|
|
4343
4416
|
},
|
|
4344
4417
|
["{{ }} 插入变量"]
|
|
4345
|
-
),
|
|
4418
|
+
), g = r(
|
|
4346
4419
|
"button",
|
|
4347
4420
|
{ class: "sm-btn", type: "button", onclick: this.opts.onPreview },
|
|
4348
|
-
[
|
|
4421
|
+
[gs(), "预览"]
|
|
4349
4422
|
), d = r(
|
|
4350
4423
|
"button",
|
|
4351
4424
|
{ class: "sm-btn sm-btn--primary", type: "button", onclick: this.opts.onExport },
|
|
4352
4425
|
["导出 HTML"]
|
|
4353
|
-
), u = this.opts.showMailSettingsButton !== !1,
|
|
4354
|
-
u &&
|
|
4426
|
+
), u = this.opts.showMailSettingsButton !== !1, m = [];
|
|
4427
|
+
u && m.push(
|
|
4355
4428
|
r(
|
|
4356
4429
|
"button",
|
|
4357
4430
|
{
|
|
@@ -4362,9 +4435,9 @@ class os {
|
|
|
4362
4435
|
},
|
|
4363
4436
|
["邮件设置"]
|
|
4364
4437
|
)
|
|
4365
|
-
),
|
|
4366
|
-
const
|
|
4367
|
-
typeof this.opts.onLayoutBordersToggle == "function" ?
|
|
4438
|
+
), m.push(p, g, d);
|
|
4439
|
+
const f = [];
|
|
4440
|
+
typeof this.opts.onLayoutBordersToggle == "function" ? f.push(
|
|
4368
4441
|
this.layoutBordersBtn = r(
|
|
4369
4442
|
"button",
|
|
4370
4443
|
{
|
|
@@ -4375,9 +4448,9 @@ class os {
|
|
|
4375
4448
|
"aria-pressed": "false",
|
|
4376
4449
|
onclick: () => this.opts.onLayoutBordersToggle()
|
|
4377
4450
|
},
|
|
4378
|
-
[
|
|
4451
|
+
[bs()]
|
|
4379
4452
|
)
|
|
4380
|
-
) : this.layoutBordersBtn = void 0, this.opts.showFullscreenButton !== !1 && typeof this.opts.onFullscreenToggle == "function" ?
|
|
4453
|
+
) : this.layoutBordersBtn = void 0, this.opts.showFullscreenButton !== !1 && typeof this.opts.onFullscreenToggle == "function" ? f.push(
|
|
4381
4454
|
this.fullscreenBtn = r(
|
|
4382
4455
|
"button",
|
|
4383
4456
|
{
|
|
@@ -4388,111 +4461,113 @@ class os {
|
|
|
4388
4461
|
"aria-pressed": "false",
|
|
4389
4462
|
onclick: () => this.opts.onFullscreenToggle()
|
|
4390
4463
|
},
|
|
4391
|
-
[
|
|
4464
|
+
[Dt()]
|
|
4392
4465
|
)
|
|
4393
4466
|
) : this.fullscreenBtn = void 0;
|
|
4394
|
-
const
|
|
4467
|
+
const y = f.length > 0 && r("div", { class: "sm-topbar__group" }, f), h = [];
|
|
4395
4468
|
this.opts.showTitle !== !1 && h.push(r("div", { class: "sm-topbar__title" }, ["Simple Mail Editor"])), this.el.append(
|
|
4396
4469
|
...h,
|
|
4397
4470
|
r("div", { class: "sm-topbar__group" }, [t]),
|
|
4398
4471
|
r("div", { class: "sm-topbar__group sm-topbar__theme-group" }, l),
|
|
4399
4472
|
r("div", { class: "sm-topbar__group" }, [this.undoBtn, this.redoBtn]),
|
|
4400
4473
|
...a ? [a] : [],
|
|
4401
|
-
...
|
|
4474
|
+
...y ? [y] : [],
|
|
4402
4475
|
r("div", { class: "sm-topbar__spacer" }),
|
|
4403
|
-
r("div", { class: "sm-topbar__group" },
|
|
4476
|
+
r("div", { class: "sm-topbar__group" }, m)
|
|
4404
4477
|
), this.setMode(this.opts.mode), this.syncTheme(this.opts.theme);
|
|
4405
4478
|
}
|
|
4406
4479
|
_sync() {
|
|
4407
4480
|
this.undoBtn.disabled = !this.opts.store.canUndo(), this.redoBtn.disabled = !this.opts.store.canRedo();
|
|
4408
4481
|
}
|
|
4409
4482
|
}
|
|
4410
|
-
function
|
|
4411
|
-
return
|
|
4483
|
+
function ms() {
|
|
4484
|
+
return G(
|
|
4412
4485
|
'<path d="M9 14l-4-4 4-4" stroke="currentColor" stroke-width="1.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/><path d="M5 10h7a4 4 0 010 8h-1" stroke="currentColor" stroke-width="1.5" fill="none" stroke-linecap="round"/>'
|
|
4413
4486
|
);
|
|
4414
4487
|
}
|
|
4415
|
-
function
|
|
4416
|
-
return
|
|
4488
|
+
function fs() {
|
|
4489
|
+
return G(
|
|
4417
4490
|
'<path d="M11 14l4-4-4-4" stroke="currentColor" stroke-width="1.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/><path d="M15 10H8a4 4 0 000 8h1" stroke="currentColor" stroke-width="1.5" fill="none" stroke-linecap="round"/>'
|
|
4418
4491
|
);
|
|
4419
4492
|
}
|
|
4420
|
-
function
|
|
4421
|
-
return
|
|
4493
|
+
function gs() {
|
|
4494
|
+
return G(
|
|
4422
4495
|
'<path d="M2 10s3-5 8-5 8 5 8 5-3 5-8 5-8-5-8-5z" stroke="currentColor" stroke-width="1.5" fill="none"/><circle cx="10" cy="10" r="2.4" stroke="currentColor" stroke-width="1.5" fill="none"/>'
|
|
4423
4496
|
);
|
|
4424
4497
|
}
|
|
4425
|
-
function
|
|
4426
|
-
return
|
|
4498
|
+
function bs() {
|
|
4499
|
+
return G(
|
|
4427
4500
|
'<rect x="4.5" y="4.5" width="11" height="11" rx="1.5" stroke="currentColor" stroke-width="1.5" fill="none" stroke-dasharray="2.5 2"/><path d="M7.2 10.1l1.8 1.8 3.8-3.9" stroke="currentColor" stroke-width="1.5" fill="none" stroke-linecap="round" stroke-linejoin="round" class="sm-layout-borders-check"/>'
|
|
4428
4501
|
);
|
|
4429
4502
|
}
|
|
4430
|
-
function
|
|
4431
|
-
return
|
|
4503
|
+
function Dt() {
|
|
4504
|
+
return G(
|
|
4432
4505
|
'<path d="M6 4H4v2M14 4h2v2M6 16H4v-2M14 16h2v-2M4 6V4h2M16 6V4h-2M4 14v2h2M16 14v2h-2" stroke="currentColor" stroke-width="1.5" fill="none" stroke-linecap="round"/>'
|
|
4433
4506
|
);
|
|
4434
4507
|
}
|
|
4435
|
-
function
|
|
4436
|
-
return
|
|
4508
|
+
function ys() {
|
|
4509
|
+
return G(
|
|
4437
4510
|
'<path d="M8 4v4H4M12 4v4h4M8 16v-4H4M12 16v-4h4M4 8h4v4H4M16 8h-4v4h4" stroke="currentColor" stroke-width="1.5" fill="none" stroke-linecap="round"/>'
|
|
4438
4511
|
);
|
|
4439
4512
|
}
|
|
4440
|
-
function
|
|
4441
|
-
return
|
|
4513
|
+
function _s() {
|
|
4514
|
+
return Et(
|
|
4442
4515
|
'<circle cx="10" cy="10" r="3.2" fill="none" stroke="currentColor" stroke-width="1.5"/><path d="M10 3.5V5M10 15v1.5M16.5 10H15M5 10H3.5M14.1 5.9 13 7M7 13 5.9 14.1M14.1 14.1 13 13M7 7 5.9 5.9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>'
|
|
4443
4516
|
);
|
|
4444
4517
|
}
|
|
4445
|
-
function
|
|
4446
|
-
return
|
|
4518
|
+
function vs() {
|
|
4519
|
+
return Et(
|
|
4447
4520
|
'<path d="M8.5 4.2a5.8 5.8 0 100 11.3 4.8 4.8 0 01-1.3-11.3z" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>'
|
|
4448
4521
|
);
|
|
4449
4522
|
}
|
|
4450
|
-
function
|
|
4451
|
-
return
|
|
4523
|
+
function ks() {
|
|
4524
|
+
return Et(
|
|
4452
4525
|
'<path d="M5 5.5h10c.8 0 1.5.7 1.5 1.5v6c0 .8-.7 1.5-1.5 1.5H5c-.8 0-1.5-.7-1.5-1.5v-6c0-.8.7-1.5 1.5-1.5z" fill="none" stroke="currentColor" stroke-width="1.5"/><path d="M8 16h4M10 14.2V16" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>'
|
|
4453
4526
|
);
|
|
4454
4527
|
}
|
|
4455
|
-
function
|
|
4528
|
+
function G(o) {
|
|
4456
4529
|
const t = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
4457
4530
|
return t.setAttribute("width", "14"), t.setAttribute("height", "14"), t.setAttribute("viewBox", "0 0 20 20"), t.innerHTML = o, t;
|
|
4458
4531
|
}
|
|
4459
|
-
function
|
|
4532
|
+
function Et(o) {
|
|
4460
4533
|
const t = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
4461
4534
|
return t.setAttribute("width", "15"), t.setAttribute("height", "15"), t.setAttribute("viewBox", "0 0 20 20"), t.setAttribute("aria-hidden", "true"), t.innerHTML = o, t;
|
|
4462
4535
|
}
|
|
4463
|
-
class
|
|
4536
|
+
class Ts {
|
|
4464
4537
|
constructor(t) {
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4538
|
+
_(this, "store");
|
|
4539
|
+
_(this, "registry");
|
|
4540
|
+
_(this, "opts");
|
|
4541
|
+
_(this, "root");
|
|
4542
|
+
_(this, "theme");
|
|
4543
|
+
_(this, "mode", "design");
|
|
4544
|
+
_(this, "topbar");
|
|
4545
|
+
_(this, "leftPanel");
|
|
4546
|
+
_(this, "canvas");
|
|
4547
|
+
_(this, "rightPanel");
|
|
4548
|
+
_(this, "sourceView");
|
|
4549
|
+
_(this, "toolbar");
|
|
4550
|
+
_(this, "body");
|
|
4551
|
+
_(this, "changeTimer", null);
|
|
4479
4552
|
/** 显式品牌色时覆盖 CSS 变量;未设置则由 styles 按 light/dark 使用默认紫/靛 */
|
|
4480
|
-
|
|
4553
|
+
_(this, "accentColorOverride");
|
|
4481
4554
|
/** 顶栏开关:是否在画布上始终显示 Section / Block 轻量虚线边框 */
|
|
4482
|
-
|
|
4555
|
+
_(this, "showLayoutBorders", !1);
|
|
4483
4556
|
/** 「重置内容」时恢复的文档快照(与当前画布内容无关) */
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4557
|
+
_(this, "presetContentDoc");
|
|
4558
|
+
/** 宿主通过 setVariables 注入的列表;setValue 恢复文档后仍会写回,避免被 doc JSON 里的空数组覆盖 */
|
|
4559
|
+
_(this, "configuredVariables", []);
|
|
4560
|
+
_(this, "systemThemeMq", null);
|
|
4561
|
+
_(this, "_onSystemThemeMqChange", () => {
|
|
4487
4562
|
this.accentColorOverride && this._applyAccentVars();
|
|
4488
4563
|
});
|
|
4489
|
-
|
|
4564
|
+
_(this, "_onFullscreenChange", () => {
|
|
4490
4565
|
var e;
|
|
4491
|
-
const t =
|
|
4566
|
+
const t = gt();
|
|
4492
4567
|
(e = this.topbar) == null || e.setFullscreenActive(t === this.root);
|
|
4493
4568
|
});
|
|
4494
4569
|
/** design 态 Esc:块 → 父级 Section → 文档级面板(邮件设置或版式/全局样式,取决于 `ui.hideMailMeta`) */
|
|
4495
|
-
|
|
4570
|
+
_(this, "_mailEscHandler", (t) => {
|
|
4496
4571
|
var i;
|
|
4497
4572
|
if (t.key !== "Escape" || this.mode !== "design" || !this.store.selection || document.querySelector(".sm-modal__mask.is-open")) return;
|
|
4498
4573
|
const e = t.target;
|
|
@@ -4511,25 +4586,25 @@ class Ss {
|
|
|
4511
4586
|
* 文档级撤销/重做(捕获阶段):焦点在右栏 input/CodeMirror 内时,冒泡到 root 的监听太晚,
|
|
4512
4587
|
* 浏览器会先处理控件内撤销;仅在 store 仍有历史时拦截并走全局 undo/redo。
|
|
4513
4588
|
*/
|
|
4514
|
-
|
|
4589
|
+
_(this, "_mailUndoRedoHandler", (t) => {
|
|
4515
4590
|
if (!(t.metaKey || t.ctrlKey) || t.key.toLowerCase() !== "z") return;
|
|
4516
4591
|
const n = t.target;
|
|
4517
4592
|
if (!n || !this.root.contains(n)) return;
|
|
4518
4593
|
const i = !t.shiftKey, l = t.shiftKey;
|
|
4519
4594
|
i && !this.store.canUndo() || l && !this.store.canRedo() || (t.preventDefault(), i ? this.store.undo() : this.store.redo());
|
|
4520
4595
|
});
|
|
4521
|
-
if (this.opts = t, this.registry = new
|
|
4596
|
+
if (this.opts = t, this.registry = new ee(), t.blocks)
|
|
4522
4597
|
for (const n of t.blocks) this.registry.register(n);
|
|
4523
|
-
const e =
|
|
4598
|
+
const e = bt(t.initialDoc);
|
|
4524
4599
|
this.presetContentDoc = structuredClone(
|
|
4525
|
-
|
|
4526
|
-
), this.store = new
|
|
4600
|
+
bt(t.presetDoc ?? t.initialDoc)
|
|
4601
|
+
), this.store = new _e(e);
|
|
4527
4602
|
const s = A(this.opts.accentColor ?? "");
|
|
4528
4603
|
this.opts.accentColor != null && String(this.opts.accentColor).trim() !== "" && !s && console.warn("[simple-mail] accentColor 无效,已忽略:", this.opts.accentColor), this.accentColorOverride = s ?? void 0, this.theme = t.theme ?? "light", this.root = r("div", { class: "sm-root" }), this._applyThemeAttr(), this.body = r("div", { class: "sm-body" }), t.container.append(this.root), this._buildUI(), this._bindKeyboard(), this._bindFullscreen(), this._applyAccentVars(), this._refreshAccentMqBinding(), this._syncTopbarAccentPicker(), this.store.subscribe(() => this._onChange());
|
|
4529
4604
|
}
|
|
4530
4605
|
/* ------------------------------ Public API ------------------------------ */
|
|
4531
4606
|
setValue(t) {
|
|
4532
|
-
this._blurRightPanelIfFocused(), this.store.replace(t);
|
|
4607
|
+
this._blurRightPanelIfFocused(), this.store.replace(t), this._applyConfiguredVariables();
|
|
4533
4608
|
}
|
|
4534
4609
|
getValue() {
|
|
4535
4610
|
return this.store.doc;
|
|
@@ -4545,19 +4620,53 @@ class Ss {
|
|
|
4545
4620
|
}
|
|
4546
4621
|
/** 将画布恢复为构造时 `presetDoc`(或 `initialDoc`)对应的预置内容。 */
|
|
4547
4622
|
resetToPreset() {
|
|
4548
|
-
this._blurRightPanelIfFocused(), this.store.replace(structuredClone(this.presetContentDoc)), this.store.setSelection(null);
|
|
4623
|
+
this._blurRightPanelIfFocused(), this.store.replace(structuredClone(this.presetContentDoc)), this._applyConfiguredVariables(), this.store.setSelection(null);
|
|
4549
4624
|
}
|
|
4550
4625
|
/** 更新「重置内容」的目标(例如宿主异步加载默认模板后)。 */
|
|
4551
4626
|
setPresetDoc(t) {
|
|
4552
|
-
this.presetContentDoc = structuredClone(
|
|
4627
|
+
this.presetContentDoc = structuredClone(bt(t));
|
|
4553
4628
|
}
|
|
4554
4629
|
setVariables(t) {
|
|
4630
|
+
this.configuredVariables = t.map(O), this._applyConfiguredVariables();
|
|
4631
|
+
}
|
|
4632
|
+
getVariables() {
|
|
4633
|
+
return this.configuredVariables.length ? this.configuredVariables : this.store.doc.variables;
|
|
4634
|
+
}
|
|
4635
|
+
_applyConfiguredVariables() {
|
|
4636
|
+
if (!this.configuredVariables.length) return;
|
|
4637
|
+
const t = this.configuredVariables.map((e) => ({ ...e }));
|
|
4555
4638
|
this.store.update((e) => {
|
|
4556
4639
|
e.variables = t;
|
|
4557
4640
|
});
|
|
4558
4641
|
}
|
|
4559
|
-
|
|
4560
|
-
|
|
4642
|
+
/**
|
|
4643
|
+
* 插入变量 key(`{{key}}`)。
|
|
4644
|
+
* @returns 是否成功插入
|
|
4645
|
+
*/
|
|
4646
|
+
insertVariableKey(t) {
|
|
4647
|
+
const e = O(t);
|
|
4648
|
+
return this._insertAtFocus(q(e.key), !1);
|
|
4649
|
+
}
|
|
4650
|
+
/**
|
|
4651
|
+
* 插入链接 / 图片变量对应元素(`<a>` / image 块等)。
|
|
4652
|
+
* 非 link/image 时退化为 insertVariableKey。
|
|
4653
|
+
*/
|
|
4654
|
+
insertVariableElement(t) {
|
|
4655
|
+
const e = O(t);
|
|
4656
|
+
if (e.kind === "image")
|
|
4657
|
+
return this._insertImageVariable(e);
|
|
4658
|
+
if (e.kind === "link") {
|
|
4659
|
+
const s = q(e.key), n = Gt(
|
|
4660
|
+
s,
|
|
4661
|
+
this.store.doc.styles.linkColor || "#ff5a00"
|
|
4662
|
+
);
|
|
4663
|
+
return this._insertAtFocus(n, !0);
|
|
4664
|
+
}
|
|
4665
|
+
return this.insertVariableKey(e);
|
|
4666
|
+
}
|
|
4667
|
+
/** 同 {@link insertVariableKey} */
|
|
4668
|
+
insertVariable(t) {
|
|
4669
|
+
return this.insertVariableKey(t);
|
|
4561
4670
|
}
|
|
4562
4671
|
/** 当前界面主题(`system` 不解析为 light/dark)。 */
|
|
4563
4672
|
getTheme() {
|
|
@@ -4590,7 +4699,7 @@ class Ss {
|
|
|
4590
4699
|
}
|
|
4591
4700
|
/** 导出 MJML 与编译后的 HTML。withSampleVariables=true 时把 {{var}} 替换为 sample 值用于预览。 */
|
|
4592
4701
|
export(t = {}) {
|
|
4593
|
-
return
|
|
4702
|
+
return at(this.store.doc, this.registry, {
|
|
4594
4703
|
engine: this.opts.engine ?? "mjml",
|
|
4595
4704
|
withSampleVariables: t.withSampleVariables ?? !1
|
|
4596
4705
|
});
|
|
@@ -4604,7 +4713,7 @@ class Ss {
|
|
|
4604
4713
|
}
|
|
4605
4714
|
destroy() {
|
|
4606
4715
|
var t, e, s, n, i, l;
|
|
4607
|
-
this._unbindFullscreen(), this._unbindSystemThemeMqForAccent(), this.changeTimer && window.clearTimeout(this.changeTimer),
|
|
4716
|
+
this._unbindFullscreen(), this._unbindSystemThemeMqForAccent(), this.changeTimer && window.clearTimeout(this.changeTimer), gt() === this.root && Vt(), document.removeEventListener("keydown", this._mailEscHandler, !0), document.removeEventListener("keydown", this._mailUndoRedoHandler, !0), (e = (t = this.canvas) == null ? void 0 : t.destroy) == null || e.call(t), (n = (s = this.sourceView) == null ? void 0 : s.destroy) == null || n.call(s), (l = (i = this.toolbar) == null ? void 0 : i.destroy) == null || l.call(i), this.root.remove();
|
|
4608
4717
|
}
|
|
4609
4718
|
/* -------------------------------- 私有 ---------------------------------- */
|
|
4610
4719
|
_applyThemeAttr() {
|
|
@@ -4619,7 +4728,7 @@ class Ss {
|
|
|
4619
4728
|
return;
|
|
4620
4729
|
}
|
|
4621
4730
|
const t = this._chromeIsEffectivelyDark();
|
|
4622
|
-
this.root.style.setProperty("--sm-primary", this.accentColorOverride), this.root.style.setProperty("--sm-primary-soft",
|
|
4731
|
+
this.root.style.setProperty("--sm-primary", this.accentColorOverride), this.root.style.setProperty("--sm-primary-soft", Me(this.accentColorOverride, t));
|
|
4623
4732
|
}
|
|
4624
4733
|
_unbindSystemThemeMqForAccent() {
|
|
4625
4734
|
this.systemThemeMq && (this.systemThemeMq.removeEventListener("change", this._onSystemThemeMqChange), this.systemThemeMq = null);
|
|
@@ -4637,7 +4746,7 @@ class Ss {
|
|
|
4637
4746
|
}
|
|
4638
4747
|
_buildUI() {
|
|
4639
4748
|
var e, s, n, i, l, c;
|
|
4640
|
-
this.topbar = new
|
|
4749
|
+
this.topbar = new ps({
|
|
4641
4750
|
store: this.store,
|
|
4642
4751
|
mode: this.mode,
|
|
4643
4752
|
theme: this.theme,
|
|
@@ -4662,19 +4771,19 @@ class Ss {
|
|
|
4662
4771
|
onFullscreenToggle: () => void this._toggleFullscreen(),
|
|
4663
4772
|
onLayoutBordersToggle: () => this._toggleLayoutBorders(),
|
|
4664
4773
|
showClearCanvasButton: ((i = this.opts.ui) == null ? void 0 : i.hideTopbarClearCanvas) !== !0,
|
|
4665
|
-
onClearCanvas: () => this.
|
|
4774
|
+
onClearCanvas: () => this.clearCanvas(),
|
|
4666
4775
|
showResetContentButton: ((l = this.opts.ui) == null ? void 0 : l.hideTopbarResetContent) !== !0,
|
|
4667
|
-
onResetContent: () => this.
|
|
4668
|
-
}), this.toolbar = new
|
|
4776
|
+
onResetContent: () => this.resetToPreset()
|
|
4777
|
+
}), this.toolbar = new ns({ positionRoot: this.root }), this.leftPanel = new es({ registry: this.registry });
|
|
4669
4778
|
const t = this.opts.autoWrapSection !== !1;
|
|
4670
|
-
this.root.classList.toggle("sm-allow-auto-wrap", t), this.canvas = new
|
|
4779
|
+
this.root.classList.toggle("sm-allow-auto-wrap", t), this.canvas = new Ge({
|
|
4671
4780
|
store: this.store,
|
|
4672
4781
|
registry: this.registry,
|
|
4673
4782
|
toolbar: this.toolbar,
|
|
4674
4783
|
autoWrapSection: t,
|
|
4675
4784
|
clearSelectionOnCanvasMargin: this.opts.clearSelectionOnCanvasMargin === !0,
|
|
4676
4785
|
layerRoot: this.root
|
|
4677
|
-
}), this.rightPanel = new
|
|
4786
|
+
}), this.rightPanel = new us({
|
|
4678
4787
|
store: this.store,
|
|
4679
4788
|
registry: this.registry,
|
|
4680
4789
|
docRootLabel: (c = this.opts.ui) != null && c.hideMailMeta ? "版式" : "邮件",
|
|
@@ -4684,7 +4793,7 @@ class Ss {
|
|
|
4684
4793
|
onFocusDocument: () => this._focusMailSettings(),
|
|
4685
4794
|
imageAssets: this.opts.imageAssets,
|
|
4686
4795
|
ui: this.opts.ui
|
|
4687
|
-
}), this.sourceView = new
|
|
4796
|
+
}), this.sourceView = new hs({ store: this.store, registry: this.registry }), this.body.append(this.leftPanel.el, this.canvas.el, this.rightPanel.el), this.root.append(this.topbar.el, this.body);
|
|
4688
4797
|
}
|
|
4689
4798
|
/** 撤销/替换文档前先失焦右栏,否则 RightPanel 会因「保留焦点」跳过重绘而仍显示旧值 */
|
|
4690
4799
|
_blurRightPanelIfFocused() {
|
|
@@ -4695,18 +4804,8 @@ class Ss {
|
|
|
4695
4804
|
_focusMailSettings() {
|
|
4696
4805
|
this.canvas.commitInlineEdit(), this.store.setSelection(null);
|
|
4697
4806
|
}
|
|
4698
|
-
_confirmClearCanvas() {
|
|
4699
|
-
window.confirm(
|
|
4700
|
-
"将移除画布上所有 Section 与组件,邮件全局样式与变量列表会保留。此操作可用撤销(⌘Z)恢复。"
|
|
4701
|
-
) && this.clearCanvas();
|
|
4702
|
-
}
|
|
4703
|
-
_confirmResetContent() {
|
|
4704
|
-
window.confirm(
|
|
4705
|
-
"将把邮件正文恢复为预置内容,当前画布上的所有模块将被替换。确定继续?"
|
|
4706
|
-
) && this.resetToPreset();
|
|
4707
|
-
}
|
|
4708
4807
|
_setMode(t) {
|
|
4709
|
-
this.mode !== t && (t !== "design" && this.canvas.commitInlineEdit(), this.mode = t, this.topbar.setMode(t),
|
|
4808
|
+
this.mode !== t && (t !== "design" && this.canvas.commitInlineEdit(), this.mode = t, this.topbar.setMode(t), R(this.body), t === "design" ? (this.body.classList.remove("sm-body--source"), this.body.style.removeProperty("grid-template-columns"), this.body.append(this.leftPanel.el, this.canvas.el, this.rightPanel.el)) : (this.body.classList.add("sm-body--source"), this.body.style.removeProperty("grid-template-columns"), this.body.append(this.sourceView.el), queueMicrotask(() => this.sourceView.refreshDoc())));
|
|
4710
4809
|
}
|
|
4711
4810
|
_bindKeyboard() {
|
|
4712
4811
|
this.root.addEventListener("keydown", (t) => {
|
|
@@ -4722,7 +4821,7 @@ class Ss {
|
|
|
4722
4821
|
const i = n.sections.find((c) => c.id === s.sectionId);
|
|
4723
4822
|
if (!i) return;
|
|
4724
4823
|
const l = i.columns[s.columnIndex];
|
|
4725
|
-
l && (l.blocks = l.blocks.filter((c) => c.id !== s.blockId),
|
|
4824
|
+
l && (l.blocks = l.blocks.filter((c) => c.id !== s.blockId), et(n, s.sectionId));
|
|
4726
4825
|
}), this.store.setSelection(null));
|
|
4727
4826
|
}
|
|
4728
4827
|
}), document.addEventListener("keydown", this._mailUndoRedoHandler, !0), document.addEventListener("keydown", this._mailEscHandler, !0), this.root.tabIndex = 0;
|
|
@@ -4734,9 +4833,11 @@ class Ss {
|
|
|
4734
4833
|
}, 60));
|
|
4735
4834
|
}
|
|
4736
4835
|
_showVariablePopover(t) {
|
|
4737
|
-
|
|
4836
|
+
var p;
|
|
4837
|
+
(p = this.canvas.currentInlineEditor) == null || p.saveSelection();
|
|
4838
|
+
const e = this.getVariables();
|
|
4738
4839
|
if (!e.length) {
|
|
4739
|
-
|
|
4840
|
+
this._showToast("暂无可用变量");
|
|
4740
4841
|
return;
|
|
4741
4842
|
}
|
|
4742
4843
|
const s = this.root.querySelector(".sm-popover");
|
|
@@ -4744,72 +4845,141 @@ class Ss {
|
|
|
4744
4845
|
s.remove();
|
|
4745
4846
|
return;
|
|
4746
4847
|
}
|
|
4747
|
-
const n = r("div", { class: "sm-popover" });
|
|
4748
|
-
|
|
4749
|
-
|
|
4848
|
+
const n = r("div", { class: "sm-popover sm-popover--variables" });
|
|
4849
|
+
let i = null;
|
|
4850
|
+
const l = () => {
|
|
4851
|
+
n.remove(), i && document.removeEventListener("click", i, !0);
|
|
4852
|
+
};
|
|
4853
|
+
for (const g of e) {
|
|
4854
|
+
const d = q(g.key), u = r("div", { class: "sm-popover__row" }), m = r("div", { class: "sm-popover__actions" });
|
|
4855
|
+
(g.kind === "link" || g.kind === "image") && m.append(
|
|
4856
|
+
r(
|
|
4857
|
+
"button",
|
|
4858
|
+
{
|
|
4859
|
+
class: "sm-popover__action",
|
|
4860
|
+
type: "button",
|
|
4861
|
+
onclick: (f) => {
|
|
4862
|
+
f.stopPropagation(), this.insertVariableElement(g), l();
|
|
4863
|
+
}
|
|
4864
|
+
},
|
|
4865
|
+
["插入元素"]
|
|
4866
|
+
)
|
|
4867
|
+
), m.append(
|
|
4868
|
+
r(
|
|
4869
|
+
"button",
|
|
4870
|
+
{
|
|
4871
|
+
class: "sm-popover__action sm-popover__action--copy",
|
|
4872
|
+
type: "button",
|
|
4873
|
+
title: `复制 ${d}`,
|
|
4874
|
+
onclick: (f) => {
|
|
4875
|
+
f.stopPropagation(), ws(d).then((b) => {
|
|
4876
|
+
b && (l(), this._showToast("已复制变量"));
|
|
4877
|
+
});
|
|
4878
|
+
}
|
|
4879
|
+
},
|
|
4880
|
+
["复制"]
|
|
4881
|
+
)
|
|
4882
|
+
), u.append(
|
|
4750
4883
|
r(
|
|
4751
4884
|
"button",
|
|
4752
4885
|
{
|
|
4753
4886
|
class: "sm-popover__item",
|
|
4754
4887
|
type: "button",
|
|
4755
4888
|
onclick: () => {
|
|
4756
|
-
this.
|
|
4889
|
+
this.insertVariableKey(g), l();
|
|
4757
4890
|
}
|
|
4758
4891
|
},
|
|
4759
4892
|
[
|
|
4760
|
-
r("span", { class: "sm-
|
|
4761
|
-
r("span", { class: "sm-
|
|
4893
|
+
r("span", { class: "sm-popover__label" }, [g.label]),
|
|
4894
|
+
r("span", { class: "sm-popover__key" }, [d])
|
|
4762
4895
|
]
|
|
4763
|
-
)
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
n.style.top = `${i.bottom - l.top + 4}px`, n.style.left = `${i.left - l.left}px`, this.root.append(n);
|
|
4767
|
-
const c = (a) => {
|
|
4768
|
-
!n.contains(a.target) && a.target !== t && (n.remove(), document.removeEventListener("click", c, !0));
|
|
4769
|
-
};
|
|
4770
|
-
setTimeout(() => document.addEventListener("click", c, !0), 0);
|
|
4771
|
-
}
|
|
4772
|
-
_insertVariable(t) {
|
|
4773
|
-
const e = this.store.selection, s = `{{${t.key}}}`, n = this.canvas.currentInlineEditor;
|
|
4774
|
-
if (n) {
|
|
4775
|
-
n.insertText(s);
|
|
4776
|
-
return;
|
|
4896
|
+
),
|
|
4897
|
+
m
|
|
4898
|
+
), n.append(u);
|
|
4777
4899
|
}
|
|
4778
|
-
const
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4900
|
+
const c = t.getBoundingClientRect(), a = this.root.getBoundingClientRect();
|
|
4901
|
+
n.style.top = `${c.bottom - a.top + 4}px`, n.style.left = `${c.left - a.left}px`, this.root.append(n), i = (g) => {
|
|
4902
|
+
!n.contains(g.target) && g.target !== t && l();
|
|
4903
|
+
}, setTimeout(() => {
|
|
4904
|
+
i && document.addEventListener("click", i, !0);
|
|
4905
|
+
}, 0);
|
|
4906
|
+
}
|
|
4907
|
+
_showToast(t) {
|
|
4908
|
+
const e = r("div", { class: "sm-toast" }, [t]);
|
|
4909
|
+
this.root.append(e), requestAnimationFrame(() => e.classList.add("is-visible")), setTimeout(() => {
|
|
4910
|
+
e.classList.remove("is-visible"), setTimeout(() => e.remove(), 200);
|
|
4911
|
+
}, 1400);
|
|
4912
|
+
}
|
|
4913
|
+
_insertImageVariable(t) {
|
|
4914
|
+
var l;
|
|
4915
|
+
const e = q(t.key), s = this.registry.createBlock("image"), n = s.props;
|
|
4916
|
+
n.src = e, n.alt = ((l = t.label) == null ? void 0 : l.trim()) || t.key;
|
|
4917
|
+
const i = this.store.selection;
|
|
4918
|
+
return this.store.update((c) => {
|
|
4919
|
+
var p;
|
|
4920
|
+
if ((i == null ? void 0 : i.kind) === "block") {
|
|
4921
|
+
const g = c.sections.find((u) => u.id === i.sectionId), d = g == null ? void 0 : g.columns[i.columnIndex];
|
|
4922
|
+
if (d) {
|
|
4923
|
+
const u = d.blocks.findIndex((m) => m.id === i.blockId);
|
|
4924
|
+
d.blocks.splice(u >= 0 ? u + 1 : d.blocks.length, 0, s);
|
|
4925
|
+
return;
|
|
4926
|
+
}
|
|
4927
|
+
}
|
|
4928
|
+
let a = c.sections[c.sections.length - 1];
|
|
4929
|
+
a || (a = W("1"), c.sections.push(a)), (p = a.columns[0]) == null || p.blocks.push(s);
|
|
4930
|
+
}), !0;
|
|
4931
|
+
}
|
|
4932
|
+
/** 在焦点处插入文本或 HTML;失败时返回 false */
|
|
4933
|
+
_insertAtFocus(t, e) {
|
|
4934
|
+
const s = this.canvas.currentInlineEditor;
|
|
4935
|
+
if (s)
|
|
4936
|
+
return e ? s.insertHtml(t) : s.insertText(t), !0;
|
|
4937
|
+
const n = document.activeElement;
|
|
4938
|
+
if (n && (n.tagName === "INPUT" || n.tagName === "TEXTAREA") && this.root.contains(n)) {
|
|
4939
|
+
const a = n.selectionStart ?? n.value.length, p = n.selectionEnd ?? n.value.length;
|
|
4940
|
+
return n.value = n.value.slice(0, a) + t + n.value.slice(p), n.dispatchEvent(new Event("input", { bubbles: !0 })), !0;
|
|
4785
4941
|
}
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
const
|
|
4794
|
-
if (f)
|
|
4795
|
-
|
|
4796
|
-
|
|
4942
|
+
const i = this.store.selection;
|
|
4943
|
+
if ((i == null ? void 0 : i.kind) === "block") {
|
|
4944
|
+
let a = !1;
|
|
4945
|
+
if (this.store.update((p) => {
|
|
4946
|
+
var g, d;
|
|
4947
|
+
for (const u of p.sections)
|
|
4948
|
+
for (const m of u.columns) {
|
|
4949
|
+
const f = m.blocks.find((h) => h.id === i.blockId);
|
|
4950
|
+
if (!f) continue;
|
|
4951
|
+
const b = this.registry.get(f.type), y = ((g = b == null ? void 0 : b.inlineEditable) == null ? void 0 : g.propKey) ?? ((d = b == null ? void 0 : b.schema.find((h) => h.type === "text" || h.type === "textarea")) == null ? void 0 : d.key);
|
|
4952
|
+
if (y) {
|
|
4953
|
+
const h = String(f.props[y] ?? ""), v = (b == null ? void 0 : b.inlineEditable) && b.inlineEditable.mode !== "plain";
|
|
4954
|
+
f.props[y] = v ? $t(h, t) : h + t, a = !0;
|
|
4797
4955
|
}
|
|
4798
4956
|
}
|
|
4799
|
-
});
|
|
4800
|
-
return;
|
|
4957
|
+
}), a) return !0;
|
|
4801
4958
|
}
|
|
4802
|
-
|
|
4959
|
+
const l = this.registry.createBlock("text"), c = $t("", t);
|
|
4960
|
+
return l.props.content = c, this.store.update((a) => {
|
|
4961
|
+
var g;
|
|
4962
|
+
let p = a.sections[a.sections.length - 1];
|
|
4963
|
+
if (p || (p = W("1"), a.sections.push(p)), (i == null ? void 0 : i.kind) === "block") {
|
|
4964
|
+
const d = a.sections.find((m) => m.id === i.sectionId), u = d == null ? void 0 : d.columns[i.columnIndex];
|
|
4965
|
+
if (u) {
|
|
4966
|
+
const m = u.blocks.findIndex((f) => f.id === i.blockId);
|
|
4967
|
+
u.blocks.splice(m >= 0 ? m + 1 : u.blocks.length, 0, l);
|
|
4968
|
+
return;
|
|
4969
|
+
}
|
|
4970
|
+
}
|
|
4971
|
+
(g = p.columns[0]) == null || g.blocks.push(l);
|
|
4972
|
+
}), !0;
|
|
4803
4973
|
}
|
|
4804
4974
|
_showExport() {
|
|
4805
|
-
this.canvas.commitInlineEdit(), new
|
|
4975
|
+
this.canvas.commitInlineEdit(), new Ze({
|
|
4806
4976
|
store: this.store,
|
|
4807
4977
|
registry: this.registry,
|
|
4808
4978
|
withSampleVariables: !0
|
|
4809
4979
|
}).open(this.root);
|
|
4810
4980
|
}
|
|
4811
4981
|
_showPreview() {
|
|
4812
|
-
this.canvas.commitInlineEdit(), new
|
|
4982
|
+
this.canvas.commitInlineEdit(), new wt({
|
|
4813
4983
|
store: this.store,
|
|
4814
4984
|
registry: this.registry
|
|
4815
4985
|
}).open(this.root);
|
|
@@ -4823,7 +4993,7 @@ class Ss {
|
|
|
4823
4993
|
}
|
|
4824
4994
|
async _toggleFullscreen() {
|
|
4825
4995
|
try {
|
|
4826
|
-
|
|
4996
|
+
gt() === this.root ? await Vt() : await Cs(this.root);
|
|
4827
4997
|
} catch (t) {
|
|
4828
4998
|
console.warn("[simple-mail] 全屏不可用:", t);
|
|
4829
4999
|
}
|
|
@@ -4832,19 +5002,33 @@ class Ss {
|
|
|
4832
5002
|
this.showLayoutBorders = !this.showLayoutBorders, this.root.classList.toggle("sm-show-layout-borders", this.showLayoutBorders), this.topbar.setLayoutBordersActive(this.showLayoutBorders);
|
|
4833
5003
|
}
|
|
4834
5004
|
}
|
|
4835
|
-
function
|
|
5005
|
+
async function ws(o) {
|
|
5006
|
+
try {
|
|
5007
|
+
return await navigator.clipboard.writeText(o), !0;
|
|
5008
|
+
} catch {
|
|
5009
|
+
}
|
|
5010
|
+
try {
|
|
5011
|
+
const t = document.createElement("textarea");
|
|
5012
|
+
t.value = o, t.setAttribute("readonly", "true"), t.style.position = "fixed", t.style.left = "-9999px", document.body.appendChild(t), t.select();
|
|
5013
|
+
const e = document.execCommand("copy");
|
|
5014
|
+
return document.body.removeChild(t), e;
|
|
5015
|
+
} catch {
|
|
5016
|
+
return !1;
|
|
5017
|
+
}
|
|
5018
|
+
}
|
|
5019
|
+
function gt() {
|
|
4836
5020
|
const o = document;
|
|
4837
5021
|
return document.fullscreenElement ?? o.webkitFullscreenElement ?? null;
|
|
4838
5022
|
}
|
|
4839
|
-
async function
|
|
5023
|
+
async function Cs(o) {
|
|
4840
5024
|
const t = o;
|
|
4841
5025
|
typeof t.requestFullscreen == "function" ? await t.requestFullscreen() : typeof t.webkitRequestFullscreen == "function" && await t.webkitRequestFullscreen();
|
|
4842
5026
|
}
|
|
4843
|
-
async function
|
|
5027
|
+
async function Vt() {
|
|
4844
5028
|
const o = document;
|
|
4845
5029
|
typeof document.exitFullscreen == "function" ? await document.exitFullscreen() : typeof o.webkitExitFullscreen == "function" && await o.webkitExitFullscreen();
|
|
4846
5030
|
}
|
|
4847
|
-
function
|
|
5031
|
+
function bt(o) {
|
|
4848
5032
|
const t = {
|
|
4849
5033
|
backgroundColor: "#ffffff",
|
|
4850
5034
|
contentBackgroundColor: "#ffffff",
|
|
@@ -4874,32 +5058,40 @@ function ft(o) {
|
|
|
4874
5058
|
};
|
|
4875
5059
|
}
|
|
4876
5060
|
export {
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
5061
|
+
it as FONT_WEIGHT_STEP_OPTIONS,
|
|
5062
|
+
le as FONT_WEIGHT_STEP_VALUES,
|
|
5063
|
+
Ts as MailEditor,
|
|
5064
|
+
ee as Registry,
|
|
5065
|
+
_e as Store,
|
|
5066
|
+
Bs as TWO_COLUMN_LAYOUTS,
|
|
5067
|
+
Ct as blockButtonWidthCss,
|
|
5068
|
+
Ce as buildBodyVariableElementInsert,
|
|
5069
|
+
Is as buildBodyVariableInsert,
|
|
5070
|
+
Kt as buildBodyVariableKeyInsert,
|
|
5071
|
+
Gt as buildLinkVariableHtml,
|
|
5072
|
+
W as createSection,
|
|
5073
|
+
we as defaultVariableSample,
|
|
5074
|
+
$s as defineBlock,
|
|
5075
|
+
zt as docContentWidthCss,
|
|
5076
|
+
pe as docToMjml,
|
|
4888
5077
|
L as findBlockLocation,
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
5078
|
+
H as findSection,
|
|
5079
|
+
ve as isTwoColumnLayout,
|
|
5080
|
+
ie as metaWidthInputString,
|
|
5081
|
+
ce as mjRawCellTypographyFromStyles,
|
|
5082
|
+
qt as mjRawEmailTableWrap,
|
|
5083
|
+
j as normalizeFontWeightStep,
|
|
5084
|
+
O as normalizeVariable,
|
|
5085
|
+
as as openImageGalleryModal,
|
|
5086
|
+
ne as parseMetaWidthFromUserInput,
|
|
5087
|
+
oe as parseSectionWidthFromUserInput,
|
|
5088
|
+
As as pruneEmptySections,
|
|
5089
|
+
et as pruneSectionIfEmpty,
|
|
5090
|
+
at as renderDoc,
|
|
5091
|
+
ye as replaceVariables,
|
|
5092
|
+
re as sectionWidthInputString,
|
|
5093
|
+
ke as setSectionLayout,
|
|
5094
|
+
Ut as tokenToVariableKey,
|
|
5095
|
+
q as variablePlaceholder
|
|
4904
5096
|
};
|
|
4905
5097
|
//# sourceMappingURL=index.js.map
|