web-remarq 0.4.1 → 0.4.3
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 +260 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +260 -52
- package/dist/index.js.map +1 -1
- package/dist/web-remarq.global.global.js +260 -52
- package/dist/web-remarq.global.global.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -145,7 +145,7 @@ var AnnotationStorage = class {
|
|
|
145
145
|
const raw = localStorage.getItem(STORAGE_KEY);
|
|
146
146
|
if (raw) {
|
|
147
147
|
const parsed = JSON.parse(raw);
|
|
148
|
-
const
|
|
148
|
+
const _a3 = parsed, { version, annotations } = _a3, rest = __objRest(_a3, ["version", "annotations"]);
|
|
149
149
|
this.annotations = annotations != null ? annotations : [];
|
|
150
150
|
this.extraFields = rest;
|
|
151
151
|
this.migrateViewportBuckets();
|
|
@@ -227,13 +227,13 @@ function detectRemarqPlugin(el) {
|
|
|
227
227
|
};
|
|
228
228
|
}
|
|
229
229
|
function detectExternalSource(el) {
|
|
230
|
-
var
|
|
231
|
-
const source = (
|
|
230
|
+
var _a3;
|
|
231
|
+
const source = (_a3 = el.dataset.source) != null ? _a3 : el.getAttribute("data-locator");
|
|
232
232
|
if (!source) return { source: null, component: null };
|
|
233
233
|
return { source, component: null };
|
|
234
234
|
}
|
|
235
235
|
function detectReactFiber(el) {
|
|
236
|
-
var
|
|
236
|
+
var _a3, _b, _c, _d;
|
|
237
237
|
const key = Object.keys(el).find((k) => k.startsWith("__reactFiber$"));
|
|
238
238
|
if (!key) return { source: null, component: null };
|
|
239
239
|
let current = el[key];
|
|
@@ -241,7 +241,7 @@ function detectReactFiber(el) {
|
|
|
241
241
|
while (current && depth < 15) {
|
|
242
242
|
const debugSource = current._debugSource;
|
|
243
243
|
if (debugSource == null ? void 0 : debugSource.fileName) {
|
|
244
|
-
const source = `${debugSource.fileName}:${(
|
|
244
|
+
const source = `${debugSource.fileName}:${(_a3 = debugSource.lineNumber) != null ? _a3 : 0}:${(_b = debugSource.columnNumber) != null ? _b : 0}`;
|
|
245
245
|
const fiberType = current.type;
|
|
246
246
|
const component = typeof fiberType === "object" && fiberType ? (_d = (_c = fiberType.displayName) != null ? _c : fiberType.name) != null ? _d : null : null;
|
|
247
247
|
return { source, component };
|
|
@@ -262,8 +262,8 @@ function detectSource(el) {
|
|
|
262
262
|
// src/core/fingerprint.ts
|
|
263
263
|
var TEXT_MAX_LENGTH = 50;
|
|
264
264
|
function createFingerprint(el, options2) {
|
|
265
|
-
var
|
|
266
|
-
const dataAttr = (
|
|
265
|
+
var _a3, _b, _c, _d, _e, _f, _g;
|
|
266
|
+
const dataAttr = (_a3 = options2 == null ? void 0 : options2.dataAttribute) != null ? _a3 : "data-annotate";
|
|
267
267
|
return __spreadValues({
|
|
268
268
|
dataAnnotate: (_b = el.getAttribute(dataAttr)) != null ? _b : null,
|
|
269
269
|
dataTestId: (_e = (_d = (_c = el.getAttribute("data-testid")) != null ? _c : el.getAttribute("data-test")) != null ? _d : el.getAttribute("data-cy")) != null ? _e : null,
|
|
@@ -308,11 +308,11 @@ function getStableId(el) {
|
|
|
308
308
|
return id;
|
|
309
309
|
}
|
|
310
310
|
function getTextContent(el) {
|
|
311
|
-
var
|
|
311
|
+
var _a3, _b, _c;
|
|
312
312
|
let text = "";
|
|
313
313
|
for (const node of Array.from(el.childNodes)) {
|
|
314
314
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
315
|
-
text += (
|
|
315
|
+
text += (_a3 = node.textContent) != null ? _a3 : "";
|
|
316
316
|
}
|
|
317
317
|
}
|
|
318
318
|
text = text.trim();
|
|
@@ -397,13 +397,13 @@ function jaccardSimilarity(a, b) {
|
|
|
397
397
|
return union === 0 ? 0 : intersection / union;
|
|
398
398
|
}
|
|
399
399
|
function scoreCandidate(el, fp, dataAttr) {
|
|
400
|
-
var
|
|
400
|
+
var _a3, _b;
|
|
401
401
|
let score = 0;
|
|
402
402
|
const elAnnotate = el.getAttribute(dataAttr);
|
|
403
403
|
if (fp.dataAnnotate && elAnnotate === fp.dataAnnotate) {
|
|
404
404
|
score += 100;
|
|
405
405
|
}
|
|
406
|
-
const elText = (_b = (
|
|
406
|
+
const elText = (_b = (_a3 = el.textContent) == null ? void 0 : _a3.trim().slice(0, 50)) != null ? _b : null;
|
|
407
407
|
const textSim = textSimilarity(fp.textContent, elText);
|
|
408
408
|
if (textSim > 0.7) {
|
|
409
409
|
score += textSim * 35;
|
|
@@ -455,8 +455,8 @@ function buildDomPath2(el) {
|
|
|
455
455
|
return parts.join(" > ");
|
|
456
456
|
}
|
|
457
457
|
function matchElement(fp, options2) {
|
|
458
|
-
var
|
|
459
|
-
const dataAttr = (
|
|
458
|
+
var _a3;
|
|
459
|
+
const dataAttr = (_a3 = options2 == null ? void 0 : options2.dataAttribute) != null ? _a3 : "data-annotate";
|
|
460
460
|
if (fp.dataAnnotate) {
|
|
461
461
|
const el = document.querySelector(`[${dataAttr}="${fp.dataAnnotate}"]`);
|
|
462
462
|
if (el) return el;
|
|
@@ -495,10 +495,10 @@ function parseSourceLocation(raw) {
|
|
|
495
495
|
return { file, line, column: isNaN(column) ? 0 : column };
|
|
496
496
|
}
|
|
497
497
|
function resolveSource(fp) {
|
|
498
|
-
var
|
|
498
|
+
var _a3, _b;
|
|
499
499
|
if (fp.sourceLocation) {
|
|
500
500
|
const parsed = parseSourceLocation(fp.sourceLocation);
|
|
501
|
-
if (parsed) return __spreadProps(__spreadValues({}, parsed), { component: (
|
|
501
|
+
if (parsed) return __spreadProps(__spreadValues({}, parsed), { component: (_a3 = fp.componentName) != null ? _a3 : null });
|
|
502
502
|
}
|
|
503
503
|
if (fp.detectedSource) {
|
|
504
504
|
const parsed = parseSourceLocation(fp.detectedSource);
|
|
@@ -510,7 +510,7 @@ var TEMPLATE_GLOB = "*.{tsx,jsx,vue,svelte,html}";
|
|
|
510
510
|
var CSS_MODULE_GLOB = "*.module.{css,scss,less}";
|
|
511
511
|
var COMPONENT_GLOB = "*.{tsx,jsx,vue,ts,js}";
|
|
512
512
|
function buildSearchHints(fp) {
|
|
513
|
-
var
|
|
513
|
+
var _a3, _b;
|
|
514
514
|
const grepQueries = [];
|
|
515
515
|
if (fp.dataAnnotate) {
|
|
516
516
|
grepQueries.push({ query: `data-annotate="${fp.dataAnnotate}"`, glob: TEMPLATE_GLOB, confidence: "high" });
|
|
@@ -530,7 +530,7 @@ function buildSearchHints(fp) {
|
|
|
530
530
|
if (fp.role) {
|
|
531
531
|
grepQueries.push({ query: `role="${fp.role}"`, glob: TEMPLATE_GLOB, confidence: "medium" });
|
|
532
532
|
}
|
|
533
|
-
if ((
|
|
533
|
+
if ((_a3 = fp.cssModules) == null ? void 0 : _a3.length) {
|
|
534
534
|
for (const mod of fp.cssModules) {
|
|
535
535
|
grepQueries.push({ query: `.${mod.localName}`, glob: CSS_MODULE_GLOB, confidence: "medium" });
|
|
536
536
|
grepQueries.push({ query: `styles.${mod.localName}`, glob: COMPONENT_GLOB, confidence: "medium" });
|
|
@@ -597,8 +597,6 @@ var CSS = `
|
|
|
597
597
|
|
|
598
598
|
.remarq-toolbar {
|
|
599
599
|
position: fixed;
|
|
600
|
-
bottom: 16px;
|
|
601
|
-
right: 16px;
|
|
602
600
|
z-index: 2147483647;
|
|
603
601
|
display: flex;
|
|
604
602
|
gap: 4px;
|
|
@@ -612,6 +610,11 @@ var CSS = `
|
|
|
612
610
|
color: var(--remarq-text);
|
|
613
611
|
}
|
|
614
612
|
|
|
613
|
+
.remarq-toolbar.remarq-pos-bottom-right { bottom: 16px; right: 16px; }
|
|
614
|
+
.remarq-toolbar.remarq-pos-bottom-left { bottom: 16px; left: 16px; flex-direction: row-reverse; }
|
|
615
|
+
.remarq-toolbar.remarq-pos-top-right { top: 16px; right: 16px; }
|
|
616
|
+
.remarq-toolbar.remarq-pos-top-left { top: 16px; left: 16px; flex-direction: row-reverse; }
|
|
617
|
+
|
|
615
618
|
.remarq-toolbar.remarq-minimized { padding: 4px; }
|
|
616
619
|
|
|
617
620
|
.remarq-toolbar-btn {
|
|
@@ -765,8 +768,6 @@ var CSS = `
|
|
|
765
768
|
|
|
766
769
|
.remarq-detached-panel {
|
|
767
770
|
position: fixed;
|
|
768
|
-
bottom: 60px;
|
|
769
|
-
right: 16px;
|
|
770
771
|
z-index: 2147483646;
|
|
771
772
|
width: 280px;
|
|
772
773
|
max-height: 300px;
|
|
@@ -780,6 +781,11 @@ var CSS = `
|
|
|
780
781
|
color: var(--remarq-text);
|
|
781
782
|
}
|
|
782
783
|
|
|
784
|
+
.remarq-detached-panel.remarq-pos-bottom-right { bottom: 60px; right: 16px; }
|
|
785
|
+
.remarq-detached-panel.remarq-pos-bottom-left { bottom: 60px; left: 16px; }
|
|
786
|
+
.remarq-detached-panel.remarq-pos-top-right { top: 60px; right: 16px; }
|
|
787
|
+
.remarq-detached-panel.remarq-pos-top-left { top: 60px; left: 16px; }
|
|
788
|
+
|
|
783
789
|
.remarq-detached-header {
|
|
784
790
|
padding: 8px 12px;
|
|
785
791
|
border-bottom: 1px solid var(--remarq-border);
|
|
@@ -834,6 +840,20 @@ var CSS = `
|
|
|
834
840
|
overflow: hidden;
|
|
835
841
|
}
|
|
836
842
|
|
|
843
|
+
.remarq-pos-top-right .remarq-export-menu,
|
|
844
|
+
.remarq-pos-top-left .remarq-export-menu {
|
|
845
|
+
bottom: auto;
|
|
846
|
+
top: 100%;
|
|
847
|
+
margin-bottom: 0;
|
|
848
|
+
margin-top: 4px;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
.remarq-pos-bottom-left .remarq-export-menu,
|
|
852
|
+
.remarq-pos-top-left .remarq-export-menu {
|
|
853
|
+
right: auto;
|
|
854
|
+
left: 0;
|
|
855
|
+
}
|
|
856
|
+
|
|
837
857
|
.remarq-export-menu button {
|
|
838
858
|
display: block;
|
|
839
859
|
width: 100%;
|
|
@@ -937,6 +957,70 @@ var CSS = `
|
|
|
937
957
|
.remarq-toolbar-btn:disabled { opacity: 0.3; cursor: default; }
|
|
938
958
|
.remarq-toolbar-btn:disabled:hover { background: transparent; }
|
|
939
959
|
|
|
960
|
+
.remarq-shortcuts-backdrop {
|
|
961
|
+
position: fixed;
|
|
962
|
+
top: 0;
|
|
963
|
+
left: 0;
|
|
964
|
+
width: 100%;
|
|
965
|
+
height: 100%;
|
|
966
|
+
background: rgba(0, 0, 0, 0.4);
|
|
967
|
+
z-index: 2147483647;
|
|
968
|
+
display: flex;
|
|
969
|
+
align-items: center;
|
|
970
|
+
justify-content: center;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
.remarq-shortcuts-modal {
|
|
974
|
+
background: var(--remarq-bg);
|
|
975
|
+
border: 1px solid var(--remarq-border);
|
|
976
|
+
border-radius: 12px;
|
|
977
|
+
box-shadow: var(--remarq-shadow);
|
|
978
|
+
padding: 20px 24px;
|
|
979
|
+
min-width: 300px;
|
|
980
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
981
|
+
color: var(--remarq-text);
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
.remarq-shortcuts-title {
|
|
985
|
+
font-size: 15px;
|
|
986
|
+
font-weight: 600;
|
|
987
|
+
margin-bottom: 12px;
|
|
988
|
+
padding-bottom: 8px;
|
|
989
|
+
border-bottom: 1px solid var(--remarq-border);
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
.remarq-shortcuts-row {
|
|
993
|
+
display: flex;
|
|
994
|
+
align-items: center;
|
|
995
|
+
gap: 12px;
|
|
996
|
+
padding: 4px 0;
|
|
997
|
+
font-size: 13px;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
.remarq-shortcuts-key {
|
|
1001
|
+
display: inline-flex;
|
|
1002
|
+
align-items: center;
|
|
1003
|
+
justify-content: center;
|
|
1004
|
+
min-width: 28px;
|
|
1005
|
+
padding: 2px 8px;
|
|
1006
|
+
background: var(--remarq-bg-secondary);
|
|
1007
|
+
border: 1px solid var(--remarq-border);
|
|
1008
|
+
border-radius: 4px;
|
|
1009
|
+
font-family: inherit;
|
|
1010
|
+
font-size: 12px;
|
|
1011
|
+
font-weight: 600;
|
|
1012
|
+
white-space: nowrap;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
.remarq-shortcuts-context {
|
|
1016
|
+
font-size: 10px;
|
|
1017
|
+
color: var(--remarq-text-secondary);
|
|
1018
|
+
background: var(--remarq-bg-secondary);
|
|
1019
|
+
border-radius: 3px;
|
|
1020
|
+
padding: 1px 6px;
|
|
1021
|
+
margin-left: auto;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
940
1024
|
.remarq-popup-hint {
|
|
941
1025
|
font-size: 11px;
|
|
942
1026
|
color: var(--remarq-text-secondary);
|
|
@@ -972,9 +1056,9 @@ function removeStyles() {
|
|
|
972
1056
|
var THEME_KEY = "remarq:theme";
|
|
973
1057
|
var ThemeManager = class {
|
|
974
1058
|
constructor(parent, initialTheme) {
|
|
975
|
-
var
|
|
1059
|
+
var _a3;
|
|
976
1060
|
const persisted = this.loadTheme();
|
|
977
|
-
this.theme = (
|
|
1061
|
+
this.theme = (_a3 = initialTheme != null ? initialTheme : persisted) != null ? _a3 : "light";
|
|
978
1062
|
this.container = document.createElement("div");
|
|
979
1063
|
this.container.setAttribute("data-remarq-theme", this.theme);
|
|
980
1064
|
parent.appendChild(this.container);
|
|
@@ -1011,14 +1095,18 @@ var ThemeManager = class {
|
|
|
1011
1095
|
};
|
|
1012
1096
|
|
|
1013
1097
|
// src/ui/toolbar.ts
|
|
1098
|
+
var _a;
|
|
1099
|
+
var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test((_a = navigator.platform) != null ? _a : "");
|
|
1100
|
+
var modKey = isMac ? "\u2325" : "Alt";
|
|
1014
1101
|
var TOOLTIPS = {
|
|
1015
|
-
inspect:
|
|
1102
|
+
inspect: `Inspect element (${modKey}+I)`,
|
|
1016
1103
|
spacing: "Spacing overlay (S)",
|
|
1017
|
-
copy: "Copy as Markdown",
|
|
1104
|
+
copy: "Copy as Markdown (C)",
|
|
1018
1105
|
export: "Export",
|
|
1019
1106
|
import: "Import JSON",
|
|
1020
1107
|
clear: "Clear all",
|
|
1021
1108
|
theme: "Toggle theme",
|
|
1109
|
+
help: "Keyboard shortcuts (?)",
|
|
1022
1110
|
minimize: "Minimize"
|
|
1023
1111
|
};
|
|
1024
1112
|
var ICONS = {
|
|
@@ -1029,17 +1117,19 @@ var ICONS = {
|
|
|
1029
1117
|
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>',
|
|
1030
1118
|
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>',
|
|
1031
1119
|
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>',
|
|
1120
|
+
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>',
|
|
1032
1121
|
minimize: '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M4 8h8"/></svg>'
|
|
1033
1122
|
};
|
|
1034
1123
|
var Toolbar = class {
|
|
1035
|
-
constructor(container, callbacks) {
|
|
1124
|
+
constructor(container, callbacks, position = "bottom-right") {
|
|
1036
1125
|
this.container = container;
|
|
1037
1126
|
this.callbacks = callbacks;
|
|
1127
|
+
this.position = position;
|
|
1038
1128
|
this.exportMenu = null;
|
|
1039
1129
|
this.minimized = false;
|
|
1040
1130
|
this.buttons = [];
|
|
1041
1131
|
this.toolbarEl = document.createElement("div");
|
|
1042
|
-
this.toolbarEl.className =
|
|
1132
|
+
this.toolbarEl.className = `remarq-toolbar remarq-pos-${position}`;
|
|
1043
1133
|
this.inspectBtn = this.createButton("inspect", ICONS.inspect, () => callbacks.onInspect());
|
|
1044
1134
|
this.badgeEl = document.createElement("span");
|
|
1045
1135
|
this.badgeEl.className = "remarq-badge";
|
|
@@ -1060,8 +1150,9 @@ var Toolbar = class {
|
|
|
1060
1150
|
const importBtn = this.createButton("import", ICONS.import, () => this.fileInput.click());
|
|
1061
1151
|
const clearBtn = this.createButton("clear", ICONS.clear, () => callbacks.onClear());
|
|
1062
1152
|
const themeBtn = this.createButton("theme", ICONS.theme, () => callbacks.onThemeToggle());
|
|
1153
|
+
const helpBtn = this.createButton("help", ICONS.help, () => callbacks.onHelp());
|
|
1063
1154
|
const minimizeBtn = this.createButton("minimize", ICONS.minimize, () => this.toggleMinimize());
|
|
1064
|
-
this.buttons = [this.inspectBtn, this.spacingBtn, copyBtn, exportBtn, importBtn, clearBtn, themeBtn];
|
|
1155
|
+
this.buttons = [this.inspectBtn, this.spacingBtn, copyBtn, exportBtn, importBtn, clearBtn, themeBtn, helpBtn];
|
|
1065
1156
|
this.toolbarEl.appendChild(this.inspectBtn);
|
|
1066
1157
|
this.toolbarEl.appendChild(this.spacingBtn);
|
|
1067
1158
|
this.toolbarEl.appendChild(copyBtn);
|
|
@@ -1069,6 +1160,7 @@ var Toolbar = class {
|
|
|
1069
1160
|
this.toolbarEl.appendChild(importBtn);
|
|
1070
1161
|
this.toolbarEl.appendChild(clearBtn);
|
|
1071
1162
|
this.toolbarEl.appendChild(themeBtn);
|
|
1163
|
+
this.toolbarEl.appendChild(helpBtn);
|
|
1072
1164
|
this.toolbarEl.appendChild(minimizeBtn);
|
|
1073
1165
|
this.toolbarEl.appendChild(this.fileInput);
|
|
1074
1166
|
container.appendChild(this.toolbarEl);
|
|
@@ -1100,11 +1192,11 @@ var Toolbar = class {
|
|
|
1100
1192
|
this.toolbarEl.remove();
|
|
1101
1193
|
}
|
|
1102
1194
|
createButton(action, icon, handler) {
|
|
1103
|
-
var
|
|
1195
|
+
var _a3;
|
|
1104
1196
|
const btn = document.createElement("button");
|
|
1105
1197
|
btn.className = "remarq-toolbar-btn";
|
|
1106
1198
|
btn.setAttribute("data-remarq-action", action);
|
|
1107
|
-
btn.title = (
|
|
1199
|
+
btn.title = (_a3 = TOOLTIPS[action]) != null ? _a3 : "";
|
|
1108
1200
|
btn.innerHTML = icon;
|
|
1109
1201
|
btn.addEventListener("click", handler);
|
|
1110
1202
|
return btn;
|
|
@@ -1226,11 +1318,11 @@ function describeElement(el) {
|
|
|
1226
1318
|
return parts.join(" ");
|
|
1227
1319
|
}
|
|
1228
1320
|
function getDirectText(el) {
|
|
1229
|
-
var
|
|
1321
|
+
var _a3, _b, _c;
|
|
1230
1322
|
let text = "";
|
|
1231
1323
|
for (const node of Array.from(el.childNodes)) {
|
|
1232
1324
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
1233
|
-
text += (
|
|
1325
|
+
text += (_a3 = node.textContent) != null ? _a3 : "";
|
|
1234
1326
|
}
|
|
1235
1327
|
}
|
|
1236
1328
|
text = text.trim();
|
|
@@ -1589,6 +1681,12 @@ var Popup = class {
|
|
|
1589
1681
|
});
|
|
1590
1682
|
actions.appendChild(resolveBtn);
|
|
1591
1683
|
}
|
|
1684
|
+
const copyBtn = document.createElement("button");
|
|
1685
|
+
copyBtn.textContent = "Copy";
|
|
1686
|
+
copyBtn.addEventListener("click", () => {
|
|
1687
|
+
callbacks.onCopy();
|
|
1688
|
+
});
|
|
1689
|
+
actions.appendChild(copyBtn);
|
|
1592
1690
|
const deleteBtn = document.createElement("button");
|
|
1593
1691
|
deleteBtn.textContent = "Delete";
|
|
1594
1692
|
deleteBtn.addEventListener("click", () => {
|
|
@@ -1742,17 +1840,19 @@ var MarkerManager = class {
|
|
|
1742
1840
|
markerEl.textContent = String(this.counter);
|
|
1743
1841
|
markerEl.title = annotation.comment;
|
|
1744
1842
|
markerEl.addEventListener("click", () => {
|
|
1745
|
-
var
|
|
1746
|
-
(
|
|
1843
|
+
var _a3;
|
|
1844
|
+
(_a3 = this.onClick) == null ? void 0 : _a3.call(this, annotation.id);
|
|
1747
1845
|
});
|
|
1748
1846
|
this.container.appendChild(markerEl);
|
|
1749
1847
|
this.markers.set(annotation.id, { annotation, target, markerEl });
|
|
1848
|
+
this.applyOutline(target, annotation.status);
|
|
1750
1849
|
this.updatePosition(annotation.id);
|
|
1751
1850
|
}
|
|
1752
1851
|
removeMarker(id) {
|
|
1753
1852
|
const entry = this.markers.get(id);
|
|
1754
1853
|
if (entry) {
|
|
1755
1854
|
entry.markerEl.remove();
|
|
1855
|
+
this.removeOutline(entry.target);
|
|
1756
1856
|
this.markers.delete(id);
|
|
1757
1857
|
}
|
|
1758
1858
|
}
|
|
@@ -1766,6 +1866,7 @@ var MarkerManager = class {
|
|
|
1766
1866
|
clear() {
|
|
1767
1867
|
for (const entry of this.markers.values()) {
|
|
1768
1868
|
entry.markerEl.remove();
|
|
1869
|
+
this.removeOutline(entry.target);
|
|
1769
1870
|
}
|
|
1770
1871
|
this.markers.clear();
|
|
1771
1872
|
this.counter = 0;
|
|
@@ -1777,6 +1878,15 @@ var MarkerManager = class {
|
|
|
1777
1878
|
}
|
|
1778
1879
|
this.clear();
|
|
1779
1880
|
}
|
|
1881
|
+
applyOutline(target, status) {
|
|
1882
|
+
const color = status === "pending" ? "#f97316" : "rgba(34, 197, 94, 0.5)";
|
|
1883
|
+
target.style.outline = `2px solid ${color}`;
|
|
1884
|
+
target.style.outlineOffset = "2px";
|
|
1885
|
+
}
|
|
1886
|
+
removeOutline(target) {
|
|
1887
|
+
target.style.outline = "";
|
|
1888
|
+
target.style.outlineOffset = "";
|
|
1889
|
+
}
|
|
1780
1890
|
updatePosition(id) {
|
|
1781
1891
|
const entry = this.markers.get(id);
|
|
1782
1892
|
if (!entry) return;
|
|
@@ -1828,16 +1938,17 @@ function hideToast() {
|
|
|
1828
1938
|
|
|
1829
1939
|
// src/ui/detached-panel.ts
|
|
1830
1940
|
var DetachedPanel = class {
|
|
1831
|
-
constructor(container, onDelete) {
|
|
1941
|
+
constructor(container, onDelete, position = "bottom-right") {
|
|
1832
1942
|
this.container = container;
|
|
1833
1943
|
this.onDelete = onDelete;
|
|
1944
|
+
this.position = position;
|
|
1834
1945
|
this.panelEl = null;
|
|
1835
1946
|
}
|
|
1836
1947
|
update(otherBreakpoint, detached) {
|
|
1837
1948
|
this.remove();
|
|
1838
1949
|
if (otherBreakpoint.length === 0 && detached.length === 0) return;
|
|
1839
1950
|
const panel = document.createElement("div");
|
|
1840
|
-
panel.className =
|
|
1951
|
+
panel.className = `remarq-detached-panel remarq-pos-${this.position}`;
|
|
1841
1952
|
if (otherBreakpoint.length > 0) {
|
|
1842
1953
|
this.renderSection(panel, `Other viewport (${otherBreakpoint.length})`, otherBreakpoint, "other");
|
|
1843
1954
|
}
|
|
@@ -1885,8 +1996,8 @@ var DetachedPanel = class {
|
|
|
1885
1996
|
deleteBtn.className = "remarq-detached-delete";
|
|
1886
1997
|
deleteBtn.textContent = "\xD7";
|
|
1887
1998
|
deleteBtn.addEventListener("click", () => {
|
|
1888
|
-
var
|
|
1889
|
-
(
|
|
1999
|
+
var _a3;
|
|
2000
|
+
(_a3 = this.onDelete) == null ? void 0 : _a3.call(this, ann.id);
|
|
1890
2001
|
});
|
|
1891
2002
|
item.appendChild(deleteBtn);
|
|
1892
2003
|
}
|
|
@@ -1901,6 +2012,76 @@ var DetachedPanel = class {
|
|
|
1901
2012
|
}
|
|
1902
2013
|
};
|
|
1903
2014
|
|
|
2015
|
+
// src/ui/shortcuts-modal.ts
|
|
2016
|
+
var _a2;
|
|
2017
|
+
var isMac2 = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test((_a2 = navigator.platform) != null ? _a2 : "");
|
|
2018
|
+
var modKey2 = isMac2 ? "\u2325" : "Alt";
|
|
2019
|
+
var SHORTCUTS = [
|
|
2020
|
+
{ key: `${modKey2}+I`, description: "Toggle inspect mode" },
|
|
2021
|
+
{ key: "S", description: "Toggle spacing overlay", context: "inspect" },
|
|
2022
|
+
{ key: "C", description: "Copy all annotations to clipboard", context: "inspect" },
|
|
2023
|
+
{ key: "Esc", description: "Exit inspect mode / close popup" },
|
|
2024
|
+
{ key: "?", description: "Show this help" },
|
|
2025
|
+
{ key: "Enter", description: "Submit annotation", context: "popup" },
|
|
2026
|
+
{ key: "Shift+Enter", description: "New line", context: "popup" }
|
|
2027
|
+
];
|
|
2028
|
+
var modalEl = null;
|
|
2029
|
+
var keyHandler = null;
|
|
2030
|
+
function showShortcutsModal(container) {
|
|
2031
|
+
if (modalEl) {
|
|
2032
|
+
hideShortcutsModal();
|
|
2033
|
+
return;
|
|
2034
|
+
}
|
|
2035
|
+
const backdrop = document.createElement("div");
|
|
2036
|
+
backdrop.className = "remarq-shortcuts-backdrop";
|
|
2037
|
+
const modal = document.createElement("div");
|
|
2038
|
+
modal.className = "remarq-shortcuts-modal";
|
|
2039
|
+
const title = document.createElement("div");
|
|
2040
|
+
title.className = "remarq-shortcuts-title";
|
|
2041
|
+
title.textContent = "Keyboard Shortcuts";
|
|
2042
|
+
modal.appendChild(title);
|
|
2043
|
+
for (const s of SHORTCUTS) {
|
|
2044
|
+
const row = document.createElement("div");
|
|
2045
|
+
row.className = "remarq-shortcuts-row";
|
|
2046
|
+
const key = document.createElement("kbd");
|
|
2047
|
+
key.className = "remarq-shortcuts-key";
|
|
2048
|
+
key.textContent = s.key;
|
|
2049
|
+
const desc = document.createElement("span");
|
|
2050
|
+
desc.textContent = s.description;
|
|
2051
|
+
row.appendChild(key);
|
|
2052
|
+
row.appendChild(desc);
|
|
2053
|
+
if ("context" in s && s.context) {
|
|
2054
|
+
const badge = document.createElement("span");
|
|
2055
|
+
badge.className = "remarq-shortcuts-context";
|
|
2056
|
+
badge.textContent = s.context;
|
|
2057
|
+
row.appendChild(badge);
|
|
2058
|
+
}
|
|
2059
|
+
modal.appendChild(row);
|
|
2060
|
+
}
|
|
2061
|
+
backdrop.appendChild(modal);
|
|
2062
|
+
container.appendChild(backdrop);
|
|
2063
|
+
modalEl = backdrop;
|
|
2064
|
+
backdrop.addEventListener("click", (e) => {
|
|
2065
|
+
if (e.target === backdrop) hideShortcutsModal();
|
|
2066
|
+
});
|
|
2067
|
+
keyHandler = (e) => {
|
|
2068
|
+
if (e.key === "Escape" || e.key === "?") {
|
|
2069
|
+
hideShortcutsModal();
|
|
2070
|
+
}
|
|
2071
|
+
};
|
|
2072
|
+
document.addEventListener("keydown", keyHandler);
|
|
2073
|
+
}
|
|
2074
|
+
function hideShortcutsModal() {
|
|
2075
|
+
if (modalEl) {
|
|
2076
|
+
modalEl.remove();
|
|
2077
|
+
modalEl = null;
|
|
2078
|
+
}
|
|
2079
|
+
if (keyHandler) {
|
|
2080
|
+
document.removeEventListener("keydown", keyHandler);
|
|
2081
|
+
keyHandler = null;
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
|
|
1904
2085
|
// src/spa.ts
|
|
1905
2086
|
var RouteObserver = class {
|
|
1906
2087
|
constructor() {
|
|
@@ -1968,10 +2149,10 @@ var refreshScheduled = false;
|
|
|
1968
2149
|
var savedCursor = "";
|
|
1969
2150
|
var elementCache = /* @__PURE__ */ new Map();
|
|
1970
2151
|
function describeTarget(el) {
|
|
1971
|
-
var
|
|
2152
|
+
var _a3, _b, _c, _d;
|
|
1972
2153
|
const parts = [];
|
|
1973
2154
|
if (el.id) parts.push(`#${el.id}`);
|
|
1974
|
-
const dataAnnotate = el.getAttribute((
|
|
2155
|
+
const dataAnnotate = el.getAttribute((_a3 = options.dataAttribute) != null ? _a3 : "data-annotate");
|
|
1975
2156
|
const dataTestId = el.getAttribute("data-testid") || el.getAttribute("data-test") || el.getAttribute("data-cy");
|
|
1976
2157
|
if (dataAnnotate) parts.push(`[${dataAnnotate}]`);
|
|
1977
2158
|
else if (dataTestId) parts.push(`[${dataTestId}]`);
|
|
@@ -2106,8 +2287,9 @@ function handleInspectHover(e) {
|
|
|
2106
2287
|
overlay.updateTooltipPosition(e.clientX, e.clientY);
|
|
2107
2288
|
}
|
|
2108
2289
|
function handleInspectKeydown(e) {
|
|
2109
|
-
var
|
|
2110
|
-
|
|
2290
|
+
var _a3, _b;
|
|
2291
|
+
if (options.shortcuts === false) return;
|
|
2292
|
+
const tag = (_a3 = e.target) == null ? void 0 : _a3.tagName;
|
|
2111
2293
|
if (tag === "INPUT" || tag === "TEXTAREA" || ((_b = e.target) == null ? void 0 : _b.isContentEditable)) return;
|
|
2112
2294
|
if (e.key === "Escape" && inspecting) {
|
|
2113
2295
|
setInspecting(false);
|
|
@@ -2119,13 +2301,20 @@ function handleInspectKeydown(e) {
|
|
|
2119
2301
|
toolbar.setSpacingActive(spacingMode);
|
|
2120
2302
|
if (!spacingMode) spacingOverlay.hide();
|
|
2121
2303
|
}
|
|
2122
|
-
if (e.key === "i") {
|
|
2304
|
+
if (e.key === "i" && e.altKey) {
|
|
2305
|
+
e.preventDefault();
|
|
2123
2306
|
setInspecting(!inspecting);
|
|
2124
2307
|
if (!inspecting) {
|
|
2125
2308
|
overlay.hide();
|
|
2126
2309
|
spacingOverlay.hide();
|
|
2127
2310
|
}
|
|
2128
2311
|
}
|
|
2312
|
+
if (e.key === "c" && inspecting) {
|
|
2313
|
+
copyToClipboard();
|
|
2314
|
+
}
|
|
2315
|
+
if (e.key === "?") {
|
|
2316
|
+
showShortcutsModal(themeManager.container);
|
|
2317
|
+
}
|
|
2129
2318
|
}
|
|
2130
2319
|
function setInspecting(value) {
|
|
2131
2320
|
if (value && !inspecting) {
|
|
@@ -2146,7 +2335,7 @@ function setInspecting(value) {
|
|
|
2146
2335
|
}
|
|
2147
2336
|
}
|
|
2148
2337
|
function handleMarkerClick(annotationId) {
|
|
2149
|
-
var
|
|
2338
|
+
var _a3;
|
|
2150
2339
|
const ann = storage.getAll().find((a) => a.id === annotationId);
|
|
2151
2340
|
if (!ann) return;
|
|
2152
2341
|
const el = resolveElement(ann);
|
|
@@ -2155,7 +2344,7 @@ function handleMarkerClick(annotationId) {
|
|
|
2155
2344
|
popup.showDetail(
|
|
2156
2345
|
{
|
|
2157
2346
|
tag: ann.fingerprint.tagName,
|
|
2158
|
-
text: (
|
|
2347
|
+
text: (_a3 = ann.fingerprint.textContent) != null ? _a3 : "",
|
|
2159
2348
|
comment: ann.comment,
|
|
2160
2349
|
status: ann.status
|
|
2161
2350
|
},
|
|
@@ -2179,6 +2368,21 @@ function handleMarkerClick(annotationId) {
|
|
|
2179
2368
|
onEdit: (newComment) => {
|
|
2180
2369
|
storage.update(ann.id, { comment: newComment });
|
|
2181
2370
|
refreshMarkers();
|
|
2371
|
+
},
|
|
2372
|
+
onCopy: () => {
|
|
2373
|
+
const fp = ann.fingerprint;
|
|
2374
|
+
const lines = [
|
|
2375
|
+
`[${ann.status}] "${ann.comment}"`,
|
|
2376
|
+
`Element: <${fp.tagName}>${fp.textContent ? ` "${fp.textContent}"` : ""}`,
|
|
2377
|
+
`Route: ${ann.route}`,
|
|
2378
|
+
`Viewport: ${ann.viewportBucket}px`
|
|
2379
|
+
];
|
|
2380
|
+
if (fp.sourceLocation) lines.push(`Source: ${fp.sourceLocation}`);
|
|
2381
|
+
navigator.clipboard.writeText(lines.join("\n")).then(() => {
|
|
2382
|
+
showToast(themeManager.container, "Annotation copied");
|
|
2383
|
+
}).catch(() => {
|
|
2384
|
+
console.warn("[web-remarq] Clipboard write failed");
|
|
2385
|
+
});
|
|
2182
2386
|
}
|
|
2183
2387
|
}
|
|
2184
2388
|
);
|
|
@@ -2189,7 +2393,7 @@ function generateMarkdown() {
|
|
|
2189
2393
|
if (!anns.length) return "";
|
|
2190
2394
|
const lines = [`## Annotations \u2014 ${route} (${anns.length})`, ""];
|
|
2191
2395
|
anns.forEach((ann, i) => {
|
|
2192
|
-
var
|
|
2396
|
+
var _a3, _b;
|
|
2193
2397
|
const fp = ann.fingerprint;
|
|
2194
2398
|
lines.push(`### ${i + 1}. [${ann.status}] "${ann.comment}"`);
|
|
2195
2399
|
let elDesc = `Element: <${fp.tagName}>`;
|
|
@@ -2220,7 +2424,7 @@ function generateMarkdown() {
|
|
|
2220
2424
|
if (fp.textContent) {
|
|
2221
2425
|
lines.push(`- \`"${fp.textContent}"\` \u2014 text content in templates`);
|
|
2222
2426
|
}
|
|
2223
|
-
if ((
|
|
2427
|
+
if ((_a3 = fp.cssModules) == null ? void 0 : _a3.length) {
|
|
2224
2428
|
for (const mod of fp.cssModules) {
|
|
2225
2429
|
lines.push(`- \`.${mod.localName}\` \u2014 in CSS Module file (likely \`${mod.moduleHint}.module.*\`)`);
|
|
2226
2430
|
lines.push(`- \`styles.${mod.localName}\` \u2014 in component JS/TS`);
|
|
@@ -2299,6 +2503,7 @@ function setupMutationObserver() {
|
|
|
2299
2503
|
}
|
|
2300
2504
|
var WebRemarq = {
|
|
2301
2505
|
init(opts) {
|
|
2506
|
+
var _a3;
|
|
2302
2507
|
if (initialized) return;
|
|
2303
2508
|
options = opts != null ? opts : {};
|
|
2304
2509
|
try {
|
|
@@ -2309,11 +2514,12 @@ var WebRemarq = {
|
|
|
2309
2514
|
spacingOverlay = new SpacingOverlay(themeManager.container);
|
|
2310
2515
|
popup = new Popup(themeManager.container);
|
|
2311
2516
|
markers = new MarkerManager(themeManager.container, handleMarkerClick);
|
|
2517
|
+
const position = (_a3 = options.position) != null ? _a3 : "bottom-right";
|
|
2312
2518
|
detachedPanel = new DetachedPanel(themeManager.container, (id) => {
|
|
2313
2519
|
elementCache.delete(id);
|
|
2314
2520
|
storage.remove(id);
|
|
2315
2521
|
refreshMarkers();
|
|
2316
|
-
});
|
|
2522
|
+
}, position);
|
|
2317
2523
|
toolbar = new Toolbar(themeManager.container, {
|
|
2318
2524
|
onInspect: () => setInspecting(!inspecting),
|
|
2319
2525
|
onSpacingToggle: () => {
|
|
@@ -2326,8 +2532,8 @@ var WebRemarq = {
|
|
|
2326
2532
|
onExportMd: exportMarkdown,
|
|
2327
2533
|
onExportJson: exportJSON,
|
|
2328
2534
|
onImport: () => {
|
|
2329
|
-
var
|
|
2330
|
-
const file = (
|
|
2535
|
+
var _a4;
|
|
2536
|
+
const file = (_a4 = toolbar.getFileInput().files) == null ? void 0 : _a4[0];
|
|
2331
2537
|
if (file) {
|
|
2332
2538
|
WebRemarq.import(file);
|
|
2333
2539
|
}
|
|
@@ -2338,8 +2544,9 @@ var WebRemarq = {
|
|
|
2338
2544
|
refreshMarkers();
|
|
2339
2545
|
showToast(themeManager.container, "All annotations cleared");
|
|
2340
2546
|
},
|
|
2341
|
-
onThemeToggle: () => themeManager.toggle()
|
|
2342
|
-
|
|
2547
|
+
onThemeToggle: () => themeManager.toggle(),
|
|
2548
|
+
onHelp: () => showShortcutsModal(themeManager.container)
|
|
2549
|
+
}, position);
|
|
2343
2550
|
if (storage.isMemoryOnly) {
|
|
2344
2551
|
toolbar.setMemoryWarning(true);
|
|
2345
2552
|
}
|
|
@@ -2369,6 +2576,7 @@ var WebRemarq = {
|
|
|
2369
2576
|
document.body.style.cursor = savedCursor;
|
|
2370
2577
|
}
|
|
2371
2578
|
hideToast();
|
|
2579
|
+
hideShortcutsModal();
|
|
2372
2580
|
destroyViewportListener();
|
|
2373
2581
|
unsubRoute == null ? void 0 : unsubRoute();
|
|
2374
2582
|
routeObserver == null ? void 0 : routeObserver.destroy();
|