@textbus/platform-browser 4.0.0-alpha.5 → 4.0.0-alpha.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -114
- package/bundles/browser-module.d.ts +22 -7
- package/bundles/collaborate-cursor.d.ts +7 -13
- package/bundles/dom-adapter.d.ts +4 -64
- package/bundles/index.esm.js +169 -226
- package/bundles/index.js +171 -228
- package/bundles/magic-input.d.ts +9 -9
- package/bundles/native-input.d.ts +3 -5
- package/bundles/parser.d.ts +10 -11
- package/bundles/public-api.d.ts +1 -0
- package/bundles/selection-bridge.d.ts +3 -4
- package/bundles/types.d.ts +0 -7
- package/package.json +6 -5
package/bundles/index.js
CHANGED
@@ -2,8 +2,9 @@
|
|
2
2
|
|
3
3
|
require('reflect-metadata');
|
4
4
|
var core$1 = require('@textbus/core');
|
5
|
-
var core = require('@viewfly/core');
|
6
5
|
var stream = require('@tanbo/stream');
|
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);
|
@@ -168,9 +169,9 @@ exports.Parser = Parser_1 = class Parser {
|
|
168
169
|
static parseHTML(html) {
|
169
170
|
return new DOMParser().parseFromString(html, 'text/html').body;
|
170
171
|
}
|
171
|
-
constructor(options,
|
172
|
+
constructor(options, textbus) {
|
172
173
|
this.options = options;
|
173
|
-
this.
|
174
|
+
this.textbus = textbus;
|
174
175
|
const componentLoaders = [
|
175
176
|
...(options.componentLoaders || [])
|
176
177
|
];
|
@@ -195,7 +196,7 @@ exports.Parser = Parser_1 = class Parser {
|
|
195
196
|
*/
|
196
197
|
parseDoc(html, rootComponentLoader) {
|
197
198
|
const element = typeof html === 'string' ? Parser_1.parseHTML(html) : html;
|
198
|
-
return rootComponentLoader.read(element, this.
|
199
|
+
return rootComponentLoader.read(element, this.textbus, (childSlot, slotRootElement, slotContentHostElement = slotRootElement) => {
|
199
200
|
return this.readSlot(childSlot, slotRootElement, slotContentHostElement);
|
200
201
|
});
|
201
202
|
}
|
@@ -216,7 +217,7 @@ exports.Parser = Parser_1 = class Parser {
|
|
216
217
|
}
|
217
218
|
for (const t of this.componentLoaders) {
|
218
219
|
if (t.match(el)) {
|
219
|
-
const result = t.read(el, this.
|
220
|
+
const result = t.read(el, this.textbus, (childSlot, slotRootElement, slotContentHostElement = slotRootElement) => {
|
220
221
|
return this.readSlot(childSlot, slotRootElement, slotContentHostElement);
|
221
222
|
});
|
222
223
|
if (!result) {
|
@@ -296,19 +297,16 @@ exports.Parser = Parser_1 = class Parser {
|
|
296
297
|
exports.Parser = Parser_1 = __decorate([
|
297
298
|
core.Injectable(),
|
298
299
|
__param(0, core.Inject(EDITOR_OPTIONS)),
|
299
|
-
__metadata("design:paramtypes", [Object, core.
|
300
|
+
__metadata("design:paramtypes", [Object, core$1.Textbus])
|
300
301
|
], exports.Parser);
|
301
302
|
|
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
|
|
@@ -451,7 +329,7 @@ class DomAdapter extends core$1.ViewAdapter {
|
|
451
329
|
* Textbus PC 端选区桥接实现
|
452
330
|
*/
|
453
331
|
exports.SelectionBridge = class SelectionBridge {
|
454
|
-
constructor(config,
|
332
|
+
constructor(config, textbus, controller, selection, rootComponentRef, input, domAdapter) {
|
455
333
|
this.config = config;
|
456
334
|
this.selection = selection;
|
457
335
|
this.rootComponentRef = rootComponentRef;
|
@@ -463,7 +341,7 @@ exports.SelectionBridge = class SelectionBridge {
|
|
463
341
|
this.connector = null;
|
464
342
|
this.ignoreSelectionChange = false;
|
465
343
|
this.changeFromUser = false;
|
466
|
-
this.docContainer =
|
344
|
+
this.docContainer = textbus.get(VIEW_DOCUMENT);
|
467
345
|
this.onSelectionChange = this.selectionChangeEvent.asObservable().pipe(stream.filter(() => {
|
468
346
|
return !controller.readonly;
|
469
347
|
}));
|
@@ -647,6 +525,7 @@ exports.SelectionBridge = class SelectionBridge {
|
|
647
525
|
}
|
648
526
|
minLeft = rect2.left;
|
649
527
|
minTop = rect2.top;
|
528
|
+
oldPosition = position;
|
650
529
|
}
|
651
530
|
if (isToPrevLine) {
|
652
531
|
if (rect2.left < startLeft) {
|
@@ -753,7 +632,7 @@ exports.SelectionBridge = class SelectionBridge {
|
|
753
632
|
this.input.composition ||
|
754
633
|
selection.rangeCount === 0 ||
|
755
634
|
!this.docContainer.contains(selection.anchorNode) ||
|
756
|
-
this.rootComponentRef.component.
|
635
|
+
this.rootComponentRef.component.__slots__.length === 0) {
|
757
636
|
return;
|
758
637
|
}
|
759
638
|
const rawRange = selection.getRangeAt(0);
|
@@ -762,14 +641,14 @@ exports.SelectionBridge = class SelectionBridge {
|
|
762
641
|
const isFocusStart = selection.focusNode === nativeRange.startContainer && selection.focusOffset === nativeRange.startOffset;
|
763
642
|
if (!this.docContainer.contains(selection.focusNode)) {
|
764
643
|
if (isFocusEnd) {
|
765
|
-
const nativeNode = this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.
|
644
|
+
const nativeNode = this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.__slots__.first);
|
766
645
|
if (!nativeNode) {
|
767
646
|
return;
|
768
647
|
}
|
769
648
|
nativeRange.setEndAfter(nativeNode.lastChild);
|
770
649
|
}
|
771
650
|
else {
|
772
|
-
const nativeNode = this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.
|
651
|
+
const nativeNode = this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.__slots__.last);
|
773
652
|
if (!nativeNode) {
|
774
653
|
return;
|
775
654
|
}
|
@@ -992,7 +871,7 @@ exports.SelectionBridge = class SelectionBridge {
|
|
992
871
|
exports.SelectionBridge = __decorate([
|
993
872
|
core.Injectable(),
|
994
873
|
__param(0, core.Inject(EDITOR_OPTIONS)),
|
995
|
-
__metadata("design:paramtypes", [Object, core.
|
874
|
+
__metadata("design:paramtypes", [Object, core$1.Textbus,
|
996
875
|
core$1.Controller,
|
997
876
|
core$1.Selection,
|
998
877
|
core$1.RootComponentRef,
|
@@ -1030,15 +909,10 @@ class ExperimentalCaret {
|
|
1030
909
|
get display() {
|
1031
910
|
return this._display;
|
1032
911
|
}
|
1033
|
-
constructor(scheduler, editorMask) {
|
912
|
+
constructor(domRenderer, scheduler, editorMask) {
|
913
|
+
this.domRenderer = domRenderer;
|
1034
914
|
this.scheduler = scheduler;
|
1035
915
|
this.editorMask = editorMask;
|
1036
|
-
this.compositionState = null;
|
1037
|
-
this.compositionElement = createElement('span', {
|
1038
|
-
styles: {
|
1039
|
-
textDecoration: 'underline'
|
1040
|
-
}
|
1041
|
-
});
|
1042
916
|
this.timer = null;
|
1043
917
|
this.oldPosition = null;
|
1044
918
|
this._display = true;
|
@@ -1182,12 +1056,10 @@ class ExperimentalCaret {
|
|
1182
1056
|
this.positionChangeEvent.next(null);
|
1183
1057
|
return;
|
1184
1058
|
}
|
1185
|
-
|
1186
|
-
|
1187
|
-
compositionElement.innerText = this.compositionState.data;
|
1059
|
+
const compositionNode = this.domRenderer.compositionNode;
|
1060
|
+
if (compositionNode) {
|
1188
1061
|
nativeRange = nativeRange.cloneRange();
|
1189
|
-
nativeRange.
|
1190
|
-
nativeRange.selectNodeContents(compositionElement);
|
1062
|
+
nativeRange.selectNodeContents(compositionNode);
|
1191
1063
|
nativeRange.collapse();
|
1192
1064
|
}
|
1193
1065
|
const rect = getLayoutRectByRange(nativeRange);
|
@@ -1248,18 +1120,18 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1248
1120
|
get disabled() {
|
1249
1121
|
return this._disabled;
|
1250
1122
|
}
|
1251
|
-
constructor(parser, keyboard, commander, selection, controller, scheduler,
|
1123
|
+
constructor(domAdapter, parser, keyboard, commander, selection, controller, scheduler, textbus) {
|
1252
1124
|
super();
|
1125
|
+
this.domAdapter = domAdapter;
|
1253
1126
|
this.parser = parser;
|
1254
1127
|
this.keyboard = keyboard;
|
1255
1128
|
this.commander = commander;
|
1256
1129
|
this.selection = selection;
|
1257
1130
|
this.controller = controller;
|
1258
1131
|
this.scheduler = scheduler;
|
1259
|
-
this.
|
1132
|
+
this.textbus = textbus;
|
1260
1133
|
this.composition = false;
|
1261
|
-
this.
|
1262
|
-
this.caret = new ExperimentalCaret(this.scheduler, this.injector.get(VIEW_MASK));
|
1134
|
+
this.caret = new ExperimentalCaret(this.domAdapter, this.scheduler, this.textbus.get(VIEW_MASK));
|
1263
1135
|
this.isSafari = isSafari();
|
1264
1136
|
this.isFirefox = isFirefox();
|
1265
1137
|
this.isMac = isMac();
|
@@ -1299,13 +1171,8 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1299
1171
|
if (!this.isFocus) {
|
1300
1172
|
(_a = this.textarea) === null || _a === void 0 ? void 0 : _a.focus();
|
1301
1173
|
setTimeout(() => {
|
1302
|
-
var _a, _b, _c;
|
1303
1174
|
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();
|
1175
|
+
this.reInit();
|
1309
1176
|
}
|
1310
1177
|
});
|
1311
1178
|
}
|
@@ -1321,6 +1188,22 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1321
1188
|
this.caret.destroy();
|
1322
1189
|
this.subscription.unsubscribe();
|
1323
1190
|
}
|
1191
|
+
reInit(delay = false) {
|
1192
|
+
var _a, _b, _c;
|
1193
|
+
this.subscription.unsubscribe();
|
1194
|
+
(_b = (_a = this.textarea) === null || _a === void 0 ? void 0 : _a.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(this.textarea);
|
1195
|
+
this.subscription = new stream.Subscription();
|
1196
|
+
this.init();
|
1197
|
+
if (delay) {
|
1198
|
+
setTimeout(() => {
|
1199
|
+
var _a;
|
1200
|
+
(_a = this.textarea) === null || _a === void 0 ? void 0 : _a.focus();
|
1201
|
+
});
|
1202
|
+
}
|
1203
|
+
else {
|
1204
|
+
(_c = this.textarea) === null || _c === void 0 ? void 0 : _c.focus();
|
1205
|
+
}
|
1206
|
+
}
|
1324
1207
|
init() {
|
1325
1208
|
const doc = this.doc;
|
1326
1209
|
const contentBody = doc.body;
|
@@ -1329,9 +1212,19 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1329
1212
|
contentBody.appendChild(textarea);
|
1330
1213
|
this.textarea = textarea;
|
1331
1214
|
this.subscription.add(stream.fromEvent(textarea, 'blur').subscribe(() => {
|
1215
|
+
// if (this.isFocus) {
|
1216
|
+
// this.isFocus = false
|
1217
|
+
// this.reInit(true)
|
1218
|
+
// }
|
1332
1219
|
this.isFocus = false;
|
1333
1220
|
this.nativeFocus = false;
|
1334
1221
|
this.caret.hide();
|
1222
|
+
if (this.domAdapter.composition) {
|
1223
|
+
const slot = this.domAdapter.composition.slot;
|
1224
|
+
this.domAdapter.composition = null;
|
1225
|
+
this.domAdapter.compositionNode = null;
|
1226
|
+
slot.__changeMarker__.forceMarkDirtied();
|
1227
|
+
}
|
1335
1228
|
}), stream.fromEvent(textarea, 'focus').subscribe(() => {
|
1336
1229
|
this.nativeFocus = true;
|
1337
1230
|
}), this.caret.onStyleChange.subscribe(style => {
|
@@ -1342,7 +1235,7 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1342
1235
|
this.handleDefaultActions(textarea);
|
1343
1236
|
}
|
1344
1237
|
handleDefaultActions(textarea) {
|
1345
|
-
this.subscription.add(stream.fromEvent(document, 'copy').subscribe(ev => {
|
1238
|
+
this.subscription.add(stream.fromEvent(isFirefox() ? textarea : document, 'copy').subscribe(ev => {
|
1346
1239
|
const selection = this.selection;
|
1347
1240
|
if (!selection.isSelected) {
|
1348
1241
|
return;
|
@@ -1454,7 +1347,6 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1454
1347
|
this.commander.delete();
|
1455
1348
|
}
|
1456
1349
|
this.composition = true;
|
1457
|
-
this.caret.compositionState = this.compositionState = null;
|
1458
1350
|
startIndex = this.selection.startOffset;
|
1459
1351
|
const startSlot = this.selection.startSlot;
|
1460
1352
|
const event = new core$1.Event(startSlot, {
|
@@ -1471,10 +1363,11 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1471
1363
|
return;
|
1472
1364
|
}
|
1473
1365
|
const startSlot = this.selection.startSlot;
|
1474
|
-
this.
|
1366
|
+
this.domAdapter.composition = {
|
1475
1367
|
slot: startSlot,
|
1476
|
-
|
1477
|
-
|
1368
|
+
text: ev.data,
|
1369
|
+
offset: ev.data.length,
|
1370
|
+
index: startIndex
|
1478
1371
|
};
|
1479
1372
|
this.caret.refresh(true);
|
1480
1373
|
const event = new core$1.Event(startSlot, {
|
@@ -1482,6 +1375,7 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1482
1375
|
data: ev.data
|
1483
1376
|
});
|
1484
1377
|
core$1.invokeListener(startSlot.parent, 'onCompositionUpdate', event);
|
1378
|
+
startSlot.__changeMarker__.forceMarkDirtied();
|
1485
1379
|
}));
|
1486
1380
|
let isCompositionEnd = false;
|
1487
1381
|
this.subscription.add(stream.merge(stream.fromEvent(textarea, 'beforeinput').pipe(stream.filter(ev => {
|
@@ -1505,24 +1399,15 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1505
1399
|
textarea.value = '';
|
1506
1400
|
return ev.data;
|
1507
1401
|
}))).subscribe(text => {
|
1402
|
+
var _a;
|
1508
1403
|
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();
|
1404
|
+
this.domAdapter.composition = null;
|
1523
1405
|
if (text) {
|
1524
1406
|
this.commander.write(text);
|
1525
1407
|
}
|
1408
|
+
else {
|
1409
|
+
(_a = this.selection.startSlot) === null || _a === void 0 ? void 0 : _a.__changeMarker__.forceMarkDirtied();
|
1410
|
+
}
|
1526
1411
|
if (isCompositionEnd) {
|
1527
1412
|
const startSlot = this.selection.startSlot;
|
1528
1413
|
if (startSlot) {
|
@@ -1551,13 +1436,14 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1551
1436
|
};
|
1552
1437
|
exports.MagicInput = __decorate([
|
1553
1438
|
core.Injectable(),
|
1554
|
-
__metadata("design:paramtypes", [
|
1439
|
+
__metadata("design:paramtypes", [DomAdapter,
|
1440
|
+
exports.Parser,
|
1555
1441
|
core$1.Keyboard,
|
1556
1442
|
core$1.Commander,
|
1557
1443
|
core$1.Selection,
|
1558
1444
|
core$1.Controller,
|
1559
1445
|
core$1.Scheduler,
|
1560
|
-
core.
|
1446
|
+
core$1.Textbus])
|
1561
1447
|
], exports.MagicInput);
|
1562
1448
|
|
1563
1449
|
/**
|
@@ -1569,10 +1455,11 @@ class CollaborateSelectionAwarenessDelegate {
|
|
1569
1455
|
* 协作光标绘制类
|
1570
1456
|
*/
|
1571
1457
|
exports.CollaborateCursor = class CollaborateCursor {
|
1572
|
-
constructor(
|
1458
|
+
constructor(textbus, nativeSelection, scheduler, selection, userActivity, awarenessDelegate) {
|
1573
1459
|
this.nativeSelection = nativeSelection;
|
1574
1460
|
this.scheduler = scheduler;
|
1575
1461
|
this.selection = selection;
|
1462
|
+
this.userActivity = userActivity;
|
1576
1463
|
this.awarenessDelegate = awarenessDelegate;
|
1577
1464
|
this.host = createElement('div', {
|
1578
1465
|
styles: {
|
@@ -1622,7 +1509,8 @@ exports.CollaborateCursor = class CollaborateCursor {
|
|
1622
1509
|
this.onRectsChange = new stream.Subject();
|
1623
1510
|
this.subscription = new stream.Subscription();
|
1624
1511
|
this.currentSelection = [];
|
1625
|
-
this.
|
1512
|
+
this.ratio = window.devicePixelRatio || 1;
|
1513
|
+
this.container = textbus.get(VIEW_CONTAINER);
|
1626
1514
|
this.canvasContainer.append(this.canvas);
|
1627
1515
|
this.host.append(this.canvasContainer, this.tooltips);
|
1628
1516
|
this.container.prepend(this.host);
|
@@ -1641,6 +1529,13 @@ exports.CollaborateCursor = class CollaborateCursor {
|
|
1641
1529
|
this.refresh();
|
1642
1530
|
}));
|
1643
1531
|
}
|
1532
|
+
init() {
|
1533
|
+
if (this.userActivity) {
|
1534
|
+
this.subscription.add(this.userActivity.onStateChange.subscribe(v => {
|
1535
|
+
this.draw(v);
|
1536
|
+
}));
|
1537
|
+
}
|
1538
|
+
}
|
1644
1539
|
/**
|
1645
1540
|
* 刷新协作光标,由于 Textbus 只会绘制可视区域的光标,当可视区域发生变化时,需要重新绘制
|
1646
1541
|
*/
|
@@ -1658,15 +1553,16 @@ exports.CollaborateCursor = class CollaborateCursor {
|
|
1658
1553
|
this.currentSelection = paths;
|
1659
1554
|
const containerRect = this.container.getBoundingClientRect();
|
1660
1555
|
this.canvas.style.top = containerRect.top * -1 + 'px';
|
1661
|
-
this.canvas.width = this.canvas.offsetWidth;
|
1662
|
-
this.canvas.height = this.canvas.offsetHeight;
|
1556
|
+
this.canvas.width = this.canvas.offsetWidth * this.ratio;
|
1557
|
+
this.canvas.height = this.canvas.offsetHeight * this.ratio;
|
1558
|
+
this.context.scale(this.ratio, this.ratio);
|
1663
1559
|
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
1664
1560
|
const users = [];
|
1665
1561
|
paths.filter(i => {
|
1666
|
-
return i.
|
1562
|
+
return i.selection.anchor.length && i.selection.focus.length;
|
1667
1563
|
}).forEach(item => {
|
1668
|
-
const anchorPaths = [...item.
|
1669
|
-
const focusPaths = [...item.
|
1564
|
+
const anchorPaths = [...item.selection.anchor];
|
1565
|
+
const focusPaths = [...item.selection.focus];
|
1670
1566
|
const anchorOffset = anchorPaths.pop();
|
1671
1567
|
const anchorSlot = this.selection.findSlotByPaths(anchorPaths);
|
1672
1568
|
const focusOffset = focusPaths.pop();
|
@@ -1684,8 +1580,13 @@ exports.CollaborateCursor = class CollaborateCursor {
|
|
1684
1580
|
return;
|
1685
1581
|
}
|
1686
1582
|
const nativeRange = document.createRange();
|
1687
|
-
|
1688
|
-
|
1583
|
+
try {
|
1584
|
+
nativeRange.setStart(anchor.node, anchor.offset);
|
1585
|
+
nativeRange.setEnd(focus.node, focus.offset);
|
1586
|
+
}
|
1587
|
+
catch (e) {
|
1588
|
+
return;
|
1589
|
+
}
|
1689
1590
|
if ((anchor.node !== focus.node || anchor.offset !== focus.offset) && nativeRange.collapsed) {
|
1690
1591
|
nativeRange.setStart(focus.node, focus.offset);
|
1691
1592
|
nativeRange.setEnd(anchor.node, anchor.offset);
|
@@ -1814,10 +1715,12 @@ exports.CollaborateCursor = class CollaborateCursor {
|
|
1814
1715
|
exports.CollaborateCursor = __decorate([
|
1815
1716
|
core.Injectable(),
|
1816
1717
|
__param(4, core.Optional()),
|
1817
|
-
|
1718
|
+
__param(5, core.Optional()),
|
1719
|
+
__metadata("design:paramtypes", [core$1.Textbus,
|
1818
1720
|
exports.SelectionBridge,
|
1819
1721
|
core$1.Scheduler,
|
1820
1722
|
core$1.Selection,
|
1723
|
+
collaborate.UserActivity,
|
1821
1724
|
CollaborateSelectionAwarenessDelegate])
|
1822
1725
|
], exports.CollaborateCursor);
|
1823
1726
|
|
@@ -1923,7 +1826,7 @@ class NativeCaret {
|
|
1923
1826
|
this.subs = [];
|
1924
1827
|
}
|
1925
1828
|
}
|
1926
|
-
|
1829
|
+
exports.NativeInput = class NativeInput extends Input {
|
1927
1830
|
set disabled(b) {
|
1928
1831
|
this._disabled = b;
|
1929
1832
|
if (this.controller.readonly) {
|
@@ -1935,7 +1838,7 @@ let NativeInput = class NativeInput extends Input {
|
|
1935
1838
|
get disabled() {
|
1936
1839
|
return this._disabled;
|
1937
1840
|
}
|
1938
|
-
constructor(
|
1841
|
+
constructor(textbus, parser, scheduler, selection, keyboard, domAdapter, commander, controller) {
|
1939
1842
|
super();
|
1940
1843
|
this.parser = parser;
|
1941
1844
|
this.scheduler = scheduler;
|
@@ -1946,7 +1849,7 @@ let NativeInput = class NativeInput extends Input {
|
|
1946
1849
|
this.controller = controller;
|
1947
1850
|
this.caret = new NativeCaret(this.scheduler);
|
1948
1851
|
this.composition = false;
|
1949
|
-
|
1852
|
+
// compositionState: CompositionState | null = null
|
1950
1853
|
this.onReady = Promise.resolve();
|
1951
1854
|
this._disabled = false;
|
1952
1855
|
this.nativeSelection = document.getSelection();
|
@@ -1956,7 +1859,7 @@ let NativeInput = class NativeInput extends Input {
|
|
1956
1859
|
this.isMac = isMac();
|
1957
1860
|
this.isMobileBrowser = isMobileBrowser();
|
1958
1861
|
this.ignoreComposition = false; // 有 bug 版本搜狗拼音
|
1959
|
-
this.documentView =
|
1862
|
+
this.documentView = textbus.get(VIEW_DOCUMENT);
|
1960
1863
|
if (!controller.readonly) {
|
1961
1864
|
this.documentView.contentEditable = 'true';
|
1962
1865
|
}
|
@@ -1989,7 +1892,7 @@ let NativeInput = class NativeInput extends Input {
|
|
1989
1892
|
this.subscription.unsubscribe();
|
1990
1893
|
}
|
1991
1894
|
handleDefaultActions(textarea) {
|
1992
|
-
this.subscription.add(stream.fromEvent(document, 'copy').subscribe(ev => {
|
1895
|
+
this.subscription.add(stream.fromEvent(isFirefox() ? textarea : document, 'copy').subscribe(ev => {
|
1993
1896
|
const selection = this.selection;
|
1994
1897
|
if (!selection.isSelected) {
|
1995
1898
|
return;
|
@@ -2043,8 +1946,8 @@ let NativeInput = class NativeInput extends Input {
|
|
2043
1946
|
});
|
2044
1947
|
}));
|
2045
1948
|
}
|
2046
|
-
handlePaste(
|
2047
|
-
const slot = this.parser.parse(
|
1949
|
+
handlePaste(dom, text) {
|
1950
|
+
const slot = this.parser.parse(dom, new core$1.Slot([
|
2048
1951
|
core$1.ContentType.BlockComponent,
|
2049
1952
|
core$1.ContentType.InlineComponent,
|
2050
1953
|
core$1.ContentType.Text
|
@@ -2104,7 +2007,6 @@ let NativeInput = class NativeInput extends Input {
|
|
2104
2007
|
let startIndex;
|
2105
2008
|
const compositionStart = () => {
|
2106
2009
|
this.composition = true;
|
2107
|
-
this.compositionState = null;
|
2108
2010
|
startIndex = this.selection.startOffset;
|
2109
2011
|
const startSlot = this.selection.startSlot;
|
2110
2012
|
const event = new core$1.Event(startSlot, {
|
@@ -2114,11 +2016,6 @@ let NativeInput = class NativeInput extends Input {
|
|
2114
2016
|
};
|
2115
2017
|
const compositionUpdate = (data) => {
|
2116
2018
|
const startSlot = this.selection.startSlot;
|
2117
|
-
this.compositionState = {
|
2118
|
-
slot: startSlot,
|
2119
|
-
index: startIndex,
|
2120
|
-
data
|
2121
|
-
};
|
2122
2019
|
const event = new core$1.Event(startSlot, {
|
2123
2020
|
index: startIndex,
|
2124
2021
|
data
|
@@ -2205,7 +2102,6 @@ let NativeInput = class NativeInput extends Input {
|
|
2205
2102
|
return !this.ignoreComposition;
|
2206
2103
|
})).subscribe(() => {
|
2207
2104
|
this.composition = true;
|
2208
|
-
this.compositionState = null;
|
2209
2105
|
startIndex = this.selection.startOffset;
|
2210
2106
|
const startSlot = this.selection.startSlot;
|
2211
2107
|
const event = new core$1.Event(startSlot, {
|
@@ -2216,11 +2112,6 @@ let NativeInput = class NativeInput extends Input {
|
|
2216
2112
|
return !this.ignoreComposition;
|
2217
2113
|
})).subscribe(ev => {
|
2218
2114
|
const startSlot = this.selection.startSlot;
|
2219
|
-
this.compositionState = {
|
2220
|
-
slot: startSlot,
|
2221
|
-
index: startIndex,
|
2222
|
-
data: ev.data
|
2223
|
-
};
|
2224
2115
|
const event = new core$1.Event(startSlot, {
|
2225
2116
|
index: startIndex,
|
2226
2117
|
data: ev.data
|
@@ -2270,7 +2161,6 @@ let NativeInput = class NativeInput extends Input {
|
|
2270
2161
|
return !b;
|
2271
2162
|
}))).subscribe(text => {
|
2272
2163
|
this.composition = false;
|
2273
|
-
this.compositionState = null;
|
2274
2164
|
if (text) {
|
2275
2165
|
this.commander.write(text);
|
2276
2166
|
}
|
@@ -2285,9 +2175,9 @@ let NativeInput = class NativeInput extends Input {
|
|
2285
2175
|
}));
|
2286
2176
|
}
|
2287
2177
|
};
|
2288
|
-
NativeInput = __decorate([
|
2178
|
+
exports.NativeInput = __decorate([
|
2289
2179
|
core.Injectable(),
|
2290
|
-
__metadata("design:paramtypes", [core.
|
2180
|
+
__metadata("design:paramtypes", [core$1.Textbus,
|
2291
2181
|
exports.Parser,
|
2292
2182
|
core$1.Scheduler,
|
2293
2183
|
core$1.Selection,
|
@@ -2295,11 +2185,11 @@ NativeInput = __decorate([
|
|
2295
2185
|
DomAdapter,
|
2296
2186
|
core$1.Commander,
|
2297
2187
|
core$1.Controller])
|
2298
|
-
], NativeInput);
|
2188
|
+
], exports.NativeInput);
|
2299
2189
|
|
2190
|
+
const browserErrorFn = core$1.makeError('BrowserModule');
|
2300
2191
|
class BrowserModule {
|
2301
|
-
constructor(
|
2302
|
-
this.host = host;
|
2192
|
+
constructor(config) {
|
2303
2193
|
this.config = config;
|
2304
2194
|
const { mask, wrapper } = BrowserModule.createLayout();
|
2305
2195
|
wrapper.prepend(config.adapter.host);
|
@@ -2323,26 +2213,79 @@ class BrowserModule {
|
|
2323
2213
|
useExisting: exports.SelectionBridge
|
2324
2214
|
}, {
|
2325
2215
|
provide: Input,
|
2326
|
-
useClass: config.useContentEditable ? NativeInput : exports.MagicInput
|
2216
|
+
useClass: config.useContentEditable ? exports.NativeInput : exports.MagicInput
|
2327
2217
|
}, {
|
2328
|
-
provide: core$1.
|
2329
|
-
|
2330
|
-
return v;
|
2331
|
-
},
|
2332
|
-
deps: [DomAdapter]
|
2218
|
+
provide: core$1.Adapter,
|
2219
|
+
useValue: config.adapter
|
2333
2220
|
}, {
|
2334
2221
|
provide: DomAdapter,
|
2335
2222
|
useValue: config.adapter
|
2223
|
+
}, {
|
2224
|
+
provide: core$1.FocusManager,
|
2225
|
+
useFactory: (input) => {
|
2226
|
+
const focusEvent = new stream.Subject();
|
2227
|
+
const blurEvent = new stream.Subject();
|
2228
|
+
input.caret.onPositionChange.pipe(stream.map(p => !!p), stream.distinctUntilChanged()).subscribe(b => {
|
2229
|
+
if (b) {
|
2230
|
+
focusEvent.next();
|
2231
|
+
}
|
2232
|
+
else {
|
2233
|
+
blurEvent.next();
|
2234
|
+
}
|
2235
|
+
});
|
2236
|
+
return {
|
2237
|
+
onFocus: focusEvent,
|
2238
|
+
onBlur: blurEvent
|
2239
|
+
};
|
2240
|
+
},
|
2241
|
+
deps: [Input]
|
2336
2242
|
},
|
2337
2243
|
exports.Parser,
|
2338
2244
|
exports.SelectionBridge,
|
2339
|
-
exports.CollaborateCursor
|
2340
|
-
];
|
2245
|
+
exports.CollaborateCursor];
|
2341
2246
|
this.workbench = wrapper;
|
2342
|
-
this.host.append(wrapper);
|
2343
2247
|
}
|
2344
|
-
|
2345
|
-
|
2248
|
+
/**
|
2249
|
+
* 解析 HTML 并返回一个组件实例
|
2250
|
+
* @param html 要解析的 HTML
|
2251
|
+
* @param rootComponentLoader 文档根组件加载器
|
2252
|
+
* @param textbus
|
2253
|
+
*/
|
2254
|
+
readDocumentByHTML(html, rootComponentLoader, textbus) {
|
2255
|
+
const parser = textbus.get(exports.Parser);
|
2256
|
+
const doc = parser.parseDoc(html, rootComponentLoader);
|
2257
|
+
if (doc instanceof core$1.Component) {
|
2258
|
+
return doc;
|
2259
|
+
}
|
2260
|
+
throw browserErrorFn('rootComponentLoader must return a component instance.');
|
2261
|
+
}
|
2262
|
+
/**
|
2263
|
+
* 将组件数据解析到组件实例中
|
2264
|
+
* @param data 要解析的 JSON 数据
|
2265
|
+
* @param rootComponent 根组件
|
2266
|
+
* @param textbus
|
2267
|
+
*/
|
2268
|
+
readDocumentByComponentLiteral(data, rootComponent, textbus) {
|
2269
|
+
const registry = textbus.get(core$1.Registry);
|
2270
|
+
return registry.createComponentByFactory(data, rootComponent);
|
2271
|
+
}
|
2272
|
+
setup(textbus) {
|
2273
|
+
const host = this.config.renderTo();
|
2274
|
+
if (!(host instanceof HTMLElement)) {
|
2275
|
+
throw browserErrorFn('view container is not a HTMLElement');
|
2276
|
+
}
|
2277
|
+
const cursor = textbus.get(exports.CollaborateCursor);
|
2278
|
+
cursor.init();
|
2279
|
+
host.append(this.workbench);
|
2280
|
+
return () => {
|
2281
|
+
cursor.destroy();
|
2282
|
+
this.workbench.remove();
|
2283
|
+
};
|
2284
|
+
}
|
2285
|
+
onAfterStartup(textbus) {
|
2286
|
+
if (this.config.autoFocus) {
|
2287
|
+
textbus.focus();
|
2288
|
+
}
|
2346
2289
|
}
|
2347
2290
|
static createLayout() {
|
2348
2291
|
const mask = createElement('div', {
|