@textbus/platform-browser 3.0.0-alpha.33 → 3.0.0-alpha.35

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.
@@ -1,11 +1,11 @@
1
1
  import { Injector } from '@tanbo/di';
2
- import { Subject } from '@tanbo/stream';
2
+ import { Observable } from '@tanbo/stream';
3
3
  import { Commander, Controller, Keyboard, Scheduler, Selection } from '@textbus/core';
4
4
  import { Caret, CaretPosition, Input, Scroller } from './types';
5
5
  import { Parser } from '../dom-support/parser';
6
6
  declare class NativeCaret implements Caret {
7
7
  private scheduler;
8
- onPositionChange: Subject<CaretPosition | null>;
8
+ onPositionChange: Observable<CaretPosition | null>;
9
9
  set nativeRange(range: Range | null);
10
10
  get nativeRange(): Range | null;
11
11
  get rect(): DOMRect | {
@@ -17,6 +17,7 @@ declare class NativeCaret implements Caret {
17
17
  private oldPosition;
18
18
  private _nativeRange;
19
19
  private subs;
20
+ private positionChangeEvent;
20
21
  constructor(scheduler: Scheduler);
21
22
  refresh(): void;
22
23
  correctScrollTop(scroller: Scroller): void;
@@ -315,6 +315,49 @@ let SelectionBridge = class SelectionBridge {
315
315
  getNextLinePositionByCurrent(position) {
316
316
  return this.getLinePosition(position, true);
317
317
  }
318
+ // private getLinePosition(currentPosition: SelectionPosition, toNext: boolean): SelectionPosition | null {
319
+ // clearTimeout(this.cacheCaretPositionTimer)
320
+ // let p: SelectionPosition | null
321
+ // if (this.oldCaretPosition) {
322
+ // p = this.caretRangeFromPoint(currentPosition, this.oldCaretPosition.left, toNext)
323
+ // } else {
324
+ // this.oldCaretPosition = this.getRect(currentPosition)!
325
+ // p = this.caretRangeFromPoint(currentPosition, this.oldCaretPosition.left, toNext)
326
+ // }
327
+ // this.cacheCaretPositionTimer = setTimeout(() => {
328
+ // this.oldCaretPosition = null
329
+ // }, 3000)
330
+ // return p
331
+ // }
332
+ //
333
+ // private caretRangeFromPoint(currentPosition: SelectionPosition, x: number, toNext: boolean): SelectionPosition | null {
334
+ // const rect = this.getRect(currentPosition)!
335
+ // const fn = document.caretRangeFromPoint || function (x: number, y: number) {
336
+ // const range = (document as any).caretPositionFromPoint(x, y)
337
+ // return {
338
+ // startContainer: range.offsetNode,
339
+ // startOffset: range.offset
340
+ // }
341
+ // }
342
+ //
343
+ // const current = fn.call(document, rect.left, rect.top)!
344
+ //
345
+ // let startTop = toNext ? rect.top + rect.height : rect.top
346
+ // const step = toNext ? 5 : -5
347
+ // while (true) {
348
+ // startTop += step
349
+ // const newPosition = fn.call(document, x, startTop)
350
+ // if (!newPosition) {
351
+ // return toNext ?
352
+ // this.selection.findLastPosition(this.rootComponentRef.component.slots.last, true) :
353
+ // this.selection.findFirstPosition(this.rootComponentRef.component.slots.first, true)
354
+ // }
355
+ // if (newPosition.startContainer !== current.startContainer || newPosition.startOffset !== current.startOffset) {
356
+ // return this.getCorrectedPosition(newPosition.startContainer, newPosition.startOffset, toNext)
357
+ // }
358
+ // }
359
+ // return null
360
+ // }
318
361
  getLinePosition(currentPosition, toNext) {
319
362
  clearTimeout(this.cacheCaretPositionTimer);
320
363
  let p;
@@ -359,7 +402,7 @@ let SelectionBridge = class SelectionBridge {
359
402
  focusOffset = position.offset;
360
403
  const rect2 = this.getRect(position);
361
404
  if (!isToPrevLine) {
362
- if (rect2.left > minLeft || rect2.top < minTop) {
405
+ if (rect2.left > minLeft || rect2.top + rect2.height <= minTop) {
363
406
  isToPrevLine = true;
364
407
  }
365
408
  else if (rect2.left === minLeft && rect2.top === minTop) {
@@ -400,10 +443,11 @@ let SelectionBridge = class SelectionBridge {
400
443
  let maxRight = startLeft;
401
444
  let focusSlot = currentPosition.slot;
402
445
  let focusOffset = currentPosition.offset;
403
- let minTop = this.getRect({
446
+ const rect = this.getRect({
404
447
  slot: focusSlot,
405
448
  offset: focusOffset
406
- }).top;
449
+ });
450
+ let minTop = rect.top;
407
451
  let oldPosition;
408
452
  let oldLeft = 0;
409
453
  while (true) {
@@ -413,7 +457,7 @@ let SelectionBridge = class SelectionBridge {
413
457
  focusOffset = position.offset;
414
458
  const rect2 = this.getRect(position);
415
459
  if (!isToNextLine) {
416
- if (rect2.left < maxRight || rect2.top > minTop) {
460
+ if (rect2.left < maxRight || rect2.top >= minTop + rect.height) {
417
461
  isToNextLine = true;
418
462
  }
419
463
  else if (rect2.left === maxRight && rect2.top === minTop) {
@@ -1441,7 +1485,7 @@ class ExperimentalCaret {
1441
1485
  updateCursorPosition(nativeRange) {
1442
1486
  const startContainer = nativeRange.startContainer;
1443
1487
  const node = (startContainer.nodeType === Node.ELEMENT_NODE ? startContainer : startContainer.parentNode);
1444
- if ((node === null || node === void 0 ? void 0 : node.nodeType) !== Node.ELEMENT_NODE || !nativeRange.collapsed) {
1488
+ if ((node === null || node === void 0 ? void 0 : node.nodeType) !== Node.ELEMENT_NODE) {
1445
1489
  this.positionChangeEvent.next(null);
1446
1490
  return;
1447
1491
  }
@@ -1735,15 +1779,26 @@ MagicInput = __decorate([
1735
1779
  class NativeCaret {
1736
1780
  constructor(scheduler) {
1737
1781
  this.scheduler = scheduler;
1738
- this.onPositionChange = new Subject();
1739
1782
  this.oldPosition = null;
1740
1783
  this._nativeRange = null;
1741
1784
  this.subs = [];
1785
+ this.positionChangeEvent = new Subject();
1786
+ this.onPositionChange = this.positionChangeEvent.pipe(distinctUntilChanged());
1742
1787
  }
1743
1788
  set nativeRange(range) {
1744
1789
  this._nativeRange = range;
1745
- if (range && range.collapsed) {
1746
- this.onPositionChange.next(range.getBoundingClientRect());
1790
+ if (range) {
1791
+ const r = range.cloneRange();
1792
+ r.collapse(true);
1793
+ const rect = r.getBoundingClientRect();
1794
+ this.positionChangeEvent.next({
1795
+ left: rect.left,
1796
+ top: rect.top,
1797
+ height: rect.height
1798
+ });
1799
+ }
1800
+ else {
1801
+ this.positionChangeEvent.next(null);
1747
1802
  }
1748
1803
  }
1749
1804
  get nativeRange() {
@@ -1751,7 +1806,9 @@ class NativeCaret {
1751
1806
  }
1752
1807
  get rect() {
1753
1808
  if (this.nativeRange) {
1754
- return this.nativeRange.getBoundingClientRect();
1809
+ const range = this.nativeRange.cloneRange();
1810
+ range.collapse(true);
1811
+ return range.getBoundingClientRect();
1755
1812
  }
1756
1813
  return {
1757
1814
  left: 0,
package/bundles/index.js CHANGED
@@ -317,6 +317,49 @@ exports.SelectionBridge = class SelectionBridge {
317
317
  getNextLinePositionByCurrent(position) {
318
318
  return this.getLinePosition(position, true);
319
319
  }
320
+ // private getLinePosition(currentPosition: SelectionPosition, toNext: boolean): SelectionPosition | null {
321
+ // clearTimeout(this.cacheCaretPositionTimer)
322
+ // let p: SelectionPosition | null
323
+ // if (this.oldCaretPosition) {
324
+ // p = this.caretRangeFromPoint(currentPosition, this.oldCaretPosition.left, toNext)
325
+ // } else {
326
+ // this.oldCaretPosition = this.getRect(currentPosition)!
327
+ // p = this.caretRangeFromPoint(currentPosition, this.oldCaretPosition.left, toNext)
328
+ // }
329
+ // this.cacheCaretPositionTimer = setTimeout(() => {
330
+ // this.oldCaretPosition = null
331
+ // }, 3000)
332
+ // return p
333
+ // }
334
+ //
335
+ // private caretRangeFromPoint(currentPosition: SelectionPosition, x: number, toNext: boolean): SelectionPosition | null {
336
+ // const rect = this.getRect(currentPosition)!
337
+ // const fn = document.caretRangeFromPoint || function (x: number, y: number) {
338
+ // const range = (document as any).caretPositionFromPoint(x, y)
339
+ // return {
340
+ // startContainer: range.offsetNode,
341
+ // startOffset: range.offset
342
+ // }
343
+ // }
344
+ //
345
+ // const current = fn.call(document, rect.left, rect.top)!
346
+ //
347
+ // let startTop = toNext ? rect.top + rect.height : rect.top
348
+ // const step = toNext ? 5 : -5
349
+ // while (true) {
350
+ // startTop += step
351
+ // const newPosition = fn.call(document, x, startTop)
352
+ // if (!newPosition) {
353
+ // return toNext ?
354
+ // this.selection.findLastPosition(this.rootComponentRef.component.slots.last, true) :
355
+ // this.selection.findFirstPosition(this.rootComponentRef.component.slots.first, true)
356
+ // }
357
+ // if (newPosition.startContainer !== current.startContainer || newPosition.startOffset !== current.startOffset) {
358
+ // return this.getCorrectedPosition(newPosition.startContainer, newPosition.startOffset, toNext)
359
+ // }
360
+ // }
361
+ // return null
362
+ // }
320
363
  getLinePosition(currentPosition, toNext) {
321
364
  clearTimeout(this.cacheCaretPositionTimer);
322
365
  let p;
@@ -361,7 +404,7 @@ exports.SelectionBridge = class SelectionBridge {
361
404
  focusOffset = position.offset;
362
405
  const rect2 = this.getRect(position);
363
406
  if (!isToPrevLine) {
364
- if (rect2.left > minLeft || rect2.top < minTop) {
407
+ if (rect2.left > minLeft || rect2.top + rect2.height <= minTop) {
365
408
  isToPrevLine = true;
366
409
  }
367
410
  else if (rect2.left === minLeft && rect2.top === minTop) {
@@ -402,10 +445,11 @@ exports.SelectionBridge = class SelectionBridge {
402
445
  let maxRight = startLeft;
403
446
  let focusSlot = currentPosition.slot;
404
447
  let focusOffset = currentPosition.offset;
405
- let minTop = this.getRect({
448
+ const rect = this.getRect({
406
449
  slot: focusSlot,
407
450
  offset: focusOffset
408
- }).top;
451
+ });
452
+ let minTop = rect.top;
409
453
  let oldPosition;
410
454
  let oldLeft = 0;
411
455
  while (true) {
@@ -415,7 +459,7 @@ exports.SelectionBridge = class SelectionBridge {
415
459
  focusOffset = position.offset;
416
460
  const rect2 = this.getRect(position);
417
461
  if (!isToNextLine) {
418
- if (rect2.left < maxRight || rect2.top > minTop) {
462
+ if (rect2.left < maxRight || rect2.top >= minTop + rect.height) {
419
463
  isToNextLine = true;
420
464
  }
421
465
  else if (rect2.left === maxRight && rect2.top === minTop) {
@@ -1443,7 +1487,7 @@ class ExperimentalCaret {
1443
1487
  updateCursorPosition(nativeRange) {
1444
1488
  const startContainer = nativeRange.startContainer;
1445
1489
  const node = (startContainer.nodeType === Node.ELEMENT_NODE ? startContainer : startContainer.parentNode);
1446
- if ((node === null || node === void 0 ? void 0 : node.nodeType) !== Node.ELEMENT_NODE || !nativeRange.collapsed) {
1490
+ if ((node === null || node === void 0 ? void 0 : node.nodeType) !== Node.ELEMENT_NODE) {
1447
1491
  this.positionChangeEvent.next(null);
1448
1492
  return;
1449
1493
  }
@@ -1737,15 +1781,26 @@ exports.MagicInput = __decorate([
1737
1781
  class NativeCaret {
1738
1782
  constructor(scheduler) {
1739
1783
  this.scheduler = scheduler;
1740
- this.onPositionChange = new stream.Subject();
1741
1784
  this.oldPosition = null;
1742
1785
  this._nativeRange = null;
1743
1786
  this.subs = [];
1787
+ this.positionChangeEvent = new stream.Subject();
1788
+ this.onPositionChange = this.positionChangeEvent.pipe(stream.distinctUntilChanged());
1744
1789
  }
1745
1790
  set nativeRange(range) {
1746
1791
  this._nativeRange = range;
1747
- if (range && range.collapsed) {
1748
- this.onPositionChange.next(range.getBoundingClientRect());
1792
+ if (range) {
1793
+ const r = range.cloneRange();
1794
+ r.collapse(true);
1795
+ const rect = r.getBoundingClientRect();
1796
+ this.positionChangeEvent.next({
1797
+ left: rect.left,
1798
+ top: rect.top,
1799
+ height: rect.height
1800
+ });
1801
+ }
1802
+ else {
1803
+ this.positionChangeEvent.next(null);
1749
1804
  }
1750
1805
  }
1751
1806
  get nativeRange() {
@@ -1753,7 +1808,9 @@ class NativeCaret {
1753
1808
  }
1754
1809
  get rect() {
1755
1810
  if (this.nativeRange) {
1756
- return this.nativeRange.getBoundingClientRect();
1811
+ const range = this.nativeRange.cloneRange();
1812
+ range.collapse(true);
1813
+ return range.getBoundingClientRect();
1757
1814
  }
1758
1815
  return {
1759
1816
  left: 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@textbus/platform-browser",
3
- "version": "3.0.0-alpha.33",
3
+ "version": "3.0.0-alpha.35",
4
4
  "description": "Textbus is a rich text editor and framework that is highly customizable and extensible to achieve rich wysiwyg effects.",
5
5
  "main": "./bundles/index.js",
6
6
  "module": "./bundles/index.esm.js",
@@ -27,7 +27,7 @@
27
27
  "dependencies": {
28
28
  "@tanbo/di": "^1.1.4",
29
29
  "@tanbo/stream": "^1.1.8",
30
- "@textbus/core": "^3.0.0-alpha.33",
30
+ "@textbus/core": "^3.0.0-alpha.35",
31
31
  "reflect-metadata": "^0.1.13"
32
32
  },
33
33
  "devDependencies": {
@@ -48,5 +48,5 @@
48
48
  "bugs": {
49
49
  "url": "https://github.com/textbus/textbus.git/issues"
50
50
  },
51
- "gitHead": "7888d3b0a0977343c4f8483bb5792cb24a32939a"
51
+ "gitHead": "e324984a67b1bf7d1c3a6dc282c289b0b4622496"
52
52
  }