suneditor 3.0.0-beta.2 → 3.0.0-beta.20
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/CONTRIBUTING.md +186 -184
- package/LICENSE +21 -21
- package/README.md +157 -180
- package/dist/suneditor.min.css +1 -1
- package/dist/suneditor.min.js +1 -1
- package/package.json +126 -123
- package/src/assets/design/color.css +131 -121
- package/src/assets/design/index.css +3 -3
- package/src/assets/design/size.css +37 -35
- package/src/assets/design/typography.css +37 -37
- package/src/assets/icons/defaultIcons.js +247 -232
- package/src/assets/suneditor-contents.css +779 -778
- package/src/assets/suneditor.css +43 -35
- package/src/core/base/eventHandlers/handler_toolbar.js +135 -135
- package/src/core/base/eventHandlers/handler_ww_clipboard.js +56 -56
- package/src/core/base/eventHandlers/handler_ww_dragDrop.js +115 -113
- package/src/core/base/eventHandlers/handler_ww_key_input.js +1200 -1200
- package/src/core/base/eventHandlers/handler_ww_mouse.js +194 -194
- package/src/core/base/eventManager.js +1550 -1484
- package/src/core/base/history.js +355 -355
- package/src/core/class/char.js +163 -162
- package/src/core/class/component.js +856 -842
- package/src/core/class/format.js +3433 -3422
- package/src/core/class/html.js +1927 -1890
- package/src/core/class/menu.js +357 -346
- package/src/core/class/nodeTransform.js +424 -424
- package/src/core/class/offset.js +858 -891
- package/src/core/class/selection.js +710 -620
- package/src/core/class/shortcuts.js +98 -98
- package/src/core/class/toolbar.js +438 -430
- package/src/core/class/ui.js +424 -422
- package/src/core/class/viewer.js +750 -750
- package/src/core/editor.js +1810 -1708
- package/src/core/section/actives.js +268 -241
- package/src/core/section/constructor.js +1348 -1661
- package/src/core/section/context.js +102 -102
- package/src/core/section/documentType.js +582 -561
- package/src/core/section/options.js +367 -0
- package/src/core/util/instanceCheck.js +59 -0
- package/src/editorInjector/_classes.js +36 -36
- package/src/editorInjector/_core.js +92 -92
- package/src/editorInjector/index.js +75 -75
- package/src/events.js +634 -622
- package/src/helper/clipboard.js +59 -59
- package/src/helper/converter.js +586 -564
- package/src/helper/dom/domCheck.js +304 -304
- package/src/helper/dom/domQuery.js +677 -669
- package/src/helper/dom/domUtils.js +618 -557
- package/src/helper/dom/index.js +12 -12
- package/src/helper/env.js +249 -240
- package/src/helper/index.js +25 -25
- package/src/helper/keyCodeMap.js +183 -183
- package/src/helper/numbers.js +72 -72
- package/src/helper/unicode.js +47 -47
- package/src/langs/ckb.js +231 -231
- package/src/langs/cs.js +231 -231
- package/src/langs/da.js +231 -231
- package/src/langs/de.js +231 -231
- package/src/langs/en.js +230 -230
- package/src/langs/es.js +231 -231
- package/src/langs/fa.js +231 -231
- package/src/langs/fr.js +231 -231
- package/src/langs/he.js +231 -231
- package/src/langs/hu.js +230 -230
- package/src/langs/index.js +28 -28
- package/src/langs/it.js +231 -231
- package/src/langs/ja.js +230 -230
- package/src/langs/km.js +230 -230
- package/src/langs/ko.js +230 -230
- package/src/langs/lv.js +231 -231
- package/src/langs/nl.js +231 -231
- package/src/langs/pl.js +231 -231
- package/src/langs/pt_br.js +231 -231
- package/src/langs/ro.js +231 -231
- package/src/langs/ru.js +231 -231
- package/src/langs/se.js +231 -231
- package/src/langs/tr.js +231 -231
- package/src/langs/uk.js +231 -231
- package/src/langs/ur.js +231 -231
- package/src/langs/zh_cn.js +231 -231
- package/src/modules/ApiManager.js +191 -191
- package/src/modules/Browser.js +669 -667
- package/src/modules/ColorPicker.js +364 -362
- package/src/modules/Controller.js +474 -454
- package/src/modules/Figure.js +1620 -1617
- package/src/modules/FileManager.js +359 -359
- package/src/modules/HueSlider.js +577 -565
- package/src/modules/Modal.js +346 -346
- package/src/modules/ModalAnchorEditor.js +643 -643
- package/src/modules/SelectMenu.js +549 -549
- package/src/modules/_DragHandle.js +17 -17
- package/src/modules/index.js +14 -14
- package/src/plugins/browser/audioGallery.js +83 -83
- package/src/plugins/browser/fileBrowser.js +103 -103
- package/src/plugins/browser/fileGallery.js +83 -83
- package/src/plugins/browser/imageGallery.js +81 -81
- package/src/plugins/browser/videoGallery.js +103 -103
- package/src/plugins/command/blockquote.js +61 -60
- package/src/plugins/command/exportPDF.js +134 -134
- package/src/plugins/command/fileUpload.js +456 -456
- package/src/plugins/command/list_bulleted.js +149 -148
- package/src/plugins/command/list_numbered.js +152 -151
- package/src/plugins/dropdown/align.js +157 -155
- package/src/plugins/dropdown/backgroundColor.js +108 -104
- package/src/plugins/dropdown/font.js +141 -137
- package/src/plugins/dropdown/fontColor.js +109 -105
- package/src/plugins/dropdown/formatBlock.js +170 -178
- package/src/plugins/dropdown/hr.js +152 -152
- package/src/plugins/dropdown/layout.js +83 -83
- package/src/plugins/dropdown/lineHeight.js +131 -130
- package/src/plugins/dropdown/list.js +123 -122
- package/src/plugins/dropdown/paragraphStyle.js +138 -138
- package/src/plugins/dropdown/table.js +4110 -4000
- package/src/plugins/dropdown/template.js +83 -83
- package/src/plugins/dropdown/textStyle.js +149 -149
- package/src/plugins/field/mention.js +242 -242
- package/src/plugins/index.js +120 -120
- package/src/plugins/input/fontSize.js +414 -410
- package/src/plugins/input/pageNavigator.js +71 -70
- package/src/plugins/modal/audio.js +677 -677
- package/src/plugins/modal/drawing.js +537 -531
- package/src/plugins/modal/embed.js +886 -886
- package/src/plugins/modal/image.js +1377 -1376
- package/src/plugins/modal/link.js +248 -240
- package/src/plugins/modal/math.js +563 -563
- package/src/plugins/modal/video.js +1226 -1226
- package/src/plugins/popup/anchor.js +224 -222
- package/src/suneditor.js +114 -107
- package/src/themes/dark.css +132 -122
- package/src/typedef.js +132 -130
- package/types/assets/icons/defaultIcons.d.ts +8 -0
- package/types/core/base/eventManager.d.ts +29 -4
- package/types/core/class/char.d.ts +2 -1
- package/types/core/class/component.d.ts +1 -2
- package/types/core/class/format.d.ts +8 -1
- package/types/core/class/html.d.ts +8 -0
- package/types/core/class/menu.d.ts +8 -0
- package/types/core/class/offset.d.ts +24 -26
- package/types/core/class/selection.d.ts +2 -0
- package/types/core/class/toolbar.d.ts +6 -0
- package/types/core/class/ui.d.ts +1 -1
- package/types/core/editor.d.ts +34 -12
- package/types/core/section/constructor.d.ts +5 -638
- package/types/core/section/documentType.d.ts +12 -2
- package/types/core/section/options.d.ts +740 -0
- package/types/core/util/instanceCheck.d.ts +50 -0
- package/types/editorInjector/_core.d.ts +5 -5
- package/types/editorInjector/index.d.ts +2 -2
- package/types/events.d.ts +2 -0
- package/types/helper/converter.d.ts +9 -0
- package/types/helper/dom/domQuery.d.ts +5 -5
- package/types/helper/dom/domUtils.d.ts +8 -0
- package/types/helper/env.d.ts +6 -1
- package/types/helper/index.d.ts +4 -1
- package/types/index.d.ts +122 -120
- package/types/langs/_Lang.d.ts +194 -194
- package/types/modules/ColorPicker.d.ts +5 -1
- package/types/modules/Controller.d.ts +8 -4
- package/types/modules/Figure.d.ts +2 -1
- package/types/modules/HueSlider.d.ts +4 -1
- package/types/modules/SelectMenu.d.ts +1 -1
- package/types/plugins/command/blockquote.d.ts +1 -0
- package/types/plugins/command/list_bulleted.d.ts +1 -0
- package/types/plugins/command/list_numbered.d.ts +1 -0
- package/types/plugins/dropdown/align.d.ts +1 -0
- package/types/plugins/dropdown/backgroundColor.d.ts +1 -0
- package/types/plugins/dropdown/font.d.ts +1 -0
- package/types/plugins/dropdown/fontColor.d.ts +1 -0
- package/types/plugins/dropdown/formatBlock.d.ts +3 -2
- package/types/plugins/dropdown/lineHeight.d.ts +1 -0
- package/types/plugins/dropdown/list.d.ts +1 -0
- package/types/plugins/dropdown/table.d.ts +6 -0
- package/types/plugins/input/fontSize.d.ts +1 -0
- package/types/plugins/modal/drawing.d.ts +4 -0
- package/types/plugins/modal/link.d.ts +32 -15
- package/types/suneditor.d.ts +13 -9
- package/types/typedef.d.ts +8 -0
|
@@ -1,557 +1,618 @@
|
|
|
1
|
-
import { _d, _w } from '../env';
|
|
2
|
-
import check from './domCheck';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* @
|
|
7
|
-
* @
|
|
8
|
-
* @param {
|
|
9
|
-
* @returns {
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
* @
|
|
18
|
-
* @
|
|
19
|
-
* @param {
|
|
20
|
-
* @
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
* @
|
|
54
|
-
* @param {
|
|
55
|
-
* @
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
* @
|
|
100
|
-
* @param {
|
|
101
|
-
* @
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
* @
|
|
170
|
-
* @param {
|
|
171
|
-
* @
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
* @
|
|
205
|
-
* @
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
* @
|
|
216
|
-
* @param {Node} item
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
* @
|
|
227
|
-
* @param {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
* @
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
* @
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
1
|
+
import { _d, _w } from '../env';
|
|
2
|
+
import check from './domCheck';
|
|
3
|
+
|
|
4
|
+
// ----- iframe-safe type check [START] -----
|
|
5
|
+
/**
|
|
6
|
+
* @private
|
|
7
|
+
* @description iframe-safe : Node type [HTMLCollection, NodeList, Array] check.
|
|
8
|
+
* @param {*} element
|
|
9
|
+
* @returns {element is HTMLCollection|NodeList|Array}
|
|
10
|
+
*/
|
|
11
|
+
function IsElementArray(element) {
|
|
12
|
+
const type = Object.prototype.toString.call(element);
|
|
13
|
+
return type === '[object HTMLCollection]' || type === '[object NodeList]' || type === '[object Array]';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @private
|
|
18
|
+
* @description iframe-safe: check if element is an HTMLImageElement
|
|
19
|
+
* @param {*} element
|
|
20
|
+
* @returns {element is HTMLImageElement}
|
|
21
|
+
*/
|
|
22
|
+
function IsHTMLImageElement(element) {
|
|
23
|
+
const type = Object.prototype.toString.call(element);
|
|
24
|
+
return type === '[object HTMLImageElement]';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @private
|
|
29
|
+
* @description iframe-safe: check if element is an HTMLMediaElement (video or audio)
|
|
30
|
+
* @param {*} element
|
|
31
|
+
* @returns {element is HTMLMediaElement}
|
|
32
|
+
*/
|
|
33
|
+
function IsHTMLMediaElement(element) {
|
|
34
|
+
const type = Object.prototype.toString.call(element);
|
|
35
|
+
return type === '[object HTMLVideoElement]' || type === '[object HTMLAudioElement]';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @private
|
|
40
|
+
* @description iframe-safe: check if element is an HTMLIFrameElement
|
|
41
|
+
* @param {*} element
|
|
42
|
+
* @returns {element is HTMLIFrameElement}
|
|
43
|
+
*/
|
|
44
|
+
function IsHTMLIFrameElement(element) {
|
|
45
|
+
const type = Object.prototype.toString.call(element);
|
|
46
|
+
return type === '[object HTMLIFrameElement]';
|
|
47
|
+
}
|
|
48
|
+
// ----- iframe-safe type check [END] -----
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @template {Node} T
|
|
52
|
+
* @description Clones a node while preserving its type.
|
|
53
|
+
* @param {T} node - The node to clone.
|
|
54
|
+
* @param {boolean} [deep=false] - Whether to perform a deep clone.
|
|
55
|
+
* @returns {T} - The cloned node.
|
|
56
|
+
*/
|
|
57
|
+
export function clone(node, deep = false) {
|
|
58
|
+
return /** @type {T} */ (node.cloneNode(deep));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @template {HTMLElement} T
|
|
63
|
+
* @description Create Element node
|
|
64
|
+
* @param {string} elementName Element name
|
|
65
|
+
* @param {?Object<string, string>=} attributes The attributes of the tag. {style: 'font-size:12px;..', class: 'el_class',..}
|
|
66
|
+
* @param {?string|Node=} inner A innerHTML string or inner node.
|
|
67
|
+
* @returns {T}
|
|
68
|
+
*/
|
|
69
|
+
export function createElement(elementName, attributes, inner) {
|
|
70
|
+
const el = _d.createElement(elementName);
|
|
71
|
+
|
|
72
|
+
if (attributes) {
|
|
73
|
+
for (const key in attributes) {
|
|
74
|
+
if (attributes[key] !== undefined && attributes[key] !== null) el.setAttribute(key, attributes[key]);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (inner) {
|
|
79
|
+
if (typeof inner === 'string') {
|
|
80
|
+
el.innerHTML = inner;
|
|
81
|
+
} else if (typeof inner === 'object') {
|
|
82
|
+
el.appendChild(inner);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return /** @type {T} */ (el);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @description Create text node
|
|
91
|
+
* @param {string} text text content
|
|
92
|
+
* @returns {Text}
|
|
93
|
+
*/
|
|
94
|
+
export function createTextNode(text) {
|
|
95
|
+
return _d.createTextNode(text || '');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @description Get attributes of argument element to string ('class="---" name="---" ')
|
|
100
|
+
* @param {Node} element Element object
|
|
101
|
+
* @param {Array<string>|null} exceptAttrs Array of attribute names to exclude from the result
|
|
102
|
+
* @returns {string}
|
|
103
|
+
*/
|
|
104
|
+
export function getAttributesToString(element, exceptAttrs) {
|
|
105
|
+
const attrs = /** @type {HTMLElement} */ (element).attributes;
|
|
106
|
+
if (!attrs) return '';
|
|
107
|
+
|
|
108
|
+
let attrString = '';
|
|
109
|
+
for (let i = 0, len = attrs.length; i < len; i++) {
|
|
110
|
+
if (exceptAttrs?.includes(attrs[i].name)) continue;
|
|
111
|
+
attrString += attrs[i].name + '="' + attrs[i].value + '" ';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return attrString;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @description Get the items array from the array that matches the condition.
|
|
119
|
+
* @param {__se__NodeCollection} array Array to get item
|
|
120
|
+
* @param {?(current: *) => boolean} validation Conditional function
|
|
121
|
+
* @returns {Array<Node>|null}
|
|
122
|
+
*/
|
|
123
|
+
export function arrayFilter(array, validation) {
|
|
124
|
+
if (!array || array.length === 0) return null;
|
|
125
|
+
|
|
126
|
+
validation =
|
|
127
|
+
validation ||
|
|
128
|
+
function () {
|
|
129
|
+
return true;
|
|
130
|
+
};
|
|
131
|
+
const arr = [];
|
|
132
|
+
|
|
133
|
+
for (let i = 0, len = array.length, a; i < len; i++) {
|
|
134
|
+
a = array[i];
|
|
135
|
+
if (validation(a)) {
|
|
136
|
+
arr.push(a);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return arr;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @description Get the item from the array that matches the condition.
|
|
145
|
+
* @param {__se__NodeCollection} array Array to get item
|
|
146
|
+
* @param {?(current: *) => boolean} validation Conditional function
|
|
147
|
+
* @returns {Node|null}
|
|
148
|
+
*/
|
|
149
|
+
export function arrayFind(array, validation) {
|
|
150
|
+
if (!array || array.length === 0) return null;
|
|
151
|
+
|
|
152
|
+
validation =
|
|
153
|
+
validation ||
|
|
154
|
+
function () {
|
|
155
|
+
return true;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
for (let i = 0, len = array.length, a; i < len; i++) {
|
|
159
|
+
a = array[i];
|
|
160
|
+
if (validation(a)) {
|
|
161
|
+
return a;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @description Check if an array contains an element
|
|
170
|
+
* @param {__se__NodeCollection} array element array
|
|
171
|
+
* @param {Node} node The node to check for
|
|
172
|
+
* @returns {boolean}
|
|
173
|
+
*/
|
|
174
|
+
export function arrayIncludes(array, node) {
|
|
175
|
+
for (let i = 0; i < array.length; i++) {
|
|
176
|
+
if (array[i] === node) {
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @description Get the index of the argument value in the element array
|
|
185
|
+
* @param {__se__NodeCollection} array element array
|
|
186
|
+
* @param {Node} node The element to find index
|
|
187
|
+
* @returns {number}
|
|
188
|
+
*/
|
|
189
|
+
export function getArrayIndex(array, node) {
|
|
190
|
+
let idx = -1;
|
|
191
|
+
for (let i = 0, len = array.length; i < len; i++) {
|
|
192
|
+
if (array[i] === node) {
|
|
193
|
+
idx = i;
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return idx;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* @description Get the next index of the argument value in the element array
|
|
203
|
+
* @param {__se__NodeCollection} array element array
|
|
204
|
+
* @param {Node} item The element to find index
|
|
205
|
+
* @returns {number}
|
|
206
|
+
*/
|
|
207
|
+
export function nextIndex(array, item) {
|
|
208
|
+
const idx = getArrayIndex(array, item);
|
|
209
|
+
if (idx === -1) return -1;
|
|
210
|
+
return idx + 1;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @description Get the previous index of the argument value in the element array
|
|
215
|
+
* @param {__se__NodeCollection} array Element array
|
|
216
|
+
* @param {Node} item The element to find index
|
|
217
|
+
* @returns {number}
|
|
218
|
+
*/
|
|
219
|
+
export function prevIndex(array, item) {
|
|
220
|
+
const idx = getArrayIndex(array, item);
|
|
221
|
+
if (idx === -1) return -1;
|
|
222
|
+
return idx - 1;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* @description Add style and className of copyEl to originEl
|
|
227
|
+
* @param {Node} originEl Origin element
|
|
228
|
+
* @param {Node} copyEl Element to copy
|
|
229
|
+
* @param {?Array<string>=} blacklist Blacklist array(LowerCase)
|
|
230
|
+
*/
|
|
231
|
+
export function copyTagAttributes(originEl, copyEl, blacklist) {
|
|
232
|
+
const o = /** @type {HTMLElement} */ (originEl);
|
|
233
|
+
const c = /** @type {HTMLElement} */ (copyEl);
|
|
234
|
+
if (c.style.cssText) {
|
|
235
|
+
const copyStyles = c.style;
|
|
236
|
+
for (let i = 0, len = copyStyles.length; i < len; i++) {
|
|
237
|
+
o.style[copyStyles[i]] = copyStyles[copyStyles[i]];
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const attrs = c.attributes;
|
|
242
|
+
for (let i = 0, len = attrs.length, name; i < len; i++) {
|
|
243
|
+
name = attrs[i].name.toLowerCase();
|
|
244
|
+
if (blacklist?.includes(name) || !attrs[i].value) o.removeAttribute(name);
|
|
245
|
+
else if (name !== 'style') o.setAttribute(attrs[i].name, attrs[i].value);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* @description Copy and apply attributes of format tag that should be maintained. (style, class) Ignore "__se__format__" class
|
|
251
|
+
* @param {Node} originEl Origin element
|
|
252
|
+
* @param {Node} copyEl Element to copy
|
|
253
|
+
*/
|
|
254
|
+
export function copyFormatAttributes(originEl, copyEl) {
|
|
255
|
+
const c = /** @type {HTMLElement} */ (copyEl.cloneNode(false));
|
|
256
|
+
c.className = c.className.replace(/(\s|^)__se__format__[^\s]+/g, '');
|
|
257
|
+
copyTagAttributes(originEl, c);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* @description Delete argumenu value element
|
|
262
|
+
* @param {Node} item Node to be remove
|
|
263
|
+
*/
|
|
264
|
+
export function removeItem(item) {
|
|
265
|
+
if (!item) return;
|
|
266
|
+
if ('remove' in item && typeof item.remove === 'function') item.remove();
|
|
267
|
+
else if (item.parentNode) item.parentNode.removeChild(item);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* @description Replace element
|
|
272
|
+
* @param {Node} element Target element
|
|
273
|
+
* @param {string|Node} newElement String or element of the new element to apply
|
|
274
|
+
*/
|
|
275
|
+
export function changeElement(element, newElement) {
|
|
276
|
+
if (!element) return;
|
|
277
|
+
|
|
278
|
+
if (typeof newElement === 'string') {
|
|
279
|
+
if ('outerHTML' in element) {
|
|
280
|
+
element.outerHTML = newElement;
|
|
281
|
+
} else {
|
|
282
|
+
const doc = createElement('DIV');
|
|
283
|
+
doc.innerHTML = newElement;
|
|
284
|
+
element.parentNode.replaceChild(doc.firstChild, element);
|
|
285
|
+
}
|
|
286
|
+
} else if (newElement?.nodeType === 1) {
|
|
287
|
+
element.parentNode.replaceChild(newElement, element);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* @description Set the text content value of the argument value element
|
|
293
|
+
* @param {Node} node Element to replace text content
|
|
294
|
+
* @param {string} txt Text to be applied
|
|
295
|
+
*/
|
|
296
|
+
export function changeTxt(node, txt) {
|
|
297
|
+
if (!node || !txt) return;
|
|
298
|
+
node.textContent = txt;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* @description Set style, if all styles are deleted, the style properties are deleted.
|
|
303
|
+
* @param {Node|Node[]} elements Element to set style
|
|
304
|
+
* @param {string} styleName Style attribute name (marginLeft, textAlign...)
|
|
305
|
+
* @param {string|number} value Style value
|
|
306
|
+
*/
|
|
307
|
+
export function setStyle(elements, styleName, value) {
|
|
308
|
+
elements = Array.isArray(elements) ? elements : [elements];
|
|
309
|
+
|
|
310
|
+
for (let i = 0, len = elements.length, e; i < len; i++) {
|
|
311
|
+
e = /** @type {HTMLElement} */ (elements[i]);
|
|
312
|
+
e.style[styleName] = value;
|
|
313
|
+
if (!e.style.cssText) {
|
|
314
|
+
e.removeAttribute('style');
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* @description Gets the style value of the element. If the elements is an array, the style of the first element is returned.
|
|
321
|
+
* @param {Node} element Element to get style from.
|
|
322
|
+
* @param {string} styleName Style attribute name (e.g., 'marginLeft', 'textAlign').
|
|
323
|
+
* @returns {string | undefined} The value of the style attribute, or undefined if the element does not exist.
|
|
324
|
+
*/
|
|
325
|
+
export function getStyle(element, styleName) {
|
|
326
|
+
if (element?.nodeType !== 1) {
|
|
327
|
+
return undefined;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return /** @type {HTMLElement} */ (element).style[styleName];
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* @description In the predefined code view mode, the buttons except the executable button are changed to the 'disabled' state.
|
|
335
|
+
* @param {Array<HTMLButtonElement|HTMLInputElement>} buttonList (Button | Input) Element array
|
|
336
|
+
* @param {boolean} disabled Disabled value
|
|
337
|
+
* @param {boolean} [important=false] If priveleged mode should be used (Necessary to switch importantDisabled buttons)
|
|
338
|
+
*/
|
|
339
|
+
export function setDisabled(buttonList, disabled, important) {
|
|
340
|
+
for (let i = 0, len = buttonList.length; i < len; i++) {
|
|
341
|
+
const button = buttonList[i];
|
|
342
|
+
if (important || !check.isImportantDisabled(button)) button.disabled = disabled;
|
|
343
|
+
if (important) {
|
|
344
|
+
if (disabled) {
|
|
345
|
+
button.setAttribute('data-important-disabled', '');
|
|
346
|
+
} else {
|
|
347
|
+
button.removeAttribute('data-important-disabled');
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* @description Determine whether any of the matched elements are assigned the given class
|
|
355
|
+
* @param {?Node} element Elements to search class name
|
|
356
|
+
* @param {string} className Class name to search for
|
|
357
|
+
* @returns {boolean}
|
|
358
|
+
*/
|
|
359
|
+
export function hasClass(element, className) {
|
|
360
|
+
if (!element || element.nodeType !== 1) return;
|
|
361
|
+
const valid = new RegExp(`(\\s|^)${className}(\\s|$)`);
|
|
362
|
+
return valid.test(/** @type {HTMLElement} */ (element).className);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* @description Append the className value of the argument value element
|
|
367
|
+
* @param {Node|__se__NodeCollection} element Elements to add class name
|
|
368
|
+
* @param {string} className Class name to be add
|
|
369
|
+
*/
|
|
370
|
+
export function addClass(element, className) {
|
|
371
|
+
if (!element) return;
|
|
372
|
+
|
|
373
|
+
const elements = IsElementArray(element) ? element : [element];
|
|
374
|
+
const classNames = className.split('|');
|
|
375
|
+
|
|
376
|
+
for (let i = 0, len = elements.length; i < len; i++) {
|
|
377
|
+
const e = elements[i];
|
|
378
|
+
if (!e || e.nodeType !== 1) continue;
|
|
379
|
+
for (const c of classNames) {
|
|
380
|
+
if (c) /** @type {HTMLElement} */ (e).classList.add(c);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* @description Delete the className value of the argument value element
|
|
387
|
+
* @param {Node|__se__NodeCollection} element Elements to remove class name
|
|
388
|
+
* @param {string} className Class name to be remove
|
|
389
|
+
*/
|
|
390
|
+
export function removeClass(element, className) {
|
|
391
|
+
if (!element) return;
|
|
392
|
+
|
|
393
|
+
const elements = IsElementArray(element) ? element : [element];
|
|
394
|
+
const classNames = className.split('|');
|
|
395
|
+
|
|
396
|
+
for (let i = 0, len = elements.length; i < len; i++) {
|
|
397
|
+
const e = elements[i];
|
|
398
|
+
if (!e || e.nodeType !== 1) continue;
|
|
399
|
+
for (const c of classNames) {
|
|
400
|
+
if (c) /** @type {HTMLElement} */ (e).classList.remove(c);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* @description Argument value If there is no class name, insert it and delete the class name if it exists
|
|
407
|
+
* @param {Node} element Element to replace class name
|
|
408
|
+
* @param {string} className Class name to be change
|
|
409
|
+
* @returns {boolean|undefined}
|
|
410
|
+
*/
|
|
411
|
+
export function toggleClass(element, className) {
|
|
412
|
+
if (!element || element.nodeType !== 1) return;
|
|
413
|
+
|
|
414
|
+
const el = /** @type {HTMLElement} */ (element);
|
|
415
|
+
|
|
416
|
+
let result = false;
|
|
417
|
+
const valid = new RegExp(`(\\s|^)${className}(\\s|$)`);
|
|
418
|
+
if (valid.test(el.className)) {
|
|
419
|
+
el.className = el.className.replace(valid, ' ').trim();
|
|
420
|
+
} else {
|
|
421
|
+
el.className += ' ' + className;
|
|
422
|
+
result = true;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (!el.className.trim()) el.removeAttribute('class');
|
|
426
|
+
|
|
427
|
+
return result;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* @description Flash the class name of the argument value element for a certain time
|
|
432
|
+
* @param {Node} element Element to flash class name
|
|
433
|
+
* @param {string} className class name
|
|
434
|
+
* @param {number} [duration=120] duration milliseconds
|
|
435
|
+
*/
|
|
436
|
+
export function flashClass(element, className, duration = 120) {
|
|
437
|
+
addClass(element, className);
|
|
438
|
+
_w.setTimeout(() => {
|
|
439
|
+
removeClass(element, className);
|
|
440
|
+
}, duration);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* @description Gets the size of the documentElement client size.
|
|
445
|
+
* @param {Document} doc Document object
|
|
446
|
+
* @returns {{w: number, h: number}} documentElement.clientWidth, documentElement.clientHeight
|
|
447
|
+
*/
|
|
448
|
+
export function getClientSize(doc = _d) {
|
|
449
|
+
return {
|
|
450
|
+
w: doc.documentElement.clientWidth,
|
|
451
|
+
h: doc.documentElement.clientHeight
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* @description Gets the size of the window visualViewport size
|
|
457
|
+
* @returns {{top: number, left: number, scale: number}}
|
|
458
|
+
*/
|
|
459
|
+
export function getViewportSize() {
|
|
460
|
+
if ('visualViewport' in _w) {
|
|
461
|
+
return {
|
|
462
|
+
top: _w.visualViewport.pageTop,
|
|
463
|
+
left: _w.visualViewport.pageLeft,
|
|
464
|
+
scale: _w.visualViewport.scale
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return {
|
|
469
|
+
top: 0,
|
|
470
|
+
left: 0,
|
|
471
|
+
scale: 1
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* @description Copies the "wwTarget" element and returns it with inline all styles applied.
|
|
477
|
+
* @param {Node} wwTarget Target element to copy(.sun-editor.sun-editor-editable)
|
|
478
|
+
* @param {boolean} includeWW Include the "wwTarget" element in the copy
|
|
479
|
+
* @param {Array<string>} styles Style list - kamel case
|
|
480
|
+
* @returns
|
|
481
|
+
*/
|
|
482
|
+
export function applyInlineStylesAll(wwTarget, includeWW, styles) {
|
|
483
|
+
if (!wwTarget) {
|
|
484
|
+
console.warn('"parentTarget" is not exist');
|
|
485
|
+
return null;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
let ww = /** @type {HTMLElement} */ (wwTarget);
|
|
489
|
+
const tempTarget = _d.createElement('DIV');
|
|
490
|
+
tempTarget.style.display = 'none';
|
|
491
|
+
|
|
492
|
+
if (/body/i.test(ww.nodeName)) {
|
|
493
|
+
const wwDiv = _d.createElement('DIV');
|
|
494
|
+
const attrs = ww.attributes;
|
|
495
|
+
for (let i = 0, len = attrs.length; i < len; i++) {
|
|
496
|
+
wwDiv.setAttribute(attrs[i].name, attrs[i].value);
|
|
497
|
+
}
|
|
498
|
+
wwDiv.innerHTML = ww.innerHTML;
|
|
499
|
+
ww = wwDiv;
|
|
500
|
+
} else {
|
|
501
|
+
ww = /** @type {HTMLElement} */ (ww.cloneNode(true));
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
tempTarget.appendChild(ww);
|
|
505
|
+
_d.body.appendChild(tempTarget);
|
|
506
|
+
|
|
507
|
+
/** @type {HTMLElement[]} */
|
|
508
|
+
const allElements = Array.from(ww.querySelectorAll('*'));
|
|
509
|
+
const elements = includeWW ? [ww].concat(allElements) : allElements;
|
|
510
|
+
for (let i = 0, el; (el = elements[i]); i++) {
|
|
511
|
+
if (el.nodeType !== 1) continue;
|
|
512
|
+
const computedStyle = _w.getComputedStyle(el);
|
|
513
|
+
const els = el.style;
|
|
514
|
+
for (const props of styles) {
|
|
515
|
+
els.setProperty(props, computedStyle.getPropertyValue(props) || '');
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
_d.body.removeChild(tempTarget);
|
|
520
|
+
|
|
521
|
+
return ww;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* @description Wait for media elements to load
|
|
526
|
+
* @param {Node} target Target element
|
|
527
|
+
* @param {number} timeout Timeout milliseconds
|
|
528
|
+
* @returns {Promise<void>}
|
|
529
|
+
*/
|
|
530
|
+
export function waitForMediaLoad(target, timeout = 5000) {
|
|
531
|
+
const doc = /** @type {HTMLElement|Document} */ (target || _d);
|
|
532
|
+
return new Promise((resolveAll) => {
|
|
533
|
+
const selectors = ['img', 'video', 'audio', 'iframe'];
|
|
534
|
+
const mediaElements = selectors.flatMap((selector) => Array.from(doc.querySelectorAll(selector)));
|
|
535
|
+
|
|
536
|
+
if (mediaElements.length === 0) {
|
|
537
|
+
resolveAll();
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
const mediaPromises = mediaElements.map((element) => {
|
|
542
|
+
// image
|
|
543
|
+
if (IsHTMLImageElement(element)) {
|
|
544
|
+
if (element.complete) {
|
|
545
|
+
return Promise.resolve();
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
// video, audio
|
|
549
|
+
else if (IsHTMLMediaElement(element)) {
|
|
550
|
+
if (element.readyState >= 2) {
|
|
551
|
+
return Promise.resolve();
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
// iframe
|
|
555
|
+
else if (IsHTMLIFrameElement(element)) {
|
|
556
|
+
try {
|
|
557
|
+
if (element.contentDocument?.readyState === 'complete') {
|
|
558
|
+
return Promise.resolve();
|
|
559
|
+
}
|
|
560
|
+
} catch (e) {
|
|
561
|
+
console.warn(['[SUNEDITOR] Iframe load error', e]);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// load event
|
|
566
|
+
return new Promise((resolve) => {
|
|
567
|
+
element.addEventListener('load', resolve, { once: true });
|
|
568
|
+
element.addEventListener('error', resolve, { once: true });
|
|
569
|
+
});
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
Promise.race([Promise.all(mediaPromises), new Promise((resolve) => _w.setTimeout(resolve, timeout))]).then(() => {
|
|
573
|
+
resolveAll();
|
|
574
|
+
});
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* @description Create tooltip HTML
|
|
580
|
+
* @param {string} text Tooltip text
|
|
581
|
+
* @returns {string} Tooltip HTML
|
|
582
|
+
*/
|
|
583
|
+
export function createTooltipInner(text) {
|
|
584
|
+
return `<span class="se-tooltip-inner"><span class="se-tooltip-text">${text}</span></span>`;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
const utils = {
|
|
588
|
+
clone,
|
|
589
|
+
createElement,
|
|
590
|
+
createTextNode,
|
|
591
|
+
getAttributesToString,
|
|
592
|
+
arrayFilter,
|
|
593
|
+
arrayFind,
|
|
594
|
+
arrayIncludes,
|
|
595
|
+
getArrayIndex,
|
|
596
|
+
nextIndex,
|
|
597
|
+
prevIndex,
|
|
598
|
+
copyTagAttributes,
|
|
599
|
+
copyFormatAttributes,
|
|
600
|
+
removeItem,
|
|
601
|
+
changeElement,
|
|
602
|
+
changeTxt,
|
|
603
|
+
setStyle,
|
|
604
|
+
getStyle,
|
|
605
|
+
setDisabled,
|
|
606
|
+
hasClass,
|
|
607
|
+
addClass,
|
|
608
|
+
removeClass,
|
|
609
|
+
toggleClass,
|
|
610
|
+
flashClass,
|
|
611
|
+
getClientSize,
|
|
612
|
+
getViewportSize,
|
|
613
|
+
applyInlineStylesAll,
|
|
614
|
+
waitForMediaLoad,
|
|
615
|
+
createTooltipInner
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
export default utils;
|