@blankdotpage/cake 0.1.4 → 0.1.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.
@@ -56,6 +56,7 @@ export declare class CakeEngine {
56
56
  private spellCheckEnabled;
57
57
  private extensionsRoot;
58
58
  private placeholderRoot;
59
+ private resizeObserver;
59
60
  private lastFocusRect;
60
61
  private verticalNavGoalX;
61
62
  private lastRenderPerf;
@@ -89,6 +90,7 @@ export declare class CakeEngine {
89
90
  private pointerDownPosition;
90
91
  private hasMovedSincePointerDown;
91
92
  private lastTouchTime;
93
+ private isTouchDevice;
92
94
  constructor(options: EngineOptions);
93
95
  destroy(): void;
94
96
  setReadOnly(readOnly: boolean): void;
@@ -126,7 +128,7 @@ export declare class CakeEngine {
126
128
  private render;
127
129
  private isEmptyParagraphDoc;
128
130
  private updatePlaceholder;
129
- private syncPlaceholderPadding;
131
+ private syncPlaceholderPosition;
130
132
  private updateContentRootAttributes;
131
133
  private applySelection;
132
134
  private handleSelectionChange;
package/dist/index.cjs CHANGED
@@ -7627,6 +7627,7 @@ class CakeEngine {
7627
7627
  this.lastSelectionRects = null;
7628
7628
  this.extensionsRoot = null;
7629
7629
  this.placeholderRoot = null;
7630
+ this.resizeObserver = null;
7630
7631
  this.lastFocusRect = null;
7631
7632
  this.verticalNavGoalX = null;
7632
7633
  this.lastRenderPerf = null;
@@ -7696,6 +7697,11 @@ class CakeEngine {
7696
7697
  }
7697
7698
  return target instanceof Node && (target === this.contentRoot || this.contentRoot.contains(target));
7698
7699
  }
7700
+ // Detect if this is a touch-primary device (mobile/tablet)
7701
+ // We check for touch support AND coarse pointer to exclude laptops with touchscreens
7702
+ isTouchDevice() {
7703
+ return "ontouchstart" in window && window.matchMedia("(pointer: coarse)").matches;
7704
+ }
7699
7705
  destroy() {
7700
7706
  this.detachListeners();
7701
7707
  this.uninstallCaretRangeFromPointShim();
@@ -7890,6 +7896,11 @@ class CakeEngine {
7890
7896
  );
7891
7897
  this.container.addEventListener("scroll", this.handleScrollBound);
7892
7898
  window.addEventListener("resize", this.handleResizeBound);
7899
+ this.resizeObserver = new ResizeObserver(() => {
7900
+ this.syncPlaceholderPosition();
7901
+ this.scheduleOverlayUpdate();
7902
+ });
7903
+ this.resizeObserver.observe(this.container);
7893
7904
  this.container.addEventListener("click", this.handleClickBound);
7894
7905
  this.container.addEventListener("keydown", this.handleKeyDownBound);
7895
7906
  this.container.addEventListener("paste", this.handlePasteBound);
@@ -7921,6 +7932,7 @@ class CakeEngine {
7921
7932
  this.contentRoot.removeEventListener("dragend", this.handleDragEndBound);
7922
7933
  }
7923
7934
  detachListeners() {
7935
+ var _a;
7924
7936
  this.container.removeEventListener(
7925
7937
  "beforeinput",
7926
7938
  this.handleBeforeInputBound
@@ -7940,6 +7952,8 @@ class CakeEngine {
7940
7952
  );
7941
7953
  this.container.removeEventListener("scroll", this.handleScrollBound);
7942
7954
  window.removeEventListener("resize", this.handleResizeBound);
7955
+ (_a = this.resizeObserver) == null ? void 0 : _a.disconnect();
7956
+ this.resizeObserver = null;
7943
7957
  this.container.removeEventListener("click", this.handleClickBound);
7944
7958
  this.container.removeEventListener("keydown", this.handleKeyDownBound);
7945
7959
  this.container.removeEventListener("paste", this.handlePasteBound);
@@ -8048,6 +8062,9 @@ class CakeEngine {
8048
8062
  }
8049
8063
  this.contentRoot = document.createElement("div");
8050
8064
  this.contentRoot.className = "cake-content";
8065
+ if (this.isTouchDevice()) {
8066
+ this.contentRoot.classList.add("cake-touch-mode");
8067
+ }
8051
8068
  this.updateContentRootAttributes();
8052
8069
  const overlay = this.ensureOverlayRoot();
8053
8070
  const extensionsRoot = this.ensureExtensionsRoot();
@@ -8118,6 +8135,8 @@ class CakeEngine {
8118
8135
  if (!this.placeholderRoot) {
8119
8136
  this.placeholderRoot = document.createElement("div");
8120
8137
  this.placeholderRoot.className = "cake-placeholder";
8138
+ this.placeholderRoot.style.position = "absolute";
8139
+ this.placeholderRoot.style.pointerEvents = "none";
8121
8140
  }
8122
8141
  if (!shouldShow) {
8123
8142
  if (this.placeholderRoot.isConnected) {
@@ -8127,20 +8146,21 @@ class CakeEngine {
8127
8146
  return;
8128
8147
  }
8129
8148
  this.placeholderRoot.textContent = placeholderText ?? "";
8130
- this.syncPlaceholderPadding();
8131
8149
  if (!this.placeholderRoot.isConnected) {
8132
8150
  this.container.prepend(this.placeholderRoot);
8133
8151
  }
8152
+ this.syncPlaceholderPosition();
8134
8153
  }
8135
- syncPlaceholderPadding() {
8136
- if (!this.placeholderRoot) {
8154
+ syncPlaceholderPosition() {
8155
+ if (!this.placeholderRoot || !this.contentRoot) {
8137
8156
  return;
8138
8157
  }
8139
- const style = window.getComputedStyle(this.container);
8140
- this.placeholderRoot.style.paddingTop = style.paddingTop;
8141
- this.placeholderRoot.style.paddingRight = style.paddingRight;
8142
- this.placeholderRoot.style.paddingBottom = style.paddingBottom;
8143
- this.placeholderRoot.style.paddingLeft = style.paddingLeft;
8158
+ const containerRect = this.container.getBoundingClientRect();
8159
+ const contentRect = this.contentRoot.getBoundingClientRect();
8160
+ this.placeholderRoot.style.top = `${contentRect.top - containerRect.top}px`;
8161
+ this.placeholderRoot.style.left = `${contentRect.left - containerRect.left}px`;
8162
+ this.placeholderRoot.style.width = `${contentRect.width}px`;
8163
+ this.placeholderRoot.style.height = `${contentRect.height}px`;
8144
8164
  }
8145
8165
  updateContentRootAttributes() {
8146
8166
  if (!this.contentRoot) {
@@ -10075,8 +10095,13 @@ class CakeEngine {
10075
10095
  if (!this.overlayRoot || !this.contentRoot) {
10076
10096
  return;
10077
10097
  }
10098
+ if (!this.hasFocus()) {
10099
+ this.updateCaret(null);
10100
+ this.syncSelectionRects([]);
10101
+ return;
10102
+ }
10078
10103
  const isRecentTouch = Date.now() - this.lastTouchTime < 2e3;
10079
- if (isRecentTouch) {
10104
+ if (this.isTouchDevice() || isRecentTouch) {
10080
10105
  this.contentRoot.classList.add("cake-touch-mode");
10081
10106
  this.updateCaret(null);
10082
10107
  this.syncSelectionRects([]);
package/dist/index.js CHANGED
@@ -7625,6 +7625,7 @@ class CakeEngine {
7625
7625
  this.lastSelectionRects = null;
7626
7626
  this.extensionsRoot = null;
7627
7627
  this.placeholderRoot = null;
7628
+ this.resizeObserver = null;
7628
7629
  this.lastFocusRect = null;
7629
7630
  this.verticalNavGoalX = null;
7630
7631
  this.lastRenderPerf = null;
@@ -7694,6 +7695,11 @@ class CakeEngine {
7694
7695
  }
7695
7696
  return target instanceof Node && (target === this.contentRoot || this.contentRoot.contains(target));
7696
7697
  }
7698
+ // Detect if this is a touch-primary device (mobile/tablet)
7699
+ // We check for touch support AND coarse pointer to exclude laptops with touchscreens
7700
+ isTouchDevice() {
7701
+ return "ontouchstart" in window && window.matchMedia("(pointer: coarse)").matches;
7702
+ }
7697
7703
  destroy() {
7698
7704
  this.detachListeners();
7699
7705
  this.uninstallCaretRangeFromPointShim();
@@ -7888,6 +7894,11 @@ class CakeEngine {
7888
7894
  );
7889
7895
  this.container.addEventListener("scroll", this.handleScrollBound);
7890
7896
  window.addEventListener("resize", this.handleResizeBound);
7897
+ this.resizeObserver = new ResizeObserver(() => {
7898
+ this.syncPlaceholderPosition();
7899
+ this.scheduleOverlayUpdate();
7900
+ });
7901
+ this.resizeObserver.observe(this.container);
7891
7902
  this.container.addEventListener("click", this.handleClickBound);
7892
7903
  this.container.addEventListener("keydown", this.handleKeyDownBound);
7893
7904
  this.container.addEventListener("paste", this.handlePasteBound);
@@ -7919,6 +7930,7 @@ class CakeEngine {
7919
7930
  this.contentRoot.removeEventListener("dragend", this.handleDragEndBound);
7920
7931
  }
7921
7932
  detachListeners() {
7933
+ var _a;
7922
7934
  this.container.removeEventListener(
7923
7935
  "beforeinput",
7924
7936
  this.handleBeforeInputBound
@@ -7938,6 +7950,8 @@ class CakeEngine {
7938
7950
  );
7939
7951
  this.container.removeEventListener("scroll", this.handleScrollBound);
7940
7952
  window.removeEventListener("resize", this.handleResizeBound);
7953
+ (_a = this.resizeObserver) == null ? void 0 : _a.disconnect();
7954
+ this.resizeObserver = null;
7941
7955
  this.container.removeEventListener("click", this.handleClickBound);
7942
7956
  this.container.removeEventListener("keydown", this.handleKeyDownBound);
7943
7957
  this.container.removeEventListener("paste", this.handlePasteBound);
@@ -8046,6 +8060,9 @@ class CakeEngine {
8046
8060
  }
8047
8061
  this.contentRoot = document.createElement("div");
8048
8062
  this.contentRoot.className = "cake-content";
8063
+ if (this.isTouchDevice()) {
8064
+ this.contentRoot.classList.add("cake-touch-mode");
8065
+ }
8049
8066
  this.updateContentRootAttributes();
8050
8067
  const overlay = this.ensureOverlayRoot();
8051
8068
  const extensionsRoot = this.ensureExtensionsRoot();
@@ -8116,6 +8133,8 @@ class CakeEngine {
8116
8133
  if (!this.placeholderRoot) {
8117
8134
  this.placeholderRoot = document.createElement("div");
8118
8135
  this.placeholderRoot.className = "cake-placeholder";
8136
+ this.placeholderRoot.style.position = "absolute";
8137
+ this.placeholderRoot.style.pointerEvents = "none";
8119
8138
  }
8120
8139
  if (!shouldShow) {
8121
8140
  if (this.placeholderRoot.isConnected) {
@@ -8125,20 +8144,21 @@ class CakeEngine {
8125
8144
  return;
8126
8145
  }
8127
8146
  this.placeholderRoot.textContent = placeholderText ?? "";
8128
- this.syncPlaceholderPadding();
8129
8147
  if (!this.placeholderRoot.isConnected) {
8130
8148
  this.container.prepend(this.placeholderRoot);
8131
8149
  }
8150
+ this.syncPlaceholderPosition();
8132
8151
  }
8133
- syncPlaceholderPadding() {
8134
- if (!this.placeholderRoot) {
8152
+ syncPlaceholderPosition() {
8153
+ if (!this.placeholderRoot || !this.contentRoot) {
8135
8154
  return;
8136
8155
  }
8137
- const style = window.getComputedStyle(this.container);
8138
- this.placeholderRoot.style.paddingTop = style.paddingTop;
8139
- this.placeholderRoot.style.paddingRight = style.paddingRight;
8140
- this.placeholderRoot.style.paddingBottom = style.paddingBottom;
8141
- this.placeholderRoot.style.paddingLeft = style.paddingLeft;
8156
+ const containerRect = this.container.getBoundingClientRect();
8157
+ const contentRect = this.contentRoot.getBoundingClientRect();
8158
+ this.placeholderRoot.style.top = `${contentRect.top - containerRect.top}px`;
8159
+ this.placeholderRoot.style.left = `${contentRect.left - containerRect.left}px`;
8160
+ this.placeholderRoot.style.width = `${contentRect.width}px`;
8161
+ this.placeholderRoot.style.height = `${contentRect.height}px`;
8142
8162
  }
8143
8163
  updateContentRootAttributes() {
8144
8164
  if (!this.contentRoot) {
@@ -10073,8 +10093,13 @@ class CakeEngine {
10073
10093
  if (!this.overlayRoot || !this.contentRoot) {
10074
10094
  return;
10075
10095
  }
10096
+ if (!this.hasFocus()) {
10097
+ this.updateCaret(null);
10098
+ this.syncSelectionRects([]);
10099
+ return;
10100
+ }
10076
10101
  const isRecentTouch = Date.now() - this.lastTouchTime < 2e3;
10077
- if (isRecentTouch) {
10102
+ if (this.isTouchDevice() || isRecentTouch) {
10078
10103
  this.contentRoot.classList.add("cake-touch-mode");
10079
10104
  this.updateCaret(null);
10080
10105
  this.syncSelectionRects([]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blankdotpage/cake",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",