issue-sticker 0.12.0 → 0.13.0

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,8 +1,8 @@
1
- import { c as createLucideIcon, u as ungzip_1, R as REPLAY_EVENT_TYPE, C as CANVAS_INTERACTION_TAG, a as cn, b as Replayer, M as MousePointer2 } from "./three-B228j4M6.js";
2
- import { r } from "./three-B228j4M6.js";
1
+ import { c as createLucideIcon, u as ungzip_1, a as REPLAY_MASKED_ATTRIBUTE, M as MASKING_COPY, b as REPLAY_EVENT_TYPE, C as CANVAS_INTERACTION_TAG, d as REPLAY_MASKED_STYLE_RULES, e as cn, f as Replayer, g as MousePointer2 } from "./three-FamoZZKK.js";
2
+ import { r } from "./three-FamoZZKK.js";
3
3
  import { jsxs, jsx } from "react/jsx-runtime";
4
4
  import { memo, useRef, useEffect, useState, useCallback, useMemo } from "react";
5
- import { T as TooltipProvider, a as Tooltip, b as TooltipTrigger, c as TooltipContent } from "./tooltip-CT7e9xbU.js";
5
+ import { T as TooltipProvider, a as Tooltip, b as TooltipTrigger, c as TooltipContent } from "./tooltip-BVA6ikuJ.js";
6
6
  /**
7
7
  * @license lucide-react v0.468.0 - ISC
8
8
  *
@@ -120,6 +120,7 @@ class NodeIndex {
120
120
  }
121
121
  /**
122
122
  * 상호작용 대상을 사람이 읽을 짧은 레이블로 바꾼다. 우선순위는 다음과 같다.
123
+ * 0. 마스킹 정책으로 가린 노드: 보안 정책으로 가려짐
123
124
  * 1. aria-label / title
124
125
  * 2. form 컨트롤: placeholder → name → type (예: input[email])
125
126
  * 3. 직접 자식 Text 노드만 결합 (컨테이너가 자손 텍스트를 통째로 빨아들이는 것 방지)
@@ -132,6 +133,7 @@ class NodeIndex {
132
133
  const node = id === void 0 ? void 0 : this.get(id);
133
134
  if (!node || node.type !== NODE_TYPE_ELEMENT || id === void 0) return TYPE_LABEL[type];
134
135
  const attrs = node.attributes ?? {};
136
+ if (REPLAY_MASKED_ATTRIBUTE in attrs) return MASKING_COPY.maskedLabel;
135
137
  const attr = (name) => {
136
138
  const value = attrs[name];
137
139
  return typeof value === "string" ? value : "";
@@ -392,6 +394,52 @@ function stripWidgetEvents(events) {
392
394
  }
393
395
  return { events: out, stripped: widgetIds.size > 0, removedEvents };
394
396
  }
397
+ const STYLED = /* @__PURE__ */ new WeakSet();
398
+ function isShadowRoot(node) {
399
+ return node.nodeType === 11 && "host" in node;
400
+ }
401
+ function adoptMaskedSheet(root, view) {
402
+ var _a;
403
+ let proto = Object.getPrototypeOf(root);
404
+ let native;
405
+ while (proto && !native) {
406
+ native = Object.getOwnPropertyDescriptor(proto, "adoptedStyleSheets");
407
+ proto = Object.getPrototypeOf(proto);
408
+ }
409
+ if (!(native == null ? void 0 : native.get) || !native.set || typeof ((_a = view.CSSStyleSheet) == null ? void 0 : _a.prototype.replaceSync) !== "function")
410
+ return false;
411
+ const sheet = new view.CSSStyleSheet();
412
+ sheet.replaceSync(REPLAY_MASKED_STYLE_RULES.join("\n"));
413
+ const { get, set } = native;
414
+ const adopt = (sheets) => set.call(root, [...Array.from(sheets).filter((other) => other !== sheet), sheet]);
415
+ Object.defineProperty(root, "adoptedStyleSheets", {
416
+ configurable: true,
417
+ get: () => get.call(root),
418
+ set: adopt
419
+ });
420
+ adopt(get.call(root));
421
+ return true;
422
+ }
423
+ function styleShadowRoot(root) {
424
+ if (STYLED.has(root)) return;
425
+ STYLED.add(root);
426
+ const doc = root.ownerDocument;
427
+ const view = doc.defaultView;
428
+ if (view && adoptMaskedSheet(root, view)) return;
429
+ const style = doc.createElement("style");
430
+ style.textContent = REPLAY_MASKED_STYLE_RULES.join("\n");
431
+ root.prepend(style);
432
+ }
433
+ const maskedShadowStylePlugin = {
434
+ onBuild(node) {
435
+ const built = node;
436
+ if (typeof built.getRootNode !== "function") return;
437
+ const own = built.shadowRoot;
438
+ if (own) styleShadowRoot(own);
439
+ const root = built.getRootNode();
440
+ if (isShadowRoot(root)) styleShadowRoot(root);
441
+ }
442
+ };
395
443
  const MOUSE_TAIL_CONFIG = {
396
444
  lineCap: "round",
397
445
  lineWidth: 3,
@@ -495,6 +543,9 @@ async function waitForReplayCanvas(replayerRef, shot, cancelled) {
495
543
  await new Promise((resolve) => requestAnimationFrame(resolve));
496
544
  }
497
545
  }
