@textbus/platform-browser 5.4.3 → 5.4.5

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/dist/index.esm.js CHANGED
@@ -12,6 +12,14 @@ import { InjectionToken, Injectable, Inject, Optional } from '@viewfly/core';
12
12
  function _array_without_holes$2(arr) {
13
13
  if (Array.isArray(arr)) return _array_like_to_array$2(arr);
14
14
  }
15
+ function _instanceof$4(left, right) {
16
+ "@swc/helpers - instanceof";
17
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
18
+ return !!right[Symbol.hasInstance](left);
19
+ } else {
20
+ return left instanceof right;
21
+ }
22
+ }
15
23
  function _iterable_to_array$2(iter) {
16
24
  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
17
25
  }
@@ -29,6 +37,247 @@ function _unsupported_iterable_to_array$2(o, minLen) {
29
37
  if (n === "Map" || n === "Set") return Array.from(n);
30
38
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$2(o, minLen);
31
39
  }
40
+ var OVERFLOW_CLIP_VALUES = new Set([
41
+ 'auto',
42
+ 'hidden',
43
+ 'scroll',
44
+ 'clip'
45
+ ]);
46
+ function rectRight(r) {
47
+ return r.left + r.width;
48
+ }
49
+ function rectBottom(r) {
50
+ return r.top + r.height;
51
+ }
52
+ function isOverflowClipAxis(value) {
53
+ return OVERFLOW_CLIP_VALUES.has(value);
54
+ }
55
+ function readOverflowClipAxes(style) {
56
+ var overflow = style.overflow;
57
+ var overflowX = style.overflowX;
58
+ var overflowY = style.overflowY;
59
+ if (!isOverflowClipAxis(overflow) && !isOverflowClipAxis(overflowX) && !isOverflowClipAxis(overflowY)) {
60
+ return null;
61
+ }
62
+ return {
63
+ clipX: isOverflowClipAxis(overflowX) || isOverflowClipAxis(overflow),
64
+ clipY: isOverflowClipAxis(overflowY) || isOverflowClipAxis(overflow)
65
+ };
66
+ }
67
+ /**
68
+ * 一次遍历祖先链:缓存 overflow 轴信息,并收集滚动监听目标。
69
+ */ function getOverflowClipContext(anchor, extraRoot) {
70
+ var _ref, _ref1;
71
+ var _clipAncestors_;
72
+ var clipAncestors = [];
73
+ var scrollContainers = new Set();
74
+ var node = anchor.nodeType === Node.ELEMENT_NODE ? anchor : anchor.parentNode;
75
+ while(node){
76
+ var _node_ownerDocument;
77
+ if (_instanceof$4(node, Element)) {
78
+ var flags = readOverflowClipAxes(getComputedStyle(node));
79
+ if (flags) {
80
+ clipAncestors.push({
81
+ element: node,
82
+ clipX: flags.clipX,
83
+ clipY: flags.clipY
84
+ });
85
+ scrollContainers.add(node);
86
+ }
87
+ }
88
+ if (node === ((_node_ownerDocument = node.ownerDocument) === null || _node_ownerDocument === void 0 ? void 0 : _node_ownerDocument.documentElement)) {
89
+ break;
90
+ }
91
+ node = node.parentNode;
92
+ }
93
+ var doc = anchor.ownerDocument;
94
+ var documentElement = (_ref = doc === null || doc === void 0 ? void 0 : doc.documentElement) !== null && _ref !== void 0 ? _ref : document.documentElement;
95
+ scrollContainers.add(documentElement);
96
+ if (extraRoot) {
97
+ scrollContainers.add(extraRoot);
98
+ }
99
+ return {
100
+ clipAncestors: clipAncestors,
101
+ scrollContainers: _to_consumable_array$2(scrollContainers),
102
+ firstScrollContainer: (_ref1 = (_clipAncestors_ = clipAncestors[0]) === null || _clipAncestors_ === void 0 ? void 0 : _clipAncestors_.element) !== null && _ref1 !== void 0 ? _ref1 : documentElement
103
+ };
104
+ }
105
+ function intersectRect(a, b) {
106
+ var left = Math.max(a.left, b.left);
107
+ var top = Math.max(a.top, b.top);
108
+ var right = Math.min(rectRight(a), rectRight(b));
109
+ var bottom = Math.min(rectBottom(a), rectBottom(b));
110
+ if (left >= right || top >= bottom) {
111
+ return null;
112
+ }
113
+ return {
114
+ left: left,
115
+ top: top,
116
+ width: right - left,
117
+ height: bottom - top
118
+ };
119
+ }
120
+ function rectContainsPoint(rect, x, y) {
121
+ return x >= rect.left && x <= rectRight(rect) && y >= rect.top && y <= rectBottom(rect);
122
+ }
123
+ function intersectRectWithClipAncestor(ancestor, visible) {
124
+ var el = ancestor.element;
125
+ var border = el.getBoundingClientRect();
126
+ var left = visible.left;
127
+ var top = visible.top;
128
+ var right = rectRight(visible);
129
+ var bottom = rectBottom(visible);
130
+ if (ancestor.clipX) {
131
+ var clipLeft = border.left + el.clientLeft;
132
+ var clipRight = clipLeft + el.clientWidth;
133
+ left = Math.max(left, clipLeft);
134
+ right = Math.min(right, clipRight);
135
+ }
136
+ if (ancestor.clipY) {
137
+ var clipTop = border.top + el.clientTop;
138
+ var clipBottom = clipTop + el.clientHeight;
139
+ top = Math.max(top, clipTop);
140
+ bottom = Math.min(bottom, clipBottom);
141
+ }
142
+ if (left >= right || top >= bottom) {
143
+ return null;
144
+ }
145
+ return {
146
+ left: left,
147
+ top: top,
148
+ width: right - left,
149
+ height: bottom - top
150
+ };
151
+ }
152
+ function getVisibleRectInOverflowClipsFromAncestors(rect, clipAncestors) {
153
+ var visible = rect;
154
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
155
+ try {
156
+ for(var _iterator = clipAncestors[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
157
+ var ancestor = _step.value;
158
+ var next = intersectRectWithClipAncestor(ancestor, visible);
159
+ if (!next) {
160
+ return null;
161
+ }
162
+ visible = next;
163
+ }
164
+ } catch (err) {
165
+ _didIteratorError = true;
166
+ _iteratorError = err;
167
+ } finally{
168
+ try {
169
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
170
+ _iterator.return();
171
+ }
172
+ } finally{
173
+ if (_didIteratorError) {
174
+ throw _iteratorError;
175
+ }
176
+ }
177
+ }
178
+ return visible;
179
+ }
180
+ /** 锚点是否被 CSS 隐藏(opacity / visibility 等);不做点命中,避免 mask 层挡住误判 */ function isCaretAnchorCssVisible(anchor) {
181
+ var anchorEl = anchor.nodeType === Node.ELEMENT_NODE ? anchor : anchor.parentElement;
182
+ if (!(anchorEl === null || anchorEl === void 0 ? void 0 : anchorEl.isConnected)) {
183
+ return false;
184
+ }
185
+ if (typeof anchorEl.checkVisibility === 'function') {
186
+ return anchorEl.checkVisibility({
187
+ checkOpacity: true,
188
+ checkVisibilityCSS: true
189
+ });
190
+ }
191
+ return true;
192
+ }
193
+ var CLIP_INSET_EPSILON = 0.5;
194
+ function clipPathInsetFromVisibleRegion(elRect, visible) {
195
+ var top = Math.max(0, visible.top - elRect.top);
196
+ var left = Math.max(0, visible.left - elRect.left);
197
+ var bottom = Math.max(0, rectBottom(elRect) - rectBottom(visible));
198
+ var right = Math.max(0, rectRight(elRect) - rectRight(visible));
199
+ if (top < CLIP_INSET_EPSILON && left < CLIP_INSET_EPSILON && bottom < CLIP_INSET_EPSILON && right < CLIP_INSET_EPSILON) {
200
+ return 'none';
201
+ }
202
+ return "inset(".concat(top, "px ").concat(right, "px ").concat(bottom, "px ").concat(left, "px)");
203
+ }
204
+ /** 根据行高与内容矩形计算光标盒高度与顶部(视口坐标) */ function measureCaretBoxLayout(contentRect, style) {
205
+ var fontSize = style.fontSize, lineHeight = style.lineHeight;
206
+ var height;
207
+ if (isNaN(+lineHeight)) {
208
+ var f = parseFloat(lineHeight);
209
+ height = isNaN(f) ? parseFloat(fontSize) : f;
210
+ } else {
211
+ height = parseFloat(fontSize) * parseFloat(lineHeight);
212
+ }
213
+ var boxHeight = Math.max(Math.floor(Math.max(height, contentRect.height)), 12);
214
+ var rectTop = contentRect.top;
215
+ if (contentRect.height < height) {
216
+ rectTop -= (height - contentRect.height) / 2;
217
+ }
218
+ return {
219
+ boxHeight: boxHeight,
220
+ rectTop: Math.floor(rectTop)
221
+ };
222
+ }
223
+ /** 测量行内旋转角度(writing-mode 继承) */ function measureInlineCaretRotate(node, initialRotate, writingMode) {
224
+ var rotate = initialRotate;
225
+ if (rotate !== 0) {
226
+ var hackEle = document.createElement('span');
227
+ hackEle.style.cssText = 'display: inline-block; width: 10px; height: 10px; position: relative; contain: layout style size; writing-mode: inherit';
228
+ var pointEle = document.createElement('span');
229
+ pointEle.style.cssText = 'position: absolute; left: 0; top: 0; width:0;height:0';
230
+ hackEle.append(pointEle);
231
+ node.append(hackEle);
232
+ var p1 = pointEle.getBoundingClientRect();
233
+ pointEle.style.right = '0';
234
+ pointEle.style.left = '';
235
+ var p2 = pointEle.getBoundingClientRect();
236
+ rotate = Math.atan2(p1.y - p2.y, p1.x - p2.x) * 180 / Math.PI;
237
+ hackEle.remove();
238
+ }
239
+ if (writingMode === 'vertical-lr' || writingMode === 'vertical-rl') {
240
+ rotate += 90;
241
+ }
242
+ return rotate;
243
+ }
244
+ /**
245
+ * 在 element 样式已写入后调用:计算裁剪、是否移出视口及对外事件数据。
246
+ */ function computeCaretPresentation(options) {
247
+ var anchor = options.anchor, maskRect = options.maskRect, clipAncestors = options.clipAncestors, maskLeft = options.maskLeft, maskTop = options.maskTop, boxHeight = options.boxHeight, rectTop = options.rectTop, contentRect = options.contentRect, fontSize = options.fontSize, color = options.color, measureElementRect = options.measureElementRect;
248
+ var caretCenterX = contentRect.left + contentRect.width / 2;
249
+ var caretCenterY = rectTop + boxHeight / 2;
250
+ var layoutElRect = {
251
+ left: maskRect.left + maskLeft,
252
+ top: maskRect.top + maskTop,
253
+ width: 2,
254
+ height: boxHeight
255
+ };
256
+ var visibleRect = getVisibleRectInOverflowClipsFromAncestors(layoutElRect, clipAncestors);
257
+ visibleRect = visibleRect ? intersectRect(visibleRect, maskRect) : null;
258
+ var inClipBounds = !!visibleRect && rectContainsPoint(visibleRect, caretCenterX, caretCenterY);
259
+ var outOfView = !inClipBounds || !isCaretAnchorCssVisible(anchor);
260
+ var clipPath = 'none';
261
+ if (!outOfView && visibleRect) {
262
+ clipPath = clipPathInsetFromVisibleRegion(measureElementRect(), visibleRect);
263
+ }
264
+ return {
265
+ outOfView: outOfView,
266
+ clipPath: clipPath,
267
+ layoutElRect: layoutElRect,
268
+ position: {
269
+ left: maskLeft,
270
+ top: rectTop,
271
+ height: boxHeight
272
+ },
273
+ caretColor: color === 'rgba(0, 0, 0, 0)' ? '#000' : color,
274
+ style: {
275
+ height: boxHeight + 'px',
276
+ lineHeight: boxHeight + 'px',
277
+ fontSize: fontSize
278
+ }
279
+ };
280
+ }
32
281
  function createElement(tagName) {
33
282
  var options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
34
283
  var el = document.createElement(tagName);
@@ -209,7 +458,7 @@ function _define_property$6(obj, key, value) {
209
458
  }
210
459
  return obj;
211
460
  }
