@textbus/platform-browser 4.0.0-alpha.7 → 4.0.0-alpha.71
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/bundles/browser-module.d.ts +24 -7
- package/bundles/collaborate-cursor.d.ts +7 -12
- package/bundles/dom-adapter.d.ts +4 -64
- package/bundles/index.esm.js +228 -341
- package/bundles/index.js +230 -343
- package/bundles/magic-input.d.ts +10 -11
- package/bundles/native-input.d.ts +4 -9
- package/bundles/parser.d.ts +9 -10
- package/bundles/public-api.d.ts +1 -0
- package/bundles/selection-bridge.d.ts +2 -2
- package/bundles/types.d.ts +1 -14
- package/package.json +6 -6
package/bundles/index.js
CHANGED
@@ -4,6 +4,7 @@ require('reflect-metadata');
|
|
4
4
|
var core$1 = require('@textbus/core');
|
5
5
|
var stream = require('@tanbo/stream');
|
6
6
|
var core = require('@viewfly/core');
|
7
|
+
var collaborate = require('@textbus/collaborate');
|
7
8
|
|
8
9
|
function createElement(tagName, options = {}) {
|
9
10
|
const el = document.createElement(tagName);
|
@@ -169,7 +170,6 @@ exports.Parser = Parser_1 = class Parser {
|
|
169
170
|
return new DOMParser().parseFromString(html, 'text/html').body;
|
170
171
|
}
|
171
172
|
constructor(options, textbus) {
|
172
|
-
this.options = options;
|
173
173
|
this.textbus = textbus;
|
174
174
|
const componentLoaders = [
|
175
175
|
...(options.componentLoaders || [])
|
@@ -214,8 +214,9 @@ exports.Parser = Parser_1 = class Parser {
|
|
214
214
|
slot.insert('\n');
|
215
215
|
return;
|
216
216
|
}
|
217
|
+
const schema = [...slot.schema];
|
217
218
|
for (const t of this.componentLoaders) {
|
218
|
-
if (t.match(el)) {
|
219
|
+
if (t.match(el, schema)) {
|
219
220
|
const result = t.read(el, this.textbus, (childSlot, slotRootElement, slotContentHostElement = slotRootElement) => {
|
220
221
|
return this.readSlot(childSlot, slotRootElement, slotContentHostElement);
|
221
222
|
});
|
@@ -302,13 +303,10 @@ exports.Parser = Parser_1 = __decorate([
|
|
302
303
|
class Input {
|
303
304
|
}
|
304
305
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
constructor(mount) {
|
310
|
-
super();
|
311
|
-
this.mount = mount;
|
306
|
+
class DomAdapter extends core$1.Adapter {
|
307
|
+
constructor() {
|
308
|
+
super(...arguments);
|
309
|
+
this.onViewUpdated = new stream.Subject();
|
312
310
|
this.host = createElement('div', {
|
313
311
|
styles: {
|
314
312
|
cursor: 'text',
|
@@ -324,126 +322,6 @@ class DomAdapter extends core$1.ViewAdapter {
|
|
324
322
|
id: 'textbus-' + Number((Math.random() + '').substring(2)).toString(16)
|
325
323
|
}
|
326
324
|
});
|
327
|
-
this.componentRootElementCaches = core$1.createBidirectionalMapping(a => {
|
328
|
-
return a instanceof core$1.ComponentInstance;
|
329
|
-
});
|
330
|
-
this.slotRootNativeElementCaches = core$1.createBidirectionalMapping(a => {
|
331
|
-
return a instanceof core$1.Slot;
|
332
|
-
});
|
333
|
-
this.slotRootVElementCaches = new WeakMap();
|
334
|
-
}
|
335
|
-
render(rootComponent) {
|
336
|
-
const view = this.componentRender(rootComponent);
|
337
|
-
return this.mount(this.host, view);
|
338
|
-
}
|
339
|
-
copy() {
|
340
|
-
document.execCommand('copy');
|
341
|
-
}
|
342
|
-
/**
|
343
|
-
* 根据组件获取组件的根 DOM 节点
|
344
|
-
* @param component
|
345
|
-
*/
|
346
|
-
getNativeNodeByComponent(component) {
|
347
|
-
return this.componentRootElementCaches.get(component) || null;
|
348
|
-
}
|
349
|
-
/**
|
350
|
-
* 根据 DOM 节点,获对对应的组件根节点,如传入的 DOM 节点不为组件的根节点,则返回 null
|
351
|
-
* @param node
|
352
|
-
*/
|
353
|
-
getComponentByNativeNode(node) {
|
354
|
-
return this.componentRootElementCaches.get(node) || null;
|
355
|
-
}
|
356
|
-
/**
|
357
|
-
* 根据插槽获取插槽的根 DOM 节点
|
358
|
-
* @param slot
|
359
|
-
*/
|
360
|
-
getNativeNodeBySlot(slot) {
|
361
|
-
return this.slotRootNativeElementCaches.get(slot) || null;
|
362
|
-
}
|
363
|
-
/**
|
364
|
-
* 根据 DOM 节点,获对对应的插槽根节点,如传入的 DOM 节点不为插槽的根节点,则返回 null
|
365
|
-
* @param node
|
366
|
-
*/
|
367
|
-
getSlotByNativeNode(node) {
|
368
|
-
return this.slotRootNativeElementCaches.get(node) || null;
|
369
|
-
}
|
370
|
-
/**
|
371
|
-
* 获取插槽内容节点集合
|
372
|
-
* @param slot
|
373
|
-
*/
|
374
|
-
getNodesBySlot(slot) {
|
375
|
-
const rootNativeNode = this.getNativeNodeBySlot(slot);
|
376
|
-
if (!rootNativeNode) {
|
377
|
-
return [];
|
378
|
-
}
|
379
|
-
const rootVNode = this.slotRootVElementCaches.get(slot);
|
380
|
-
const getNodes = (vElement, nativeNode, result) => {
|
381
|
-
if (vElement.location) {
|
382
|
-
result.push(nativeNode);
|
383
|
-
}
|
384
|
-
for (let i = 0; i < vElement.children.length; i++) {
|
385
|
-
const vChild = vElement.children[i];
|
386
|
-
const nativeChild = nativeNode.childNodes[i];
|
387
|
-
if (vChild instanceof core$1.VElement) {
|
388
|
-
getNodes(vChild, nativeChild, result);
|
389
|
-
}
|
390
|
-
else if (vChild instanceof core$1.VTextNode) {
|
391
|
-
result.push(nativeChild);
|
392
|
-
}
|
393
|
-
else {
|
394
|
-
result.push(this.getNativeNodeByComponent(vChild));
|
395
|
-
}
|
396
|
-
}
|
397
|
-
return result;
|
398
|
-
};
|
399
|
-
return getNodes(rootVNode, rootNativeNode, []);
|
400
|
-
}
|
401
|
-
/**
|
402
|
-
* 获取原生节点的原始数据在文档中的位置
|
403
|
-
* @param node
|
404
|
-
*/
|
405
|
-
getLocationByNativeNode(node) {
|
406
|
-
let slotRootNode = node;
|
407
|
-
while (!this.slotRootNativeElementCaches.get(slotRootNode)) {
|
408
|
-
slotRootNode = slotRootNode.parentNode;
|
409
|
-
if (!slotRootNode) {
|
410
|
-
return null;
|
411
|
-
}
|
412
|
-
}
|
413
|
-
const slot = this.slotRootNativeElementCaches.get(slotRootNode);
|
414
|
-
const rootVNode = this.slotRootVElementCaches.get(slot);
|
415
|
-
const getLocation = (target, tree, vNodeTree) => {
|
416
|
-
if (target === tree) {
|
417
|
-
return Object.assign({}, vNodeTree.location);
|
418
|
-
}
|
419
|
-
const childNodes = tree.childNodes;
|
420
|
-
for (let i = 0; i < childNodes.length; i++) {
|
421
|
-
const child = vNodeTree.children[i];
|
422
|
-
const nativeChild = tree.childNodes[i];
|
423
|
-
if (nativeChild === target) {
|
424
|
-
if (child instanceof core$1.ComponentInstance) {
|
425
|
-
const index = child.parent.indexOf(child);
|
426
|
-
return {
|
427
|
-
slot: child.parent,
|
428
|
-
startIndex: index,
|
429
|
-
endIndex: index + 1
|
430
|
-
};
|
431
|
-
}
|
432
|
-
return child.location;
|
433
|
-
}
|
434
|
-
else if (child instanceof core$1.VElement) {
|
435
|
-
let r = null;
|
436
|
-
if (nativeChild.nodeType === Node.ELEMENT_NODE) {
|
437
|
-
r = getLocation(target, nativeChild, child);
|
438
|
-
}
|
439
|
-
if (r) {
|
440
|
-
return r;
|
441
|
-
}
|
442
|
-
}
|
443
|
-
}
|
444
|
-
return null;
|
445
|
-
};
|
446
|
-
return getLocation(node, slotRootNode, rootVNode);
|
447
325
|
}
|
448
326
|
}
|
449
327
|
|
@@ -542,7 +420,33 @@ exports.SelectionBridge = class SelectionBridge {
|
|
542
420
|
this.listen(this.connector);
|
543
421
|
return;
|
544
422
|
}
|
545
|
-
|
423
|
+
function tryOffset(position) {
|
424
|
+
if (!position.node) {
|
425
|
+
return;
|
426
|
+
}
|
427
|
+
if (position.node.nodeType === Node.TEXT_NODE) {
|
428
|
+
const len = position.node.textContent.length;
|
429
|
+
if (position.offset > len) {
|
430
|
+
position.offset = len;
|
431
|
+
}
|
432
|
+
}
|
433
|
+
else if (position.node.nodeType === Node.ELEMENT_NODE) {
|
434
|
+
const len = position.node.childNodes.length;
|
435
|
+
if (position.offset > len) {
|
436
|
+
position.offset = len;
|
437
|
+
}
|
438
|
+
}
|
439
|
+
}
|
440
|
+
try {
|
441
|
+
tryOffset(focus);
|
442
|
+
tryOffset(anchor);
|
443
|
+
this.nativeSelection.setBaseAndExtent(anchor.node, anchor.offset, focus.node, focus.offset);
|
444
|
+
}
|
445
|
+
catch (e) {
|
446
|
+
setTimeout(() => {
|
447
|
+
throw e;
|
448
|
+
});
|
449
|
+
}
|
546
450
|
if (this.nativeSelection.rangeCount) {
|
547
451
|
const nativeRange = this.nativeSelection.getRangeAt(0);
|
548
452
|
this.selectionChangeEvent.next(nativeRange);
|
@@ -565,6 +469,7 @@ exports.SelectionBridge = class SelectionBridge {
|
|
565
469
|
// hack end
|
566
470
|
}
|
567
471
|
destroy() {
|
472
|
+
this.subs.forEach(i => i.unsubscribe());
|
568
473
|
this.sub.unsubscribe();
|
569
474
|
}
|
570
475
|
getPositionByRange(abstractSelection) {
|
@@ -647,9 +552,10 @@ exports.SelectionBridge = class SelectionBridge {
|
|
647
552
|
}
|
648
553
|
minLeft = rect2.left;
|
649
554
|
minTop = rect2.top;
|
555
|
+
// oldPosition = position
|
650
556
|
}
|
651
557
|
if (isToPrevLine) {
|
652
|
-
if (rect2.left
|
558
|
+
if (rect2.left <= startLeft) {
|
653
559
|
return position;
|
654
560
|
}
|
655
561
|
if (oldPosition) {
|
@@ -762,14 +668,14 @@ exports.SelectionBridge = class SelectionBridge {
|
|
762
668
|
const isFocusStart = selection.focusNode === nativeRange.startContainer && selection.focusOffset === nativeRange.startOffset;
|
763
669
|
if (!this.docContainer.contains(selection.focusNode)) {
|
764
670
|
if (isFocusEnd) {
|
765
|
-
const nativeNode = this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.slots.
|
671
|
+
const nativeNode = this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.slots.at(0));
|
766
672
|
if (!nativeNode) {
|
767
673
|
return;
|
768
674
|
}
|
769
675
|
nativeRange.setEndAfter(nativeNode.lastChild);
|
770
676
|
}
|
771
677
|
else {
|
772
|
-
const nativeNode = this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.slots.
|
678
|
+
const nativeNode = this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.slots.at(-1));
|
773
679
|
if (!nativeNode) {
|
774
680
|
return;
|
775
681
|
}
|
@@ -1030,25 +936,24 @@ class ExperimentalCaret {
|
|
1030
936
|
get display() {
|
1031
937
|
return this._display;
|
1032
938
|
}
|
1033
|
-
constructor(scheduler, editorMask) {
|
939
|
+
constructor(domRenderer, scheduler, editorMask) {
|
940
|
+
this.domRenderer = domRenderer;
|
1034
941
|
this.scheduler = scheduler;
|
1035
942
|
this.editorMask = editorMask;
|
1036
|
-
this.
|
1037
|
-
this.
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
943
|
+
this.changeFromSelf = false;
|
944
|
+
this.getLimit = function () {
|
945
|
+
return {
|
946
|
+
top: 0,
|
947
|
+
bottom: document.documentElement.clientHeight
|
948
|
+
};
|
949
|
+
};
|
1042
950
|
this.timer = null;
|
1043
|
-
this.oldPosition = null;
|
1044
951
|
this._display = true;
|
1045
952
|
this.flashing = true;
|
1046
|
-
this.subs = [];
|
1047
953
|
this.subscription = new stream.Subscription();
|
1048
954
|
this.positionChangeEvent = new stream.Subject();
|
1049
955
|
this.styleChangeEvent = new stream.Subject();
|
1050
956
|
this.oldRange = null;
|
1051
|
-
this.isFixed = false;
|
1052
957
|
this.onPositionChange = this.positionChangeEvent.pipe(stream.distinctUntilChanged());
|
1053
958
|
this.onStyleChange = this.styleChangeEvent.asObservable();
|
1054
959
|
this.elementRef = createElement('div', {
|
@@ -1076,20 +981,12 @@ class ExperimentalCaret {
|
|
1076
981
|
}));
|
1077
982
|
this.editorMask.appendChild(this.elementRef);
|
1078
983
|
}
|
1079
|
-
refresh(
|
1080
|
-
this.isFixed = isFixedCaret;
|
984
|
+
refresh() {
|
1081
985
|
if (this.oldRange) {
|
1082
986
|
this.show(this.oldRange, false);
|
1083
987
|
}
|
1084
|
-
this.isFixed = false;
|
1085
988
|
}
|
1086
989
|
show(range, restart) {
|
1087
|
-
const oldRect = this.elementRef.getBoundingClientRect();
|
1088
|
-
this.oldPosition = {
|
1089
|
-
top: oldRect.top,
|
1090
|
-
left: oldRect.left,
|
1091
|
-
height: oldRect.height
|
1092
|
-
};
|
1093
990
|
this.oldRange = range;
|
1094
991
|
if (restart || this.scheduler.lastChangesHasLocalUpdate) {
|
1095
992
|
clearTimeout(this.timer);
|
@@ -1118,62 +1015,8 @@ class ExperimentalCaret {
|
|
1118
1015
|
}
|
1119
1016
|
destroy() {
|
1120
1017
|
clearTimeout(this.timer);
|
1018
|
+
// this.caret.
|
1121
1019
|
this.subscription.unsubscribe();
|
1122
|
-
this.subs.forEach(i => i.unsubscribe());
|
1123
|
-
}
|
1124
|
-
correctScrollTop(scroller) {
|
1125
|
-
this.subs.forEach(i => i.unsubscribe());
|
1126
|
-
this.subs = [];
|
1127
|
-
const scheduler = this.scheduler;
|
1128
|
-
let docIsChanged = true;
|
1129
|
-
function limitPosition(position) {
|
1130
|
-
const { top, bottom } = scroller.getLimit();
|
1131
|
-
const caretTop = position.top;
|
1132
|
-
if (caretTop + position.height > bottom) {
|
1133
|
-
const offset = caretTop - bottom + position.height;
|
1134
|
-
scroller.setOffset(offset);
|
1135
|
-
}
|
1136
|
-
else if (position.top < top) {
|
1137
|
-
scroller.setOffset(-(top - position.top));
|
1138
|
-
}
|
1139
|
-
}
|
1140
|
-
let isPressed = false;
|
1141
|
-
this.subs.push(scroller.onScroll.subscribe(() => {
|
1142
|
-
if (this.oldPosition) {
|
1143
|
-
const rect = this.rect;
|
1144
|
-
this.oldPosition.top = rect.top;
|
1145
|
-
this.oldPosition.left = rect.left;
|
1146
|
-
this.oldPosition.height = rect.height;
|
1147
|
-
}
|
1148
|
-
}), stream.fromEvent(document, 'mousedown', true).subscribe(() => {
|
1149
|
-
isPressed = true;
|
1150
|
-
}), stream.fromEvent(document, 'mouseup', true).subscribe(() => {
|
1151
|
-
isPressed = false;
|
1152
|
-
}), scheduler.onDocChange.subscribe(() => {
|
1153
|
-
docIsChanged = true;
|
1154
|
-
}), this.onPositionChange.subscribe(position => {
|
1155
|
-
if (position) {
|
1156
|
-
if (docIsChanged) {
|
1157
|
-
if (scheduler.lastChangesHasLocalUpdate) {
|
1158
|
-
limitPosition(position);
|
1159
|
-
}
|
1160
|
-
else if (this.oldPosition) {
|
1161
|
-
const offset = Math.floor(position.top - this.oldPosition.top);
|
1162
|
-
scroller.setOffset(offset);
|
1163
|
-
}
|
1164
|
-
}
|
1165
|
-
else if (!isPressed) {
|
1166
|
-
if (this.isFixed && this.oldPosition) {
|
1167
|
-
const offset = Math.floor(position.top - this.oldPosition.top);
|
1168
|
-
scroller.setOffset(offset);
|
1169
|
-
}
|
1170
|
-
else {
|
1171
|
-
limitPosition(position);
|
1172
|
-
}
|
1173
|
-
}
|
1174
|
-
}
|
1175
|
-
docIsChanged = false;
|
1176
|
-
}));
|
1177
1020
|
}
|
1178
1021
|
updateCursorPosition(nativeRange) {
|
1179
1022
|
const startContainer = nativeRange.startContainer;
|
@@ -1182,12 +1025,10 @@ class ExperimentalCaret {
|
|
1182
1025
|
this.positionChangeEvent.next(null);
|
1183
1026
|
return;
|
1184
1027
|
}
|
1185
|
-
|
1186
|
-
|
1187
|
-
compositionElement.innerText = this.compositionState.data;
|
1028
|
+
const compositionNode = this.domRenderer.compositionNode;
|
1029
|
+
if (compositionNode) {
|
1188
1030
|
nativeRange = nativeRange.cloneRange();
|
1189
|
-
nativeRange.
|
1190
|
-
nativeRange.selectNodeContents(compositionElement);
|
1031
|
+
nativeRange.selectNodeContents(compositionNode);
|
1191
1032
|
nativeRange.collapse();
|
1192
1033
|
}
|
1193
1034
|
const rect = getLayoutRectByRange(nativeRange);
|
@@ -1233,6 +1074,21 @@ class ExperimentalCaret {
|
|
1233
1074
|
top: rectTop,
|
1234
1075
|
height: boxHeight
|
1235
1076
|
});
|
1077
|
+
if (this.changeFromSelf) {
|
1078
|
+
this.changeFromSelf = false;
|
1079
|
+
const selfRect = this.elementRef.getBoundingClientRect();
|
1080
|
+
const limit = this.getLimit();
|
1081
|
+
if (selfRect.top < limit.top) {
|
1082
|
+
this.elementRef.scrollIntoView({
|
1083
|
+
block: 'start'
|
1084
|
+
});
|
1085
|
+
}
|
1086
|
+
else if (selfRect.bottom > limit.bottom) {
|
1087
|
+
this.elementRef.scrollIntoView({
|
1088
|
+
block: 'end'
|
1089
|
+
});
|
1090
|
+
}
|
1091
|
+
}
|
1236
1092
|
}
|
1237
1093
|
}
|
1238
1094
|
/**
|
@@ -1248,8 +1104,9 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1248
1104
|
get disabled() {
|
1249
1105
|
return this._disabled;
|
1250
1106
|
}
|
1251
|
-
constructor(parser, keyboard, commander, selection, controller, scheduler, textbus) {
|
1107
|
+
constructor(domAdapter, parser, keyboard, commander, selection, controller, scheduler, textbus) {
|
1252
1108
|
super();
|
1109
|
+
this.domAdapter = domAdapter;
|
1253
1110
|
this.parser = parser;
|
1254
1111
|
this.keyboard = keyboard;
|
1255
1112
|
this.commander = commander;
|
@@ -1258,8 +1115,7 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1258
1115
|
this.scheduler = scheduler;
|
1259
1116
|
this.textbus = textbus;
|
1260
1117
|
this.composition = false;
|
1261
|
-
this.
|
1262
|
-
this.caret = new ExperimentalCaret(this.scheduler, this.textbus.get(VIEW_MASK));
|
1118
|
+
this.caret = new ExperimentalCaret(this.domAdapter, this.scheduler, this.textbus.get(VIEW_MASK));
|
1263
1119
|
this.isSafari = isSafari();
|
1264
1120
|
this.isFirefox = isFirefox();
|
1265
1121
|
this.isMac = isMac();
|
@@ -1299,13 +1155,8 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1299
1155
|
if (!this.isFocus) {
|
1300
1156
|
(_a = this.textarea) === null || _a === void 0 ? void 0 : _a.focus();
|
1301
1157
|
setTimeout(() => {
|
1302
|
-
var _a, _b, _c;
|
1303
1158
|
if (!this.nativeFocus && this.isFocus) {
|
1304
|
-
this.
|
1305
|
-
(_b = (_a = this.textarea) === null || _a === void 0 ? void 0 : _a.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(this.textarea);
|
1306
|
-
this.subscription = new stream.Subscription();
|
1307
|
-
this.init();
|
1308
|
-
(_c = this.textarea) === null || _c === void 0 ? void 0 : _c.focus();
|
1159
|
+
this.reInit();
|
1309
1160
|
}
|
1310
1161
|
});
|
1311
1162
|
}
|
@@ -1321,6 +1172,22 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1321
1172
|
this.caret.destroy();
|
1322
1173
|
this.subscription.unsubscribe();
|
1323
1174
|
}
|
1175
|
+
reInit(delay = false) {
|
1176
|
+
var _a, _b, _c;
|
1177
|
+
this.subscription.unsubscribe();
|
1178
|
+
(_b = (_a = this.textarea) === null || _a === void 0 ? void 0 : _a.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(this.textarea);
|
1179
|
+
this.subscription = new stream.Subscription();
|
1180
|
+
this.init();
|
1181
|
+
if (delay) {
|
1182
|
+
setTimeout(() => {
|
1183
|
+
var _a;
|
1184
|
+
(_a = this.textarea) === null || _a === void 0 ? void 0 : _a.focus();
|
1185
|
+
});
|
1186
|
+
}
|
1187
|
+
else {
|
1188
|
+
(_c = this.textarea) === null || _c === void 0 ? void 0 : _c.focus();
|
1189
|
+
}
|
1190
|
+
}
|
1324
1191
|
init() {
|
1325
1192
|
const doc = this.doc;
|
1326
1193
|
const contentBody = doc.body;
|
@@ -1329,9 +1196,19 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1329
1196
|
contentBody.appendChild(textarea);
|
1330
1197
|
this.textarea = textarea;
|
1331
1198
|
this.subscription.add(stream.fromEvent(textarea, 'blur').subscribe(() => {
|
1199
|
+
// if (this.isFocus) {
|
1200
|
+
// this.isFocus = false
|
1201
|
+
// this.reInit(true)
|
1202
|
+
// }
|
1332
1203
|
this.isFocus = false;
|
1333
1204
|
this.nativeFocus = false;
|
1334
1205
|
this.caret.hide();
|
1206
|
+
if (this.domAdapter.composition) {
|
1207
|
+
const slot = this.domAdapter.composition.slot;
|
1208
|
+
this.domAdapter.composition = null;
|
1209
|
+
this.domAdapter.compositionNode = null;
|
1210
|
+
slot.__changeMarker__.forceMarkDirtied();
|
1211
|
+
}
|
1335
1212
|
}), stream.fromEvent(textarea, 'focus').subscribe(() => {
|
1336
1213
|
this.nativeFocus = true;
|
1337
1214
|
}), this.caret.onStyleChange.subscribe(style => {
|
@@ -1342,7 +1219,7 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1342
1219
|
this.handleDefaultActions(textarea);
|
1343
1220
|
}
|
1344
1221
|
handleDefaultActions(textarea) {
|
1345
|
-
this.subscription.add(stream.fromEvent(document, 'copy').subscribe(ev => {
|
1222
|
+
this.subscription.add(stream.fromEvent(isFirefox() ? textarea : document, 'copy').subscribe(ev => {
|
1346
1223
|
const selection = this.selection;
|
1347
1224
|
if (!selection.isSelected) {
|
1348
1225
|
return;
|
@@ -1412,6 +1289,7 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1412
1289
|
}), stream.fromEvent(textarea, 'compositionend').subscribe(() => {
|
1413
1290
|
isWriting = false;
|
1414
1291
|
}), stream.fromEvent(textarea, 'beforeinput').subscribe(ev => {
|
1292
|
+
this.ignoreComposition = false;
|
1415
1293
|
if (this.isSafari) {
|
1416
1294
|
if (ev.inputType === 'insertFromComposition') {
|
1417
1295
|
isIgnore = true;
|
@@ -1433,6 +1311,7 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1433
1311
|
key = keys.charAt(+ev.code.substring(5));
|
1434
1312
|
ev.preventDefault();
|
1435
1313
|
}
|
1314
|
+
this.caret.changeFromSelf = true;
|
1436
1315
|
const is = this.keyboard.execShortcut({
|
1437
1316
|
key: key,
|
1438
1317
|
altKey: ev.altKey,
|
@@ -1443,6 +1322,9 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1443
1322
|
this.ignoreComposition = true;
|
1444
1323
|
ev.preventDefault();
|
1445
1324
|
}
|
1325
|
+
else {
|
1326
|
+
this.caret.changeFromSelf = false;
|
1327
|
+
}
|
1446
1328
|
}));
|
1447
1329
|
}
|
1448
1330
|
handleInput(textarea) {
|
@@ -1451,10 +1333,10 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1451
1333
|
return !this.ignoreComposition;
|
1452
1334
|
})).subscribe(() => {
|
1453
1335
|
if (!this.selection.isCollapsed) {
|
1336
|
+
this.caret.changeFromSelf = true;
|
1454
1337
|
this.commander.delete();
|
1455
1338
|
}
|
1456
1339
|
this.composition = true;
|
1457
|
-
this.caret.compositionState = this.compositionState = null;
|
1458
1340
|
startIndex = this.selection.startOffset;
|
1459
1341
|
const startSlot = this.selection.startSlot;
|
1460
1342
|
const event = new core$1.Event(startSlot, {
|
@@ -1471,17 +1353,20 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1471
1353
|
return;
|
1472
1354
|
}
|
1473
1355
|
const startSlot = this.selection.startSlot;
|
1474
|
-
this.
|
1356
|
+
this.domAdapter.composition = {
|
1475
1357
|
slot: startSlot,
|
1476
|
-
|
1477
|
-
|
1358
|
+
text: ev.data,
|
1359
|
+
offset: ev.data.length,
|
1360
|
+
index: startIndex
|
1478
1361
|
};
|
1479
|
-
this.caret.
|
1362
|
+
this.caret.changeFromSelf = true;
|
1363
|
+
this.caret.refresh();
|
1480
1364
|
const event = new core$1.Event(startSlot, {
|
1481
1365
|
index: startIndex,
|
1482
1366
|
data: ev.data
|
1483
1367
|
});
|
1484
1368
|
core$1.invokeListener(startSlot.parent, 'onCompositionUpdate', event);
|
1369
|
+
startSlot.__changeMarker__.forceMarkDirtied();
|
1485
1370
|
}));
|
1486
1371
|
let isCompositionEnd = false;
|
1487
1372
|
this.subscription.add(stream.merge(stream.fromEvent(textarea, 'beforeinput').pipe(stream.filter(ev => {
|
@@ -1505,24 +1390,16 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1505
1390
|
textarea.value = '';
|
1506
1391
|
return ev.data;
|
1507
1392
|
}))).subscribe(text => {
|
1393
|
+
var _a;
|
1508
1394
|
this.composition = false;
|
1509
|
-
this.
|
1510
|
-
const compositionElement = this.caret.compositionElement;
|
1511
|
-
let nextSibling = compositionElement.nextSibling;
|
1512
|
-
while (nextSibling) {
|
1513
|
-
if (!nextSibling.textContent) {
|
1514
|
-
const next = nextSibling.nextSibling;
|
1515
|
-
nextSibling.remove();
|
1516
|
-
nextSibling = next;
|
1517
|
-
continue;
|
1518
|
-
}
|
1519
|
-
nextSibling.remove();
|
1520
|
-
break;
|
1521
|
-
}
|
1522
|
-
compositionElement.remove();
|
1395
|
+
this.domAdapter.composition = null;
|
1523
1396
|
if (text) {
|
1397
|
+
this.caret.changeFromSelf = true;
|
1524
1398
|
this.commander.write(text);
|
1525
1399
|
}
|
1400
|
+
else {
|
1401
|
+
(_a = this.selection.startSlot) === null || _a === void 0 ? void 0 : _a.__changeMarker__.forceMarkDirtied();
|
1402
|
+
}
|
1526
1403
|
if (isCompositionEnd) {
|
1527
1404
|
const startSlot = this.selection.startSlot;
|
1528
1405
|
if (startSlot) {
|
@@ -1551,7 +1428,8 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1551
1428
|
};
|
1552
1429
|
exports.MagicInput = __decorate([
|
1553
1430
|
core.Injectable(),
|
1554
|
-
__metadata("design:paramtypes", [
|
1431
|
+
__metadata("design:paramtypes", [DomAdapter,
|
1432
|
+
exports.Parser,
|
1555
1433
|
core$1.Keyboard,
|
1556
1434
|
core$1.Commander,
|
1557
1435
|
core$1.Selection,
|
@@ -1569,10 +1447,11 @@ class CollaborateSelectionAwarenessDelegate {
|
|
1569
1447
|
* 协作光标绘制类
|
1570
1448
|
*/
|
1571
1449
|
exports.CollaborateCursor = class CollaborateCursor {
|
1572
|
-
constructor(textbus, nativeSelection, scheduler, selection, awarenessDelegate) {
|
1450
|
+
constructor(textbus, nativeSelection, scheduler, selection, userActivity, awarenessDelegate) {
|
1573
1451
|
this.nativeSelection = nativeSelection;
|
1574
1452
|
this.scheduler = scheduler;
|
1575
1453
|
this.selection = selection;
|
1454
|
+
this.userActivity = userActivity;
|
1576
1455
|
this.awarenessDelegate = awarenessDelegate;
|
1577
1456
|
this.host = createElement('div', {
|
1578
1457
|
styles: {
|
@@ -1622,6 +1501,7 @@ exports.CollaborateCursor = class CollaborateCursor {
|
|
1622
1501
|
this.onRectsChange = new stream.Subject();
|
1623
1502
|
this.subscription = new stream.Subscription();
|
1624
1503
|
this.currentSelection = [];
|
1504
|
+
this.ratio = window.devicePixelRatio || 1;
|
1625
1505
|
this.container = textbus.get(VIEW_CONTAINER);
|
1626
1506
|
this.canvasContainer.append(this.canvas);
|
1627
1507
|
this.host.append(this.canvasContainer, this.tooltips);
|
@@ -1641,6 +1521,13 @@ exports.CollaborateCursor = class CollaborateCursor {
|
|
1641
1521
|
this.refresh();
|
1642
1522
|
}));
|
1643
1523
|
}
|
1524
|
+
init() {
|
1525
|
+
if (this.userActivity) {
|
1526
|
+
this.subscription.add(this.userActivity.onStateChange.subscribe(v => {
|
1527
|
+
this.draw(v);
|
1528
|
+
}));
|
1529
|
+
}
|
1530
|
+
}
|
1644
1531
|
/**
|
1645
1532
|
* 刷新协作光标,由于 Textbus 只会绘制可视区域的光标,当可视区域发生变化时,需要重新绘制
|
1646
1533
|
*/
|
@@ -1658,15 +1545,16 @@ exports.CollaborateCursor = class CollaborateCursor {
|
|
1658
1545
|
this.currentSelection = paths;
|
1659
1546
|
const containerRect = this.container.getBoundingClientRect();
|
1660
1547
|
this.canvas.style.top = containerRect.top * -1 + 'px';
|
1661
|
-
this.canvas.width = this.canvas.offsetWidth;
|
1662
|
-
this.canvas.height = this.canvas.offsetHeight;
|
1548
|
+
this.canvas.width = this.canvas.offsetWidth * this.ratio;
|
1549
|
+
this.canvas.height = this.canvas.offsetHeight * this.ratio;
|
1550
|
+
this.context.scale(this.ratio, this.ratio);
|
1663
1551
|
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
1664
1552
|
const users = [];
|
1665
1553
|
paths.filter(i => {
|
1666
|
-
return i.
|
1554
|
+
return i.selection.anchor.length && i.selection.focus.length;
|
1667
1555
|
}).forEach(item => {
|
1668
|
-
const anchorPaths = [...item.
|
1669
|
-
const focusPaths = [...item.
|
1556
|
+
const anchorPaths = [...item.selection.anchor];
|
1557
|
+
const focusPaths = [...item.selection.focus];
|
1670
1558
|
const anchorOffset = anchorPaths.pop();
|
1671
1559
|
const anchorSlot = this.selection.findSlotByPaths(anchorPaths);
|
1672
1560
|
const focusOffset = focusPaths.pop();
|
@@ -1684,8 +1572,13 @@ exports.CollaborateCursor = class CollaborateCursor {
|
|
1684
1572
|
return;
|
1685
1573
|
}
|
1686
1574
|
const nativeRange = document.createRange();
|
1687
|
-
|
1688
|
-
|
1575
|
+
try {
|
1576
|
+
nativeRange.setStart(anchor.node, anchor.offset);
|
1577
|
+
nativeRange.setEnd(focus.node, focus.offset);
|
1578
|
+
}
|
1579
|
+
catch (e) {
|
1580
|
+
return;
|
1581
|
+
}
|
1689
1582
|
if ((anchor.node !== focus.node || anchor.offset !== focus.offset) && nativeRange.collapsed) {
|
1690
1583
|
nativeRange.setStart(focus.node, focus.offset);
|
1691
1584
|
nativeRange.setEnd(anchor.node, anchor.offset);
|
@@ -1814,10 +1707,12 @@ exports.CollaborateCursor = class CollaborateCursor {
|
|
1814
1707
|
exports.CollaborateCursor = __decorate([
|
1815
1708
|
core.Injectable(),
|
1816
1709
|
__param(4, core.Optional()),
|
1710
|
+
__param(5, core.Optional()),
|
1817
1711
|
__metadata("design:paramtypes", [core$1.Textbus,
|
1818
1712
|
exports.SelectionBridge,
|
1819
1713
|
core$1.Scheduler,
|
1820
1714
|
core$1.Selection,
|
1715
|
+
collaborate.UserActivity,
|
1821
1716
|
CollaborateSelectionAwarenessDelegate])
|
1822
1717
|
], exports.CollaborateCursor);
|
1823
1718
|
|
@@ -1854,9 +1749,7 @@ class NativeCaret {
|
|
1854
1749
|
height: 0
|
1855
1750
|
};
|
1856
1751
|
}
|
1857
|
-
constructor(
|
1858
|
-
this.scheduler = scheduler;
|
1859
|
-
this.oldPosition = null;
|
1752
|
+
constructor() {
|
1860
1753
|
this._nativeRange = null;
|
1861
1754
|
this.subs = [];
|
1862
1755
|
this.positionChangeEvent = new stream.Subject();
|
@@ -1865,65 +1758,12 @@ class NativeCaret {
|
|
1865
1758
|
refresh() {
|
1866
1759
|
//
|
1867
1760
|
}
|
1868
|
-
correctScrollTop(scroller) {
|
1869
|
-
this.destroy();
|
1870
|
-
const scheduler = this.scheduler;
|
1871
|
-
let docIsChanged = true;
|
1872
|
-
function limitPosition(position) {
|
1873
|
-
const { top, bottom } = scroller.getLimit();
|
1874
|
-
const caretTop = position.top;
|
1875
|
-
if (caretTop + position.height > bottom) {
|
1876
|
-
const offset = caretTop - bottom + position.height;
|
1877
|
-
scroller.setOffset(offset);
|
1878
|
-
}
|
1879
|
-
else if (position.top < top) {
|
1880
|
-
scroller.setOffset(-(top - position.top));
|
1881
|
-
}
|
1882
|
-
}
|
1883
|
-
let isPressed = false;
|
1884
|
-
this.subs.push(scroller.onScroll.subscribe(() => {
|
1885
|
-
if (this.oldPosition) {
|
1886
|
-
const rect = this.rect;
|
1887
|
-
this.oldPosition.top = rect.top;
|
1888
|
-
this.oldPosition.left = rect.left;
|
1889
|
-
this.oldPosition.height = rect.height;
|
1890
|
-
}
|
1891
|
-
}), stream.fromEvent(document, 'mousedown', true).subscribe(() => {
|
1892
|
-
isPressed = true;
|
1893
|
-
}), stream.fromEvent(document, 'mouseup', true).subscribe(() => {
|
1894
|
-
isPressed = false;
|
1895
|
-
}), scheduler.onDocChange.subscribe(() => {
|
1896
|
-
docIsChanged = true;
|
1897
|
-
}), this.onPositionChange.subscribe(position => {
|
1898
|
-
if (position) {
|
1899
|
-
if (docIsChanged) {
|
1900
|
-
if (scheduler.lastChangesHasLocalUpdate) {
|
1901
|
-
limitPosition(position);
|
1902
|
-
}
|
1903
|
-
else if (this.oldPosition) {
|
1904
|
-
const offset = Math.floor(position.top - this.oldPosition.top);
|
1905
|
-
scroller.setOffset(offset);
|
1906
|
-
}
|
1907
|
-
}
|
1908
|
-
else if (!isPressed) {
|
1909
|
-
if (this.oldPosition) {
|
1910
|
-
const offset = Math.floor(position.top - this.oldPosition.top);
|
1911
|
-
scroller.setOffset(offset);
|
1912
|
-
}
|
1913
|
-
else {
|
1914
|
-
limitPosition(position);
|
1915
|
-
}
|
1916
|
-
}
|
1917
|
-
}
|
1918
|
-
docIsChanged = false;
|
1919
|
-
}));
|
1920
|
-
}
|
1921
1761
|
destroy() {
|
1922
1762
|
this.subs.forEach(i => i.unsubscribe());
|
1923
1763
|
this.subs = [];
|
1924
1764
|
}
|
1925
1765
|
}
|
1926
|
-
|
1766
|
+
exports.NativeInput = class NativeInput extends Input {
|
1927
1767
|
set disabled(b) {
|
1928
1768
|
this._disabled = b;
|
1929
1769
|
if (this.controller.readonly) {
|
@@ -1935,18 +1775,17 @@ let NativeInput = class NativeInput extends Input {
|
|
1935
1775
|
get disabled() {
|
1936
1776
|
return this._disabled;
|
1937
1777
|
}
|
1938
|
-
constructor(textbus, parser,
|
1778
|
+
constructor(textbus, parser, selection, keyboard, domAdapter, commander, controller) {
|
1939
1779
|
super();
|
1940
1780
|
this.parser = parser;
|
1941
|
-
this.scheduler = scheduler;
|
1942
1781
|
this.selection = selection;
|
1943
1782
|
this.keyboard = keyboard;
|
1944
1783
|
this.domAdapter = domAdapter;
|
1945
1784
|
this.commander = commander;
|
1946
1785
|
this.controller = controller;
|
1947
|
-
this.caret = new NativeCaret(
|
1786
|
+
this.caret = new NativeCaret();
|
1948
1787
|
this.composition = false;
|
1949
|
-
|
1788
|
+
// compositionState: CompositionState | null = null
|
1950
1789
|
this.onReady = Promise.resolve();
|
1951
1790
|
this._disabled = false;
|
1952
1791
|
this.nativeSelection = document.getSelection();
|
@@ -1989,7 +1828,7 @@ let NativeInput = class NativeInput extends Input {
|
|
1989
1828
|
this.subscription.unsubscribe();
|
1990
1829
|
}
|
1991
1830
|
handleDefaultActions(textarea) {
|
1992
|
-
this.subscription.add(stream.fromEvent(document, 'copy').subscribe(ev => {
|
1831
|
+
this.subscription.add(stream.fromEvent(isFirefox() ? textarea : document, 'copy').subscribe(ev => {
|
1993
1832
|
const selection = this.selection;
|
1994
1833
|
if (!selection.isSelected) {
|
1995
1834
|
return;
|
@@ -2043,8 +1882,8 @@ let NativeInput = class NativeInput extends Input {
|
|
2043
1882
|
});
|
2044
1883
|
}));
|
2045
1884
|
}
|
2046
|
-
handlePaste(
|
2047
|
-
const slot = this.parser.parse(
|
1885
|
+
handlePaste(dom, text) {
|
1886
|
+
const slot = this.parser.parse(dom, new core$1.Slot([
|
2048
1887
|
core$1.ContentType.BlockComponent,
|
2049
1888
|
core$1.ContentType.InlineComponent,
|
2050
1889
|
core$1.ContentType.Text
|
@@ -2104,7 +1943,6 @@ let NativeInput = class NativeInput extends Input {
|
|
2104
1943
|
let startIndex;
|
2105
1944
|
const compositionStart = () => {
|
2106
1945
|
this.composition = true;
|
2107
|
-
this.compositionState = null;
|
2108
1946
|
startIndex = this.selection.startOffset;
|
2109
1947
|
const startSlot = this.selection.startSlot;
|
2110
1948
|
const event = new core$1.Event(startSlot, {
|
@@ -2114,11 +1952,6 @@ let NativeInput = class NativeInput extends Input {
|
|
2114
1952
|
};
|
2115
1953
|
const compositionUpdate = (data) => {
|
2116
1954
|
const startSlot = this.selection.startSlot;
|
2117
|
-
this.compositionState = {
|
2118
|
-
slot: startSlot,
|
2119
|
-
index: startIndex,
|
2120
|
-
data
|
2121
|
-
};
|
2122
1955
|
const event = new core$1.Event(startSlot, {
|
2123
1956
|
index: startIndex,
|
2124
1957
|
data
|
@@ -2142,6 +1975,10 @@ let NativeInput = class NativeInput extends Input {
|
|
2142
1975
|
compositionUpdate(ev.data);
|
2143
1976
|
}), stream.fromEvent(input, 'compositionend').subscribe(ev => {
|
2144
1977
|
compositionEnd(ev.data);
|
1978
|
+
const startContainer = this.nativeSelection.focusNode;
|
1979
|
+
if (startContainer instanceof Text && startContainer.textContent === ev.data) {
|
1980
|
+
startContainer.remove();
|
1981
|
+
}
|
2145
1982
|
}), stream.fromEvent(input, 'beforeinput').subscribe(ev => {
|
2146
1983
|
var _a;
|
2147
1984
|
switch (ev.inputType) {
|
@@ -2205,7 +2042,6 @@ let NativeInput = class NativeInput extends Input {
|
|
2205
2042
|
return !this.ignoreComposition;
|
2206
2043
|
})).subscribe(() => {
|
2207
2044
|
this.composition = true;
|
2208
|
-
this.compositionState = null;
|
2209
2045
|
startIndex = this.selection.startOffset;
|
2210
2046
|
const startSlot = this.selection.startSlot;
|
2211
2047
|
const event = new core$1.Event(startSlot, {
|
@@ -2216,11 +2052,6 @@ let NativeInput = class NativeInput extends Input {
|
|
2216
2052
|
return !this.ignoreComposition;
|
2217
2053
|
})).subscribe(ev => {
|
2218
2054
|
const startSlot = this.selection.startSlot;
|
2219
|
-
this.compositionState = {
|
2220
|
-
slot: startSlot,
|
2221
|
-
index: startIndex,
|
2222
|
-
data: ev.data
|
2223
|
-
};
|
2224
2055
|
const event = new core$1.Event(startSlot, {
|
2225
2056
|
index: startIndex,
|
2226
2057
|
data: ev.data
|
@@ -2270,8 +2101,11 @@ let NativeInput = class NativeInput extends Input {
|
|
2270
2101
|
return !b;
|
2271
2102
|
}))).subscribe(text => {
|
2272
2103
|
this.composition = false;
|
2273
|
-
this.compositionState = null;
|
2274
2104
|
if (text) {
|
2105
|
+
const startContainer = this.nativeSelection.focusNode;
|
2106
|
+
if (startContainer instanceof Text && startContainer.textContent === text) {
|
2107
|
+
startContainer.remove();
|
2108
|
+
}
|
2275
2109
|
this.commander.write(text);
|
2276
2110
|
}
|
2277
2111
|
if (isCompositionEnd) {
|
@@ -2285,21 +2119,20 @@ let NativeInput = class NativeInput extends Input {
|
|
2285
2119
|
}));
|
2286
2120
|
}
|
2287
2121
|
};
|
2288
|
-
NativeInput = __decorate([
|
2122
|
+
exports.NativeInput = __decorate([
|
2289
2123
|
core.Injectable(),
|
2290
2124
|
__metadata("design:paramtypes", [core$1.Textbus,
|
2291
2125
|
exports.Parser,
|
2292
|
-
core$1.Scheduler,
|
2293
2126
|
core$1.Selection,
|
2294
2127
|
core$1.Keyboard,
|
2295
2128
|
DomAdapter,
|
2296
2129
|
core$1.Commander,
|
2297
2130
|
core$1.Controller])
|
2298
|
-
], NativeInput);
|
2131
|
+
], exports.NativeInput);
|
2299
2132
|
|
2133
|
+
const browserErrorFn = core$1.makeError('BrowserModule');
|
2300
2134
|
class BrowserModule {
|
2301
|
-
constructor(
|
2302
|
-
this.host = host;
|
2135
|
+
constructor(config) {
|
2303
2136
|
this.config = config;
|
2304
2137
|
const { mask, wrapper } = BrowserModule.createLayout();
|
2305
2138
|
wrapper.prepend(config.adapter.host);
|
@@ -2323,13 +2156,10 @@ class BrowserModule {
|
|
2323
2156
|
useExisting: exports.SelectionBridge
|
2324
2157
|
}, {
|
2325
2158
|
provide: Input,
|
2326
|
-
useClass: config.useContentEditable ? NativeInput : exports.MagicInput
|
2159
|
+
useClass: config.useContentEditable ? exports.NativeInput : exports.MagicInput
|
2327
2160
|
}, {
|
2328
|
-
provide: core$1.
|
2329
|
-
|
2330
|
-
return v;
|
2331
|
-
},
|
2332
|
-
deps: [DomAdapter]
|
2161
|
+
provide: core$1.Adapter,
|
2162
|
+
useValue: config.adapter
|
2333
2163
|
}, {
|
2334
2164
|
provide: DomAdapter,
|
2335
2165
|
useValue: config.adapter
|
@@ -2357,10 +2187,54 @@ class BrowserModule {
|
|
2357
2187
|
exports.SelectionBridge,
|
2358
2188
|
exports.CollaborateCursor];
|
2359
2189
|
this.workbench = wrapper;
|
2360
|
-
this.host.append(wrapper);
|
2361
2190
|
}
|
2362
|
-
|
2363
|
-
|
2191
|
+
/**
|
2192
|
+
* 解析 HTML 并返回一个组件实例
|
2193
|
+
* @param html 要解析的 HTML
|
2194
|
+
* @param rootComponentLoader 文档根组件加载器
|
2195
|
+
* @param textbus
|
2196
|
+
*/
|
2197
|
+
readDocumentByHTML(html, rootComponentLoader, textbus) {
|
2198
|
+
const parser = textbus.get(exports.Parser);
|
2199
|
+
const doc = parser.parseDoc(html, rootComponentLoader);
|
2200
|
+
if (doc instanceof core$1.Component) {
|
2201
|
+
return doc;
|
2202
|
+
}
|
2203
|
+
throw browserErrorFn('rootComponentLoader must return a component instance.');
|
2204
|
+
}
|
2205
|
+
/**
|
2206
|
+
* 将组件数据解析到组件实例中
|
2207
|
+
* @param data 要解析的 JSON 数据
|
2208
|
+
* @param rootComponent 根组件
|
2209
|
+
* @param textbus
|
2210
|
+
*/
|
2211
|
+
readDocumentByComponentLiteral(data, rootComponent, textbus) {
|
2212
|
+
const registry = textbus.get(core$1.Registry);
|
2213
|
+
return registry.createComponentByFactory(data, rootComponent);
|
2214
|
+
}
|
2215
|
+
setup(textbus) {
|
2216
|
+
this.textbus = textbus;
|
2217
|
+
const host = this.config.renderTo();
|
2218
|
+
if (!(host instanceof HTMLElement)) {
|
2219
|
+
throw browserErrorFn('view container is not a HTMLElement');
|
2220
|
+
}
|
2221
|
+
const cursor = textbus.get(exports.CollaborateCursor);
|
2222
|
+
cursor.init();
|
2223
|
+
host.append(this.workbench);
|
2224
|
+
return () => {
|
2225
|
+
cursor.destroy();
|
2226
|
+
this.workbench.remove();
|
2227
|
+
};
|
2228
|
+
}
|
2229
|
+
onAfterStartup(textbus) {
|
2230
|
+
if (this.config.autoFocus) {
|
2231
|
+
textbus.focus();
|
2232
|
+
}
|
2233
|
+
}
|
2234
|
+
onDestroy(textbus) {
|
2235
|
+
textbus.get(Input).destroy();
|
2236
|
+
textbus.get(exports.SelectionBridge).destroy();
|
2237
|
+
textbus.get(exports.CollaborateCursor).destroy();
|
2364
2238
|
}
|
2365
2239
|
static createLayout() {
|
2366
2240
|
const mask = createElement('div', {
|
@@ -2373,10 +2247,23 @@ class BrowserModule {
|
|
2373
2247
|
right: 0,
|
2374
2248
|
top: 0,
|
2375
2249
|
bottom: 0,
|
2250
|
+
pointerEvents: 'none',
|
2251
|
+
// overflow: 'hidden'
|
2252
|
+
}
|
2253
|
+
});
|
2254
|
+
const maskWrapper = createElement('div', {
|
2255
|
+
styles: {
|
2256
|
+
position: 'absolute',
|
2257
|
+
left: 0,
|
2258
|
+
right: 0,
|
2259
|
+
top: 0,
|
2260
|
+
bottom: 0,
|
2261
|
+
margin: '0 -2px',
|
2376
2262
|
zIndex: 1,
|
2377
2263
|
pointerEvents: 'none',
|
2378
2264
|
overflow: 'hidden'
|
2379
|
-
}
|
2265
|
+
},
|
2266
|
+
children: [mask]
|
2380
2267
|
});
|
2381
2268
|
const wrapper = createElement('div', {
|
2382
2269
|
attrs: {
|
@@ -2388,7 +2275,7 @@ class BrowserModule {
|
|
2388
2275
|
position: 'relative',
|
2389
2276
|
flexDirection: 'column'
|
2390
2277
|
},
|
2391
|
-
children: [
|
2278
|
+
children: [maskWrapper]
|
2392
2279
|
});
|
2393
2280
|
return {
|
2394
2281
|
wrapper,
|