546
+ function canvasKey(shot) {
547
+ return shot.nodeId ?? `i${shot.canvasIndex}`;
548
+ }
498
549
  function findReplayCanvas(replayer, shot) {
499
550
  var _a, _b;
500
551
  const replayDocument = (_a = replayer == null ? void 0 : replayer.iframe) == null ? void 0 : _a.contentDocument;
@@ -604,7 +655,11 @@ function SessionReplayPlayer({ url }) {
604
655
  root: stage,
605
656
  speed: 1,
606
657
  showWarning: false,
607
- mouseTail: INITIAL_SHOW_TRAIL ? MOUSE_TAIL_CONFIG : false
658
+ mouseTail: INITIAL_SHOW_TRAIL ? MOUSE_TAIL_CONFIG : false,
659
+ // 마스킹 정책으로 가린 상자. rrweb 기본 차단 표시(currentColor 단색)는 "깨졌다"로 읽힌다.
660
+ insertStyleRules: REPLAY_MASKED_STYLE_RULES,
661
+ // insertStyleRules 는 shadow root 안에 닿지 않는다. 같은 규칙을 shadow root 마다 넣는다.
662
+ plugins: [maskedShadowStylePlugin]
608
663
  }
609
664
  );
610
665
  replayer.on("fullsnapshot-rebuilded", () => {
@@ -727,20 +782,21 @@ function SessionReplayPlayer({ url }) {
727
782
  const currentShots = useMemo(() => {
728
783
  const byCanvas = /* @__PURE__ */ new Map();
729
784
  for (const shot of canvasShots) {
730
- const applies = shot.t <= currentMs || shot.baseline && !byCanvas.has(shot.canvasIndex);
785
+ const key = canvasKey(shot);
786
+ const applies = shot.t <= currentMs || shot.baseline && !byCanvas.has(key);
731
787
  if (applies) {
732
- byCanvas.set(shot.canvasIndex, shot);
788
+ byCanvas.set(key, shot);
733
789
  }
734
790
  }
735
791
  return Array.from(byCanvas.values());
736
792
  }, [canvasShots, currentMs]);
737
- const shotKey = currentShots.map((shot) => `${shot.canvasIndex}:${shot.t}`).join("|");
793
+ const shotKey = currentShots.map((shot) => `${canvasKey(shot)}:${shot.t}`).join("|");
738
794
  useEffect(() => {
739
795
  let cancelled = false;
740
796
  const painted = paintedCanvasRef.current;
741
797
  const apply = async () => {
742
798
  for (const shot of currentShots) {
743
- const prev = painted.get(shot.canvasIndex);
799
+ const prev = painted.get(canvasKey(shot));
744
800
  if (prev && prev.src === shot.src && prev.rebuild === rebuildTick && prev.node.isConnected) {
745
801
  continue;
746
802
  }
@@ -761,12 +817,12 @@ function SessionReplayPlayer({ url }) {
761
817
  node.style.backgroundImage = `url("${shot.src}")`;
762
818
  node.style.backgroundSize = "100% 100%";
763
819
  node.style.backgroundRepeat = "no-repeat";
764
- painted.set(shot.canvasIndex, { node, src: shot.src, rebuild: rebuildTick });
820
+ painted.set(canvasKey(shot), { node, src: shot.src, rebuild: rebuildTick });
765
821
  }
766
- for (const [canvasIndex, entry] of Array.from(painted.entries())) {
767
- if (!currentShots.some((shot) => shot.canvasIndex === canvasIndex)) {
822
+ for (const [key, entry] of Array.from(painted.entries())) {
823
+ if (!currentShots.some((shot) => canvasKey(shot) === key)) {
768
824
  entry.node.style.backgroundImage = "";
769
- painted.delete(canvasIndex);
825
+ painted.delete(key);
770
826
  }
771
827
  }
772
828
  };