@teriusu/rich-editor 0.11.5 → 0.11.6

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 +1 @@
1
- {"version":3,"file":"resize.d.ts","sourceRoot":"","sources":["../../src/utils/resize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEhE;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,UAAU,GAAG,GAAG,GAAG,GAAG,CAAC;AAEnC,MAAM,WAAW,mBAAmB;IACnC,uCAAuC;IACvC,GAAG,EAAE,WAAW,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACjC,mDAAmD;IACnD,OAAO,EAAE,MAAM,eAAe,CAAC;IAC/B,qCAAqC;IACrC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC;;;;OAIG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/E;AA4BD,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,IAAI,CA+HrE"}
1
+ {"version":3,"file":"resize.d.ts","sourceRoot":"","sources":["../../src/utils/resize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEhE;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,UAAU,GAAG,GAAG,GAAG,GAAG,CAAC;AAEnC,MAAM,WAAW,mBAAmB;IACnC,uCAAuC;IACvC,GAAG,EAAE,WAAW,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACjC,mDAAmD;IACnD,OAAO,EAAE,MAAM,eAAe,CAAC;IAC/B,qCAAqC;IACrC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC;;;;OAIG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/E;AA4BD,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,IAAI,CA0LrE"}
@@ -45,6 +45,52 @@ export function attachResize(options) {
45
45
  let resizing = false;
46
46
  let start = 0;
47
47
  let startSize = 0;
48
+ /*
49
+ * ── 왜 프레임에 한 번만 쓰는가 ────────────────────────────────────────────────
50
+ *
51
+ * `pointermove` 는 **화면 주사율과 무관하게** 들어온다 — 고폴링 마우스는 한 프레임에
52
+ * 여러 번 던진다. 예전엔 들어오는 족족 `dom.style.width` 를 썼는데, 이 상자는 안에
53
+ * `aspect-ratio` 박스와 **교차 출처 iframe**(영상)을 품고 있어서 한 번 쓸 때마다
54
+ * 레이아웃이 iframe 까지 내려간다. 즉 한 프레임에 같은 일을 여러 번 하고, 마지막 값만
55
+ * 화면에 남는다 — 앞의 것들은 전부 버려지는 계산이다.
56
+ *
57
+ * 값은 즉시 받아 두되 **적용은 프레임당 한 번**으로 접는다. 끄는 감각(지연)은 그대로고
58
+ * 버려지던 레이아웃만 사라진다.
59
+ */
60
+ let pendingSize = 0;
61
+ let frame = 0;
62
+ const applyPending = () => {
63
+ frame = 0;
64
+ if (axis === "x")
65
+ dom.style.width = `${pendingSize}px`;
66
+ else
67
+ dom.style.height = `${pendingSize}px`;
68
+ };
69
+ const flushPending = () => {
70
+ if (!frame)
71
+ return;
72
+ cancelAnimationFrame(frame);
73
+ applyPending();
74
+ };
75
+ /*
76
+ * ⚠️ **드래그하는 동안 iframe 이 포인터를 가로채지 못하게 막는다.**
77
+ *
78
+ * 손잡이는 상자 오른쪽 12px 밖에 있고, 끌면 커서는 곧바로 상자 **안**(영상 iframe 위)을
79
+ * 지난다. 교차 출처 iframe 위에서는 그 이벤트가 iframe 문서로 가고 부모 window 에는
80
+ * 오지 않는다 — 위 `attachWindow` 가 window 에 걸어 둔 리스너도 마찬가지다. 그러면
81
+ * 끌던 도중에 크기가 멈췄다 튀었다 한다.
82
+ *
83
+ * `setPointerCapture` 로도 막히지만 이 코드는 그걸 일부러 피한다(아래 주석) — 대신
84
+ * **드래그 동안만** 자식 임베드의 포인터를 끈다. 드래그가 끝나면 되돌린다.
85
+ * ⚠️ 빈 문자열로 되돌린다(`none` → `''`). `auto` 로 되돌리면 원래 CSS 가 갖고 있던
86
+ * 값을 덮어쓴다.
87
+ */
88
+ const EMBEDS = "iframe, embed, object, video";
89
+ const shieldEmbeds = (on) => {
90
+ for (const el of Array.from(dom.querySelectorAll(EMBEDS))) {
91
+ el.style.pointerEvents = on ? "none" : "";
92
+ }
93
+ };
48
94
  const paint = (active) => {
49
95
  bar.style.background = active ? ACTIVE : IDLE;
50
96
  };
@@ -68,17 +114,21 @@ export function attachResize(options) {
68
114
  if (!resizing)
69
115
  return;
70
116
  const delta = (axis === "x" ? e.clientX : e.clientY) - start;
71
- const next = Math.max(min, Math.min(max, startSize + delta));
72
- if (axis === "x")
73
- dom.style.width = `${next}px`;
74
- else
75
- dom.style.height = `${next}px`;
117
+ pendingSize = Math.max(min, Math.min(max, startSize + delta));
118
+ if (!frame)
119
+ frame = requestAnimationFrame(applyPending);
76
120
  };
77
121
  const endResize = () => {
78
122
  if (!resizing)
79
123
  return;
80
124
  resizing = false;
125
+ /*
126
+ * ⚠️ **밀린 프레임을 먼저 적용한다.** 아래에서 커밋할 값을 `dom.style` 에서 읽는데,
127
+ * 예약만 된 채 아직 안 쓴 값이 있으면 **직전 프레임의 크기로 저장**된다.
128
+ */
129
+ flushPending();
81
130
  paint(false);
131
+ shieldEmbeds(false);
82
132
  detachWindow();
83
133
  document.body.style.removeProperty("user-select");
84
134
  document.body.style.removeProperty("cursor");
@@ -117,6 +167,8 @@ export function attachResize(options) {
117
167
  start = axis === "x" ? e.clientX : e.clientY;
118
168
  startSize = axis === "x" ? rect.width : rect.height;
119
169
  paint(true);
170
+ pendingSize = startSize;
171
+ shieldEmbeds(true);
120
172
  // 드래그 중 텍스트가 선택되며 파랗게 물드는 것을 막는다.
121
173
  document.body.style.userSelect = "none";
122
174
  document.body.style.cursor = preset.cursor;
@@ -130,6 +182,13 @@ export function attachResize(options) {
130
182
  handle.removeEventListener("mouseenter", onEnter);
131
183
  handle.removeEventListener("mouseleave", onLeave);
132
184
  handle.removeEventListener("pointerdown", onPointerDown);
185
+ /* 드래그 도중에 노드가 사라질 수 있다 — 예약 프레임과 가림막을 반드시 걷는다. */
186
+ if (frame) {
187
+ cancelAnimationFrame(frame);
188
+ frame = 0;
189
+ }
190
+ if (resizing)
191
+ shieldEmbeds(false);
133
192
  detachWindow();
134
193
  handle.remove();
135
194
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teriusu/rich-editor",
3
- "version": "0.11.5",
3
+ "version": "0.11.6",
4
4
  "description": "TipTap 기반 Notion-style 리치 텍스트 에디터 (Svelte)",
5
5
  "type": "module",
6
6
  "svelte": "./dist/index.js",