212
- function _instanceof$4(left, right) {
461
+ function _instanceof$3(left, right) {
213
462
  "@swc/helpers - instanceof";
214
463
  if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
215
464
  return !!right[Symbol.hasInstance](left);
@@ -316,7 +565,7 @@ var Parser = /*#__PURE__*/ function() {
316
565
  if (!result) {
317
566
  return;
318
567
  }
319
- if (_instanceof$4(result, Slot)) {
568
+ if (_instanceof$3(result, Slot)) {
320
569
  result.toDelta().forEach(function(i) {
321
570
  return slot.insert(i.insert, i.formats);
322
571
  });
@@ -438,6 +687,15 @@ function _class_call_check$6(instance, Constructor) {
438
687
  throw new TypeError("Cannot call a class as a function");
439
688
  }
440
689
  }
690
+ function caretPositionEqual(a, b) {
691
+ if (a === b) {
692
+ return true;
693
+ }
694
+ if (a === null || b === null) {
695
+ return false;
696
+ }
697
+ return a.left === b.left && a.top === b.top && a.height === b.height;
698
+ }
441
699
  var Input = function Input() {
442
700
  _class_call_check$6(this, Input);
443
701
  };
@@ -522,7 +780,7 @@ var DomAdapter = /*#__PURE__*/ function(Adapter) {
522
780
  _this = _call_super$2(this, DomAdapter, arguments), _define_property$5(_this, "onViewUpdated", new Subject()), _define_property$5(_this, "host", createElement('div', {
523
781
  styles: {
524
782
  cursor: 'text',
525
- wordBreak: 'break-all',
783
+ overflowWrap: 'break-word',
526
784
  boxSizing: 'border-box',
527
785
  flex: 1,
528
786
  outline: 'none'
@@ -570,7 +828,7 @@ function _define_property$4(obj, key, value) {
570
828
  }
571
829
  return obj;
572
830
  }
573
- function _instanceof$3(left, right) {
831
+ function _instanceof$2(left, right) {
574
832
  "@swc/helpers - instanceof";
575
833
  if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
576
834
  return !!right[Symbol.hasInstance](left);
@@ -1077,7 +1335,7 @@ var SelectionBridge = /*#__PURE__*/ function() {
1077
1335
  try {
1078
1336
  for(var _iterator = nodes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1079
1337
  var node = _step.value;
1080
- if (_instanceof$3(node, Text)) {
1338
+ if (_instanceof$2(node, Text)) {
1081
1339
  continue;
1082
1340
  }
1083
1341
  if (node.nodeName === 'BR') {
@@ -1121,7 +1379,7 @@ var SelectionBridge = /*#__PURE__*/ function() {
1121
1379
  try {
1122
1380
  for(var _iterator1 = nodes[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
1123
1381
  var node1 = _step1.value;
1124
- if (_instanceof$3(node1, Element)) {
1382
+ if (_instanceof$2(node1, Element)) {
1125
1383
  if (node1.tagName === 'BR') {
1126
1384
  var position1 = this.domAdapter.getLocationByNativeNode(node1);
1127
1385
  if (position1) {
@@ -1349,14 +1607,6 @@ function _inherits$1(subClass, superClass) {
1349
1607
  });
1350
1608
  if (superClass) _set_prototype_of$1(subClass, superClass);
1351
1609
  }
1352
- function _instanceof$2(left, right) {
1353
- "@swc/helpers - instanceof";
1354
- if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
1355
- return !!right[Symbol.hasInstance](left);
1356
- } else {
1357
- return left instanceof right;
1358
- }
1359
- }
1360
1610
  function _possible_constructor_return$1(self, call) {
1361
1611
  if (call && (_type_of$1(call) === "object" || typeof call === "function")) {
1362
1612
  return call;
@@ -1408,7 +1658,13 @@ var ExperimentalCaret = /*#__PURE__*/ function() {
1408
1658
  _define_property$3(this, "caret", void 0);
1409
1659
  _define_property$3(this, "_display", void 0);
1410
1660
  _define_property$3(this, "flashing", void 0);
1661
+ /** 被 overflow 裁出可视区(不用 display:none,避免触发 Input.hide) */ _define_property$3(this, "caretClippedOut", void 0);
1411
1662
  _define_property$3(this, "subscription", void 0);
1663
+ _define_property$3(this, "scrollSubscription", void 0);
1664
+ _define_property$3(this, "scrollRaf", void 0);
1665
+ _define_property$3(this, "clipContext", void 0);
1666
+ _define_property$3(this, "clipContextAnchor", void 0);
1667
+ _define_property$3(this, "scrollListenerAnchor", void 0);
1412
1668
  _define_property$3(this, "positionChangeEvent", void 0);
1413
1669
  _define_property$3(this, "styleChangeEvent", void 0);
1414
1670
  _define_property$3(this, "oldRange", void 0);
@@ -1425,11 +1681,17 @@ var ExperimentalCaret = /*#__PURE__*/ function() {
1425
1681
  this.timer = null;
1426
1682
  this._display = true;
1427
1683
  this.flashing = true;
1684
+ this.caretClippedOut = false;
1428
1685
  this.subscription = new Subscription();
1686
+ this.scrollSubscription = new Subscription();
1687
+ this.scrollRaf = 0;
1688
+ this.clipContext = null;
1689
+ this.clipContextAnchor = null;
1690
+ this.scrollListenerAnchor = null;
1429
1691
  this.positionChangeEvent = new Subject();
1430
1692
  this.styleChangeEvent = new Subject();
1431
1693
  this.oldRange = null;
1432
- this.onPositionChange = this.positionChangeEvent.pipe(distinctUntilChanged());
1694
+ this.onPositionChange = this.positionChangeEvent.pipe(distinctUntilChanged(caretPositionEqual));
1433
1695
  this.onStyleChange = this.styleChangeEvent.asObservable();
1434
1696
  this.elementRef = createElement('div', {
1435
1697
  styles: {
@@ -1470,14 +1732,17 @@ var ExperimentalCaret = /*#__PURE__*/ function() {
1470
1732
  },
1471
1733
  set: function set(v) {
1472
1734
  this._display = v;
1473
- this.caret.style.visibility = v ? 'visible' : 'hidden';
1735
+ if (!this.caretClippedOut) {
1736
+ this.caret.style.visibility = v ? 'visible' : 'hidden';
1737
+ }
1474
1738
  }
1475
1739
  },
1476
1740
  {
1477
1741
  key: "refresh",
1478
1742
  value: function refresh() {
1479
- if (this.oldRange) {
1480
- this.show(this.oldRange, false);
1743
+ var _this_oldRange;
1744
+ if ((_this_oldRange = this.oldRange) === null || _this_oldRange === void 0 ? void 0 : _this_oldRange.collapsed) {
1745
+ this.updateCursorPosition(this.oldRange);
1481
1746
  }
1482
1747
  }
1483
1748
  },
@@ -1489,8 +1754,15 @@ var ExperimentalCaret = /*#__PURE__*/ function() {
1489
1754
  if (restart || this.scheduler.lastChangesHasLocalUpdate) {
1490
1755
  clearTimeout(this.timer);
1491
1756
  }
1757
+ if (range.collapsed && (restart || this.scheduler.lastChangesHasLocalUpdate)) {
1758
+ this._display = true;
1759
+ }
1492
1760
  this.updateCursorPosition(range);
1493
1761
  if (range.collapsed) {
1762
+ var anchor = range.startContainer.nodeType === Node.ELEMENT_NODE ? range.startContainer : range.startContainer.parentNode;
1763
+ if (anchor) {
1764
+ this.bindScrollListeners(anchor);
1765
+ }
1494
1766
  if (restart || this.scheduler.lastChangesHasLocalUpdate) {
1495
1767
  this.display = true;
1496
1768
  var toggleShowHide = function toggleShowHide1() {
@@ -1501,6 +1773,7 @@ var ExperimentalCaret = /*#__PURE__*/ function() {
1501
1773
  this.timer = setTimeout(toggleShowHide, 400);
1502
1774
  }
1503
1775
  } else {
1776
+ this.unbindScrollListeners();
1504
1777
  this.display = false;
1505
1778
  clearTimeout(this.timer);
1506
1779
  }
@@ -1509,8 +1782,14 @@ var ExperimentalCaret = /*#__PURE__*/ function() {
1509
1782
  {
1510
1783
  key: "hide",
1511
1784
  value: function hide() {
1785
+ this.unbindScrollListeners();
1786
+ this.clearClipContext();
1512
1787
  this.display = false;
1513
1788
  clearTimeout(this.timer);
1789
+ this.caretClippedOut = false;
1790
+ this.elementRef.style.clipPath = 'none';
1791
+ this.elementRef.style.visibility = '';
1792
+ this.caret.style.visibility = 'hidden';
1514
1793
  this.positionChangeEvent.next(null);
1515
1794
  }
1516
1795
  },
@@ -1518,127 +1797,210 @@ var ExperimentalCaret = /*#__PURE__*/ function() {
1518
1797
  key: "destroy",
1519
1798
  value: function destroy() {
1520
1799
  clearTimeout(this.timer);
1521
- // this.caret.
1800
+ this.unbindScrollListeners();
1522
1801
  this.subscription.unsubscribe();
1523
1802
  }
1524
1803
  },
1804
+ {
1805
+ key: "bindScrollListeners",
1806
+ value: function bindScrollListeners(anchor) {
1807
+ var _this = this;
1808
+ var _anchor_ownerDocument;
1809
+ if (this.scrollListenerAnchor === anchor) {
1810
+ return;
1811
+ }
1812
+ this.unbindScrollListeners();
1813
+ this.scrollListenerAnchor = anchor;
1814
+ var onScroll = function onScroll() {
1815
+ if (!_this.oldRange || _this.scrollRaf) {
1816
+ return;
1817
+ }
1818
+ _this.scrollRaf = requestAnimationFrame(function() {
1819
+ _this.scrollRaf = 0;
1820
+ if (_this.oldRange) {
1821
+ _this.updateCursorPosition(_this.oldRange);
1822
+ }
1823
+ });
1824
+ };
1825
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1826
+ try {
1827
+ for(var _iterator = this.ensureClipContext(anchor).scrollContainers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1828
+ var el = _step.value;
1829
+ this.scrollSubscription.add(fromEvent(el, 'scroll').subscribe(onScroll));
1830
+ }
1831
+ } catch (err) {
1832
+ _didIteratorError = true;
1833
+ _iteratorError = err;
1834
+ } finally{
1835
+ try {
1836
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1837
+ _iterator.return();
1838
+ }
1839
+ } finally{
1840
+ if (_didIteratorError) {
1841
+ throw _iteratorError;
1842
+ }
1843
+ }
1844
+ }
1845
+ var win = (_anchor_ownerDocument = anchor.ownerDocument) === null || _anchor_ownerDocument === void 0 ? void 0 : _anchor_ownerDocument.defaultView;
1846
+ if (win) {
1847
+ this.scrollSubscription.add(fromEvent(win, 'scroll').subscribe(onScroll));
1848
+ }
1849
+ }
1850
+ },
1851
+ {
1852
+ key: "unbindScrollListeners",
1853
+ value: function unbindScrollListeners() {
1854
+ if (this.scrollRaf) {
1855
+ cancelAnimationFrame(this.scrollRaf);
1856
+ this.scrollRaf = 0;
1857
+ }
1858
+ this.scrollSubscription.unsubscribe();
1859
+ this.scrollSubscription = new Subscription();
1860
+ this.scrollListenerAnchor = null;
1861
+ }
1862
+ },
1863
+ {
1864
+ key: "ensureClipContext",
1865
+ value: function ensureClipContext(anchor) {
1866
+ if (this.clipContextAnchor !== anchor) {
1867
+ this.clipContextAnchor = anchor;
1868
+ this.clipContext = getOverflowClipContext(anchor, this.editorMask);
1869
+ }
1870
+ return this.clipContext;
1871
+ }
1872
+ },
1873
+ {
1874
+ key: "clearClipContext",
1875
+ value: function clearClipContext() {
1876
+ this.clipContext = null;
1877
+ this.clipContextAnchor = null;
1878
+ }
1879
+ },
1525
1880
  {
1526
1881
  key: "updateCursorPosition",
1527
1882
  value: function updateCursorPosition(nativeRange) {
1528
- var startContainer = nativeRange.startContainer;
1529
- var node = startContainer.nodeType === Node.ELEMENT_NODE ? startContainer : startContainer.parentNode;
1530
- if ((node === null || node === void 0 ? void 0 : node.nodeType) !== Node.ELEMENT_NODE) {
1883
+ var _this = this;
1884
+ var node = this.resolveCaretAnchor(nativeRange);
1885
+ if (!node) {
1531
1886
  this.positionChangeEvent.next(null);
1532
1887
  return;
1533
1888
  }
1534
- var compositionNode = this.domRenderer.compositionNode;
1535
- if (compositionNode) {
1536
- nativeRange = nativeRange.cloneRange();
1537
- nativeRange.selectNodeContents(compositionNode);
1538
- nativeRange.collapse();
1539
- }
1889
+ nativeRange = this.normalizeCollapsedRange(nativeRange);
1540
1890
  this.caret.style.display = nativeRange.collapsed ? 'block' : 'none';
1541
1891
  if (!nativeRange.collapsed) {
1542
1892
  return;
1543
1893
  }
1544
- var rect = getLayoutRectByRange(nativeRange);
1545
- var _getComputedStyle = getComputedStyle(node), fontSize = _getComputedStyle.fontSize, lineHeight = _getComputedStyle.lineHeight, color = _getComputedStyle.color, writingMode = _getComputedStyle.writingMode;
1546
- var height;
1547
- if (isNaN(+lineHeight)) {
1548
- var f = parseFloat(lineHeight);
1549
- if (isNaN(f)) {
1550
- height = parseFloat(fontSize);
1551
- } else {
1552
- height = f;
1894
+ var contentRect = getLayoutRectByRange(nativeRange);
1895
+ var nodeStyle = getComputedStyle(node);
1896
+ var _measureCaretBoxLayout = measureCaretBoxLayout(contentRect, nodeStyle), boxHeight = _measureCaretBoxLayout.boxHeight, rectTop = _measureCaretBoxLayout.rectTop;
1897
+ var maskRect = this.editorMask.getBoundingClientRect();
1898
+ var clipContext = this.ensureClipContext(node);
1899
+ var maskLeft = Math.floor(contentRect.left + contentRect.width / 2 - maskRect.left);
1900
+ var maskTop = Math.floor(rectTop - maskRect.top);
1901
+ var initialRotate = Math.round(Math.atan2(contentRect.width, contentRect.height) * 180 / Math.PI);
1902
+ var rotate = measureInlineCaretRotate(node, initialRotate, nodeStyle.writingMode);
1903
+ this.applyCaretElementLayout(maskLeft, maskTop, boxHeight, nodeStyle.fontSize, rotate);
1904
+ var presentation = computeCaretPresentation({
1905
+ anchor: node,
1906
+ maskRect: maskRect,
1907
+ clipAncestors: clipContext.clipAncestors,
1908
+ maskLeft: maskLeft,
1909
+ maskTop: maskTop,
1910
+ boxHeight: boxHeight,
1911
+ rectTop: rectTop,
1912
+ contentRect: contentRect,
1913
+ fontSize: nodeStyle.fontSize,
1914
+ color: nodeStyle.color,
1915
+ measureElementRect: function measureElementRect() {
1916
+ return _this.elementRef.getBoundingClientRect();
1553
1917
  }
1554
- } else {
1555
- height = parseFloat(fontSize) * parseFloat(lineHeight);
1556
- }
1557
- var boxHeight = Math.max(Math.floor(Math.max(height, rect.height)), 12);
1558
- // const boxHeight = Math.floor(height)
1559
- var rectTop = rect.top;
1560
- if (rect.height < height) {
1561
- rectTop -= (height - rect.height) / 2;
1562
- }
1563
- rectTop = Math.floor(rectTop);
1564
- var containerRect = this.editorMask.getBoundingClientRect();
1565
- var top = Math.floor(rectTop - containerRect.top);
1566
- var left = Math.floor(rect.left + rect.width / 2 - containerRect.left);
1567
- var rotate = 0;
1568
- if (nativeRange.collapsed) {
1569
- rotate = Math.round(Math.atan2(rect.width, rect.height) * 180 / Math.PI);
1570
- if (rotate !== 0) {
1571
- var hackEle = document.createElement('span');
1572
- // eslint-disable-next-line max-len
1573
- hackEle.style.cssText = 'display: inline-block; width: 10px; height: 10px; position: relative; contain: layout style size; writing-mode: inherit';
1574
- var pointEle = document.createElement('span');
1575
- pointEle.style.cssText = 'position: absolute; left: 0; top: 0; width:0;height:0';
1576
- hackEle.append(pointEle);
1577
- node.append(hackEle);
1578
- var p1 = pointEle.getBoundingClientRect();
1579
- pointEle.style.right = '0';
1580
- pointEle.style.left = '';
1581
- var p2 = pointEle.getBoundingClientRect();
1582
- var x = p1.x - p2.x;
1583
- var y = p1.y - p2.y;
1584
- rotate = Math.atan2(y, x) * 180 / Math.PI;
1585
- hackEle.remove();
1586
- }
1587
- }
1588
- if (writingMode === 'vertical-lr' || writingMode === 'vertical-rl') {
1589
- rotate += 90;
1918
+ });
1919
+ this.applyCaretPresentation(presentation);
1920
+ this.emitCaretPresentation(presentation);
1921
+ this.scrollCaretIntoViewIfNeeded(presentation.layoutElRect, clipContext);
1922
+ }
1923
+ },
1924
+ {
1925
+ key: "resolveCaretAnchor",
1926
+ value: function resolveCaretAnchor(nativeRange) {
1927
+ var startContainer = nativeRange.startContainer;
1928
+ var node = startContainer.nodeType === Node.ELEMENT_NODE ? startContainer : startContainer.parentNode;
1929
+ return (node === null || node === void 0 ? void 0 : node.nodeType) === Node.ELEMENT_NODE ? node : null;
1930
+ }
1931
+ },
1932
+ {
1933
+ key: "normalizeCollapsedRange",
1934
+ value: function normalizeCollapsedRange(nativeRange) {
1935
+ var compositionNode = this.domRenderer.compositionNode;
1936
+ if (!compositionNode) {
1937
+ return nativeRange;
1590
1938
  }
1939
+ var range = nativeRange.cloneRange();
1940
+ range.selectNodeContents(compositionNode);
1941
+ range.collapse();
1942
+ return range;
1943
+ }
1944
+ },
1945
+ {
1946
+ key: "applyCaretElementLayout",
1947
+ value: function applyCaretElementLayout(maskLeft, maskTop, boxHeight, fontSize, rotate) {
1591
1948
  Object.assign(this.elementRef.style, {
1592
- left: left + 'px',
1593
- top: top + 'px',
1949
+ left: maskLeft + 'px',
1950
+ top: maskTop + 'px',
1594
1951
  height: boxHeight + 'px',
1595
1952
  lineHeight: boxHeight + 'px',
1596
1953
  fontSize: fontSize,
1597
1954
  transform: "rotate(".concat(rotate, "deg)")
1598
1955
  });
1599
- this.caret.style.backgroundColor = color === 'rgba(0, 0, 0, 0)' ? '#000' : color;
1600
- this.styleChangeEvent.next({
1601
- height: boxHeight + 'px',
1602
- lineHeight: boxHeight + 'px',
1603
- fontSize: fontSize
1604
- });
1605
- this.positionChangeEvent.next({
1606
- left: left,
1607
- top: rectTop,
1608
- height: boxHeight
1609
- });
1610
- if (this.changeFromSelf) {
1611
- this.changeFromSelf = false;
1612
- var selfRect = this.elementRef.getBoundingClientRect();
1613
- var scrollContainer = this.getScrollContainer(startContainer);
1614
- var scrollRect = scrollContainer === document.documentElement ? {
1615
- top: 0,
1616
- bottom: document.documentElement.clientHeight
1617
- } : scrollContainer.getBoundingClientRect();
1618
- var limit = this.getLimit();
1619
- var top1 = Math.max(limit.top, scrollRect.top);
1620
- var bottom = Math.min(limit.bottom, scrollRect.bottom);
1621
- if (selfRect.top < top1) {
1622
- scrollContainer.scrollTop -= top1 - selfRect.top;
1623
- } else if (selfRect.bottom > bottom) {
1624
- scrollContainer.scrollTop += selfRect.bottom - bottom;
1625
- }
1956
+ }
1957
+ },
1958
+ {
1959
+ key: "applyCaretPresentation",
1960
+ value: function applyCaretPresentation(presentation) {
1961
+ this.caretClippedOut = presentation.outOfView;
1962
+ if (presentation.outOfView) {
1963
+ this.elementRef.style.clipPath = 'none';
1964
+ this.elementRef.style.visibility = 'hidden';
1965
+ this.caret.style.visibility = 'hidden';
1966
+ } else {
1967
+ this.elementRef.style.clipPath = presentation.clipPath;
1968
+ this.elementRef.style.visibility = '';
1969
+ this.caret.style.visibility = this._display ? 'visible' : 'hidden';
1626
1970
  }
1971
+ this.caret.style.backgroundColor = presentation.caretColor;
1627
1972
  }
1628
1973
  },
1629
1974
  {
1630
- key: "getScrollContainer",
1631
- value: function getScrollContainer(container) {
1632
- while(container){
1633
- if (_instanceof$2(container, Element)) {
1634
- var styles = getComputedStyle(container);
1635
- if (styles.overflow !== 'visible' || styles.overflowX !== 'visible' || styles.overflowY !== 'visible') {
1636
- return container;
1637
- }
1638
- }
1639
- container = container.parentNode;
1975
+ key: "emitCaretPresentation",
1976
+ value: function emitCaretPresentation(presentation) {
1977
+ this.styleChangeEvent.next(presentation.style);
1978
+ this.positionChangeEvent.next(presentation.position);
1979
+ }
1980
+ },
1981
+ {
1982
+ key: "scrollCaretIntoViewIfNeeded",
1983
+ value: function scrollCaretIntoViewIfNeeded(layoutElRect, clipContext) {
1984
+ var _scrollContainer_ownerDocument;
1985
+ if (!this.changeFromSelf) {
1986
+ return;
1987
+ }
1988
+ this.changeFromSelf = false;
1989
+ var scrollContainer = clipContext.firstScrollContainer;
1990
+ var doc = (_scrollContainer_ownerDocument = scrollContainer.ownerDocument) !== null && _scrollContainer_ownerDocument !== void 0 ? _scrollContainer_ownerDocument : document;
1991
+ var scrollRect = scrollContainer === doc.documentElement ? {
1992
+ top: 0,
1993
+ bottom: doc.documentElement.clientHeight
1994
+ } : scrollContainer.getBoundingClientRect();
1995
+ var limit = this.getLimit();
1996
+ var scrollTop = Math.max(limit.top, scrollRect.top);
1997
+ var scrollBottom = Math.min(limit.bottom, scrollRect.bottom);
1998
+ var layoutBottom = layoutElRect.top + layoutElRect.height;
1999
+ if (layoutElRect.top < scrollTop) {
2000
+ scrollContainer.scrollTop -= scrollTop - layoutElRect.top;
2001
+ } else if (layoutBottom > scrollBottom) {
2002
+ scrollContainer.scrollTop += layoutBottom - scrollBottom;
1640
2003
  }
1641
- return document.documentElement;
1642
2004
  }
1643
2005
  }
1644
2006
  ]);
@@ -2534,7 +2896,7 @@ var NativeCaret = /*#__PURE__*/ function() {
2534
2896
  _define_property$1(this, "_nativeRange", null);
2535
2897
  _define_property$1(this, "subs", []);
2536
2898
  _define_property$1(this, "positionChangeEvent", new Subject());
2537
- this.onPositionChange = this.positionChangeEvent.pipe(distinctUntilChanged());
2899
+ this.onPositionChange = this.positionChangeEvent.pipe(distinctUntilChanged(caretPositionEqual));
2538
2900
  }
2539
2901
  _create_class$1(NativeCaret, [
2540
2902
  {
@@ -3379,5 +3741,5 @@ var BrowserModule = /*#__PURE__*/ function() {
3379
3741
  return BrowserModule;
3380
3742
  }();
3381
3743
 
3382
- export { BrowserModule, CollaborateCursor, CollaborateSelectionAwarenessDelegate, DomAdapter, EDITOR_OPTIONS, Input, MagicInput, NativeInput, Parser, SelectionBridge, VIEW_CONTAINER, VIEW_DOCUMENT, VIEW_MASK, createElement, getLayoutRectByRange, isFirefox, isMac, isMobileBrowser, isSafari, isWindows };
3744
+ export { BrowserModule, CollaborateCursor, CollaborateSelectionAwarenessDelegate, DomAdapter, EDITOR_OPTIONS, Input, MagicInput, NativeInput, Parser, SelectionBridge, VIEW_CONTAINER, VIEW_DOCUMENT, VIEW_MASK, caretPositionEqual, computeCaretPresentation, createElement, getLayoutRectByRange, getOverflowClipContext, isFirefox, isMac, isMobileBrowser, isSafari, isWindows, measureCaretBoxLayout, measureInlineCaretRotate };
3383
3745
  //# sourceMappingURL=index.esm.js.map