@textbus/platform-browser 5.1.6 → 5.2.1

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.
@@ -0,0 +1,1699 @@
1
+ import { Slot as X, ContentType as T, Event as x, invokeListener as v, Adapter as Y, NativeSelectionBridge as st, FocusManager as it, Component as ot, Registry as nt, makeError as rt } from "@textbus/core";
2
+ import { filter as b, fromEvent as f, Subject as S, delay as at, Subscription as D, distinctUntilChanged as M, merge as Z, map as L, Observable as G } from "@tanbo/stream";
3
+ import { InjectionToken as H, Injectable as F, Inject as J, Optional as ct } from "@viewfly/core";
4
+ function m(s, t = {}) {
5
+ const i = document.createElement(s);
6
+ return t.classes && i.classList.add(...t.classes), t.attrs && Object.keys(t.attrs).forEach((e) => {
7
+ i.setAttribute(e, t.attrs[e]);
8
+ }), t.props && Object.keys(t.props).forEach((e) => {
9
+ i[e] = t.props[e];
10
+ }), t.styles && Object.assign(i.style, t.styles), t.children && t.children.filter((e) => e).forEach((e) => {
11
+ i.appendChild(e);
12
+ }), t.on && Object.keys(t.on).forEach((e) => {
13
+ i.addEventListener(e, t.on[e]);
14
+ }), i;
15
+ }
16
+ function B(s) {
17
+ let { startContainer: t, startOffset: i } = s;
18
+ if (t.nodeType === Node.TEXT_NODE) {
19
+ if (i > 0)
20
+ return s.getBoundingClientRect();
21
+ const c = t.parentNode;
22
+ i = Array.from(c.childNodes).indexOf(t), t = c;
23
+ }
24
+ const e = t.childNodes[i - 1];
25
+ if (e) {
26
+ if (e.nodeType === Node.ELEMENT_NODE && e.nodeName.toLowerCase() !== "br") {
27
+ const c = e.getBoundingClientRect();
28
+ return {
29
+ left: c.right,
30
+ top: c.top,
31
+ width: s.collapsed ? 1 : c.width,
32
+ height: c.height
33
+ };
34
+ } else if (e.nodeType === Node.TEXT_NODE) {
35
+ const c = document.createRange();
36
+ c.setStart(e, e.textContent.length), c.setEnd(e, e.textContent.length);
37
+ const l = c.getBoundingClientRect();
38
+ return {
39
+ left: l.right,
40
+ top: l.top,
41
+ width: s.collapsed ? 1 : l.width,
42
+ height: l.height
43
+ };
44
+ }
45
+ }
46
+ const o = t.childNodes[i];
47
+ let n = !1;
48
+ if (!o) {
49
+ const c = t.lastChild;
50
+ if (c && c.nodeType === Node.ELEMENT_NODE) {
51
+ const l = c.getBoundingClientRect();
52
+ return {
53
+ left: l.right,
54
+ top: l.top,
55
+ width: s.collapsed ? 1 : l.width,
56
+ height: l.height
57
+ };
58
+ }
59
+ }
60
+ if (o) {
61
+ if (o.nodeType === Node.ELEMENT_NODE && o.nodeName.toLowerCase() !== "br") {
62
+ const c = o.getBoundingClientRect();
63
+ return {
64
+ left: c.left,
65
+ top: c.top,
66
+ width: s.collapsed ? 1 : c.width,
67
+ height: c.height
68
+ };
69
+ }
70
+ n = !0;
71
+ }
72
+ const r = t.ownerDocument.createElement("span");
73
+ r.innerText = "​", r.style.display = "inline-block", n ? t.insertBefore(r, o) : t.appendChild(r);
74
+ const a = r.getBoundingClientRect();
75
+ return t.removeChild(r), {
76
+ left: a.left,
77
+ top: a.top,
78
+ width: s.collapsed ? 1 : a.width,
79
+ height: a.height
80
+ };
81
+ }
82
+ const lt = () => /win(dows|32|64)/i.test(navigator.userAgent), Q = () => /mac os/i.test(navigator.userAgent), tt = () => /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent), V = () => /Firefox/.test(navigator.userAgent), ht = () => /Android|iPhone|iPad/.test(navigator.userAgent), z = new H("EDITOR_OPTIONS"), j = new H("VIEW_CONTAINER"), U = new H("VIEW_DOCUMENT"), K = new H("VIEW_MASK");
83
+ var dt = Object.getOwnPropertyDescriptor, ft = (s, t, i, e) => {
84
+ for (var o = e > 1 ? void 0 : e ? dt(t, i) : t, n = s.length - 1, r; n >= 0; n--)
85
+ (r = s[n]) && (o = r(o) || o);
86
+ return o;
87
+ }, ut = (s, t) => (i, e) => t(i, e, s);
88
+ let O = class {
89
+ constructor(s, t) {
90
+ this.textbus = t;
91
+ const i = [
92
+ ...s.componentLoaders || []
93
+ ], e = [
94
+ ...s.formatLoaders || []
95
+ ], o = [
96
+ ...s.attributeLoaders || []
97
+ ];
98
+ this.componentLoaders = i, this.formatLoaders = e, this.attributeLoaders = o;
99
+ }
100
+ textbus;
101
+ static parseHTML(s) {
102
+ return new DOMParser().parseFromString(s, "text/html").body;
103
+ }
104
+ componentLoaders;
105
+ formatLoaders;
106
+ attributeLoaders;
107
+ /**
108
+ * 使用指定的组件加载器解析一段 HTML 字符串或 DOM 元素
109
+ * @param html
110
+ * @param rootComponentLoader
111
+ */
112
+ parseDoc(s, t) {
113
+ const i = typeof s == "string" ? O.parseHTML(s) : s;
114
+ return t.read(
115
+ i,
116
+ this.textbus,
117
+ (e, o, n = o) => this.readSlot(e, o, n)
118
+ );
119
+ }
120
+ /**
121
+ * 将一段 HTML 或 DOM 元素解析到指定插槽
122
+ * @param html
123
+ * @param rootSlot
124
+ */
125
+ parse(s, t) {
126
+ const i = typeof s == "string" ? O.parseHTML(s) : s;
127
+ return this.readFormats(i, t);
128
+ }
129
+ readComponent(s, t) {
130
+ if (s.nodeType === Node.ELEMENT_NODE) {
131
+ if (s.tagName === "BR") {
132
+ t.insert(`
133
+ `);
134
+ return;
135
+ }
136
+ const i = [...t.schema];
137
+ for (const e of this.componentLoaders)
138
+ if (e.match(s, i)) {
139
+ const o = e.read(
140
+ s,
141
+ this.textbus,
142
+ (n, r, a = r) => this.readSlot(n, r, a)
143
+ );
144
+ if (!o)
145
+ return;
146
+ if (o instanceof X) {
147
+ o.toDelta().forEach((n) => t.insert(n.insert, n.formats));
148
+ return;
149
+ }
150
+ t.insert(o);
151
+ return;
152
+ }
153
+ this.readFormats(s, t);
154
+ } else s.nodeType === Node.TEXT_NODE && this.readText(t, s);
155
+ }
156
+ readText(s, t) {
157
+ const i = t.textContent;
158
+ /^\s*[\r\n\u200b]+\s*$/.test(i) || s.insert(i);
159
+ }
160
+ readFormats(s, t) {
161
+ const i = this.formatLoaders.filter((r) => r.match(s)).map((r) => r.read(s)), e = t.index;
162
+ let o = s.firstChild;
163
+ for (; o; )
164
+ this.readComponent(o, t), o = o.nextSibling;
165
+ const n = t.index;
166
+ return this.applyFormats(t, i.map((r) => ({
167
+ formatter: r.formatter,
168
+ value: r.value,
169
+ startIndex: e,
170
+ endIndex: n
171
+ }))), t.retain(n), t;
172
+ }
173
+ readSlot(s, t, i) {
174
+ return t.nodeType === Node.ELEMENT_NODE && this.attributeLoaders.filter((e) => e.match(t)).forEach((e) => {
175
+ const o = e.read(t);
176
+ s.setAttribute(o.attribute, o.value);
177
+ }), i.nodeType === Node.ELEMENT_NODE ? this.readFormats(i, s) : this.readText(s, i), s;
178
+ }
179
+ applyFormats(s, t) {
180
+ s.background(() => {
181
+ t.forEach((i) => {
182
+ s.retain(i.startIndex), s.retain(i.endIndex - i.startIndex, i.formatter, i.value);
183
+ });
184
+ });
185
+ }
186
+ };
187
+ O = ft([
188
+ F(),
189
+ ut(0, J(z))
190
+ ], O);
191
+ var pt = Object.getOwnPropertyDescriptor, gt = (s, t, i, e) => {
192
+ for (var o = e > 1 ? void 0 : e ? pt(t, i) : t, n = s.length - 1, r; n >= 0; n--)
193
+ (r = s[n]) && (o = r(o) || o);
194
+ return o;
195
+ }, mt = (s, t) => (i, e) => t(i, e, s);
196
+ let P = class {
197
+ constructor(s, t, i, e, o, n, r, a) {
198
+ this.config = s, this.selection = e, this.rootComponentRef = o, this.input = n, this.scheduler = r, this.domAdapter = a, this.docContainer = t.get(U), this.onSelectionChange = this.selectionChangeEvent.asObservable().pipe(b(() => !i.readonly)), this.sub = this.onSelectionChange.subscribe((c) => {
199
+ c ? n.focus(c, this.changeFromUser) : n.blur();
200
+ }), this.sub.add(
201
+ f(document, "focusin").subscribe((c) => {
202
+ let l = c.target;
203
+ if (/^(input|textarea|select)$/i.test(l.nodeName)) {
204
+ if (l.tagName.toLowerCase() === "input" && /^(range|date)$/.test(l.type))
205
+ return;
206
+ this.ignoreSelectionChange = !0;
207
+ return;
208
+ }
209
+ if (!s.useContentEditable)
210
+ for (; l; ) {
211
+ if (l.contentEditable === "true") {
212
+ this.ignoreSelectionChange = !0;
213
+ return;
214
+ }
215
+ l = l.parentNode;
216
+ }
217
+ })
218
+ ), this.sub.add(
219
+ f(document, "focusout").subscribe(() => {
220
+ this.ignoreSelectionChange = !1;
221
+ })
222
+ );
223
+ }
224
+ config;
225
+ selection;
226
+ rootComponentRef;
227
+ input;
228
+ scheduler;
229
+ domAdapter;
230
+ onSelectionChange;
231
+ nativeSelection = document.getSelection();
232
+ syncSelectionFromNativeSelectionChange = !0;
233
+ selectionChangeEvent = new S();
234
+ subs = [];
235
+ sub;
236
+ connector = null;
237
+ ignoreSelectionChange = !1;
238
+ changeFromUser = !1;
239
+ docContainer;
240
+ cacheCaretPositionTimer;
241
+ oldCaretPosition;
242
+ connect(s) {
243
+ this.disConnect(), this.connector = s, this.syncSelection(s), this.listen(s);
244
+ }
245
+ disConnect() {
246
+ this.connector = null, this.unListen();
247
+ }
248
+ getRect(s) {
249
+ const { focus: t, anchor: i } = this.getPositionByRange({
250
+ focusOffset: s.offset,
251
+ anchorOffset: s.offset,
252
+ focusSlot: s.slot,
253
+ anchorSlot: s.slot
254
+ });
255
+ if (!t || !i)
256
+ return null;
257
+ const e = document.createRange();
258
+ return e.setStart(t.node, t.offset), e.collapse(), B(e);
259
+ }
260
+ restore(s, t) {
261
+ if (this.changeFromUser = t, this.ignoreSelectionChange || !this.connector)
262
+ return;
263
+ if (this.unListen(), !s) {
264
+ this.nativeSelection.removeAllRanges(), this.selectionChangeEvent.next(null), this.listen(this.connector);
265
+ return;
266
+ }
267
+ const { focus: i, anchor: e } = this.getPositionByRange(s);
268
+ if (!i || !e) {
269
+ this.nativeSelection.removeAllRanges(), this.selectionChangeEvent.next(null), this.listen(this.connector);
270
+ return;
271
+ }
272
+ function o(r) {
273
+ if (r.node) {
274
+ if (r.node.nodeType === Node.TEXT_NODE) {
275
+ const a = r.node.textContent.length;
276
+ r.offset > a && (r.offset = a);
277
+ } else if (r.node.nodeType === Node.ELEMENT_NODE) {
278
+ const a = r.node.childNodes.length;
279
+ r.offset > a && (r.offset = a);
280
+ }
281
+ }
282
+ }
283
+ try {
284
+ o(i), o(e), this.nativeSelection.setBaseAndExtent(e.node, e.offset, i.node, i.offset);
285
+ } catch (r) {
286
+ setTimeout(() => {
287
+ throw r;
288
+ });
289
+ }
290
+ if (this.nativeSelection.rangeCount) {
291
+ const r = this.nativeSelection.getRangeAt(0);
292
+ this.selectionChangeEvent.next(r);
293
+ } else
294
+ this.selectionChangeEvent.next(null);
295
+ const n = () => {
296
+ this.connector && this.listen(this.connector);
297
+ };
298
+ if (t) {
299
+ Promise.resolve().then(n);
300
+ return;
301
+ }
302
+ typeof requestIdleCallback == "function" ? requestIdleCallback(n) : setTimeout(n, 30);
303
+ }
304
+ destroy() {
305
+ this.subs.forEach((s) => s.unsubscribe()), this.sub.unsubscribe();
306
+ }
307
+ getPositionByRange(s) {
308
+ let t, i;
309
+ try {
310
+ return t = this.findSelectedNodeAndOffset(s.focusSlot, s.focusOffset), i = t, (s.anchorSlot !== s.focusSlot || s.anchorOffset !== s.focusOffset) && (i = this.findSelectedNodeAndOffset(s.anchorSlot, s.anchorOffset)), {
311
+ focus: t,
312
+ anchor: i
313
+ };
314
+ } catch {
315
+ return {
316
+ focus: null,
317
+ anchor: null
318
+ };
319
+ }
320
+ }
321
+ getPreviousLinePositionByCurrent(s) {
322
+ return this.getLinePosition(s, !1);
323
+ }
324
+ getNextLinePositionByCurrent(s) {
325
+ return this.getLinePosition(s, !0);
326
+ }
327
+ getLinePosition(s, t) {
328
+ clearTimeout(this.cacheCaretPositionTimer);
329
+ let i;
330
+ return this.oldCaretPosition ? i = t ? this.getNextLinePositionByOffset(s, this.oldCaretPosition.left) : this.getPreviousLinePositionByOffset(s, this.oldCaretPosition.left) : (this.oldCaretPosition = this.getRect(s), i = t ? this.getNextLinePositionByOffset(s, this.oldCaretPosition.left) : this.getPreviousLinePositionByOffset(s, this.oldCaretPosition.left)), this.cacheCaretPositionTimer = setTimeout(() => {
331
+ this.oldCaretPosition = null;
332
+ }, 3e3), i;
333
+ }
334
+ /**
335
+ * 获取选区向上移动一行的位置。
336
+ * @param currentPosition
337
+ * @param startLeft 参考位置。
338
+ */
339
+ getPreviousLinePositionByOffset(s, t) {
340
+ let i = !1, e = 0, o = t, n = s.slot, r = s.offset, a = this.getRect({
341
+ slot: n,
342
+ offset: r
343
+ }).top, c, l, u = 0;
344
+ for (; ; ) {
345
+ e++, c = this.selection.getPreviousPositionByPosition(n, r), n = c.slot, r = c.offset;
346
+ const h = this.getRect(c);
347
+ if (!i) {
348
+ if (h.left > o || h.top + h.height <= a)
349
+ i = !0;
350
+ else if (h.left === o && h.top === a)
351
+ return c;
352
+ o = h.left, a = h.top;
353
+ }
354
+ if (i) {
355
+ if (h.left <= t)
356
+ return c;
357
+ if (l && h.left >= u)
358
+ return l;
359
+ u = h.left, l = c;
360
+ }
361
+ if (e > 1e4)
362
+ break;
363
+ }
364
+ return c || {
365
+ offset: 0,
366
+ slot: n
367
+ };
368
+ }
369
+ /**
370
+ * 获取选区向下移动一行的位置。
371
+ * @param currentPosition
372
+ * @param startLeft 参考位置。
373
+ */
374
+ getNextLinePositionByOffset(s, t) {
375
+ let i = !1, e = 0, o = t, n = s.slot, r = s.offset;
376
+ const a = this.getRect({
377
+ slot: n,
378
+ offset: r
379
+ });
380
+ let c = a.top, l, u = 0;
381
+ for (; ; ) {
382
+ e++;
383
+ const h = this.selection.getNextPositionByPosition(n, r);
384
+ n = h.slot, r = h.offset;
385
+ const d = this.getRect(h);
386
+ if (!i) {
387
+ if (d.left < o || d.top >= c + a.height)
388
+ i = !0;
389
+ else if (d.left === o && d.top === c)
390
+ return h;
391
+ o = d.left, c = d.top, l = h;
392
+ }
393
+ if (i) {
394
+ if (d.left > t || l && d.left <= u)
395
+ return l;
396
+ l = h, u = d.left;
397
+ }
398
+ if (e > 1e4)
399
+ break;
400
+ }
401
+ return l || {
402
+ offset: n.length,
403
+ slot: n
404
+ };
405
+ }
406
+ unListen() {
407
+ this.subs.forEach((s) => s.unsubscribe()), this.subs = [];
408
+ }
409
+ listen(s) {
410
+ if (!this.config.useContentEditable) {
411
+ const i = this.nativeSelection;
412
+ this.subs.push(
413
+ f(this.docContainer, "mousedown").subscribe((e) => {
414
+ this.ignoreSelectionChange || e.button === 2 || e.shiftKey || i.removeAllRanges();
415
+ })
416
+ );
417
+ }
418
+ let t = !1;
419
+ this.subs.push(
420
+ this.scheduler.onDocChange.subscribe(() => {
421
+ t = !0;
422
+ }),
423
+ this.scheduler.onDocChanged.pipe(at()).subscribe(() => {
424
+ t = !1;
425
+ }),
426
+ f(document, "selectionchange").subscribe(() => {
427
+ t || this.syncSelectionFromNativeSelectionChange && this.syncSelection(s);
428
+ })
429
+ );
430
+ }
431
+ syncSelection(s) {
432
+ const t = this.nativeSelection;
433
+ if (this.changeFromUser = !0, this.ignoreSelectionChange || this.input.composition || t.rangeCount === 0 || !this.docContainer.contains(t.anchorNode) || this.rootComponentRef.component.slots.length === 0)
434
+ return;
435
+ const i = t.getRangeAt(0), e = i.cloneRange(), o = t.focusNode === e.endContainer && t.focusOffset === e.endOffset, n = t.focusNode === e.startContainer && t.focusOffset === e.startOffset;
436
+ if (!this.docContainer.contains(t.focusNode))
437
+ if (o) {
438
+ const c = this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.slots.at(0));
439
+ if (!c)
440
+ return;
441
+ e.setEndAfter(c.lastChild);
442
+ } else {
443
+ const c = this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.slots.at(-1));
444
+ if (!c)
445
+ return;
446
+ e.setStartBefore(c.firstChild);
447
+ }
448
+ const r = this.getCorrectedPosition(e.startContainer, e.startOffset, n), a = e.collapsed ? r : this.getCorrectedPosition(e.endContainer, e.endOffset, o);
449
+ if ([Node.ELEMENT_NODE, Node.TEXT_NODE].includes(e.commonAncestorContainer?.nodeType) && r && a) {
450
+ const c = s.beforeChange(o ? {
451
+ anchorSlot: r.slot,
452
+ anchorOffset: r.offset,
453
+ focusSlot: a.slot,
454
+ focusOffset: a.offset
455
+ } : {
456
+ focusSlot: r.slot,
457
+ focusOffset: r.offset,
458
+ anchorSlot: a.slot,
459
+ anchorOffset: a.offset
460
+ });
461
+ if (!c) {
462
+ this.selectionChangeEvent.next(null), s.setSelection(null);
463
+ return;
464
+ }
465
+ const { focus: l, anchor: u } = this.getPositionByRange(c);
466
+ if (l && u) {
467
+ let h = u, d = l;
468
+ n && (h = l, d = u), (e.startContainer !== h.node || e.startOffset !== h.offset) && e.setStart(h.node, h.offset), (e.endContainer !== d.node || e.endOffset !== d.offset) && e.setEnd(d.node, d.offset), s.setSelection(c), t.isCollapsed && (i.startContainer !== h.node || i.startOffset !== h.offset || i.endContainer !== d.node || i.endOffset !== d.offset) && (i.setStart(h.node, h.offset), i.setEnd(d.node, d.offset)), this.selectionChangeEvent.next(e);
469
+ } else
470
+ s.setSelection(null);
471
+ return;
472
+ }
473
+ s.setSelection(null);
474
+ }
475
+ findSelectedNodeAndOffset(s, t) {
476
+ const i = s.getContentAtIndex(t - 1), e = this.domAdapter.getNodesBySlot(s);
477
+ if (i) {
478
+ if (typeof i != "string") {
479
+ const n = this.domAdapter.getNativeNodeByComponent(i);
480
+ return {
481
+ node: n.parentNode,
482
+ offset: Array.from(n.parentNode.childNodes).indexOf(n) + 1
483
+ };
484
+ } else if (i === `
485
+ `) {
486
+ for (const n of e)
487
+ if (!(n instanceof Text) && n.nodeName === "BR") {
488
+ const r = this.domAdapter.getLocationByNativeNode(n);
489
+ if (r && r.endIndex === t) {
490
+ const a = n.parentNode;
491
+ return {
492
+ node: a,
493
+ offset: Array.from(a.childNodes).indexOf(n) + 1
494
+ };
495
+ }
496
+ }
497
+ }
498
+ }
499
+ const o = s.getContentAtIndex(t);
500
+ if (o && typeof o != "string") {
501
+ const n = this.domAdapter.getNativeNodeByComponent(o);
502
+ return {
503
+ node: n.parentNode,
504
+ offset: Array.from(n.parentNode.childNodes).indexOf(n)
505
+ };
506
+ }
507
+ for (const n of e) {
508
+ if (n instanceof Element) {
509
+ if (n.tagName === "BR") {
510
+ const a = this.domAdapter.getLocationByNativeNode(n);
511
+ if (a && a.startIndex === t) {
512
+ const c = n.parentNode;
513
+ return {
514
+ node: c,
515
+ offset: Array.from(c.childNodes).indexOf(n)
516
+ };
517
+ }
518
+ }
519
+ continue;
520
+ }
521
+ const r = this.domAdapter.getLocationByNativeNode(n);
522
+ if (r && t >= r.startIndex && t <= r.endIndex)
523
+ return {
524
+ node: n,
525
+ offset: t - r.startIndex
526
+ };
527
+ }
528
+ return null;
529
+ }
530
+ getCorrectedPosition(s, t, i, e = []) {
531
+ if (e.push(s), s.nodeType === Node.ELEMENT_NODE) {
532
+ const o = this.domAdapter.getLocationByNativeNode(s), n = s.childNodes[t];
533
+ if (n) {
534
+ const c = this.domAdapter.getLocationByNativeNode(n);
535
+ return c ? o ? {
536
+ slot: c.slot,
537
+ offset: c.startIndex
538
+ } : this.findFocusNode(n, i, e) : this.findFocusNode(n, i, e);
539
+ }
540
+ const r = s.childNodes[t - 1];
541
+ if (r) {
542
+ const c = this.domAdapter.getLocationByNativeNode(r);
543
+ if (c && o)
544
+ return {
545
+ slot: c.slot,
546
+ offset: c.endIndex
547
+ };
548
+ }
549
+ if (o)
550
+ return {
551
+ slot: o.slot,
552
+ offset: o.endIndex
553
+ };
554
+ const a = i ? s.nextSibling : s.previousSibling;
555
+ return a ? this.findFocusNode(a, i, e) : this.findFocusNodeByParent(s, i, e);
556
+ } else if (s.nodeType === Node.TEXT_NODE) {
557
+ const o = this.domAdapter.getLocationByNativeNode(s);
558
+ if (o)
559
+ return {
560
+ slot: o.slot,
561
+ offset: o.startIndex + t
562
+ };
563
+ const n = i ? s.nextSibling : s.previousSibling;
564
+ return n ? this.findFocusNode(n, i, e) : this.findFocusNodeByParent(s, i, e);
565
+ }
566
+ return null;
567
+ }
568
+ findFocusNode(s, t = !1, i = []) {
569
+ if (i.includes(s)) {
570
+ const r = t ? s.nextSibling : s.previousSibling;
571
+ return r ? this.findFocusNode(r, t, i) : this.findFocusNodeByParent(s, t, i);
572
+ }
573
+ i.push(s);
574
+ const e = this.domAdapter.getLocationByNativeNode(s);
575
+ if (e)
576
+ return {
577
+ slot: e.slot,
578
+ offset: t ? e.startIndex : e.endIndex
579
+ };
580
+ const o = t ? s.firstChild : s.lastChild;
581
+ if (o)
582
+ return this.findFocusNode(o, t, i);
583
+ const n = t ? s.nextSibling : s.previousSibling;
584
+ return n ? this.findFocusNode(n, t, i) : this.findFocusNodeByParent(s, t, i);
585
+ }
586
+ findFocusNodeByParent(s, t, i) {
587
+ const e = s.parentNode;
588
+ if (e) {
589
+ const o = this.domAdapter.getLocationByNativeNode(e);
590
+ return o ? {
591
+ slot: o.slot,
592
+ offset: t ? o.endIndex : o.startIndex
593
+ } : (i.push(s), this.findFocusNode(e, t, i));
594
+ }
595
+ return null;
596
+ }
597
+ };
598
+ P = gt([
599
+ F(),
600
+ mt(0, J(z))
601
+ ], P);
602
+ class N {
603
+ }
604
+ var bt = Object.getOwnPropertyDescriptor, yt = (s, t, i, e) => {
605
+ for (var o = e > 1 ? void 0 : e ? bt(t, i) : t, n = s.length - 1, r; n >= 0; n--)
606
+ (r = s[n]) && (o = r(o) || o);
607
+ return o;
608
+ };
609
+ const Ct = `
610
+ <!DOCTYPE html>
611
+ <html>
612
+ <head>
613
+ <meta charset="UTF-8">
614
+ <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
615
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
616
+ <title>Textbus</title>
617
+ <style>
618
+ html {position: fixed; left:0; overflow: hidden}
619
+ html, body{height: 100%;width:100%}
620
+ body{margin:0; overflow: hidden}
621
+ textarea{width: 2000px;height: 100%;opacity: 0; padding: 0; outline: none; border: none; position: absolute; left:0; top:0;}
622
+ </style>
623
+ </head>
624
+ <body>
625
+ </body>
626
+ </html>
627
+ `;
628
+ class xt {
629
+ constructor(t, i, e) {
630
+ this.domRenderer = t, this.scheduler = i, this.editorMask = e, this.onPositionChange = this.positionChangeEvent.pipe(M()), this.onStyleChange = this.styleChangeEvent.asObservable(), this.elementRef = m("div", {
631
+ styles: {
632
+ position: "absolute",
633
+ width: "2px",
634
+ pointerEvents: "none"
635
+ },
636
+ children: [
637
+ this.caret = m("span", {
638
+ styles: {
639
+ width: "100%",
640
+ height: "100%",
641
+ position: "absolute",
642
+ left: 0,
643
+ top: 0
644
+ }
645
+ })
646
+ ]
647
+ }), this.subscription.add(
648
+ f(document, "mousedown").subscribe(() => {
649
+ this.flashing = !1;
650
+ }),
651
+ f(document, "mouseup").subscribe(() => {
652
+ this.flashing = !0;
653
+ })
654
+ ), this.editorMask.appendChild(this.elementRef);
655
+ }
656
+ domRenderer;
657
+ scheduler;
658
+ editorMask;
659
+ onPositionChange;
660
+ onStyleChange;
661
+ elementRef;
662
+ changeFromSelf = !1;
663
+ getLimit = function() {
664
+ return {
665
+ top: 0,
666
+ bottom: document.documentElement.clientHeight
667
+ };
668
+ };
669
+ get rect() {
670
+ return this.caret.getBoundingClientRect();
671
+ }
672
+ timer = null;
673
+ caret;
674
+ set display(t) {
675
+ this._display = t, this.caret.style.visibility = t ? "visible" : "hidden";
676
+ }
677
+ get display() {
678
+ return this._display;
679
+ }
680
+ _display = !0;
681
+ flashing = !0;
682
+ subscription = new D();
683
+ positionChangeEvent = new S();
684
+ styleChangeEvent = new S();
685
+ oldRange = null;
686
+ refresh() {
687
+ this.oldRange && this.show(this.oldRange, !1);
688
+ }
689
+ show(t, i) {
690
+ if (this.oldRange = t, (i || this.scheduler.lastChangesHasLocalUpdate) && clearTimeout(this.timer), this.updateCursorPosition(t), t.collapsed) {
691
+ if (i || this.scheduler.lastChangesHasLocalUpdate) {
692
+ this.display = !0;
693
+ const e = () => {
694
+ this.display = !this.display || !this.flashing, this.timer = setTimeout(e, 400);
695
+ };
696
+ clearTimeout(this.timer), this.timer = setTimeout(e, 400);
697
+ }
698
+ } else
699
+ this.display = !1, clearTimeout(this.timer);
700
+ }
701
+ hide() {
702
+ this.display = !1, clearTimeout(this.timer), this.positionChangeEvent.next(null);
703
+ }
704
+ destroy() {
705
+ clearTimeout(this.timer), this.subscription.unsubscribe();
706
+ }
707
+ updateCursorPosition(t) {
708
+ const i = t.startContainer, e = i.nodeType === Node.ELEMENT_NODE ? i : i.parentNode;
709
+ if (e?.nodeType !== Node.ELEMENT_NODE) {
710
+ this.positionChangeEvent.next(null);
711
+ return;
712
+ }
713
+ const o = this.domRenderer.compositionNode;
714
+ o && (t = t.cloneRange(), t.selectNodeContents(o), t.collapse());
715
+ const n = B(t), { fontSize: r, lineHeight: a, color: c, writingMode: l } = getComputedStyle(e);
716
+ let u;
717
+ if (isNaN(+a)) {
718
+ const p = parseFloat(a);
719
+ isNaN(p) ? u = parseFloat(r) : u = p;
720
+ } else
721
+ u = parseFloat(r) * parseFloat(a);
722
+ const h = Math.max(Math.floor(Math.max(u, n.height)), 12);
723
+ let d = n.top;
724
+ n.height < u && (d -= (u - n.height) / 2), d = Math.floor(d);
725
+ const w = this.editorMask.getBoundingClientRect(), _ = Math.floor(d - w.top), E = Math.floor(n.left + n.width / 2 - w.left);
726
+ let C = 0;
727
+ if (t.collapsed && (C = Math.round(Math.atan2(n.width, n.height) * 180 / Math.PI), C !== 0)) {
728
+ const p = document.createElement("span");
729
+ p.style.cssText = "display: inline-block; width: 10px; height: 10px; position: relative; contain: layout style size; writing-mode: inherit";
730
+ const g = document.createElement("span");
731
+ g.style.cssText = "position: absolute; left: 0; top: 0; width:0;height:0", p.append(g), e.append(p);
732
+ const y = g.getBoundingClientRect();
733
+ g.style.right = "0", g.style.left = "";
734
+ const R = g.getBoundingClientRect(), A = y.x - R.x, I = y.y - R.y;
735
+ C = Math.atan2(I, A) * 180 / Math.PI, p.remove();
736
+ }
737
+ if ((l === "vertical-lr" || l === "vertical-rl") && (C += 90), Object.assign(this.elementRef.style, {
738
+ left: E + "px",
739
+ top: _ + "px",
740
+ height: h + "px",
741
+ lineHeight: h + "px",
742
+ fontSize: r,
743
+ transform: `rotate(${C}deg)`
744
+ }), this.caret.style.backgroundColor = c === "rgba(0, 0, 0, 0)" ? "#000" : c, this.styleChangeEvent.next({
745
+ height: h + "px",
746
+ lineHeight: h + "px",
747
+ fontSize: r
748
+ }), this.positionChangeEvent.next({
749
+ left: E,
750
+ top: d,
751
+ height: h
752
+ }), this.changeFromSelf) {
753
+ this.changeFromSelf = !1;
754
+ const p = this.elementRef.getBoundingClientRect(), g = this.getScrollContainer(i), y = g === document.documentElement ? { top: 0, bottom: document.documentElement.clientHeight } : g.getBoundingClientRect(), R = this.getLimit(), A = Math.max(R.top, y.top), I = Math.min(R.bottom, y.bottom);
755
+ p.top < A ? g.scrollTop -= A - p.top : p.bottom > I && (g.scrollTop += p.bottom - I);
756
+ }
757
+ }
758
+ getScrollContainer(t) {
759
+ for (; t; ) {
760
+ if (t instanceof Element) {
761
+ const i = getComputedStyle(t);
762
+ if (i.overflow !== "visible" || i.overflowX !== "visible" || i.overflowY !== "visible")
763
+ return t;
764
+ }
765
+ t = t.parentNode;
766
+ }
767
+ return document.documentElement;
768
+ }
769
+ }
770
+ let $ = class extends N {
771
+ // 有 bug 版本搜狗拼音
772
+ constructor(s, t, i, e, o, n, r, a) {
773
+ super(), this.domAdapter = s, this.parser = t, this.keyboard = i, this.commander = e, this.selection = o, this.controller = n, this.scheduler = r, this.textbus = a, this.caret = new xt(this.domAdapter, this.scheduler, this.textbus.get(K)), this.onReady = new Promise((c) => {
774
+ this.subscription.add(
775
+ f(this.container, "load").subscribe(() => {
776
+ const l = this.container.contentDocument;
777
+ l.open(), l.write(Ct), l.close(), this.doc = l, this.init(), c();
778
+ }),
779
+ n.onReadonlyStateChange.subscribe(() => {
780
+ n.readonly && this.blur();
781
+ })
782
+ );
783
+ }), this.caret.elementRef.append(this.container);
784
+ }
785
+ domAdapter;
786
+ parser;
787
+ keyboard;
788
+ commander;
789
+ selection;
790
+ controller;
791
+ scheduler;
792
+ textbus;
793
+ composition = !1;
794
+ onReady;
795
+ caret;
796
+ set disabled(s) {
797
+ this._disabled = s, s && this.textarea && (this.textarea.disabled = s);
798
+ }
799
+ get disabled() {
800
+ return this._disabled;
801
+ }
802
+ isSafari = tt();
803
+ isFirefox = V();
804
+ isMac = Q();
805
+ isWindows = lt();
806
+ _disabled = !1;
807
+ container = this.createEditableFrame();
808
+ subscription = new D();
809
+ doc;
810
+ textarea = null;
811
+ isFocus = !1;
812
+ nativeFocus = !1;
813
+ ignoreComposition = !1;
814
+ focus(s, t) {
815
+ this.disabled || this.caret.show(s, t), !this.controller.readonly && (this.isFocus || (this.textarea?.focus(), setTimeout(() => {
816
+ !this.nativeFocus && this.isFocus && this.reInit();
817
+ })), this.isFocus = !0);
818
+ }
819
+ blur() {
820
+ this.caret.hide(), this.textarea?.blur(), this.isFocus = !1;
821
+ }
822
+ destroy() {
823
+ this.caret.destroy(), this.subscription.unsubscribe();
824
+ }
825
+ reInit(s = !1) {
826
+ this.subscription.unsubscribe(), this.textarea?.parentNode?.removeChild(this.textarea), this.subscription = new D(), this.init(), s ? setTimeout(() => {
827
+ this.textarea?.focus();
828
+ }) : this.textarea?.focus();
829
+ }
830
+ init() {
831
+ const s = this.doc, t = s.body, i = s.createElement("textarea");
832
+ i.disabled = this.disabled, t.appendChild(i), this.textarea = i, this.subscription.add(
833
+ f(i, "blur").subscribe(() => {
834
+ if (this.isFocus = !1, this.nativeFocus = !1, this.caret.hide(), this.domAdapter.composition) {
835
+ const e = this.domAdapter.composition.slot;
836
+ this.domAdapter.composition = null, this.domAdapter.compositionNode = null, e.__changeMarker__.forceMarkDirtied();
837
+ }
838
+ }),
839
+ f(i, "focus").subscribe(() => {
840
+ this.nativeFocus = !0;
841
+ }),
842
+ this.caret.onStyleChange.subscribe((e) => {
843
+ Object.assign(i.style, e);
844
+ })
845
+ ), this.handleInput(i), this.handleShortcut(i), this.handleDefaultActions(i);
846
+ }
847
+ handleDefaultActions(s) {
848
+ this.subscription.add(
849
+ f(V() ? s : document, "copy").subscribe((t) => {
850
+ this.copyHandler(t);
851
+ }),
852
+ f(s, "paste").subscribe((t) => {
853
+ this.pasteHandler(t);
854
+ })
855
+ );
856
+ }
857
+ copyHandler(s) {
858
+ const t = this.selection;
859
+ if (t.isSelected && t.startSlot === t.endSlot && t.endOffset - t.startOffset === 1 && typeof t.startSlot.getContentAtIndex(t.startOffset) == "object") {
860
+ const e = s.clipboardData, n = document.getSelection().getRangeAt(0), r = document.createElement("div"), a = n.cloneContents();
861
+ r.append(a), e.setData("text/html", r.innerHTML), e.setData("text", r.innerText), s.preventDefault();
862
+ }
863
+ }
864
+ pasteHandler(s) {
865
+ const t = s.clipboardData.getData("Text"), i = Array.from(s.clipboardData.types || []), e = Array.from(s.clipboardData.files);
866
+ if (i.every((n) => n === "Files") && e.length) {
867
+ Promise.all(e.filter((n) => /image/i.test(n.type)).map((n) => {
868
+ const r = new FileReader();
869
+ return new Promise((a) => {
870
+ r.onload = (c) => {
871
+ a(c.target.result);
872
+ }, r.readAsDataURL(n);
873
+ });
874
+ })).then((n) => {
875
+ const r = n.map((a) => `<img src=${a}>`).join("");
876
+ this.paste(r, t);
877
+ }), s.preventDefault();
878
+ return;
879
+ }
880
+ const o = this.doc.createElement("div");
881
+ o.style.cssText = "width:1px; height:10px; overflow: hidden; position: fixed; left: 50%; top: 50%; opacity:0", o.contentEditable = "true", this.doc.body.appendChild(o), o.focus(), setTimeout(() => {
882
+ this.doc.body.removeChild(o), o.style.cssText = "", this.paste(o, t);
883
+ });
884
+ }
885
+ paste(s, t) {
886
+ const i = this.parser.parse(s, new X([
887
+ T.BlockComponent,
888
+ T.InlineComponent,
889
+ T.Text
890
+ ]));
891
+ this.commander.paste(i, t);
892
+ }
893
+ handleShortcut(s) {
894
+ let t = !1, i = !1;
895
+ this.subscription.add(
896
+ f(s, "compositionstart").subscribe(() => {
897
+ t = !0;
898
+ }),
899
+ f(s, "compositionend").subscribe(() => {
900
+ t = !1;
901
+ }),
902
+ f(s, "beforeinput").subscribe((e) => {
903
+ this.ignoreComposition = !1, this.isSafari && e.inputType === "insertFromComposition" && (i = !0);
904
+ }),
905
+ f(s, "keydown").pipe(b(() => this.isSafari && i ? (i = !1, !1) : !t)).subscribe((e) => {
906
+ this.ignoreComposition = !1;
907
+ let o = e.key;
908
+ o === "Process" && /Digit\d/.test(e.code) && e.shiftKey && (o = ")!@#$%^Z&*(".charAt(+e.code.substring(5)), e.preventDefault()), this.caret.changeFromSelf = !0, this.keyboard.execShortcut({
909
+ key: o,
910
+ altKey: e.altKey,
911
+ shiftKey: e.shiftKey,
912
+ modKey: this.isMac ? e.metaKey : e.ctrlKey,
913
+ agent: {
914
+ key: e.key,
915
+ code: e.code,
916
+ keyCode: e.keyCode
917
+ }
918
+ }) ? (this.ignoreComposition = !0, e.preventDefault()) : this.caret.changeFromSelf = !1;
919
+ })
920
+ );
921
+ }
922
+ handleInput(s) {
923
+ let t = 0;
924
+ this.subscription.add(
925
+ f(s, "compositionstart").pipe(b(() => !this.ignoreComposition)).subscribe(() => {
926
+ this.selection.isCollapsed || (this.caret.changeFromSelf = !0, this.commander.delete()), this.composition = !0, t = this.selection.startOffset;
927
+ const e = this.selection.startSlot, o = new x(e, {
928
+ index: t
929
+ });
930
+ v(e.parent, "onCompositionStart", o);
931
+ }),
932
+ f(s, "compositionupdate").pipe(b(() => !this.ignoreComposition)).pipe(M((e, o) => e.data !== o.data)).subscribe((e) => {
933
+ if (e.data === " ")
934
+ return;
935
+ const o = this.selection.startSlot;
936
+ this.domAdapter.composition = {
937
+ slot: o,
938
+ text: e.data,
939
+ offset: e.data.length,
940
+ index: t
941
+ }, this.caret.changeFromSelf = !0, this.caret.refresh();
942
+ const n = new x(o, {
943
+ index: t,
944
+ data: e.data
945
+ });
946
+ v(o.parent, "onCompositionUpdate", n), o.__changeMarker__.forceMarkDirtied();
947
+ })
948
+ );
949
+ let i = !1;
950
+ this.subscription.add(
951
+ Z(
952
+ f(s, "beforeinput").pipe(
953
+ b((e) => (e.preventDefault(), this.isFirefox && e.inputType === "insertFromPaste" ? !1 : this.isSafari ? (i = e.inputType === "insertFromComposition", e.inputType === "insertText" || e.inputType === "insertFromComposition") : !e.isComposing && !!e.data)),
954
+ L((e) => e.data)
955
+ ),
956
+ this.isSafari ? new G() : f(s, "compositionend").pipe(b(() => !this.ignoreComposition)).pipe(
957
+ L((e) => (i = !0, e.preventDefault(), s.value = "", e.data))
958
+ )
959
+ ).subscribe((e) => {
960
+ if (this.composition = !1, this.domAdapter.composition = null, e ? (this.caret.changeFromSelf = !0, this.commander.write(e)) : this.selection.startSlot?.__changeMarker__.forceMarkDirtied(), i) {
961
+ const o = this.selection.startSlot;
962
+ if (o) {
963
+ const n = new x(o, null);
964
+ v(o.parent, "onCompositionEnd", n);
965
+ }
966
+ }
967
+ i = !1;
968
+ })
969
+ );
970
+ }
971
+ createEditableFrame() {
972
+ return m("iframe", {
973
+ attrs: {
974
+ scrolling: "no"
975
+ },
976
+ styles: {
977
+ border: "none",
978
+ width: "100%",
979
+ display: "block",
980
+ height: "100%",
981
+ position: "relative",
982
+ top: this.isWindows ? "3px" : "0"
983
+ }
984
+ });
985
+ }
986
+ };
987
+ $ = yt([
988
+ F()
989
+ ], $);
990
+ var vt = Object.getOwnPropertyDescriptor, wt = (s, t, i, e) => {
991
+ for (var o = e > 1 ? void 0 : e ? vt(t, i) : t, n = s.length - 1, r; n >= 0; n--)
992
+ (r = s[n]) && (o = r(o) || o);
993
+ return o;
994
+ }, St = (s, t) => (i, e) => t(i, e, s);
995
+ class Lt {
996
+ }
997
+ let k = class {
998
+ constructor(s, t, i, e, o) {
999
+ this.nativeSelection = t, this.scheduler = i, this.selection = e, this.awarenessDelegate = o, this.container = s.get(j), this.canvasContainer.append(this.canvas), this.host.append(this.canvasContainer, this.tooltips), this.container.prepend(this.host), this.subscription.add(this.onRectsChange.subscribe((n) => {
1000
+ for (const r of n)
1001
+ this.context.fillStyle = r.color, this.context.beginPath(), this.context.rect(r.left, r.top, r.width, r.height), this.context.fill(), this.context.closePath();
1002
+ }), f(window, "resize").subscribe(() => {
1003
+ this.canvas.style.height = document.documentElement.clientHeight + "px", this.refresh();
1004
+ }), this.scheduler.onDocChanged.subscribe(() => {
1005
+ this.refresh();
1006
+ }));
1007
+ }
1008
+ nativeSelection;
1009
+ scheduler;
1010
+ selection;
1011
+ awarenessDelegate;
1012
+ host = m("div", {
1013
+ styles: {
1014
+ position: "absolute",
1015
+ left: 0,
1016
+ top: 0,
1017
+ width: "100%",
1018
+ height: "100%",
1019
+ pointerEvents: "none",
1020
+ zIndex: 1
1021
+ }
1022
+ });
1023
+ canvasContainer = m("div", {
1024
+ styles: {
1025
+ position: "absolute",
1026
+ left: 0,
1027
+ top: 0,
1028
+ width: "100%",
1029
+ height: "100%",
1030
+ overflow: "hidden"
1031
+ }
1032
+ });
1033
+ canvas = m("canvas", {
1034
+ styles: {
1035
+ position: "absolute",
1036
+ opacity: 0.5,
1037
+ left: 0,
1038
+ top: 0,
1039
+ width: "100%",
1040
+ height: document.documentElement.clientHeight + "px",
1041
+ pointerEvents: "none"
1042
+ }
1043
+ });
1044
+ context = this.canvas.getContext("2d");
1045
+ tooltips = m("div", {
1046
+ styles: {
1047
+ position: "absolute",
1048
+ left: 0,
1049
+ top: 0,
1050
+ width: "100%",
1051
+ height: "100%",
1052
+ pointerEvents: "none",
1053
+ fontSize: "12px",
1054
+ zIndex: 10
1055
+ }
1056
+ });
1057
+ onRectsChange = new S();
1058
+ subscription = new D();
1059
+ selectionCursors = [];
1060
+ container;
1061
+ ratio = window.devicePixelRatio || 1;
1062
+ /**
1063
+ * 刷新协作光标,由于 Textbus 只会绘制可视区域的光标,当可视区域发生变化时,需要重新绘制
1064
+ */
1065
+ refresh() {
1066
+ this.draw(this.selectionCursors);
1067
+ }
1068
+ destroy() {
1069
+ this.subscription.unsubscribe();
1070
+ }
1071
+ /**
1072
+ * 根据远程用户光标位置,绘制协作光标
1073
+ * @param paths
1074
+ */
1075
+ draw(s) {
1076
+ this.selectionCursors = s;
1077
+ const t = this.container.getBoundingClientRect();
1078
+ this.canvas.style.top = t.top * -1 + "px", this.canvas.width = this.canvas.offsetWidth * this.ratio, this.canvas.height = this.canvas.offsetHeight * this.ratio, this.context.scale(this.ratio, this.ratio), this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
1079
+ const i = [];
1080
+ s.filter((e) => e.selection.anchor.length && e.selection.focus.length).forEach((e) => {
1081
+ const o = [...e.selection.anchor], n = [...e.selection.focus], r = o.pop(), a = this.selection.findSlotByPaths(o), c = n.pop(), l = this.selection.findSlotByPaths(n);
1082
+ if (!a || !l)
1083
+ return;
1084
+ const { focus: u, anchor: h } = this.nativeSelection.getPositionByRange({
1085
+ focusOffset: c,
1086
+ anchorOffset: r,
1087
+ focusSlot: l,
1088
+ anchorSlot: a
1089
+ });
1090
+ if (!u || !h)
1091
+ return;
1092
+ const d = document.createRange();
1093
+ try {
1094
+ d.setStart(h.node, h.offset), d.setEnd(u.node, u.offset);
1095
+ } catch {
1096
+ return;
1097
+ }
1098
+ (h.node !== u.node || h.offset !== u.offset) && d.collapsed && (d.setStart(u.node, u.offset), d.setEnd(h.node, h.offset));
1099
+ let w = !1;
1100
+ this.awarenessDelegate && (w = this.awarenessDelegate.getRects({
1101
+ focusOffset: c,
1102
+ anchorOffset: r,
1103
+ focusSlot: l,
1104
+ anchorSlot: a
1105
+ }, d, e)), w || (w = d.getClientRects());
1106
+ const _ = [];
1107
+ for (let g = w.length - 1; g >= 0; g--) {
1108
+ const y = w[g];
1109
+ _.push({
1110
+ color: e.color,
1111
+ username: e.username,
1112
+ left: y.left - t.left,
1113
+ top: y.top,
1114
+ width: y.width,
1115
+ height: y.height
1116
+ });
1117
+ }
1118
+ this.onRectsChange.next(_);
1119
+ const E = d.cloneRange();
1120
+ E.setStart(u.node, u.offset), E.collapse(!0);
1121
+ const C = B(E), p = {
1122
+ username: e.username,
1123
+ color: e.color,
1124
+ left: C.left - t.left,
1125
+ top: C.top - t.top,
1126
+ width: 1,
1127
+ height: C.height
1128
+ };
1129
+ p.left < 0 || p.top < 0 || p.left > t.width || i.push(p);
1130
+ }), this.drawUserCursor(i);
1131
+ }
1132
+ drawUserCursor(s) {
1133
+ for (let t = 0; t < s.length; t++) {
1134
+ const i = s[t], { cursor: e, userTip: o, anchor: n } = this.getUserCursor(t);
1135
+ Object.assign(e.style, {
1136
+ left: i.left + "px",
1137
+ top: i.top + "px",
1138
+ width: i.width + "px",
1139
+ height: i.height + "px",
1140
+ background: i.color,
1141
+ display: "block"
1142
+ }), n.style.background = i.color, o.innerText = i.username, o.style.background = i.color;
1143
+ }
1144
+ for (let t = s.length; t < this.tooltips.children.length; t++)
1145
+ this.tooltips.removeChild(this.tooltips.children[t]);
1146
+ }
1147
+ getUserCursor(s) {
1148
+ let t = this.tooltips.children[s];
1149
+ if (t) {
1150
+ const o = t.children[0];
1151
+ return {
1152
+ cursor: t,
1153
+ anchor: o,
1154
+ userTip: o.children[0]
1155
+ };
1156
+ }
1157
+ const i = m("span", {
1158
+ styles: {
1159
+ position: "absolute",
1160
+ left: "50%",
1161
+ transform: "translateX(-50%)",
1162
+ marginBottom: "2px",
1163
+ bottom: "100%",
1164
+ whiteSpace: "nowrap",
1165
+ color: "#fff",
1166
+ boxShadow: "0 1px 2px rgba(0,0,0,.1)",
1167
+ opacity: 0.8,
1168
+ borderRadius: "3px",
1169
+ padding: "3px 5px",
1170
+ pointerEvents: "none"
1171
+ }
1172
+ }), e = m("span", {
1173
+ styles: {
1174
+ position: "absolute",
1175
+ top: "-2px",
1176
+ left: "-2px",
1177
+ width: "5px",
1178
+ height: "5px",
1179
+ borderRadius: "50%",
1180
+ pointerEvents: "auto",
1181
+ pointer: "cursor"
1182
+ },
1183
+ children: [i]
1184
+ });
1185
+ return t = m("span", {
1186
+ styles: {
1187
+ position: "absolute"
1188
+ },
1189
+ children: [
1190
+ e
1191
+ ]
1192
+ }), this.tooltips.append(t), {
1193
+ cursor: t,
1194
+ anchor: e,
1195
+ userTip: i
1196
+ };
1197
+ }
1198
+ };
1199
+ k = wt([
1200
+ F(),
1201
+ St(4, ct())
1202
+ ], k);
1203
+ var Et = Object.getOwnPropertyDescriptor, Nt = (s, t, i, e) => {
1204
+ for (var o = e > 1 ? void 0 : e ? Et(t, i) : t, n = s.length - 1, r; n >= 0; n--)
1205
+ (r = s[n]) && (o = r(o) || o);
1206
+ return o;
1207
+ };
1208
+ class Tt {
1209
+ onPositionChange;
1210
+ set nativeRange(t) {
1211
+ if (this._nativeRange = t, t) {
1212
+ const i = t.cloneRange();
1213
+ i.collapse(!0);
1214
+ const e = B(i);
1215
+ this.positionChangeEvent.next({
1216
+ left: e.left,
1217
+ top: e.top,
1218
+ height: e.height
1219
+ });
1220
+ } else
1221
+ this.positionChangeEvent.next(null);
1222
+ }
1223
+ get nativeRange() {
1224
+ return this._nativeRange;
1225
+ }
1226
+ get rect() {
1227
+ if (this.nativeRange) {
1228
+ const t = this.nativeRange.cloneRange();
1229
+ return t.collapse(!0), B(t);
1230
+ }
1231
+ return {
1232
+ left: 0,
1233
+ top: 0,
1234
+ width: 0,
1235
+ height: 0
1236
+ };
1237
+ }
1238
+ _nativeRange = null;
1239
+ subs = [];
1240
+ positionChangeEvent = new S();
1241
+ constructor() {
1242
+ this.onPositionChange = this.positionChangeEvent.pipe(M());
1243
+ }
1244
+ refresh() {
1245
+ }
1246
+ destroy() {
1247
+ this.subs.forEach((t) => t.unsubscribe()), this.subs = [];
1248
+ }
1249
+ }
1250
+ let W = class extends N {
1251
+ // 有 bug 版本搜狗拼音
1252
+ constructor(s, t, i, e, o, n, r) {
1253
+ super(), this.parser = t, this.selection = i, this.keyboard = e, this.domAdapter = o, this.commander = n, this.controller = r, this.documentView = s.get(U), r.readonly || (this.documentView.contentEditable = "true"), this.subscription.add(
1254
+ r.onReadonlyStateChange.subscribe(() => {
1255
+ this.documentView.contentEditable = r.readonly ? "false" : "true";
1256
+ })
1257
+ ), this.handleShortcut(this.documentView), this.handleInput(this.documentView), this.handleDefaultActions(this.documentView);
1258
+ }
1259
+ parser;
1260
+ selection;
1261
+ keyboard;
1262
+ domAdapter;
1263
+ commander;
1264
+ controller;
1265
+ caret = new Tt();
1266
+ composition = !1;
1267
+ // compositionState: CompositionState | null = null
1268
+ onReady = Promise.resolve();
1269
+ set disabled(s) {
1270
+ if (this._disabled = s, this.controller.readonly) {
1271
+ this.documentView.contentEditable = "false";
1272
+ return;
1273
+ }
1274
+ this.documentView.contentEditable = s ? "false" : "true";
1275
+ }
1276
+ get disabled() {
1277
+ return this._disabled;
1278
+ }
1279
+ _disabled = !1;
1280
+ documentView;
1281
+ nativeSelection = document.getSelection();
1282
+ subscription = new D();
1283
+ nativeRange = null;
1284
+ isSafari = tt();
1285
+ isMac = Q();
1286
+ isMobileBrowser = ht();
1287
+ ignoreComposition = !1;
1288
+ focus(s) {
1289
+ this.controller.readonly || (this.caret.nativeRange = s, this.nativeRange = s);
1290
+ }
1291
+ blur() {
1292
+ if (this.nativeRange && this.nativeSelection.rangeCount > 0 && this.nativeSelection.getRangeAt(0) === this.nativeRange) {
1293
+ this.nativeSelection.removeAllRanges(), this.nativeRange = null;
1294
+ return;
1295
+ }
1296
+ }
1297
+ destroy() {
1298
+ this.caret.destroy(), this.subscription.unsubscribe();
1299
+ }
1300
+ handleDefaultActions(s) {
1301
+ this.subscription.add(
1302
+ f(V() ? s : document, "copy").subscribe((t) => {
1303
+ this.copyHandler(t);
1304
+ }),
1305
+ f(s, "paste").subscribe((t) => {
1306
+ this.pasteHandler(t);
1307
+ })
1308
+ );
1309
+ }
1310
+ copyHandler(s) {
1311
+ const t = this.selection;
1312
+ if (t.isSelected && t.startSlot === t.endSlot && t.endOffset - t.startOffset === 1 && typeof t.startSlot.getContentAtIndex(t.startOffset) == "object") {
1313
+ const e = s.clipboardData, n = document.getSelection().getRangeAt(0), r = document.createElement("div"), a = n.cloneContents();
1314
+ r.append(a), e.setData("text/html", r.innerHTML), e.setData("text", r.innerText), s.preventDefault();
1315
+ }
1316
+ }
1317
+ pasteHandler(s) {
1318
+ const t = s.clipboardData.getData("Text"), i = Array.from(s.clipboardData.types || []), e = Array.from(s.clipboardData.files);
1319
+ if (i.every((n) => n === "Files") && e.length) {
1320
+ Promise.all(e.filter((n) => /image/i.test(n.type)).map((n) => {
1321
+ const r = new FileReader();
1322
+ return new Promise((a) => {
1323
+ r.onload = (c) => {
1324
+ a(c.target.result);
1325
+ }, r.readAsDataURL(n);
1326
+ });
1327
+ })).then((n) => {
1328
+ const r = n.map((a) => `<img src=${a}>`).join("");
1329
+ this.paste(r, t);
1330
+ }), s.preventDefault();
1331
+ return;
1332
+ }
1333
+ const o = document.createElement("div");
1334
+ o.style.cssText = "width:1px; height:10px; overflow: hidden; position: fixed; left: 50%; top: 50%; opacity:0", o.contentEditable = "true", document.body.appendChild(o), o.focus(), setTimeout(() => {
1335
+ document.body.removeChild(o), o.style.cssText = "", this.paste(o, t);
1336
+ });
1337
+ }
1338
+ paste(s, t) {
1339
+ const i = this.parser.parse(s, new X([
1340
+ T.BlockComponent,
1341
+ T.InlineComponent,
1342
+ T.Text
1343
+ ]));
1344
+ this.commander.paste(i, t);
1345
+ }
1346
+ handleShortcut(s) {
1347
+ let t = !1, i = !1;
1348
+ this.subscription.add(
1349
+ f(s, "compositionstart").subscribe(() => {
1350
+ t = !0;
1351
+ }),
1352
+ f(s, "compositionend").subscribe(() => {
1353
+ t = !1;
1354
+ }),
1355
+ f(s, "beforeinput").subscribe((e) => {
1356
+ this.isSafari && e.inputType === "insertFromComposition" && (i = !0);
1357
+ }),
1358
+ f(s, "keydown").pipe(b(() => this.isSafari && i ? (i = !1, !1) : !t)).subscribe((e) => {
1359
+ this.ignoreComposition = !1;
1360
+ let o = e.key;
1361
+ o === "Process" && /Digit\d/.test(e.code) && e.shiftKey && (o = ")!@#$%^Z&*(".charAt(+e.code.substring(5)), e.preventDefault()), this.keyboard.execShortcut({
1362
+ key: o,
1363
+ altKey: e.altKey,
1364
+ shiftKey: e.shiftKey,
1365
+ modKey: this.isMac ? e.metaKey : e.ctrlKey,
1366
+ agent: {
1367
+ key: e.key,
1368
+ keyCode: e.keyCode,
1369
+ code: e.code
1370
+ }
1371
+ }) && (this.ignoreComposition = !0, e.preventDefault());
1372
+ })
1373
+ );
1374
+ }
1375
+ handleInput(s) {
1376
+ this.isMobileBrowser ? this.handleMobileInput(s) : this.handlePCInput(s);
1377
+ }
1378
+ handleMobileInput(s) {
1379
+ let t = !0, i;
1380
+ const e = () => {
1381
+ this.composition = !0, i = this.selection.startOffset;
1382
+ const r = this.selection.startSlot, a = new x(r, {
1383
+ index: i
1384
+ });
1385
+ v(r.parent, "onCompositionStart", a);
1386
+ }, o = (r) => {
1387
+ const a = this.selection.startSlot, c = new x(a, {
1388
+ index: i,
1389
+ data: r
1390
+ });
1391
+ v(a.parent, "onCompositionUpdate", c);
1392
+ }, n = (r) => {
1393
+ this.composition = !1, r && this.commander.write(r);
1394
+ const a = this.selection.startSlot;
1395
+ if (a) {
1396
+ const c = new x(a, null);
1397
+ v(a.parent, "onCompositionEnd", c);
1398
+ }
1399
+ };
1400
+ this.subscription.add(
1401
+ f(s, "compositionstart").subscribe(() => {
1402
+ e();
1403
+ }),
1404
+ f(s, "compositionupdate").subscribe((r) => {
1405
+ o(r.data);
1406
+ }),
1407
+ f(s, "compositionend").subscribe((r) => {
1408
+ n(r.data);
1409
+ const a = this.nativeSelection.focusNode;
1410
+ a instanceof Text && a.textContent === r.data && a.remove();
1411
+ }),
1412
+ f(s, "beforeinput").subscribe((r) => {
1413
+ switch (r.inputType) {
1414
+ case "insertText":
1415
+ r.data && (this.commander.write(r.data), r.preventDefault());
1416
+ break;
1417
+ case "insertCompositionText":
1418
+ t ? (t = !1, e()) : o(r.data || "");
1419
+ break;
1420
+ case "deleteCompositionText":
1421
+ this.composition = !1;
1422
+ break;
1423
+ case "deleteContentBackward": {
1424
+ this.composition = !1;
1425
+ const a = r.getTargetRanges()[0];
1426
+ if (!a)
1427
+ break;
1428
+ const c = this.domAdapter.getLocationByNativeNode(a.startContainer), l = this.selection.startSlot;
1429
+ l && (this.selection.setBaseAndExtent(
1430
+ l,
1431
+ c.startIndex + a.startOffset,
1432
+ l,
1433
+ c.startIndex + a.endOffset
1434
+ ), this.commander.delete());
1435
+ break;
1436
+ }
1437
+ case "insertReplacementText": {
1438
+ this.composition = !1;
1439
+ const a = r.getTargetRanges()[0], c = this.domAdapter.getLocationByNativeNode(a.startContainer), l = this.selection.startSlot;
1440
+ this.selection.setBaseAndExtent(
1441
+ l,
1442
+ c.startIndex + a.startOffset,
1443
+ l,
1444
+ c.startIndex + a.endOffset
1445
+ ), this.commander.delete();
1446
+ const u = r.dataTransfer?.getData("text") || r.data || null;
1447
+ u && this.commander.write(u);
1448
+ break;
1449
+ }
1450
+ }
1451
+ })
1452
+ );
1453
+ }
1454
+ handlePCInput(s) {
1455
+ let t = 0, i = !1;
1456
+ this.subscription.add(
1457
+ f(s, "compositionstart").pipe(b(() => !this.ignoreComposition)).subscribe(() => {
1458
+ this.composition = !0, t = this.selection.startOffset;
1459
+ const e = this.selection.startSlot, o = new x(e, {
1460
+ index: t
1461
+ });
1462
+ v(e.parent, "onCompositionStart", o);
1463
+ }),
1464
+ f(s, "compositionupdate").pipe(b(() => !this.ignoreComposition)).subscribe((e) => {
1465
+ const o = this.selection.startSlot, n = new x(o, {
1466
+ index: t,
1467
+ data: e.data
1468
+ });
1469
+ v(o.parent, "onCompositionUpdate", n);
1470
+ }),
1471
+ Z(
1472
+ f(s, "beforeinput").pipe(
1473
+ L((e) => {
1474
+ if (e.preventDefault(), e.inputType === "insertCompositionText")
1475
+ return null;
1476
+ if (e.inputType === "insertReplacementText") {
1477
+ const o = e.getTargetRanges()[0], n = this.domAdapter.getLocationByNativeNode(o.startContainer), r = this.selection.startSlot;
1478
+ return this.selection.setBaseAndExtent(
1479
+ r,
1480
+ n.startIndex + o.startOffset,
1481
+ r,
1482
+ n.startIndex + o.endOffset
1483
+ ), this.commander.delete(), e.dataTransfer?.getData("text") || e.data || null;
1484
+ }
1485
+ return i = e.inputType === "insertFromComposition", i && this.composition ? null : this.isSafari && (e.inputType === "insertText" || i) || !e.isComposing && e.data ? e.data : null;
1486
+ }),
1487
+ b((e) => e)
1488
+ ),
1489
+ this.isSafari ? new G() : f(s, "compositionend").pipe(b(() => !this.ignoreComposition)).pipe(
1490
+ b(() => this.composition),
1491
+ L((e) => (i = !0, e.preventDefault(), e.data)),
1492
+ b(() => {
1493
+ const e = this.ignoreComposition;
1494
+ return this.ignoreComposition = !1, !e;
1495
+ })
1496
+ )
1497
+ ).subscribe((e) => {
1498
+ if (this.composition = !1, e) {
1499
+ const o = this.nativeSelection.focusNode;
1500
+ o instanceof Text && o.textContent === e && o.remove(), this.commander.write(e);
1501
+ }
1502
+ if (i) {
1503
+ const o = this.selection.startSlot;
1504
+ if (o) {
1505
+ const n = new x(o, null);
1506
+ v(o.parent, "onCompositionEnd", n);
1507
+ }
1508
+ }
1509
+ i = !1;
1510
+ })
1511
+ );
1512
+ }
1513
+ };
1514
+ W = Nt([
1515
+ F()
1516
+ ], W);
1517
+ class Ot extends Y {
1518
+ onViewUpdated = new S();
1519
+ host = m("div", {
1520
+ styles: {
1521
+ cursor: "text",
1522
+ wordBreak: "break-all",
1523
+ boxSizing: "border-box",
1524
+ flex: 1,
1525
+ outline: "none"
1526
+ },
1527
+ attrs: {
1528
+ "data-textbus-view": U
1529
+ },
1530
+ props: {
1531
+ id: "textbus-" + Number((Math.random() + "").substring(2)).toString(16)
1532
+ }
1533
+ });
1534
+ }
1535
+ const q = rt("BrowserModule");
1536
+ class et {
1537
+ constructor(t) {
1538
+ this.config = t;
1539
+ const { mask: i, wrapper: e } = et.createLayout();
1540
+ e.prepend(t.adapter.host), t.minHeight && (t.adapter.host.style.minHeight = t.minHeight), this.providers = [
1541
+ {
1542
+ provide: z,
1543
+ useValue: t
1544
+ },
1545
+ {
1546
+ provide: j,
1547
+ useValue: e
1548
+ },
1549
+ {
1550
+ provide: U,
1551
+ useValue: t.adapter.host
1552
+ },
1553
+ {
1554
+ provide: K,
1555
+ useValue: i
1556
+ },
1557
+ {
1558
+ provide: st,
1559
+ useExisting: P
1560
+ },
1561
+ {
1562
+ provide: N,
1563
+ useClass: t.useContentEditable ? W : $
1564
+ },
1565
+ {
1566
+ provide: Y,
1567
+ useValue: t.adapter
1568
+ },
1569
+ {
1570
+ provide: Ot,
1571
+ useValue: t.adapter
1572
+ },
1573
+ {
1574
+ provide: it,
1575
+ useFactory: (o) => {
1576
+ const n = new S(), r = new S();
1577
+ return o.caret.onPositionChange.pipe(
1578
+ L((a) => !!a),
1579
+ M()
1580
+ ).subscribe((a) => {
1581
+ a ? n.next() : r.next();
1582
+ }), {
1583
+ onFocus: n,
1584
+ onBlur: r
1585
+ };
1586
+ },
1587
+ deps: [N]
1588
+ },
1589
+ O,
1590
+ P,
1591
+ k
1592
+ ], this.workbench = e;
1593
+ }
1594
+ config;
1595
+ providers;
1596
+ workbench;
1597
+ /**
1598
+ * 解析 HTML 并返回一个组件实例
1599
+ * @param html 要解析的 HTML
1600
+ * @param rootComponentLoader 文档根组件加载器
1601
+ * @param textbus
1602
+ */
1603
+ readDocumentByHTML(t, i, e) {
1604
+ const n = e.get(O).parseDoc(t, i);
1605
+ if (n instanceof ot)
1606
+ return n;
1607
+ throw q("rootComponentLoader must return a component instance.");
1608
+ }
1609
+ /**
1610
+ * 将组件数据解析到组件实例中
1611
+ * @param data 要解析的 JSON 数据
1612
+ * @param rootComponent 根组件
1613
+ * @param textbus
1614
+ */
1615
+ readDocumentByComponentLiteral(t, i, e) {
1616
+ return e.get(nt).createComponentByFactory(t, i);
1617
+ }
1618
+ async setup(t) {
1619
+ const i = this.config.renderTo();
1620
+ if (!(i instanceof HTMLElement))
1621
+ throw q("view container is not a HTMLElement");
1622
+ return i.append(this.workbench), await t.get(N).onReady, () => {
1623
+ this.workbench.remove();
1624
+ };
1625
+ }
1626
+ onAfterStartup(t) {
1627
+ this.config.autoFocus && t.focus();
1628
+ }
1629
+ onDestroy(t) {
1630
+ t.get(N).destroy(), t.get(P).destroy(), t.get(k).destroy();
1631
+ }
1632
+ static createLayout() {
1633
+ const t = m("div", {
1634
+ attrs: {
1635
+ "data-textbus-view": K
1636
+ },
1637
+ styles: {
1638
+ position: "absolute",
1639
+ left: 0,
1640
+ right: 0,
1641
+ top: 0,
1642
+ bottom: 0,
1643
+ pointerEvents: "none"
1644
+ // overflow: 'hidden'
1645
+ }
1646
+ }), i = m("div", {
1647
+ styles: {
1648
+ position: "absolute",
1649
+ left: 0,
1650
+ right: 0,
1651
+ top: 0,
1652
+ bottom: 0,
1653
+ margin: "0 -2px",
1654
+ zIndex: 1,
1655
+ pointerEvents: "none",
1656
+ overflow: "hidden"
1657
+ },
1658
+ children: [t]
1659
+ });
1660
+ return {
1661
+ wrapper: m("div", {
1662
+ attrs: {
1663
+ "data-textbus-view": j
1664
+ },
1665
+ styles: {
1666
+ display: "flex",
1667
+ minHeight: "100%",
1668
+ position: "relative",
1669
+ flexDirection: "column"
1670
+ },
1671
+ children: [i]
1672
+ }),
1673
+ mask: t
1674
+ };
1675
+ }
1676
+ }
1677
+ export {
1678
+ et as BrowserModule,
1679
+ k as CollaborateCursor,
1680
+ Lt as CollaborateSelectionAwarenessDelegate,
1681
+ Ot as DomAdapter,
1682
+ z as EDITOR_OPTIONS,
1683
+ N as Input,
1684
+ $ as MagicInput,
1685
+ W as NativeInput,
1686
+ O as Parser,
1687
+ P as SelectionBridge,
1688
+ j as VIEW_CONTAINER,
1689
+ U as VIEW_DOCUMENT,
1690
+ K as VIEW_MASK,
1691
+ m as createElement,
1692
+ B as getLayoutRectByRange,
1693
+ V as isFirefox,
1694
+ Q as isMac,
1695
+ ht as isMobileBrowser,
1696
+ tt as isSafari,
1697
+ lt as isWindows
1698
+ };
1699
+ //# sourceMappingURL=index.esm.js.map