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.
- package/CHANGELOG.md +46 -0
- package/dist/{externalUserPayload-DWcXyz2U.js → externalUserPayload-CdzgCq4t.js} +10453 -7486
- package/dist/issue-sticker-headless-react.js +68 -12
- package/dist/issue-sticker-headless.js +457 -95
- package/dist/issue-sticker-react.js +1431 -400
- package/dist/{three-B228j4M6.js → three-FamoZZKK.js} +560 -33
- package/dist/{tooltip-CT7e9xbU.js → tooltip-BVA6ikuJ.js} +1 -1
- package/headless.d.ts +35 -4
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { c as createLucideIcon, u as ungzip_1,
|
|
2
|
-
import { r } from "./three-
|
|
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-
|
|
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
|
|
785
|
+
const key = canvasKey(shot);
|
|
786
|
+
const applies = shot.t <= currentMs || shot.baseline && !byCanvas.has(key);
|
|
731
787
|
if (applies) {
|
|
732
|
-
byCanvas.set(
|
|
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
|
|
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
|
|
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
|
|
820
|
+
painted.set(canvasKey(shot), { node, src: shot.src, rebuild: rebuildTick });
|
|
765
821
|
}
|
|
766
|
-
for (const [
|
|
767
|
-
if (!currentShots.some((shot) => shot
|
|
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(
|
|
825
|
+
painted.delete(key);
|
|
770
826
|
}
|
|
771
827
|
}
|
|
772
828
|
};
|