web-remarq 0.4.2 → 0.4.4
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/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +4 -1
- package/dist/core/index.d.ts +4 -1
- package/dist/index.cjs +267 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +267 -61
- package/dist/index.js.map +1 -1
- package/dist/web-remarq.global.global.js +267 -61
- package/dist/web-remarq.global.global.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -122,7 +122,7 @@ var AnnotationStorage = class {
|
|
|
122
122
|
const raw = localStorage.getItem(STORAGE_KEY);
|
|
123
123
|
if (raw) {
|
|
124
124
|
const parsed = JSON.parse(raw);
|
|
125
|
-
const
|
|
125
|
+
const _a3 = parsed, { version, annotations } = _a3, rest = __objRest(_a3, ["version", "annotations"]);
|
|
126
126
|
this.annotations = annotations != null ? annotations : [];
|
|
127
127
|
this.extraFields = rest;
|
|
128
128
|
this.migrateViewportBuckets();
|
|
@@ -204,13 +204,13 @@ function detectRemarqPlugin(el) {
|
|
|
204
204
|
};
|
|
205
205
|
}
|
|
206
206
|
function detectExternalSource(el) {
|
|
207
|
-
var
|
|
208
|
-
const source = (
|
|
207
|
+
var _a3;
|
|
208
|
+
const source = (_a3 = el.dataset.source) != null ? _a3 : el.getAttribute("data-locator");
|
|
209
209
|
if (!source) return { source: null, component: null };
|
|
210
210
|
return { source, component: null };
|
|
211
211
|
}
|
|
212
212
|
function detectReactFiber(el) {
|
|
213
|
-
var
|
|
213
|
+
var _a3, _b, _c, _d;
|
|
214
214
|
const key = Object.keys(el).find((k) => k.startsWith("__reactFiber$"));
|
|
215
215
|
if (!key) return { source: null, component: null };
|
|
216
216
|
let current = el[key];
|
|
@@ -218,7 +218,7 @@ function detectReactFiber(el) {
|
|
|
218
218
|
while (current && depth < 15) {
|
|
219
219
|
const debugSource = current._debugSource;
|
|
220
220
|
if (debugSource == null ? void 0 : debugSource.fileName) {
|
|
221
|
-
const source = `${debugSource.fileName}:${(
|
|
221
|
+
const source = `${debugSource.fileName}:${(_a3 = debugSource.lineNumber) != null ? _a3 : 0}:${(_b = debugSource.columnNumber) != null ? _b : 0}`;
|
|
222
222
|
const fiberType = current.type;
|
|
223
223
|
const component = typeof fiberType === "object" && fiberType ? (_d = (_c = fiberType.displayName) != null ? _c : fiberType.name) != null ? _d : null : null;
|
|
224
224
|
return { source, component };
|
|
@@ -239,8 +239,8 @@ function detectSource(el) {
|
|
|
239
239
|
// src/core/fingerprint.ts
|
|
240
240
|
var TEXT_MAX_LENGTH = 50;
|
|
241
241
|
function createFingerprint(el, options2) {
|
|
242
|
-
var
|
|
243
|
-
const dataAttr = (
|
|
242
|
+
var _a3, _b, _c, _d, _e, _f, _g;
|
|
243
|
+
const dataAttr = (_a3 = options2 == null ? void 0 : options2.dataAttribute) != null ? _a3 : "data-annotate";
|
|
244
244
|
return __spreadValues({
|
|
245
245
|
dataAnnotate: (_b = el.getAttribute(dataAttr)) != null ? _b : null,
|
|
246
246
|
dataTestId: (_e = (_d = (_c = el.getAttribute("data-testid")) != null ? _c : el.getAttribute("data-test")) != null ? _d : el.getAttribute("data-cy")) != null ? _e : null,
|
|
@@ -285,11 +285,11 @@ function getStableId(el) {
|
|
|
285
285
|
return id;
|
|
286
286
|
}
|
|
287
287
|
function getTextContent(el) {
|
|
288
|
-
var
|
|
288
|
+
var _a3, _b, _c;
|
|
289
289
|
let text = "";
|
|
290
290
|
for (const node of Array.from(el.childNodes)) {
|
|
291
291
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
292
|
-
text += (
|
|
292
|
+
text += (_a3 = node.textContent) != null ? _a3 : "";
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
295
|
text = text.trim();
|
|
@@ -374,13 +374,13 @@ function jaccardSimilarity(a, b) {
|
|
|
374
374
|
return union === 0 ? 0 : intersection / union;
|
|
375
375
|
}
|
|
376
376
|
function scoreCandidate(el, fp, dataAttr) {
|
|
377
|
-
var
|
|
377
|
+
var _a3, _b;
|
|
378
378
|
let score = 0;
|
|
379
379
|
const elAnnotate = el.getAttribute(dataAttr);
|
|
380
380
|
if (fp.dataAnnotate && elAnnotate === fp.dataAnnotate) {
|
|
381
381
|
score += 100;
|
|
382
382
|
}
|
|
383
|
-
const elText = (_b = (
|
|
383
|
+
const elText = (_b = (_a3 = el.textContent) == null ? void 0 : _a3.trim().slice(0, 50)) != null ? _b : null;
|
|
384
384
|
const textSim = textSimilarity(fp.textContent, elText);
|
|
385
385
|
if (textSim > 0.7) {
|
|
386
386
|
score += textSim * 35;
|
|
@@ -432,8 +432,8 @@ function buildDomPath2(el) {
|
|
|
432
432
|
return parts.join(" > ");
|
|
433
433
|
}
|
|
434
434
|
function matchElement(fp, options2) {
|
|
435
|
-
var
|
|
436
|
-
const dataAttr = (
|
|
435
|
+
var _a3;
|
|
436
|
+
const dataAttr = (_a3 = options2 == null ? void 0 : options2.dataAttribute) != null ? _a3 : "data-annotate";
|
|
437
437
|
if (fp.dataAnnotate) {
|
|
438
438
|
const el = document.querySelector(`[${dataAttr}="${fp.dataAnnotate}"]`);
|
|
439
439
|
if (el) return el;
|
|
@@ -472,10 +472,10 @@ function parseSourceLocation(raw) {
|
|
|
472
472
|
return { file, line, column: isNaN(column) ? 0 : column };
|
|
473
473
|
}
|
|
474
474
|
function resolveSource(fp) {
|
|
475
|
-
var
|
|
475
|
+
var _a3, _b;
|
|
476
476
|
if (fp.sourceLocation) {
|
|
477
477
|
const parsed = parseSourceLocation(fp.sourceLocation);
|
|
478
|
-
if (parsed) return __spreadProps(__spreadValues({}, parsed), { component: (
|
|
478
|
+
if (parsed) return __spreadProps(__spreadValues({}, parsed), { component: (_a3 = fp.componentName) != null ? _a3 : null });
|
|
479
479
|
}
|
|
480
480
|
if (fp.detectedSource) {
|
|
481
481
|
const parsed = parseSourceLocation(fp.detectedSource);
|
|
@@ -487,7 +487,7 @@ var TEMPLATE_GLOB = "*.{tsx,jsx,vue,svelte,html}";
|
|
|
487
487
|
var CSS_MODULE_GLOB = "*.module.{css,scss,less}";
|
|
488
488
|
var COMPONENT_GLOB = "*.{tsx,jsx,vue,ts,js}";
|
|
489
489
|
function buildSearchHints(fp) {
|
|
490
|
-
var
|
|
490
|
+
var _a3, _b;
|
|
491
491
|
const grepQueries = [];
|
|
492
492
|
if (fp.dataAnnotate) {
|
|
493
493
|
grepQueries.push({ query: `data-annotate="${fp.dataAnnotate}"`, glob: TEMPLATE_GLOB, confidence: "high" });
|
|
@@ -507,7 +507,7 @@ function buildSearchHints(fp) {
|
|
|
507
507
|
if (fp.role) {
|
|
508
508
|
grepQueries.push({ query: `role="${fp.role}"`, glob: TEMPLATE_GLOB, confidence: "medium" });
|
|
509
509
|
}
|
|
510
|
-
if ((
|
|
510
|
+
if ((_a3 = fp.cssModules) == null ? void 0 : _a3.length) {
|
|
511
511
|
for (const mod of fp.cssModules) {
|
|
512
512
|
grepQueries.push({ query: `.${mod.localName}`, glob: CSS_MODULE_GLOB, confidence: "medium" });
|
|
513
513
|
grepQueries.push({ query: `styles.${mod.localName}`, glob: COMPONENT_GLOB, confidence: "medium" });
|
|
@@ -574,8 +574,6 @@ var CSS = `
|
|
|
574
574
|
|
|
575
575
|
.remarq-toolbar {
|
|
576
576
|
position: fixed;
|
|
577
|
-
bottom: 16px;
|
|
578
|
-
right: 16px;
|
|
579
577
|
z-index: 2147483647;
|
|
580
578
|
display: flex;
|
|
581
579
|
gap: 4px;
|
|
@@ -589,7 +587,12 @@ var CSS = `
|
|
|
589
587
|
color: var(--remarq-text);
|
|
590
588
|
}
|
|
591
589
|
|
|
592
|
-
.remarq-toolbar.remarq-
|
|
590
|
+
.remarq-toolbar.remarq-pos-bottom-right { bottom: 16px; right: 16px; }
|
|
591
|
+
.remarq-toolbar.remarq-pos-bottom-left { bottom: 16px; left: 16px; flex-direction: row-reverse; }
|
|
592
|
+
.remarq-toolbar.remarq-pos-top-right { top: 16px; right: 16px; }
|
|
593
|
+
.remarq-toolbar.remarq-pos-top-left { top: 16px; left: 16px; flex-direction: row-reverse; }
|
|
594
|
+
|
|
595
|
+
.remarq-toolbar.remarq-minimized { padding: 8px; }
|
|
593
596
|
|
|
594
597
|
.remarq-toolbar-btn {
|
|
595
598
|
display: flex;
|
|
@@ -742,8 +745,6 @@ var CSS = `
|
|
|
742
745
|
|
|
743
746
|
.remarq-detached-panel {
|
|
744
747
|
position: fixed;
|
|
745
|
-
bottom: 60px;
|
|
746
|
-
right: 16px;
|
|
747
748
|
z-index: 2147483646;
|
|
748
749
|
width: 280px;
|
|
749
750
|
max-height: 300px;
|
|
@@ -757,6 +758,11 @@ var CSS = `
|
|
|
757
758
|
color: var(--remarq-text);
|
|
758
759
|
}
|
|
759
760
|
|
|
761
|
+
.remarq-detached-panel.remarq-pos-bottom-right { bottom: 60px; right: 16px; }
|
|
762
|
+
.remarq-detached-panel.remarq-pos-bottom-left { bottom: 60px; left: 16px; }
|
|
763
|
+
.remarq-detached-panel.remarq-pos-top-right { top: 60px; right: 16px; }
|
|
764
|
+
.remarq-detached-panel.remarq-pos-top-left { top: 60px; left: 16px; }
|
|
765
|
+
|
|
760
766
|
.remarq-detached-header {
|
|
761
767
|
padding: 8px 12px;
|
|
762
768
|
border-bottom: 1px solid var(--remarq-border);
|
|
@@ -811,6 +817,20 @@ var CSS = `
|
|
|
811
817
|
overflow: hidden;
|
|
812
818
|
}
|
|
813
819
|
|
|
820
|
+
.remarq-pos-top-right .remarq-export-menu,
|
|
821
|
+
.remarq-pos-top-left .remarq-export-menu {
|
|
822
|
+
bottom: auto;
|
|
823
|
+
top: 100%;
|
|
824
|
+
margin-bottom: 0;
|
|
825
|
+
margin-top: 4px;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
.remarq-pos-bottom-left .remarq-export-menu,
|
|
829
|
+
.remarq-pos-top-left .remarq-export-menu {
|
|
830
|
+
right: auto;
|
|
831
|
+
left: 0;
|
|
832
|
+
}
|
|
833
|
+
|
|
814
834
|
.remarq-export-menu button {
|
|
815
835
|
display: block;
|
|
816
836
|
width: 100%;
|
|
@@ -914,6 +934,70 @@ var CSS = `
|
|
|
914
934
|
.remarq-toolbar-btn:disabled { opacity: 0.3; cursor: default; }
|
|
915
935
|
.remarq-toolbar-btn:disabled:hover { background: transparent; }
|
|
916
936
|
|
|
937
|
+
.remarq-shortcuts-backdrop {
|
|
938
|
+
position: fixed;
|
|
939
|
+
top: 0;
|
|
940
|
+
left: 0;
|
|
941
|
+
width: 100%;
|
|
942
|
+
height: 100%;
|
|
943
|
+
background: rgba(0, 0, 0, 0.4);
|
|
944
|
+
z-index: 2147483647;
|
|
945
|
+
display: flex;
|
|
946
|
+
align-items: center;
|
|
947
|
+
justify-content: center;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
.remarq-shortcuts-modal {
|
|
951
|
+
background: var(--remarq-bg);
|
|
952
|
+
border: 1px solid var(--remarq-border);
|
|
953
|
+
border-radius: 12px;
|
|
954
|
+
box-shadow: var(--remarq-shadow);
|
|
955
|
+
padding: 20px 24px;
|
|
956
|
+
min-width: 300px;
|
|
957
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
958
|
+
color: var(--remarq-text);
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
.remarq-shortcuts-title {
|
|
962
|
+
font-size: 15px;
|
|
963
|
+
font-weight: 600;
|
|
964
|
+
margin-bottom: 12px;
|
|
965
|
+
padding-bottom: 8px;
|
|
966
|
+
border-bottom: 1px solid var(--remarq-border);
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
.remarq-shortcuts-row {
|
|
970
|
+
display: flex;
|
|
971
|
+
align-items: center;
|
|
972
|
+
gap: 12px;
|
|
973
|
+
padding: 4px 0;
|
|
974
|
+
font-size: 13px;
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
.remarq-shortcuts-key {
|
|
978
|
+
display: inline-flex;
|
|
979
|
+
align-items: center;
|
|
980
|
+
justify-content: center;
|
|
981
|
+
min-width: 28px;
|
|
982
|
+
padding: 2px 8px;
|
|
983
|
+
background: var(--remarq-bg-secondary);
|
|
984
|
+
border: 1px solid var(--remarq-border);
|
|
985
|
+
border-radius: 4px;
|
|
986
|
+
font-family: inherit;
|
|
987
|
+
font-size: 12px;
|
|
988
|
+
font-weight: 600;
|
|
989
|
+
white-space: nowrap;
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
.remarq-shortcuts-context {
|
|
993
|
+
font-size: 10px;
|
|
994
|
+
color: var(--remarq-text-secondary);
|
|
995
|
+
background: var(--remarq-bg-secondary);
|
|
996
|
+
border-radius: 3px;
|
|
997
|
+
padding: 1px 6px;
|
|
998
|
+
margin-left: auto;
|
|
999
|
+
}
|
|
1000
|
+
|
|
917
1001
|
.remarq-popup-hint {
|
|
918
1002
|
font-size: 11px;
|
|
919
1003
|
color: var(--remarq-text-secondary);
|
|
@@ -949,9 +1033,9 @@ function removeStyles() {
|
|
|
949
1033
|
var THEME_KEY = "remarq:theme";
|
|
950
1034
|
var ThemeManager = class {
|
|
951
1035
|
constructor(parent, initialTheme) {
|
|
952
|
-
var
|
|
1036
|
+
var _a3;
|
|
953
1037
|
const persisted = this.loadTheme();
|
|
954
|
-
this.theme = (
|
|
1038
|
+
this.theme = (_a3 = initialTheme != null ? initialTheme : persisted) != null ? _a3 : "light";
|
|
955
1039
|
this.container = document.createElement("div");
|
|
956
1040
|
this.container.setAttribute("data-remarq-theme", this.theme);
|
|
957
1041
|
parent.appendChild(this.container);
|
|
@@ -988,14 +1072,18 @@ var ThemeManager = class {
|
|
|
988
1072
|
};
|
|
989
1073
|
|
|
990
1074
|
// src/ui/toolbar.ts
|
|
1075
|
+
var _a;
|
|
1076
|
+
var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test((_a = navigator.platform) != null ? _a : "");
|
|
1077
|
+
var modKey = isMac ? "\u2325" : "Alt";
|
|
991
1078
|
var TOOLTIPS = {
|
|
992
|
-
inspect:
|
|
1079
|
+
inspect: `Inspect element (${modKey}+I)`,
|
|
993
1080
|
spacing: "Spacing overlay (S)",
|
|
994
|
-
copy: "Copy as Markdown",
|
|
1081
|
+
copy: "Copy as Markdown (C)",
|
|
995
1082
|
export: "Export",
|
|
996
1083
|
import: "Import JSON",
|
|
997
1084
|
clear: "Clear all",
|
|
998
1085
|
theme: "Toggle theme",
|
|
1086
|
+
help: "Keyboard shortcuts (?)",
|
|
999
1087
|
minimize: "Minimize"
|
|
1000
1088
|
};
|
|
1001
1089
|
var ICONS = {
|
|
@@ -1006,17 +1094,19 @@ var ICONS = {
|
|
|
1006
1094
|
import: '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M8 10V2M4 6l4 4 4-4M2 12h12"/></svg>',
|
|
1007
1095
|
clear: '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M3 4h10M6 4V3h4v1M5 4v9h6V4"/></svg>',
|
|
1008
1096
|
theme: '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="8" cy="8" r="3"/><path d="M8 1v2M8 13v2M1 8h2M13 8h2"/></svg>',
|
|
1097
|
+
help: '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="8" cy="8" r="6"/><path d="M6 6.5a2 2 0 0 1 3.5 1.5c0 1-1.5 1-1.5 2"/><circle cx="8" cy="12" r="0.5" fill="currentColor" stroke="none"/></svg>',
|
|
1009
1098
|
minimize: '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M4 8h8"/></svg>'
|
|
1010
1099
|
};
|
|
1011
1100
|
var Toolbar = class {
|
|
1012
|
-
constructor(container, callbacks) {
|
|
1101
|
+
constructor(container, callbacks, position = "bottom-right") {
|
|
1013
1102
|
this.container = container;
|
|
1014
1103
|
this.callbacks = callbacks;
|
|
1104
|
+
this.position = position;
|
|
1015
1105
|
this.exportMenu = null;
|
|
1016
1106
|
this.minimized = false;
|
|
1017
1107
|
this.buttons = [];
|
|
1018
1108
|
this.toolbarEl = document.createElement("div");
|
|
1019
|
-
this.toolbarEl.className =
|
|
1109
|
+
this.toolbarEl.className = `remarq-toolbar remarq-pos-${position}`;
|
|
1020
1110
|
this.inspectBtn = this.createButton("inspect", ICONS.inspect, () => callbacks.onInspect());
|
|
1021
1111
|
this.badgeEl = document.createElement("span");
|
|
1022
1112
|
this.badgeEl.className = "remarq-badge";
|
|
@@ -1037,8 +1127,9 @@ var Toolbar = class {
|
|
|
1037
1127
|
const importBtn = this.createButton("import", ICONS.import, () => this.fileInput.click());
|
|
1038
1128
|
const clearBtn = this.createButton("clear", ICONS.clear, () => callbacks.onClear());
|
|
1039
1129
|
const themeBtn = this.createButton("theme", ICONS.theme, () => callbacks.onThemeToggle());
|
|
1130
|
+
const helpBtn = this.createButton("help", ICONS.help, () => callbacks.onHelp());
|
|
1040
1131
|
const minimizeBtn = this.createButton("minimize", ICONS.minimize, () => this.toggleMinimize());
|
|
1041
|
-
this.buttons = [this.inspectBtn, this.spacingBtn, copyBtn, exportBtn, importBtn, clearBtn, themeBtn];
|
|
1132
|
+
this.buttons = [this.inspectBtn, this.spacingBtn, copyBtn, exportBtn, importBtn, clearBtn, themeBtn, helpBtn];
|
|
1042
1133
|
this.toolbarEl.appendChild(this.inspectBtn);
|
|
1043
1134
|
this.toolbarEl.appendChild(this.spacingBtn);
|
|
1044
1135
|
this.toolbarEl.appendChild(copyBtn);
|
|
@@ -1046,6 +1137,7 @@ var Toolbar = class {
|
|
|
1046
1137
|
this.toolbarEl.appendChild(importBtn);
|
|
1047
1138
|
this.toolbarEl.appendChild(clearBtn);
|
|
1048
1139
|
this.toolbarEl.appendChild(themeBtn);
|
|
1140
|
+
this.toolbarEl.appendChild(helpBtn);
|
|
1049
1141
|
this.toolbarEl.appendChild(minimizeBtn);
|
|
1050
1142
|
this.toolbarEl.appendChild(this.fileInput);
|
|
1051
1143
|
container.appendChild(this.toolbarEl);
|
|
@@ -1077,11 +1169,11 @@ var Toolbar = class {
|
|
|
1077
1169
|
this.toolbarEl.remove();
|
|
1078
1170
|
}
|
|
1079
1171
|
createButton(action, icon, handler) {
|
|
1080
|
-
var
|
|
1172
|
+
var _a3;
|
|
1081
1173
|
const btn = document.createElement("button");
|
|
1082
1174
|
btn.className = "remarq-toolbar-btn";
|
|
1083
1175
|
btn.setAttribute("data-remarq-action", action);
|
|
1084
|
-
btn.title = (
|
|
1176
|
+
btn.title = (_a3 = TOOLTIPS[action]) != null ? _a3 : "";
|
|
1085
1177
|
btn.innerHTML = icon;
|
|
1086
1178
|
btn.addEventListener("click", handler);
|
|
1087
1179
|
return btn;
|
|
@@ -1203,11 +1295,11 @@ function describeElement(el) {
|
|
|
1203
1295
|
return parts.join(" ");
|
|
1204
1296
|
}
|
|
1205
1297
|
function getDirectText(el) {
|
|
1206
|
-
var
|
|
1298
|
+
var _a3, _b, _c;
|
|
1207
1299
|
let text = "";
|
|
1208
1300
|
for (const node of Array.from(el.childNodes)) {
|
|
1209
1301
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
1210
|
-
text += (
|
|
1302
|
+
text += (_a3 = node.textContent) != null ? _a3 : "";
|
|
1211
1303
|
}
|
|
1212
1304
|
}
|
|
1213
1305
|
text = text.trim();
|
|
@@ -1725,8 +1817,8 @@ var MarkerManager = class {
|
|
|
1725
1817
|
markerEl.textContent = String(this.counter);
|
|
1726
1818
|
markerEl.title = annotation.comment;
|
|
1727
1819
|
markerEl.addEventListener("click", () => {
|
|
1728
|
-
var
|
|
1729
|
-
(
|
|
1820
|
+
var _a3;
|
|
1821
|
+
(_a3 = this.onClick) == null ? void 0 : _a3.call(this, annotation.id);
|
|
1730
1822
|
});
|
|
1731
1823
|
this.container.appendChild(markerEl);
|
|
1732
1824
|
this.markers.set(annotation.id, { annotation, target, markerEl });
|
|
@@ -1796,6 +1888,7 @@ var MarkerManager = class {
|
|
|
1796
1888
|
// src/ui/toast.ts
|
|
1797
1889
|
var currentToast = null;
|
|
1798
1890
|
var currentTimer = null;
|
|
1891
|
+
var fadeTimer = null;
|
|
1799
1892
|
function showToast(container, message, duration = 3e3) {
|
|
1800
1893
|
hideToast();
|
|
1801
1894
|
const toast = document.createElement("div");
|
|
@@ -1806,7 +1899,7 @@ function showToast(container, message, duration = 3e3) {
|
|
|
1806
1899
|
currentTimer = setTimeout(() => {
|
|
1807
1900
|
if (currentToast) {
|
|
1808
1901
|
currentToast.classList.add("remarq-toast-fade");
|
|
1809
|
-
setTimeout(() => hideToast(), 300);
|
|
1902
|
+
fadeTimer = setTimeout(() => hideToast(), 300);
|
|
1810
1903
|
}
|
|
1811
1904
|
}, duration);
|
|
1812
1905
|
}
|
|
@@ -1815,6 +1908,10 @@ function hideToast() {
|
|
|
1815
1908
|
clearTimeout(currentTimer);
|
|
1816
1909
|
currentTimer = null;
|
|
1817
1910
|
}
|
|
1911
|
+
if (fadeTimer) {
|
|
1912
|
+
clearTimeout(fadeTimer);
|
|
1913
|
+
fadeTimer = null;
|
|
1914
|
+
}
|
|
1818
1915
|
if (currentToast) {
|
|
1819
1916
|
currentToast.remove();
|
|
1820
1917
|
currentToast = null;
|
|
@@ -1823,16 +1920,17 @@ function hideToast() {
|
|
|
1823
1920
|
|
|
1824
1921
|
// src/ui/detached-panel.ts
|
|
1825
1922
|
var DetachedPanel = class {
|
|
1826
|
-
constructor(container, onDelete) {
|
|
1923
|
+
constructor(container, onDelete, position = "bottom-right") {
|
|
1827
1924
|
this.container = container;
|
|
1828
1925
|
this.onDelete = onDelete;
|
|
1926
|
+
this.position = position;
|
|
1829
1927
|
this.panelEl = null;
|
|
1830
1928
|
}
|
|
1831
1929
|
update(otherBreakpoint, detached) {
|
|
1832
1930
|
this.remove();
|
|
1833
1931
|
if (otherBreakpoint.length === 0 && detached.length === 0) return;
|
|
1834
1932
|
const panel = document.createElement("div");
|
|
1835
|
-
panel.className =
|
|
1933
|
+
panel.className = `remarq-detached-panel remarq-pos-${this.position}`;
|
|
1836
1934
|
if (otherBreakpoint.length > 0) {
|
|
1837
1935
|
this.renderSection(panel, `Other viewport (${otherBreakpoint.length})`, otherBreakpoint, "other");
|
|
1838
1936
|
}
|
|
@@ -1880,8 +1978,8 @@ var DetachedPanel = class {
|
|
|
1880
1978
|
deleteBtn.className = "remarq-detached-delete";
|
|
1881
1979
|
deleteBtn.textContent = "\xD7";
|
|
1882
1980
|
deleteBtn.addEventListener("click", () => {
|
|
1883
|
-
var
|
|
1884
|
-
(
|
|
1981
|
+
var _a3;
|
|
1982
|
+
(_a3 = this.onDelete) == null ? void 0 : _a3.call(this, ann.id);
|
|
1885
1983
|
});
|
|
1886
1984
|
item.appendChild(deleteBtn);
|
|
1887
1985
|
}
|
|
@@ -1896,6 +1994,76 @@ var DetachedPanel = class {
|
|
|
1896
1994
|
}
|
|
1897
1995
|
};
|
|
1898
1996
|
|
|
1997
|
+
// src/ui/shortcuts-modal.ts
|
|
1998
|
+
var _a2;
|
|
1999
|
+
var isMac2 = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test((_a2 = navigator.platform) != null ? _a2 : "");
|
|
2000
|
+
var modKey2 = isMac2 ? "\u2325" : "Alt";
|
|
2001
|
+
var SHORTCUTS = [
|
|
2002
|
+
{ key: `${modKey2}+I`, description: "Toggle inspect mode" },
|
|
2003
|
+
{ key: "S", description: "Toggle spacing overlay", context: "inspect" },
|
|
2004
|
+
{ key: "C", description: "Copy all annotations to clipboard", context: "inspect" },
|
|
2005
|
+
{ key: "Esc", description: "Exit inspect mode / close popup" },
|
|
2006
|
+
{ key: "?", description: "Show this help" },
|
|
2007
|
+
{ key: "Enter", description: "Submit annotation", context: "popup" },
|
|
2008
|
+
{ key: "Shift+Enter", description: "New line", context: "popup" }
|
|
2009
|
+
];
|
|
2010
|
+
var modalEl = null;
|
|
2011
|
+
var keyHandler = null;
|
|
2012
|
+
function showShortcutsModal(container) {
|
|
2013
|
+
if (modalEl) {
|
|
2014
|
+
hideShortcutsModal();
|
|
2015
|
+
return;
|
|
2016
|
+
}
|
|
2017
|
+
const backdrop = document.createElement("div");
|
|
2018
|
+
backdrop.className = "remarq-shortcuts-backdrop";
|
|
2019
|
+
const modal = document.createElement("div");
|
|
2020
|
+
modal.className = "remarq-shortcuts-modal";
|
|
2021
|
+
const title = document.createElement("div");
|
|
2022
|
+
title.className = "remarq-shortcuts-title";
|
|
2023
|
+
title.textContent = "Keyboard Shortcuts";
|
|
2024
|
+
modal.appendChild(title);
|
|
2025
|
+
for (const s of SHORTCUTS) {
|
|
2026
|
+
const row = document.createElement("div");
|
|
2027
|
+
row.className = "remarq-shortcuts-row";
|
|
2028
|
+
const key = document.createElement("kbd");
|
|
2029
|
+
key.className = "remarq-shortcuts-key";
|
|
2030
|
+
key.textContent = s.key;
|
|
2031
|
+
const desc = document.createElement("span");
|
|
2032
|
+
desc.textContent = s.description;
|
|
2033
|
+
row.appendChild(key);
|
|
2034
|
+
row.appendChild(desc);
|
|
2035
|
+
if ("context" in s && s.context) {
|
|
2036
|
+
const badge = document.createElement("span");
|
|
2037
|
+
badge.className = "remarq-shortcuts-context";
|
|
2038
|
+
badge.textContent = s.context;
|
|
2039
|
+
row.appendChild(badge);
|
|
2040
|
+
}
|
|
2041
|
+
modal.appendChild(row);
|
|
2042
|
+
}
|
|
2043
|
+
backdrop.appendChild(modal);
|
|
2044
|
+
container.appendChild(backdrop);
|
|
2045
|
+
modalEl = backdrop;
|
|
2046
|
+
backdrop.addEventListener("click", (e) => {
|
|
2047
|
+
if (e.target === backdrop) hideShortcutsModal();
|
|
2048
|
+
});
|
|
2049
|
+
keyHandler = (e) => {
|
|
2050
|
+
if (e.key === "Escape" || e.key === "?") {
|
|
2051
|
+
hideShortcutsModal();
|
|
2052
|
+
}
|
|
2053
|
+
};
|
|
2054
|
+
document.addEventListener("keydown", keyHandler);
|
|
2055
|
+
}
|
|
2056
|
+
function hideShortcutsModal() {
|
|
2057
|
+
if (modalEl) {
|
|
2058
|
+
modalEl.remove();
|
|
2059
|
+
modalEl = null;
|
|
2060
|
+
}
|
|
2061
|
+
if (keyHandler) {
|
|
2062
|
+
document.removeEventListener("keydown", keyHandler);
|
|
2063
|
+
keyHandler = null;
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
|
|
1899
2067
|
// src/spa.ts
|
|
1900
2068
|
var RouteObserver = class {
|
|
1901
2069
|
constructor() {
|
|
@@ -1963,10 +2131,10 @@ var refreshScheduled = false;
|
|
|
1963
2131
|
var savedCursor = "";
|
|
1964
2132
|
var elementCache = /* @__PURE__ */ new Map();
|
|
1965
2133
|
function describeTarget(el) {
|
|
1966
|
-
var
|
|
2134
|
+
var _a3, _b, _c, _d;
|
|
1967
2135
|
const parts = [];
|
|
1968
2136
|
if (el.id) parts.push(`#${el.id}`);
|
|
1969
|
-
const dataAnnotate = el.getAttribute((
|
|
2137
|
+
const dataAnnotate = el.getAttribute((_a3 = options.dataAttribute) != null ? _a3 : "data-annotate");
|
|
1970
2138
|
const dataTestId = el.getAttribute("data-testid") || el.getAttribute("data-test") || el.getAttribute("data-cy");
|
|
1971
2139
|
if (dataAnnotate) parts.push(`[${dataAnnotate}]`);
|
|
1972
2140
|
else if (dataTestId) parts.push(`[${dataTestId}]`);
|
|
@@ -2101,8 +2269,9 @@ function handleInspectHover(e) {
|
|
|
2101
2269
|
overlay.updateTooltipPosition(e.clientX, e.clientY);
|
|
2102
2270
|
}
|
|
2103
2271
|
function handleInspectKeydown(e) {
|
|
2104
|
-
var
|
|
2105
|
-
|
|
2272
|
+
var _a3, _b;
|
|
2273
|
+
if (options.shortcuts === false) return;
|
|
2274
|
+
const tag = (_a3 = e.target) == null ? void 0 : _a3.tagName;
|
|
2106
2275
|
if (tag === "INPUT" || tag === "TEXTAREA" || ((_b = e.target) == null ? void 0 : _b.isContentEditable)) return;
|
|
2107
2276
|
if (e.key === "Escape" && inspecting) {
|
|
2108
2277
|
setInspecting(false);
|
|
@@ -2114,13 +2283,20 @@ function handleInspectKeydown(e) {
|
|
|
2114
2283
|
toolbar.setSpacingActive(spacingMode);
|
|
2115
2284
|
if (!spacingMode) spacingOverlay.hide();
|
|
2116
2285
|
}
|
|
2117
|
-
if (e.
|
|
2286
|
+
if (e.altKey && e.code === "KeyI") {
|
|
2287
|
+
e.preventDefault();
|
|
2118
2288
|
setInspecting(!inspecting);
|
|
2119
2289
|
if (!inspecting) {
|
|
2120
2290
|
overlay.hide();
|
|
2121
2291
|
spacingOverlay.hide();
|
|
2122
2292
|
}
|
|
2123
2293
|
}
|
|
2294
|
+
if (e.key === "c" && inspecting) {
|
|
2295
|
+
copyToClipboard();
|
|
2296
|
+
}
|
|
2297
|
+
if (e.key === "?") {
|
|
2298
|
+
showShortcutsModal(themeManager.container);
|
|
2299
|
+
}
|
|
2124
2300
|
}
|
|
2125
2301
|
function setInspecting(value) {
|
|
2126
2302
|
if (value && !inspecting) {
|
|
@@ -2141,7 +2317,7 @@ function setInspecting(value) {
|
|
|
2141
2317
|
}
|
|
2142
2318
|
}
|
|
2143
2319
|
function handleMarkerClick(annotationId) {
|
|
2144
|
-
var
|
|
2320
|
+
var _a3;
|
|
2145
2321
|
const ann = storage.getAll().find((a) => a.id === annotationId);
|
|
2146
2322
|
if (!ann) return;
|
|
2147
2323
|
const el = resolveElement(ann);
|
|
@@ -2150,7 +2326,7 @@ function handleMarkerClick(annotationId) {
|
|
|
2150
2326
|
popup.showDetail(
|
|
2151
2327
|
{
|
|
2152
2328
|
tag: ann.fingerprint.tagName,
|
|
2153
|
-
text: (
|
|
2329
|
+
text: (_a3 = ann.fingerprint.textContent) != null ? _a3 : "",
|
|
2154
2330
|
comment: ann.comment,
|
|
2155
2331
|
status: ann.status
|
|
2156
2332
|
},
|
|
@@ -2199,7 +2375,7 @@ function generateMarkdown() {
|
|
|
2199
2375
|
if (!anns.length) return "";
|
|
2200
2376
|
const lines = [`## Annotations \u2014 ${route} (${anns.length})`, ""];
|
|
2201
2377
|
anns.forEach((ann, i) => {
|
|
2202
|
-
var
|
|
2378
|
+
var _a3, _b;
|
|
2203
2379
|
const fp = ann.fingerprint;
|
|
2204
2380
|
lines.push(`### ${i + 1}. [${ann.status}] "${ann.comment}"`);
|
|
2205
2381
|
let elDesc = `Element: <${fp.tagName}>`;
|
|
@@ -2230,7 +2406,7 @@ function generateMarkdown() {
|
|
|
2230
2406
|
if (fp.textContent) {
|
|
2231
2407
|
lines.push(`- \`"${fp.textContent}"\` \u2014 text content in templates`);
|
|
2232
2408
|
}
|
|
2233
|
-
if ((
|
|
2409
|
+
if ((_a3 = fp.cssModules) == null ? void 0 : _a3.length) {
|
|
2234
2410
|
for (const mod of fp.cssModules) {
|
|
2235
2411
|
lines.push(`- \`.${mod.localName}\` \u2014 in CSS Module file (likely \`${mod.moduleHint}.module.*\`)`);
|
|
2236
2412
|
lines.push(`- \`styles.${mod.localName}\` \u2014 in component JS/TS`);
|
|
@@ -2269,13 +2445,36 @@ function exportJSON() {
|
|
|
2269
2445
|
showToast(themeManager.container, "Exported as JSON");
|
|
2270
2446
|
}
|
|
2271
2447
|
function copyToClipboard() {
|
|
2448
|
+
var _a3;
|
|
2272
2449
|
const md = generateMarkdown();
|
|
2273
|
-
if (!md)
|
|
2274
|
-
|
|
2450
|
+
if (!md) {
|
|
2451
|
+
showToast(themeManager.container, "No annotations to copy");
|
|
2452
|
+
return;
|
|
2453
|
+
}
|
|
2454
|
+
if ((_a3 = navigator.clipboard) == null ? void 0 : _a3.writeText) {
|
|
2455
|
+
navigator.clipboard.writeText(md).then(() => {
|
|
2456
|
+
showToast(themeManager.container, "Copied to clipboard");
|
|
2457
|
+
}).catch(() => {
|
|
2458
|
+
fallbackCopy(md);
|
|
2459
|
+
});
|
|
2460
|
+
} else {
|
|
2461
|
+
fallbackCopy(md);
|
|
2462
|
+
}
|
|
2463
|
+
}
|
|
2464
|
+
function fallbackCopy(text) {
|
|
2465
|
+
const textarea = document.createElement("textarea");
|
|
2466
|
+
textarea.value = text;
|
|
2467
|
+
textarea.style.position = "fixed";
|
|
2468
|
+
textarea.style.opacity = "0";
|
|
2469
|
+
document.body.appendChild(textarea);
|
|
2470
|
+
textarea.select();
|
|
2471
|
+
try {
|
|
2472
|
+
document.execCommand("copy");
|
|
2275
2473
|
showToast(themeManager.container, "Copied to clipboard");
|
|
2276
|
-
}
|
|
2277
|
-
|
|
2278
|
-
}
|
|
2474
|
+
} catch (e) {
|
|
2475
|
+
showToast(themeManager.container, "Failed to copy");
|
|
2476
|
+
}
|
|
2477
|
+
textarea.remove();
|
|
2279
2478
|
}
|
|
2280
2479
|
function exportAgent() {
|
|
2281
2480
|
const anns = storage.getAll();
|
|
@@ -2295,10 +2494,13 @@ function copyAgentToClipboard() {
|
|
|
2295
2494
|
}
|
|
2296
2495
|
function setupMutationObserver() {
|
|
2297
2496
|
mutationObserver = new MutationObserver((mutations) => {
|
|
2497
|
+
let hasExternalMutation = false;
|
|
2298
2498
|
for (const m of mutations) {
|
|
2299
|
-
if (m.target instanceof HTMLElement && m.target.closest("[data-remarq-theme]"))
|
|
2499
|
+
if (m.target instanceof HTMLElement && m.target.closest("[data-remarq-theme]")) continue;
|
|
2500
|
+
hasExternalMutation = true;
|
|
2501
|
+
break;
|
|
2300
2502
|
}
|
|
2301
|
-
scheduleRefresh();
|
|
2503
|
+
if (hasExternalMutation) scheduleRefresh();
|
|
2302
2504
|
});
|
|
2303
2505
|
mutationObserver.observe(document.body, {
|
|
2304
2506
|
childList: true,
|
|
@@ -2309,6 +2511,7 @@ function setupMutationObserver() {
|
|
|
2309
2511
|
}
|
|
2310
2512
|
var WebRemarq = {
|
|
2311
2513
|
init(opts) {
|
|
2514
|
+
var _a3;
|
|
2312
2515
|
if (initialized) return;
|
|
2313
2516
|
options = opts != null ? opts : {};
|
|
2314
2517
|
try {
|
|
@@ -2319,11 +2522,12 @@ var WebRemarq = {
|
|
|
2319
2522
|
spacingOverlay = new SpacingOverlay(themeManager.container);
|
|
2320
2523
|
popup = new Popup(themeManager.container);
|
|
2321
2524
|
markers = new MarkerManager(themeManager.container, handleMarkerClick);
|
|
2525
|
+
const position = (_a3 = options.position) != null ? _a3 : "bottom-right";
|
|
2322
2526
|
detachedPanel = new DetachedPanel(themeManager.container, (id) => {
|
|
2323
2527
|
elementCache.delete(id);
|
|
2324
2528
|
storage.remove(id);
|
|
2325
2529
|
refreshMarkers();
|
|
2326
|
-
});
|
|
2530
|
+
}, position);
|
|
2327
2531
|
toolbar = new Toolbar(themeManager.container, {
|
|
2328
2532
|
onInspect: () => setInspecting(!inspecting),
|
|
2329
2533
|
onSpacingToggle: () => {
|
|
@@ -2336,8 +2540,8 @@ var WebRemarq = {
|
|
|
2336
2540
|
onExportMd: exportMarkdown,
|
|
2337
2541
|
onExportJson: exportJSON,
|
|
2338
2542
|
onImport: () => {
|
|
2339
|
-
var
|
|
2340
|
-
const file = (
|
|
2543
|
+
var _a4;
|
|
2544
|
+
const file = (_a4 = toolbar.getFileInput().files) == null ? void 0 : _a4[0];
|
|
2341
2545
|
if (file) {
|
|
2342
2546
|
WebRemarq.import(file);
|
|
2343
2547
|
}
|
|
@@ -2348,8 +2552,9 @@ var WebRemarq = {
|
|
|
2348
2552
|
refreshMarkers();
|
|
2349
2553
|
showToast(themeManager.container, "All annotations cleared");
|
|
2350
2554
|
},
|
|
2351
|
-
onThemeToggle: () => themeManager.toggle()
|
|
2352
|
-
|
|
2555
|
+
onThemeToggle: () => themeManager.toggle(),
|
|
2556
|
+
onHelp: () => showShortcutsModal(themeManager.container)
|
|
2557
|
+
}, position);
|
|
2353
2558
|
if (storage.isMemoryOnly) {
|
|
2354
2559
|
toolbar.setMemoryWarning(true);
|
|
2355
2560
|
}
|
|
@@ -2379,6 +2584,7 @@ var WebRemarq = {
|
|
|
2379
2584
|
document.body.style.cursor = savedCursor;
|
|
2380
2585
|
}
|
|
2381
2586
|
hideToast();
|
|
2587
|
+
hideShortcutsModal();
|
|
2382
2588
|
destroyViewportListener();
|
|
2383
2589
|
unsubRoute == null ? void 0 : unsubRoute();
|
|
2384
2590
|
routeObserver == null ? void 0 : routeObserver.destroy();
|