@ourroadmaps/web-sdk 1.2.0 → 1.3.1
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/{chunk-M2R3KO66.cjs → chunk-KDMQIQP4.cjs} +237 -30
- package/dist/chunk-KDMQIQP4.cjs.map +1 -0
- package/dist/{chunk-OHL77RGU.js → chunk-Q6BH54FY.js} +235 -30
- package/dist/chunk-Q6BH54FY.js.map +1 -0
- package/dist/index.cjs +31 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +29 -4
- package/dist/index.js.map +1 -1
- package/dist/review/index.cjs +2 -2
- package/dist/review/index.d.cts +1 -1
- package/dist/review/index.d.ts +1 -1
- package/dist/review/index.js +1 -1
- package/dist/review.global.js +6 -9
- package/dist/review.global.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-M2R3KO66.cjs.map +0 -1
- package/dist/chunk-OHL77RGU.js.map +0 -1
|
@@ -5,7 +5,7 @@ var chunk4DE2IREA_cjs = require('./chunk-4DE2IREA.cjs');
|
|
|
5
5
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
6
6
|
// src/review/api.ts
|
|
7
7
|
var API_URL = (() => {
|
|
8
|
-
if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-
|
|
8
|
+
if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-KDMQIQP4.cjs', document.baseURI).href)) }) !== "undefined" && undefined?.VITE_API_URL) {
|
|
9
9
|
return undefined.VITE_API_URL;
|
|
10
10
|
}
|
|
11
11
|
return "https://api.ourroadmaps.com";
|
|
@@ -494,33 +494,51 @@ var PinManager = class {
|
|
|
494
494
|
}
|
|
495
495
|
document.body.appendChild(this.container);
|
|
496
496
|
}
|
|
497
|
-
addPin(pinNumber, x, y, isMine) {
|
|
497
|
+
addPin(pinNumber, x, y, isMine, pageUrl) {
|
|
498
498
|
const pin = document.createElement("div");
|
|
499
499
|
pin.className = isMine ? "review-pin" : "review-pin review-pin--other";
|
|
500
500
|
pin.textContent = String(pinNumber);
|
|
501
501
|
pin.style.left = `${x}%`;
|
|
502
502
|
pin.style.top = `${y}%`;
|
|
503
503
|
pin.dataset.pinNumber = String(pinNumber);
|
|
504
|
+
pin.dataset.pageUrl = pageUrl;
|
|
504
505
|
this.container.appendChild(pin);
|
|
505
|
-
this.pins.set(pinNumber, pin);
|
|
506
|
+
this.pins.set(pinNumber, { el: pin, pageUrl });
|
|
506
507
|
}
|
|
507
508
|
removePin(pinNumber) {
|
|
508
|
-
const
|
|
509
|
-
if (
|
|
510
|
-
|
|
509
|
+
const entry = this.pins.get(pinNumber);
|
|
510
|
+
if (entry) {
|
|
511
|
+
entry.el.remove();
|
|
511
512
|
this.pins.delete(pinNumber);
|
|
512
513
|
}
|
|
513
514
|
}
|
|
514
515
|
highlightPin(pinNumber) {
|
|
515
|
-
for (const [num, el] of this.pins) {
|
|
516
|
+
for (const [num, { el }] of this.pins) {
|
|
516
517
|
el.classList.toggle("review-pin--highlighted", num === pinNumber);
|
|
517
518
|
}
|
|
518
519
|
}
|
|
519
520
|
clearHighlight() {
|
|
520
|
-
for (const el of this.pins.values()) {
|
|
521
|
+
for (const { el } of this.pins.values()) {
|
|
521
522
|
el.classList.remove("review-pin--highlighted");
|
|
522
523
|
}
|
|
523
524
|
}
|
|
525
|
+
filterByPage(currentPageId) {
|
|
526
|
+
for (const { el, pageUrl } of this.pins.values()) {
|
|
527
|
+
el.style.display = pageUrl === currentPageId ? "" : "none";
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
showAll() {
|
|
531
|
+
for (const { el } of this.pins.values()) {
|
|
532
|
+
el.style.display = "";
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
countForPage(pageId) {
|
|
536
|
+
let count = 0;
|
|
537
|
+
for (const { pageUrl } of this.pins.values()) {
|
|
538
|
+
if (pageUrl === pageId) count++;
|
|
539
|
+
}
|
|
540
|
+
return count;
|
|
541
|
+
}
|
|
524
542
|
destroy() {
|
|
525
543
|
this.container.remove();
|
|
526
544
|
this.pins.clear();
|
|
@@ -612,6 +630,60 @@ var CommentCard = class {
|
|
|
612
630
|
}
|
|
613
631
|
};
|
|
614
632
|
|
|
633
|
+
// src/review/PageTracker.ts
|
|
634
|
+
function getCurrentPageId() {
|
|
635
|
+
return window.location.pathname + window.location.search + window.location.hash;
|
|
636
|
+
}
|
|
637
|
+
var PageNavigationListener = class {
|
|
638
|
+
constructor(onChange) {
|
|
639
|
+
this.onChange = onChange;
|
|
640
|
+
chunk4DE2IREA_cjs.__publicField(this, "popstateHandler", null);
|
|
641
|
+
chunk4DE2IREA_cjs.__publicField(this, "hashchangeHandler", null);
|
|
642
|
+
chunk4DE2IREA_cjs.__publicField(this, "originalPushState", null);
|
|
643
|
+
chunk4DE2IREA_cjs.__publicField(this, "originalReplaceState", null);
|
|
644
|
+
chunk4DE2IREA_cjs.__publicField(this, "lastPageId");
|
|
645
|
+
this.lastPageId = getCurrentPageId();
|
|
646
|
+
}
|
|
647
|
+
start() {
|
|
648
|
+
if (this.originalPushState) return;
|
|
649
|
+
const check = () => {
|
|
650
|
+
const current = getCurrentPageId();
|
|
651
|
+
if (current !== this.lastPageId) {
|
|
652
|
+
this.lastPageId = current;
|
|
653
|
+
this.onChange(current);
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
this.popstateHandler = check;
|
|
657
|
+
window.addEventListener("popstate", this.popstateHandler);
|
|
658
|
+
this.hashchangeHandler = check;
|
|
659
|
+
window.addEventListener("hashchange", this.hashchangeHandler);
|
|
660
|
+
this.originalPushState = history.pushState.bind(history);
|
|
661
|
+
this.originalReplaceState = history.replaceState.bind(history);
|
|
662
|
+
history.pushState = (...args) => {
|
|
663
|
+
this.originalPushState(...args);
|
|
664
|
+
check();
|
|
665
|
+
};
|
|
666
|
+
history.replaceState = (...args) => {
|
|
667
|
+
this.originalReplaceState(...args);
|
|
668
|
+
check();
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
destroy() {
|
|
672
|
+
if (this.popstateHandler) {
|
|
673
|
+
window.removeEventListener("popstate", this.popstateHandler);
|
|
674
|
+
}
|
|
675
|
+
if (this.hashchangeHandler) {
|
|
676
|
+
window.removeEventListener("hashchange", this.hashchangeHandler);
|
|
677
|
+
}
|
|
678
|
+
if (this.originalPushState) {
|
|
679
|
+
history.pushState = this.originalPushState;
|
|
680
|
+
}
|
|
681
|
+
if (this.originalReplaceState) {
|
|
682
|
+
history.replaceState = this.originalReplaceState;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
};
|
|
686
|
+
|
|
615
687
|
// src/review/ReviewMode.ts
|
|
616
688
|
var ReviewMode = class {
|
|
617
689
|
constructor(token, shadowRoot, initData) {
|
|
@@ -625,6 +697,7 @@ var ReviewMode = class {
|
|
|
625
697
|
chunk4DE2IREA_cjs.__publicField(this, "promptEl", null);
|
|
626
698
|
chunk4DE2IREA_cjs.__publicField(this, "toolbarEl", null);
|
|
627
699
|
chunk4DE2IREA_cjs.__publicField(this, "clickHandler", null);
|
|
700
|
+
chunk4DE2IREA_cjs.__publicField(this, "pageListener", null);
|
|
628
701
|
this.pinManager = new PinManager();
|
|
629
702
|
this.commentCard = new CommentCard(shadowRoot);
|
|
630
703
|
this.nextPinNumber = initData.nextPinNumber;
|
|
@@ -635,6 +708,11 @@ var ReviewMode = class {
|
|
|
635
708
|
this.showPrompt();
|
|
636
709
|
this.renderToolbar();
|
|
637
710
|
await this.loadExistingPins();
|
|
711
|
+
this.pinManager.filterByPage(getCurrentPageId());
|
|
712
|
+
this.pageListener = new PageNavigationListener((pageId) => {
|
|
713
|
+
this.pinManager.filterByPage(pageId);
|
|
714
|
+
});
|
|
715
|
+
this.pageListener.start();
|
|
638
716
|
this.clickHandler = (e) => this.handleClick(e);
|
|
639
717
|
document.addEventListener("click", this.clickHandler, true);
|
|
640
718
|
}
|
|
@@ -679,7 +757,7 @@ var ReviewMode = class {
|
|
|
679
757
|
for (const c of comments) {
|
|
680
758
|
if (c.pinNumber != null && c.pinData) {
|
|
681
759
|
const isMine = c.commentText != null;
|
|
682
|
-
this.pinManager.addPin(c.pinNumber, c.pinData.pinX, c.pinData.pinY, isMine);
|
|
760
|
+
this.pinManager.addPin(c.pinNumber, c.pinData.pinX, c.pinData.pinY, isMine, c.pageUrl ?? "");
|
|
683
761
|
}
|
|
684
762
|
}
|
|
685
763
|
} catch {
|
|
@@ -692,7 +770,7 @@ var ReviewMode = class {
|
|
|
692
770
|
this.dismissPrompt();
|
|
693
771
|
const pinData = captureElementContext(e.clientX, e.clientY);
|
|
694
772
|
const pinNumber = this.nextPinNumber;
|
|
695
|
-
this.pinManager.addPin(pinNumber, pinData.pinX, pinData.pinY, true);
|
|
773
|
+
this.pinManager.addPin(pinNumber, pinData.pinX, pinData.pinY, true, getCurrentPageId());
|
|
696
774
|
this.pendingPinNumber = pinNumber;
|
|
697
775
|
this.commentCard.show({
|
|
698
776
|
x: e.clientX,
|
|
@@ -702,7 +780,7 @@ var ReviewMode = class {
|
|
|
702
780
|
commentText: text,
|
|
703
781
|
pinNumber,
|
|
704
782
|
pinData,
|
|
705
|
-
pageUrl:
|
|
783
|
+
pageUrl: getCurrentPageId()
|
|
706
784
|
});
|
|
707
785
|
this.pendingPinNumber = null;
|
|
708
786
|
this.nextPinNumber++;
|
|
@@ -725,7 +803,7 @@ var ReviewMode = class {
|
|
|
725
803
|
commentText: text,
|
|
726
804
|
pinNumber: null,
|
|
727
805
|
pinData: null,
|
|
728
|
-
pageUrl:
|
|
806
|
+
pageUrl: getCurrentPageId()
|
|
729
807
|
});
|
|
730
808
|
this.showToast("Comment saved");
|
|
731
809
|
},
|
|
@@ -745,6 +823,7 @@ var ReviewMode = class {
|
|
|
745
823
|
if (this.clickHandler) {
|
|
746
824
|
document.removeEventListener("click", this.clickHandler, true);
|
|
747
825
|
}
|
|
826
|
+
this.pageListener?.destroy();
|
|
748
827
|
this.dismissPrompt();
|
|
749
828
|
this.toolbarEl?.remove();
|
|
750
829
|
this.commentCard.hide();
|
|
@@ -752,6 +831,34 @@ var ReviewMode = class {
|
|
|
752
831
|
}
|
|
753
832
|
};
|
|
754
833
|
|
|
834
|
+
// src/review/TokenStorage.ts
|
|
835
|
+
var STORAGE_KEY = "ourroadmaps:token";
|
|
836
|
+
function storeToken(type, token) {
|
|
837
|
+
try {
|
|
838
|
+
sessionStorage.setItem(STORAGE_KEY, JSON.stringify({ type, token }));
|
|
839
|
+
} catch {
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
function getStoredToken() {
|
|
843
|
+
try {
|
|
844
|
+
const raw = sessionStorage.getItem(STORAGE_KEY);
|
|
845
|
+
if (!raw) return null;
|
|
846
|
+
const parsed = JSON.parse(raw);
|
|
847
|
+
if (parsed && typeof parsed.type === "string" && typeof parsed.token === "string") {
|
|
848
|
+
return parsed;
|
|
849
|
+
}
|
|
850
|
+
return null;
|
|
851
|
+
} catch {
|
|
852
|
+
return null;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
function clearStoredToken() {
|
|
856
|
+
try {
|
|
857
|
+
sessionStorage.removeItem(STORAGE_KEY);
|
|
858
|
+
} catch {
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
755
862
|
// src/review/TriageMode.ts
|
|
756
863
|
var TriageMode = class {
|
|
757
864
|
constructor(token, shadowRoot) {
|
|
@@ -762,6 +869,8 @@ var TriageMode = class {
|
|
|
762
869
|
chunk4DE2IREA_cjs.__publicField(this, "tooltipEl", null);
|
|
763
870
|
chunk4DE2IREA_cjs.__publicField(this, "comments", []);
|
|
764
871
|
chunk4DE2IREA_cjs.__publicField(this, "pinClickHandler", null);
|
|
872
|
+
chunk4DE2IREA_cjs.__publicField(this, "pageListener", null);
|
|
873
|
+
chunk4DE2IREA_cjs.__publicField(this, "showAllPages", false);
|
|
765
874
|
this.pinManager = new PinManager();
|
|
766
875
|
}
|
|
767
876
|
async init() {
|
|
@@ -770,12 +879,20 @@ var TriageMode = class {
|
|
|
770
879
|
this.comments = await fetchComments(this.token);
|
|
771
880
|
for (const c of this.comments) {
|
|
772
881
|
if (c.pinNumber != null && c.pinData) {
|
|
773
|
-
this.pinManager.addPin(c.pinNumber, c.pinData.pinX, c.pinData.pinY, true);
|
|
882
|
+
this.pinManager.addPin(c.pinNumber, c.pinData.pinX, c.pinData.pinY, true, c.pageUrl ?? "");
|
|
774
883
|
}
|
|
775
884
|
}
|
|
776
885
|
} catch {
|
|
777
886
|
}
|
|
887
|
+
this.pinManager.filterByPage(getCurrentPageId());
|
|
778
888
|
this.renderToolbar();
|
|
889
|
+
this.pageListener = new PageNavigationListener((pageId) => {
|
|
890
|
+
if (!this.showAllPages) {
|
|
891
|
+
this.pinManager.filterByPage(pageId);
|
|
892
|
+
}
|
|
893
|
+
this.updateToolbar();
|
|
894
|
+
});
|
|
895
|
+
this.pageListener.start();
|
|
779
896
|
this.pinClickHandler = (e) => {
|
|
780
897
|
const target = e.target;
|
|
781
898
|
if (target.classList?.contains("review-pin")) {
|
|
@@ -789,13 +906,48 @@ var TriageMode = class {
|
|
|
789
906
|
renderToolbar() {
|
|
790
907
|
this.toolbarEl = document.createElement("div");
|
|
791
908
|
this.toolbarEl.className = "review-toolbar";
|
|
792
|
-
|
|
793
|
-
this.toolbarEl.innerHTML = `
|
|
794
|
-
<span style="font-weight:500;">Triage Mode</span>
|
|
795
|
-
<span style="opacity:0.7;">${count} pin${count !== 1 ? "s" : ""}</span>
|
|
796
|
-
`;
|
|
909
|
+
this.updateToolbar();
|
|
797
910
|
this.shadowRoot.appendChild(this.toolbarEl);
|
|
798
911
|
}
|
|
912
|
+
updateToolbar() {
|
|
913
|
+
if (!this.toolbarEl) return;
|
|
914
|
+
const totalCount = this.comments.filter((c) => c.pinNumber != null).length;
|
|
915
|
+
const currentPageId = getCurrentPageId();
|
|
916
|
+
const pageCount = this.pinManager.countForPage(currentPageId);
|
|
917
|
+
const url = new URL(currentPageId, window.location.origin);
|
|
918
|
+
const pagePath = url.hash ? `${url.pathname}${url.hash.split("?")[0]}` : url.pathname || "/";
|
|
919
|
+
this.toolbarEl.innerHTML = "";
|
|
920
|
+
const label = document.createElement("span");
|
|
921
|
+
label.style.fontWeight = "500";
|
|
922
|
+
label.textContent = "Triage Mode";
|
|
923
|
+
this.toolbarEl.appendChild(label);
|
|
924
|
+
const count = document.createElement("span");
|
|
925
|
+
count.style.opacity = "0.7";
|
|
926
|
+
if (this.showAllPages) {
|
|
927
|
+
count.textContent = `${totalCount} pin${totalCount !== 1 ? "s" : ""}`;
|
|
928
|
+
} else {
|
|
929
|
+
count.textContent = `${pageCount} pin${pageCount !== 1 ? "s" : ""} on ${pagePath} (${totalCount} total)`;
|
|
930
|
+
}
|
|
931
|
+
this.toolbarEl.appendChild(count);
|
|
932
|
+
const toggleBtn = document.createElement("button");
|
|
933
|
+
toggleBtn.className = "review-btn review-btn--submit";
|
|
934
|
+
toggleBtn.style.cssText = "margin-left:auto;padding:6px 12px;font-size:13px;";
|
|
935
|
+
toggleBtn.textContent = this.showAllPages ? "This page" : "All pages";
|
|
936
|
+
toggleBtn.addEventListener("click", (e) => {
|
|
937
|
+
e.stopPropagation();
|
|
938
|
+
this.togglePageFilter();
|
|
939
|
+
});
|
|
940
|
+
this.toolbarEl.appendChild(toggleBtn);
|
|
941
|
+
}
|
|
942
|
+
togglePageFilter() {
|
|
943
|
+
this.showAllPages = !this.showAllPages;
|
|
944
|
+
if (this.showAllPages) {
|
|
945
|
+
this.pinManager.showAll();
|
|
946
|
+
} else {
|
|
947
|
+
this.pinManager.filterByPage(getCurrentPageId());
|
|
948
|
+
}
|
|
949
|
+
this.updateToolbar();
|
|
950
|
+
}
|
|
799
951
|
handlePinClick(pinNumber, e) {
|
|
800
952
|
this.hideTooltip();
|
|
801
953
|
this.pinManager.highlightPin(pinNumber);
|
|
@@ -826,6 +978,25 @@ var TriageMode = class {
|
|
|
826
978
|
timeEl.style.cssText = "font-size:11px;opacity:0.7;";
|
|
827
979
|
timeEl.textContent = time;
|
|
828
980
|
this.tooltipEl.appendChild(timeEl);
|
|
981
|
+
const pinPageUrl = comment.pageUrl ?? "";
|
|
982
|
+
if (pinPageUrl && pinPageUrl !== getCurrentPageId()) {
|
|
983
|
+
const navEl = document.createElement("div");
|
|
984
|
+
navEl.style.cssText = "margin-top:6px;padding-top:6px;border-top:1px solid rgba(255,255,255,0.2);font-size:12px;";
|
|
985
|
+
const pageLabel = document.createElement("span");
|
|
986
|
+
pageLabel.style.opacity = "0.7";
|
|
987
|
+
pageLabel.textContent = `Page: ${pinPageUrl.split("?")[0].split("#")[0] || "/"} \u2014 `;
|
|
988
|
+
navEl.appendChild(pageLabel);
|
|
989
|
+
const navLink = document.createElement("a");
|
|
990
|
+
navLink.style.cssText = "color:#a78bfa;cursor:pointer;text-decoration:underline;pointer-events:auto;";
|
|
991
|
+
navLink.textContent = "Navigate there?";
|
|
992
|
+
navLink.addEventListener("click", (e) => {
|
|
993
|
+
e.stopPropagation();
|
|
994
|
+
this.navigateToPin(pinPageUrl, pinNumber);
|
|
995
|
+
});
|
|
996
|
+
navEl.appendChild(navLink);
|
|
997
|
+
this.tooltipEl.appendChild(navEl);
|
|
998
|
+
this.tooltipEl.style.pointerEvents = "auto";
|
|
999
|
+
}
|
|
829
1000
|
const posX = x ?? window.innerWidth / 2;
|
|
830
1001
|
const posY = y ?? window.innerHeight / 3;
|
|
831
1002
|
this.tooltipEl.style.position = "fixed";
|
|
@@ -841,6 +1012,13 @@ var TriageMode = class {
|
|
|
841
1012
|
};
|
|
842
1013
|
setTimeout(() => document.addEventListener("click", dismiss, true), 0);
|
|
843
1014
|
}
|
|
1015
|
+
navigateToPin(pageUrl, pinNumber) {
|
|
1016
|
+
this.hideTooltip();
|
|
1017
|
+
this.pinManager.clearHighlight();
|
|
1018
|
+
const url = new URL(pageUrl, window.location.origin);
|
|
1019
|
+
url.searchParams.set("pin", String(pinNumber));
|
|
1020
|
+
window.location.href = url.toString();
|
|
1021
|
+
}
|
|
844
1022
|
autoFocusPin() {
|
|
845
1023
|
const params = new URLSearchParams(window.location.search);
|
|
846
1024
|
const pinParam = params.get("pin");
|
|
@@ -849,6 +1027,19 @@ var TriageMode = class {
|
|
|
849
1027
|
if (!pinNumber) return;
|
|
850
1028
|
const comment = this.comments.find((c) => c.pinNumber === pinNumber);
|
|
851
1029
|
if (!comment?.pinData) return;
|
|
1030
|
+
const pinPageUrl = comment.pageUrl ?? "";
|
|
1031
|
+
if (pinPageUrl) {
|
|
1032
|
+
const currentUrl = new URL(window.location.href);
|
|
1033
|
+
currentUrl.searchParams.delete("pin");
|
|
1034
|
+
const currentPageWithoutPin = currentUrl.pathname + currentUrl.search + currentUrl.hash;
|
|
1035
|
+
if (pinPageUrl !== currentPageWithoutPin) {
|
|
1036
|
+
this.navigateToPin(pinPageUrl, pinNumber);
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
this.pinManager.showAll();
|
|
1041
|
+
this.showAllPages = true;
|
|
1042
|
+
this.updateToolbar();
|
|
852
1043
|
const docEl = document.documentElement;
|
|
853
1044
|
const scrollX = comment.pinData.pinX / 100 * docEl.scrollWidth;
|
|
854
1045
|
const scrollY = comment.pinData.pinY / 100 * docEl.scrollHeight;
|
|
@@ -870,6 +1061,7 @@ var TriageMode = class {
|
|
|
870
1061
|
if (this.pinClickHandler) {
|
|
871
1062
|
document.removeEventListener("click", this.pinClickHandler, true);
|
|
872
1063
|
}
|
|
1064
|
+
this.pageListener?.destroy();
|
|
873
1065
|
this.hideTooltip();
|
|
874
1066
|
this.toolbarEl?.remove();
|
|
875
1067
|
this.pinManager.destroy();
|
|
@@ -891,29 +1083,42 @@ var Review = class {
|
|
|
891
1083
|
this.shadow.appendChild(styleEl);
|
|
892
1084
|
document.body.appendChild(this.root);
|
|
893
1085
|
}
|
|
894
|
-
async init() {
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
1086
|
+
async init(tokenType, token) {
|
|
1087
|
+
if (!tokenType || !token) {
|
|
1088
|
+
const params = new URLSearchParams(window.location.search);
|
|
1089
|
+
const reviewToken = params.get("review");
|
|
1090
|
+
const triageToken = params.get("triage");
|
|
1091
|
+
if (reviewToken) {
|
|
1092
|
+
tokenType = "review";
|
|
1093
|
+
token = reviewToken;
|
|
1094
|
+
} else if (triageToken) {
|
|
1095
|
+
tokenType = "triage";
|
|
1096
|
+
token = triageToken;
|
|
1097
|
+
} else {
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
if (tokenType === "review") {
|
|
899
1102
|
try {
|
|
900
|
-
const data = await validateToken(
|
|
901
|
-
this.mode = new ReviewMode(
|
|
1103
|
+
const data = await validateToken(token);
|
|
1104
|
+
this.mode = new ReviewMode(token, this.shadow, data);
|
|
902
1105
|
await this.mode.init();
|
|
903
1106
|
} catch (err) {
|
|
904
1107
|
if (err instanceof ReviewError) {
|
|
1108
|
+
clearStoredToken();
|
|
905
1109
|
this.showErrorOverlay(
|
|
906
1110
|
err.code === "expired" ? "This feedback session has expired" : "This review link is no longer valid"
|
|
907
1111
|
);
|
|
908
1112
|
}
|
|
909
1113
|
}
|
|
910
|
-
} else if (
|
|
1114
|
+
} else if (tokenType === "triage") {
|
|
911
1115
|
try {
|
|
912
|
-
await validateToken(
|
|
913
|
-
this.mode = new TriageMode(
|
|
1116
|
+
await validateToken(token);
|
|
1117
|
+
this.mode = new TriageMode(token, this.shadow);
|
|
914
1118
|
await this.mode.init();
|
|
915
1119
|
} catch (err) {
|
|
916
1120
|
if (err instanceof ReviewError) {
|
|
1121
|
+
clearStoredToken();
|
|
917
1122
|
this.showErrorOverlay(
|
|
918
1123
|
err.code === "expired" ? "This feedback session has expired" : "This review link is no longer valid"
|
|
919
1124
|
);
|
|
@@ -944,5 +1149,7 @@ var Review = class {
|
|
|
944
1149
|
};
|
|
945
1150
|
|
|
946
1151
|
exports.Review = Review;
|
|
947
|
-
|
|
948
|
-
|
|
1152
|
+
exports.getStoredToken = getStoredToken;
|
|
1153
|
+
exports.storeToken = storeToken;
|
|
1154
|
+
//# sourceMappingURL=chunk-KDMQIQP4.cjs.map
|
|
1155
|
+
//# sourceMappingURL=chunk-KDMQIQP4.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/review/api.ts","../src/review/ElementCapture.ts","../src/review/styles.ts","../src/review/PinManager.ts","../src/review/CommentCard.ts","../src/review/PageTracker.ts","../src/review/ReviewMode.ts","../src/review/TokenStorage.ts","../src/review/TriageMode.ts","../src/review/Review.ts"],"names":["__publicField"],"mappings":"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AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAyQtB,IAAM,mBAAA,GAAsB;AAAA;A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","file":"chunk-KDMQIQP4.cjs","sourcesContent":["import type { PinData, ReviewComment, ReviewInitData } from './types'\n\n// Default to production, override with env var for local dev\nconst API_URL = (() => {\n // Vite dev mode\n if (typeof import.meta !== 'undefined' && import.meta.env?.VITE_API_URL) {\n return import.meta.env.VITE_API_URL\n }\n return 'https://api.ourroadmaps.com'\n})()\n\nexport async function validateToken(token: string): Promise<ReviewInitData> {\n const res = await fetch(`${API_URL}/v1/prototype-review/${token}`)\n if (res.status === 410) throw new ReviewError('expired', 'This feedback session has expired')\n if (res.status === 404) throw new ReviewError('invalid', 'This review link is not valid')\n if (!res.ok) throw new ReviewError('error', 'Something went wrong')\n const body = await res.json()\n return body.data\n}\n\n// TODO: Wire into SDK — show name prompt on first visit, call identify() to transition invite status from 'pending' to 'opened'\nexport async function identify(token: string, name: string): Promise<void> {\n const res = await fetch(`${API_URL}/v1/prototype-review/${token}/identify`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ name }),\n })\n if (!res.ok) throw new ReviewError('error', 'Failed to identify')\n}\n\nexport async function submitComment(\n token: string,\n comment: { commentText: string; pinNumber: number | null; pinData: PinData | null; pageUrl: string | null },\n): Promise<{ id: string; pinNumber: number | null; createdAt: string }> {\n const res = await fetch(`${API_URL}/v1/prototype-review/${token}/comments`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(comment),\n })\n if (!res.ok) throw new ReviewError('error', 'Failed to submit comment')\n const body = await res.json()\n return body.data\n}\n\nexport async function fetchComments(token: string): Promise<ReviewComment[]> {\n const res = await fetch(`${API_URL}/v1/prototype-review/${token}/comments`)\n if (!res.ok) throw new ReviewError('error', 'Failed to load comments')\n const body = await res.json()\n return body.data\n}\n\nexport class ReviewError extends Error {\n constructor(\n public code: 'expired' | 'invalid' | 'error',\n message: string,\n ) {\n super(message)\n this.name = 'ReviewError'\n }\n}\n","import type { PinData } from './types'\n\nexport function captureElementContext(clientX: number, clientY: number): PinData {\n const el = document.elementFromPoint(clientX, clientY) as HTMLElement | null\n const docEl = document.documentElement\n\n const pinX = ((clientX + window.scrollX) / docEl.scrollWidth) * 100\n const pinY = ((clientY + window.scrollY) / docEl.scrollHeight) * 100\n\n if (!el || el === document.body || el === docEl) {\n return {\n pinX,\n pinY,\n element: {\n selector: 'body',\n tag: 'body',\n text: '',\n ariaLabel: null,\n className: '',\n boundingBox: { x: 0, y: 0, w: docEl.scrollWidth, h: docEl.scrollHeight },\n },\n context: {\n parentTag: '',\n parentText: '',\n grandparentTag: '',\n siblings: [],\n nearbyText: '',\n },\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n }\n }\n\n const rect = el.getBoundingClientRect()\n\n return {\n pinX,\n pinY,\n element: {\n selector: buildSelector(el),\n tag: el.tagName.toLowerCase(),\n text: getDirectText(el).slice(0, 200),\n ariaLabel: el.getAttribute('aria-label'),\n className: el.className && typeof el.className === 'string' ? el.className : '',\n boundingBox: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n w: Math.round(rect.width),\n h: Math.round(rect.height),\n },\n },\n context: {\n parentTag: el.parentElement ? `${el.parentElement.tagName.toLowerCase()}${classStr(el.parentElement)}` : '',\n parentText: el.parentElement ? getDirectText(el.parentElement).slice(0, 100) : '',\n grandparentTag: el.parentElement?.parentElement\n ? `${el.parentElement.parentElement.tagName.toLowerCase()}${classStr(el.parentElement.parentElement)}`\n : '',\n siblings: getSiblingsSummary(el),\n nearbyText: getNearbyText(el).slice(0, 200),\n },\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n }\n}\n\nfunction buildSelector(el: HTMLElement): string {\n const parts: string[] = []\n let current: HTMLElement | null = el\n\n while (current && current !== document.body) {\n if (current.id) {\n parts.unshift(`#${current.id}`)\n break\n }\n\n let part = current.tagName.toLowerCase()\n if (current.className && typeof current.className === 'string') {\n const classes = current.className.trim().split(/\\s+/).slice(0, 2).join('.')\n if (classes) part += `.${classes}`\n }\n\n parts.unshift(part)\n current = current.parentElement\n }\n\n return parts.join(' > ')\n}\n\nfunction getDirectText(el: HTMLElement): string {\n let text = ''\n for (const node of el.childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n text += node.textContent?.trim() || ''\n }\n }\n return text.trim() || el.textContent?.trim().slice(0, 200) || ''\n}\n\nfunction classStr(el: HTMLElement): string {\n if (!el.className || typeof el.className !== 'string') return ''\n const cls = el.className.trim().split(/\\s+/).slice(0, 2).join('.')\n return cls ? `.${cls}` : ''\n}\n\nfunction getSiblingsSummary(el: HTMLElement): string[] {\n if (!el.parentElement) return []\n const siblings: string[] = []\n for (const child of el.parentElement.children) {\n if (child === el) continue\n const tag = child.tagName.toLowerCase()\n const text = (child.textContent?.trim() || '').slice(0, 50)\n siblings.push(text ? `${tag}:${text}` : tag)\n if (siblings.length >= 4) break\n }\n return siblings\n}\n\nfunction getNearbyText(el: HTMLElement): string {\n // Walk up to find the nearest container with meaningful text\n let current: HTMLElement | null = el.parentElement\n let depth = 0\n while (current && depth < 3) {\n const text = getDirectText(current)\n if (text && text !== getDirectText(el)) return text\n current = current.parentElement\n depth++\n }\n return ''\n}\n","export const REVIEW_STYLES = `\n:host {\n all: initial;\n}\n\n/* ─── Pin Container (rendered outside shadow DOM) ─── */\n.pin-container {\n position: fixed;\n inset: 0;\n pointer-events: none;\n z-index: 10000;\n}\n\n/* ─── Pin Marker ─── */\n.review-pin {\n position: absolute;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: #7c3aed;\n color: #fff;\n font-family: system-ui, -apple-system, sans-serif;\n font-size: 12px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n transform: translate(-50%, -50%);\n pointer-events: auto;\n cursor: pointer;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);\n transition: transform 0.15s ease, box-shadow 0.15s ease;\n user-select: none;\n z-index: 1;\n}\n\n.review-pin:hover {\n transform: translate(-50%, -50%) scale(1.15);\n box-shadow: 0 3px 10px rgba(124, 58, 237, 0.4);\n}\n\n.review-pin--other {\n opacity: 0.5;\n}\n\n.review-pin--highlighted {\n transform: translate(-50%, -50%) scale(1.2);\n box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.3), 0 3px 10px rgba(124, 58, 237, 0.4);\n z-index: 2;\n}\n\n/* ─── Toolbar ─── */\n.review-toolbar {\n position: fixed;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n background: rgba(0, 0, 0, 0.85);\n color: #fff;\n font-family: system-ui, -apple-system, sans-serif;\n font-size: 14px;\n border-radius: 12px 12px 0 0;\n padding: 10px 20px;\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n z-index: 10001;\n backdrop-filter: blur(8px);\n box-shadow: 0 -2px 16px rgba(0, 0, 0, 0.2);\n}\n\n/* ─── Comment Card ─── */\n.review-comment-card {\n position: fixed;\n background: #fff;\n border-radius: 10px;\n box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15), 0 1px 4px rgba(0, 0, 0, 0.08);\n width: 300px;\n padding: 16px;\n z-index: 10002;\n font-family: system-ui, -apple-system, sans-serif;\n border: 1px solid rgba(0, 0, 0, 0.08);\n}\n\n/* ─── Comment Textarea ─── */\n.review-comment-input {\n width: 100%;\n border: 1px solid #d1d5db;\n border-radius: 8px;\n padding: 10px 12px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.5;\n color: #1f2937;\n background: #fafafa;\n box-sizing: border-box;\n outline: none;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n}\n\n.review-comment-input:focus {\n border-color: #7c3aed;\n box-shadow: 0 0 0 2px rgba(124, 58, 237, 0.15);\n background: #fff;\n}\n\n.review-comment-input::placeholder {\n color: #9ca3af;\n}\n\n.review-comment-input:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* ─── Comment Actions ─── */\n.review-comment-actions {\n display: flex;\n flex-direction: row;\n justify-content: flex-end;\n gap: 8px;\n margin-top: 12px;\n}\n\n/* ─── Buttons ─── */\n.review-btn {\n padding: 6px 14px;\n border-radius: 6px;\n cursor: pointer;\n font-family: inherit;\n font-size: 13px;\n font-weight: 500;\n border: none;\n transition: background 0.15s ease, opacity 0.15s ease;\n}\n\n.review-btn--cancel {\n color: #6b7280;\n background: transparent;\n}\n\n.review-btn--cancel:hover {\n background: #f3f4f6;\n}\n\n.review-btn--submit {\n background: #7c3aed;\n color: #fff;\n}\n\n.review-btn--submit:hover {\n background: #6d28d9;\n}\n\n.review-btn--submit:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* ─── Comment Error ─── */\n.review-comment-error {\n color: #dc2626;\n font-size: 12px;\n margin-top: 8px;\n font-family: system-ui, -apple-system, sans-serif;\n}\n\n/* ─── Name Prompt ─── */\n.review-prompt {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: #fff;\n box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2), 0 1px 4px rgba(0, 0, 0, 0.08);\n border-radius: 12px;\n padding: 28px 32px;\n z-index: 10002;\n text-align: center;\n font-family: system-ui, -apple-system, sans-serif;\n border: 1px solid rgba(0, 0, 0, 0.06);\n max-width: 360px;\n width: 90%;\n}\n\n/* ─── Expired Overlay ─── */\n.review-expired-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.6);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10003;\n backdrop-filter: blur(2px);\n}\n\n.review-expired-card {\n background: #fff;\n border-radius: 12px;\n padding: 28px 32px;\n text-align: center;\n font-family: system-ui, -apple-system, sans-serif;\n box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2);\n max-width: 400px;\n width: 90%;\n border: 1px solid rgba(0, 0, 0, 0.06);\n}\n\n/* ─── Toast ─── */\n.review-toast {\n position: fixed;\n bottom: 80px;\n left: 50%;\n transform: translateX(-50%);\n background: rgba(0, 0, 0, 0.85);\n color: #fff;\n font-family: system-ui, -apple-system, sans-serif;\n font-size: 14px;\n padding: 10px 20px;\n border-radius: 8px;\n z-index: 10003;\n pointer-events: none;\n animation: review-toast-fade 2.5s ease forwards;\n backdrop-filter: blur(8px);\n}\n\n@keyframes review-toast-fade {\n 0% { opacity: 0; transform: translateX(-50%) translateY(8px); }\n 10% { opacity: 1; transform: translateX(-50%) translateY(0); }\n 80% { opacity: 1; transform: translateX(-50%) translateY(0); }\n 100% { opacity: 0; transform: translateX(-50%) translateY(-4px); }\n}\n\n/* ─── Tooltip ─── */\n.review-tooltip {\n position: absolute;\n background: rgba(0, 0, 0, 0.85);\n color: #fff;\n font-family: system-ui, -apple-system, sans-serif;\n font-size: 13px;\n line-height: 1.4;\n border-radius: 6px;\n padding: 8px 12px;\n max-width: 280px;\n z-index: 10002;\n pointer-events: none;\n backdrop-filter: blur(8px);\n}\n\n/* ─── Reduced Motion ─── */\n@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n transition-duration: 0.01ms !important;\n }\n}\n`\n\n/**\n * Subset of styles for pins that render outside the shadow DOM.\n * Injected into document.head by PinManager.\n */\nexport const PIN_DOCUMENT_STYLES = `\nbody {\n position: relative !important;\n}\n\n.pin-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n min-height: 100%;\n pointer-events: none;\n z-index: 10000;\n}\n\n.review-pin {\n position: absolute;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: #7c3aed;\n color: #fff;\n font-family: system-ui, -apple-system, sans-serif;\n font-size: 12px;\n font-weight: 600;\n display: flex;\n align-items: center;\n justify-content: center;\n transform: translate(-50%, -50%);\n pointer-events: auto;\n cursor: pointer;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);\n transition: transform 0.15s ease, box-shadow 0.15s ease;\n user-select: none;\n z-index: 1;\n}\n\n.review-pin:hover {\n transform: translate(-50%, -50%) scale(1.15);\n box-shadow: 0 3px 10px rgba(124, 58, 237, 0.4);\n}\n\n.review-pin--other {\n opacity: 0.5;\n}\n\n.review-pin--highlighted {\n transform: translate(-50%, -50%) scale(1.2);\n box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.3), 0 3px 10px rgba(124, 58, 237, 0.4);\n z-index: 2;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .review-pin, .review-pin:hover, .review-pin--highlighted {\n transition-duration: 0.01ms !important;\n }\n}\n`\n","import { PIN_DOCUMENT_STYLES } from './styles'\n\nconst STYLE_ID = 'roadmaps-review-pin-styles'\n\ninterface PinEntry {\n el: HTMLElement\n pageUrl: string\n}\n\nexport class PinManager {\n private container: HTMLDivElement\n private pins: Map<number, PinEntry> = new Map()\n private styleEl: HTMLStyleElement | null = null\n\n constructor() {\n this.container = document.createElement('div')\n this.container.className = 'pin-container'\n }\n\n mount(): void {\n if (!document.getElementById(STYLE_ID)) {\n this.styleEl = document.createElement('style')\n this.styleEl.id = STYLE_ID\n this.styleEl.textContent = PIN_DOCUMENT_STYLES\n document.head.appendChild(this.styleEl)\n }\n\n document.body.appendChild(this.container)\n }\n\n addPin(pinNumber: number, x: number, y: number, isMine: boolean, pageUrl: string): void {\n const pin = document.createElement('div')\n pin.className = isMine ? 'review-pin' : 'review-pin review-pin--other'\n pin.textContent = String(pinNumber)\n pin.style.left = `${x}%`\n pin.style.top = `${y}%`\n pin.dataset.pinNumber = String(pinNumber)\n pin.dataset.pageUrl = pageUrl\n this.container.appendChild(pin)\n this.pins.set(pinNumber, { el: pin, pageUrl })\n }\n\n removePin(pinNumber: number): void {\n const entry = this.pins.get(pinNumber)\n if (entry) {\n entry.el.remove()\n this.pins.delete(pinNumber)\n }\n }\n\n highlightPin(pinNumber: number): void {\n for (const [num, { el }] of this.pins) {\n el.classList.toggle('review-pin--highlighted', num === pinNumber)\n }\n }\n\n clearHighlight(): void {\n for (const { el } of this.pins.values()) {\n el.classList.remove('review-pin--highlighted')\n }\n }\n\n filterByPage(currentPageId: string): void {\n for (const { el, pageUrl } of this.pins.values()) {\n el.style.display = pageUrl === currentPageId ? '' : 'none'\n }\n }\n\n showAll(): void {\n for (const { el } of this.pins.values()) {\n el.style.display = ''\n }\n }\n\n countForPage(pageId: string): number {\n let count = 0\n for (const { pageUrl } of this.pins.values()) {\n if (pageUrl === pageId) count++\n }\n return count\n }\n\n destroy(): void {\n this.container.remove()\n this.pins.clear()\n\n if (this.styleEl) {\n this.styleEl.remove()\n this.styleEl = null\n } else {\n document.getElementById(STYLE_ID)?.remove()\n }\n }\n}\n","export class CommentCard {\n private card: HTMLElement | null = null\n private onSubmit: ((text: string) => Promise<void>) | null = null\n private onCancel: (() => void) | null = null\n\n constructor(private shadowRoot: ShadowRoot) {}\n\n show(options: {\n x: number\n y: number\n onSubmit: (text: string) => Promise<void>\n onCancel: () => void\n }): void {\n this.hide()\n this.onSubmit = options.onSubmit\n this.onCancel = options.onCancel\n\n this.card = document.createElement('div')\n this.card.className = 'review-comment-card'\n // Position near click point, adjust to stay in viewport\n this.card.style.left = `${Math.min(options.x, window.innerWidth - 320)}px`\n this.card.style.top = `${Math.min(options.y + 20, window.innerHeight - 200)}px`\n\n this.card.innerHTML = `\n <textarea class=\"review-comment-input\" placeholder=\"Leave your feedback...\" rows=\"3\"></textarea>\n <div class=\"review-comment-actions\">\n <button class=\"review-btn review-btn--cancel\">Cancel</button>\n <button class=\"review-btn review-btn--submit\">Submit</button>\n </div>\n <div class=\"review-comment-error\" style=\"display:none\"></div>\n `\n\n this.attachListeners()\n this.shadowRoot.appendChild(this.card)\n\n const textarea = this.card.querySelector('textarea')\n textarea?.focus()\n }\n\n hide(): void {\n this.card?.remove()\n this.card = null\n }\n\n showForGeneral(options: {\n onSubmit: (text: string) => Promise<void>\n onCancel: () => void\n }): void {\n // Show centered for general (non-pinned) comments\n this.show({\n x: window.innerWidth / 2 - 150,\n y: window.innerHeight / 2 - 100,\n onSubmit: options.onSubmit,\n onCancel: options.onCancel,\n })\n }\n\n private attachListeners(): void {\n if (!this.card) return\n\n this.card.querySelector('.review-btn--cancel')?.addEventListener('click', () => {\n this.onCancel?.()\n this.hide()\n })\n\n this.card.querySelector('.review-btn--submit')?.addEventListener('click', () => this.handleSubmit())\n\n this.card.querySelector('textarea')?.addEventListener('keydown', (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n e.preventDefault()\n this.handleSubmit()\n }\n })\n }\n\n private async handleSubmit(): Promise<void> {\n if (!this.card) return\n const textarea = this.card.querySelector('textarea') as HTMLTextAreaElement\n const text = textarea.value.trim()\n if (!text) return\n\n const submitBtn = this.card.querySelector('.review-btn--submit') as HTMLButtonElement\n const errorEl = this.card.querySelector('.review-comment-error') as HTMLElement\n submitBtn.disabled = true\n submitBtn.textContent = 'Submitting...'\n textarea.disabled = true\n errorEl.style.display = 'none'\n\n try {\n await this.onSubmit?.(text)\n this.hide()\n } catch (err) {\n submitBtn.disabled = false\n submitBtn.textContent = 'Submit'\n textarea.disabled = false\n errorEl.textContent = err instanceof Error ? err.message : 'Failed to submit'\n errorEl.style.display = 'block'\n }\n }\n}\n","/**\n * Returns the current page identity as pathname + search + hash.\n * This captures all routing strategies: pathname, hash, and query-param based.\n */\nexport function getCurrentPageId(): string {\n return window.location.pathname + window.location.search + window.location.hash\n}\n\n/**\n * Detects page navigation within a prototype.\n * Covers: popstate (back/forward), hashchange (hash routing),\n * and pushState/replaceState (SPA routing via history API).\n */\nexport class PageNavigationListener {\n private popstateHandler: (() => void) | null = null\n private hashchangeHandler: (() => void) | null = null\n private originalPushState: typeof history.pushState | null = null\n private originalReplaceState: typeof history.replaceState | null = null\n private lastPageId: string\n\n constructor(private onChange: (pageId: string) => void) {\n this.lastPageId = getCurrentPageId()\n }\n\n start(): void {\n // Guard against double-start — would capture already-patched history methods\n if (this.originalPushState) return\n\n const check = () => {\n const current = getCurrentPageId()\n if (current !== this.lastPageId) {\n this.lastPageId = current\n this.onChange(current)\n }\n }\n\n this.popstateHandler = check\n window.addEventListener('popstate', this.popstateHandler)\n\n this.hashchangeHandler = check\n window.addEventListener('hashchange', this.hashchangeHandler)\n\n this.originalPushState = history.pushState.bind(history)\n this.originalReplaceState = history.replaceState.bind(history)\n\n history.pushState = (...args: Parameters<typeof history.pushState>) => {\n this.originalPushState!(...args)\n check()\n }\n\n history.replaceState = (...args: Parameters<typeof history.replaceState>) => {\n this.originalReplaceState!(...args)\n check()\n }\n }\n\n destroy(): void {\n if (this.popstateHandler) {\n window.removeEventListener('popstate', this.popstateHandler)\n }\n if (this.hashchangeHandler) {\n window.removeEventListener('hashchange', this.hashchangeHandler)\n }\n\n if (this.originalPushState) {\n history.pushState = this.originalPushState\n }\n if (this.originalReplaceState) {\n history.replaceState = this.originalReplaceState\n }\n }\n}\n","import { submitComment, fetchComments } from './api'\nimport { captureElementContext } from './ElementCapture'\nimport { PinManager } from './PinManager'\nimport { CommentCard } from './CommentCard'\nimport type { ReviewInitData } from './types'\nimport { getCurrentPageId, PageNavigationListener } from './PageTracker'\n\nexport class ReviewMode {\n private pinManager: PinManager\n private commentCard: CommentCard\n private nextPinNumber: number\n private pendingPinNumber: number | null = null\n private promptEl: HTMLElement | null = null\n private toolbarEl: HTMLElement | null = null\n private clickHandler: ((e: MouseEvent) => void) | null = null\n private pageListener: PageNavigationListener | null = null\n\n constructor(\n private token: string,\n private shadowRoot: ShadowRoot,\n private initData: ReviewInitData,\n ) {\n this.pinManager = new PinManager()\n this.commentCard = new CommentCard(shadowRoot)\n this.nextPinNumber = initData.nextPinNumber\n }\n\n async init(): Promise<void> {\n // Set crosshair cursor on body\n document.body.style.cursor = 'crosshair'\n\n // Mount pin manager\n this.pinManager.mount()\n\n // Render first-visit prompt\n this.showPrompt()\n\n // Render bottom toolbar\n this.renderToolbar()\n\n // Fetch and render existing pins\n await this.loadExistingPins()\n\n // Filter pins to current page and listen for navigation\n this.pinManager.filterByPage(getCurrentPageId())\n this.pageListener = new PageNavigationListener((pageId) => {\n this.pinManager.filterByPage(pageId)\n })\n this.pageListener.start()\n\n // Listen for clicks to drop pins\n this.clickHandler = (e: MouseEvent) => this.handleClick(e)\n document.addEventListener('click', this.clickHandler, true)\n }\n\n private showPrompt(): void {\n this.promptEl = document.createElement('div')\n this.promptEl.className = 'review-prompt'\n this.promptEl.innerHTML = `\n <h3 style=\"margin:0 0 8px;font-size:16px;\">Click anywhere to leave feedback</h3>\n <p style=\"margin:0;color:#666;font-size:14px;\">Drop numbered pins on elements you want to comment on</p>\n `\n this.shadowRoot.appendChild(this.promptEl)\n\n // Auto-dismiss after 5 seconds\n setTimeout(() => this.dismissPrompt(), 5000)\n }\n\n private dismissPrompt(): void {\n if (this.promptEl) {\n this.promptEl.remove()\n this.promptEl = null\n }\n }\n\n private renderToolbar(): void {\n this.toolbarEl = document.createElement('div')\n this.toolbarEl.className = 'review-toolbar'\n this.updateToolbar()\n this.shadowRoot.appendChild(this.toolbarEl)\n }\n\n private updateToolbar(): void {\n if (!this.toolbarEl) return\n const pinCount = this.nextPinNumber - 1\n this.toolbarEl.innerHTML = `\n <span style=\"font-weight:500;\">${this.initData.session.name}</span>\n <span style=\"opacity:0.7;\">${pinCount} pin${pinCount !== 1 ? 's' : ''}</span>\n <button class=\"review-btn review-btn--submit\" style=\"margin-left:auto;padding:6px 12px;font-size:13px;\">General Comment</button>\n `\n this.toolbarEl.querySelector('button')?.addEventListener('click', (e) => {\n e.stopPropagation()\n this.handleGeneralComment()\n })\n }\n\n private async loadExistingPins(): Promise<void> {\n try {\n const comments = await fetchComments(this.token)\n for (const c of comments) {\n if (c.pinNumber != null && c.pinData) {\n // commentText being non-null means it's the current reviewer's pin\n const isMine = c.commentText != null\n this.pinManager.addPin(c.pinNumber, c.pinData.pinX, c.pinData.pinY, isMine, c.pageUrl ?? '')\n }\n }\n } catch {\n // Silently fail - pins just won't show up\n }\n }\n\n private handleClick(e: MouseEvent): void {\n // Don't intercept clicks on our own shadow DOM elements\n const path = e.composedPath()\n if (path.some((el) => el instanceof HTMLElement && el.closest?.('#ourroadmaps-review'))) return\n\n // Don't intercept if comment card is open\n if (this.pendingPinNumber != null) return\n\n // Dismiss first-visit prompt on first click\n this.dismissPrompt()\n\n const pinData = captureElementContext(e.clientX, e.clientY)\n const pinNumber = this.nextPinNumber\n\n // Add pin at click position\n this.pinManager.addPin(pinNumber, pinData.pinX, pinData.pinY, true, getCurrentPageId())\n this.pendingPinNumber = pinNumber\n\n // Show comment card\n this.commentCard.show({\n x: e.clientX,\n y: e.clientY,\n onSubmit: async (text: string) => {\n await submitComment(this.token, {\n commentText: text,\n pinNumber,\n pinData,\n pageUrl: getCurrentPageId(),\n })\n this.pendingPinNumber = null\n this.nextPinNumber++\n this.updateToolbar()\n this.showToast('Comment saved')\n },\n onCancel: () => {\n // Remove the pending pin\n this.pinManager.removePin(pinNumber)\n this.pendingPinNumber = null\n },\n })\n\n e.preventDefault()\n e.stopPropagation()\n }\n\n private handleGeneralComment(): void {\n if (this.pendingPinNumber != null) return\n\n this.commentCard.showForGeneral({\n onSubmit: async (text: string) => {\n await submitComment(this.token, {\n commentText: text,\n pinNumber: null,\n pinData: null,\n pageUrl: getCurrentPageId(),\n })\n this.showToast('Comment saved')\n },\n onCancel: () => {},\n })\n }\n\n private showToast(message: string): void {\n const toast = document.createElement('div')\n toast.className = 'review-toast'\n toast.textContent = message\n this.shadowRoot.appendChild(toast)\n setTimeout(() => toast.remove(), 2500)\n }\n\n destroy(): void {\n document.body.style.cursor = ''\n if (this.clickHandler) {\n document.removeEventListener('click', this.clickHandler, true)\n }\n this.pageListener?.destroy()\n this.dismissPrompt()\n this.toolbarEl?.remove()\n this.commentCard.hide()\n this.pinManager.destroy()\n }\n}\n","const STORAGE_KEY = 'ourroadmaps:token'\n\ninterface StoredToken {\n type: 'review' | 'triage'\n token: string\n}\n\nexport function storeToken(type: 'review' | 'triage', token: string): void {\n try {\n sessionStorage.setItem(STORAGE_KEY, JSON.stringify({ type, token }))\n } catch {\n // sessionStorage unavailable (private browsing, storage full, etc.)\n }\n}\n\nexport function getStoredToken(): StoredToken | null {\n try {\n const raw = sessionStorage.getItem(STORAGE_KEY)\n if (!raw) return null\n const parsed = JSON.parse(raw)\n if (parsed && typeof parsed.type === 'string' && typeof parsed.token === 'string') {\n return parsed as StoredToken\n }\n return null\n } catch {\n return null\n }\n}\n\nexport function clearStoredToken(): void {\n try {\n sessionStorage.removeItem(STORAGE_KEY)\n } catch {\n // sessionStorage unavailable\n }\n}\n","import { fetchComments } from './api'\nimport { PinManager } from './PinManager'\nimport { getCurrentPageId, PageNavigationListener } from './PageTracker'\nimport type { ReviewComment } from './types'\n\nexport class TriageMode {\n private pinManager: PinManager\n private toolbarEl: HTMLElement | null = null\n private tooltipEl: HTMLElement | null = null\n private comments: ReviewComment[] = []\n private pinClickHandler: ((e: MouseEvent) => void) | null = null\n private pageListener: PageNavigationListener | null = null\n private showAllPages = false\n\n constructor(\n private token: string,\n private shadowRoot: ShadowRoot,\n ) {\n this.pinManager = new PinManager()\n }\n\n async init(): Promise<void> {\n this.pinManager.mount()\n\n try {\n this.comments = await fetchComments(this.token)\n for (const c of this.comments) {\n if (c.pinNumber != null && c.pinData) {\n this.pinManager.addPin(c.pinNumber, c.pinData.pinX, c.pinData.pinY, true, c.pageUrl ?? '')\n }\n }\n } catch {\n // Show error state\n }\n\n this.pinManager.filterByPage(getCurrentPageId())\n\n this.renderToolbar()\n\n this.pageListener = new PageNavigationListener((pageId) => {\n if (!this.showAllPages) {\n this.pinManager.filterByPage(pageId)\n }\n this.updateToolbar()\n })\n this.pageListener.start()\n\n this.pinClickHandler = (e: MouseEvent) => {\n const target = e.target as HTMLElement\n if (target.classList?.contains('review-pin')) {\n const num = Number(target.dataset.pinNumber)\n if (num) this.handlePinClick(num, e)\n }\n }\n document.addEventListener('click', this.pinClickHandler, true)\n\n this.autoFocusPin()\n }\n\n private renderToolbar(): void {\n this.toolbarEl = document.createElement('div')\n this.toolbarEl.className = 'review-toolbar'\n this.updateToolbar()\n this.shadowRoot.appendChild(this.toolbarEl)\n }\n\n private updateToolbar(): void {\n if (!this.toolbarEl) return\n\n const totalCount = this.comments.filter((c) => c.pinNumber != null).length\n const currentPageId = getCurrentPageId()\n const pageCount = this.pinManager.countForPage(currentPageId)\n // Show pathname for path-routed apps, or pathname#hash for hash-routed apps\n const url = new URL(currentPageId, window.location.origin)\n const pagePath = url.hash ? `${url.pathname}${url.hash.split('?')[0]}` : (url.pathname || '/')\n\n this.toolbarEl.innerHTML = ''\n\n const label = document.createElement('span')\n label.style.fontWeight = '500'\n label.textContent = 'Triage Mode'\n this.toolbarEl.appendChild(label)\n\n const count = document.createElement('span')\n count.style.opacity = '0.7'\n if (this.showAllPages) {\n count.textContent = `${totalCount} pin${totalCount !== 1 ? 's' : ''}`\n } else {\n count.textContent = `${pageCount} pin${pageCount !== 1 ? 's' : ''} on ${pagePath} (${totalCount} total)`\n }\n this.toolbarEl.appendChild(count)\n\n const toggleBtn = document.createElement('button')\n toggleBtn.className = 'review-btn review-btn--submit'\n toggleBtn.style.cssText = 'margin-left:auto;padding:6px 12px;font-size:13px;'\n toggleBtn.textContent = this.showAllPages ? 'This page' : 'All pages'\n toggleBtn.addEventListener('click', (e) => {\n e.stopPropagation()\n this.togglePageFilter()\n })\n this.toolbarEl.appendChild(toggleBtn)\n }\n\n private togglePageFilter(): void {\n this.showAllPages = !this.showAllPages\n if (this.showAllPages) {\n this.pinManager.showAll()\n } else {\n this.pinManager.filterByPage(getCurrentPageId())\n }\n this.updateToolbar()\n }\n\n private handlePinClick(pinNumber: number, e: MouseEvent): void {\n this.hideTooltip()\n this.pinManager.highlightPin(pinNumber)\n this.showTooltipForPin(pinNumber, e.clientX + 16, e.clientY - 10)\n }\n\n private showTooltipForPin(pinNumber: number, x?: number, y?: number): void {\n this.hideTooltip()\n\n const comment = this.comments.find((c) => c.pinNumber === pinNumber)\n if (!comment) return\n\n this.tooltipEl = document.createElement('div')\n this.tooltipEl.className = 'review-tooltip'\n\n const time = new Date(comment.createdAt).toLocaleString()\n\n const header = document.createElement('div')\n header.style.cssText = 'font-weight:500;margin-bottom:4px;'\n header.textContent = `Pin #${pinNumber}`\n this.tooltipEl.appendChild(header)\n\n if (comment.reviewerName) {\n const name = document.createElement('div')\n name.style.cssText = 'font-size:11px;opacity:0.7;margin-bottom:2px;'\n name.textContent = comment.reviewerName\n this.tooltipEl.appendChild(name)\n }\n\n const text = document.createElement('div')\n text.style.cssText = 'margin-bottom:4px;'\n text.textContent = comment.commentText || '(no text)'\n this.tooltipEl.appendChild(text)\n\n const timeEl = document.createElement('div')\n timeEl.style.cssText = 'font-size:11px;opacity:0.7;'\n timeEl.textContent = time\n this.tooltipEl.appendChild(timeEl)\n\n const pinPageUrl = comment.pageUrl ?? ''\n if (pinPageUrl && pinPageUrl !== getCurrentPageId()) {\n const navEl = document.createElement('div')\n navEl.style.cssText = 'margin-top:6px;padding-top:6px;border-top:1px solid rgba(255,255,255,0.2);font-size:12px;'\n\n const pageLabel = document.createElement('span')\n pageLabel.style.opacity = '0.7'\n pageLabel.textContent = `Page: ${pinPageUrl.split('?')[0].split('#')[0] || '/'} \\u2014 `\n navEl.appendChild(pageLabel)\n\n const navLink = document.createElement('a')\n navLink.style.cssText = 'color:#a78bfa;cursor:pointer;text-decoration:underline;pointer-events:auto;'\n navLink.textContent = 'Navigate there?'\n navLink.addEventListener('click', (e) => {\n e.stopPropagation()\n this.navigateToPin(pinPageUrl, pinNumber)\n })\n navEl.appendChild(navLink)\n\n this.tooltipEl.appendChild(navEl)\n this.tooltipEl.style.pointerEvents = 'auto'\n }\n\n const posX = x ?? window.innerWidth / 2\n const posY = y ?? window.innerHeight / 3\n this.tooltipEl.style.position = 'fixed'\n this.tooltipEl.style.left = `${Math.min(posX, window.innerWidth - 300)}px`\n this.tooltipEl.style.top = `${Math.min(posY, window.innerHeight - 150)}px`\n this.shadowRoot.appendChild(this.tooltipEl)\n\n const dismiss = (ev: MouseEvent) => {\n if (ev.target !== this.tooltipEl && !this.tooltipEl?.contains(ev.target as Node)) {\n this.hideTooltip()\n this.pinManager.clearHighlight()\n document.removeEventListener('click', dismiss, true)\n }\n }\n setTimeout(() => document.addEventListener('click', dismiss, true), 0)\n }\n\n private navigateToPin(pageUrl: string, pinNumber: number): void {\n this.hideTooltip()\n this.pinManager.clearHighlight()\n\n const url = new URL(pageUrl, window.location.origin)\n url.searchParams.set('pin', String(pinNumber))\n window.location.href = url.toString()\n }\n\n private autoFocusPin(): void {\n const params = new URLSearchParams(window.location.search)\n const pinParam = params.get('pin')\n if (!pinParam) return\n\n const pinNumber = Number(pinParam)\n if (!pinNumber) return\n\n const comment = this.comments.find((c) => c.pinNumber === pinNumber)\n if (!comment?.pinData) return\n\n const pinPageUrl = comment.pageUrl ?? ''\n if (pinPageUrl) {\n // Strip ?pin=N from current URL before comparing — navigateToPin adds it,\n // so after redirect getCurrentPageId() includes it but comment.pageUrl doesn't\n const currentUrl = new URL(window.location.href)\n currentUrl.searchParams.delete('pin')\n const currentPageWithoutPin = currentUrl.pathname + currentUrl.search + currentUrl.hash\n if (pinPageUrl !== currentPageWithoutPin) {\n this.navigateToPin(pinPageUrl, pinNumber)\n return\n }\n }\n\n this.pinManager.showAll()\n this.showAllPages = true\n this.updateToolbar()\n\n const docEl = document.documentElement\n const scrollX = (comment.pinData.pinX / 100) * docEl.scrollWidth\n const scrollY = (comment.pinData.pinY / 100) * docEl.scrollHeight\n\n window.scrollTo({\n left: scrollX - window.innerWidth / 2,\n top: scrollY - window.innerHeight / 2,\n behavior: 'smooth',\n })\n\n setTimeout(() => {\n this.pinManager.highlightPin(pinNumber)\n this.showTooltipForPin(pinNumber)\n }, 500)\n }\n\n private hideTooltip(): void {\n this.tooltipEl?.remove()\n this.tooltipEl = null\n }\n\n destroy(): void {\n if (this.pinClickHandler) {\n document.removeEventListener('click', this.pinClickHandler, true)\n }\n this.pageListener?.destroy()\n this.hideTooltip()\n this.toolbarEl?.remove()\n this.pinManager.destroy()\n }\n}\n","import { validateToken, ReviewError } from './api'\nimport { ReviewMode } from './ReviewMode'\nimport { clearStoredToken } from './TokenStorage'\nimport { TriageMode } from './TriageMode'\nimport { REVIEW_STYLES } from './styles'\nimport type { ReviewOptions } from './types'\n\nexport class Review {\n private root: HTMLElement\n private shadow: ShadowRoot\n private mode: ReviewMode | TriageMode | null = null\n private _isDestroyed = false\n\n constructor(_options: ReviewOptions = {}) {\n this.root = document.createElement('div')\n this.root.id = 'ourroadmaps-review'\n this.shadow = this.root.attachShadow({ mode: 'open' })\n\n const styleEl = document.createElement('style')\n styleEl.textContent = REVIEW_STYLES\n this.shadow.appendChild(styleEl)\n\n document.body.appendChild(this.root)\n }\n\n async init(tokenType?: 'review' | 'triage', token?: string): Promise<void> {\n // Backward compat: if no args, read from URL params (old inline script pattern)\n if (!tokenType || !token) {\n const params = new URLSearchParams(window.location.search)\n const reviewToken = params.get('review')\n const triageToken = params.get('triage')\n if (reviewToken) {\n tokenType = 'review'\n token = reviewToken\n } else if (triageToken) {\n tokenType = 'triage'\n token = triageToken\n } else {\n return\n }\n }\n\n if (tokenType === 'review') {\n try {\n const data = await validateToken(token)\n this.mode = new ReviewMode(token, this.shadow, data)\n await this.mode.init()\n } catch (err) {\n if (err instanceof ReviewError) {\n clearStoredToken()\n this.showErrorOverlay(\n err.code === 'expired'\n ? 'This feedback session has expired'\n : 'This review link is no longer valid',\n )\n }\n }\n } else if (tokenType === 'triage') {\n try {\n await validateToken(token)\n this.mode = new TriageMode(token, this.shadow)\n await this.mode.init()\n } catch (err) {\n if (err instanceof ReviewError) {\n clearStoredToken()\n this.showErrorOverlay(\n err.code === 'expired'\n ? 'This feedback session has expired'\n : 'This review link is no longer valid',\n )\n }\n }\n }\n }\n\n private showErrorOverlay(message: string): void {\n const overlay = document.createElement('div')\n overlay.className = 'review-expired-overlay'\n overlay.innerHTML = `\n <div class=\"review-expired-card\">\n <h2 style=\"margin:0 0 8px;font-size:18px;\">Session Unavailable</h2>\n <p style=\"margin:0;color:#666;font-size:14px;\">${message}</p>\n <p style=\"margin:12px 0 0;color:#999;font-size:13px;\">Contact the prototype owner for a new link.</p>\n </div>\n `\n this.shadow.appendChild(overlay)\n\n // Apply grayscale to body\n document.body.style.filter = 'grayscale(0.8)'\n }\n\n destroy(): void {\n if (this._isDestroyed) return\n this._isDestroyed = true\n this.mode?.destroy()\n this.root.remove()\n document.body.style.filter = ''\n }\n}\n"]}
|