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.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,6 +587,11 @@ var CSS = `
|
|
|
589
587
|
color: var(--remarq-text);
|
|
590
588
|
}
|
|
591
589
|
|
|
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
|
+
|
|
592
595
|
.remarq-toolbar.remarq-minimized { padding: 4px; }
|
|
593
596
|
|
|
594
597
|
.remarq-toolbar-btn {
|
|
@@ -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();
|
|
@@ -1566,6 +1658,12 @@ var Popup = class {
|
|
|
1566
1658
|
});
|
|
1567
1659
|
actions.appendChild(resolveBtn);
|
|
1568
1660
|
}
|
|
1661
|
+
const copyBtn = document.createElement("button");
|
|
1662
|
+
copyBtn.textContent = "Copy";
|
|
1663
|
+
copyBtn.addEventListener("click", () => {
|
|
1664
|
+
callbacks.onCopy();
|
|
1665
|
+
});
|
|
1666
|
+
actions.appendChild(copyBtn);
|
|
1569
1667
|
const deleteBtn = document.createElement("button");
|
|
1570
1668
|
deleteBtn.textContent = "Delete";
|
|
1571
1669
|
deleteBtn.addEventListener("click", () => {
|
|
@@ -1719,17 +1817,19 @@ var MarkerManager = class {
|
|
|
1719
1817
|
markerEl.textContent = String(this.counter);
|
|
1720
1818
|
markerEl.title = annotation.comment;
|
|
1721
1819
|
markerEl.addEventListener("click", () => {
|
|
1722
|
-
var
|
|
1723
|
-
(
|
|
1820
|
+
var _a3;
|
|
1821
|
+
(_a3 = this.onClick) == null ? void 0 : _a3.call(this, annotation.id);
|
|
1724
1822
|
});
|
|
1725
1823
|
this.container.appendChild(markerEl);
|
|
1726
1824
|
this.markers.set(annotation.id, { annotation, target, markerEl });
|
|
1825
|
+
this.applyOutline(target, annotation.status);
|
|
1727
1826
|
this.updatePosition(annotation.id);
|
|
1728
1827
|
}
|
|
1729
1828
|
removeMarker(id) {
|
|
1730
1829
|
const entry = this.markers.get(id);
|
|
1731
1830
|
if (entry) {
|
|
1732
1831
|
entry.markerEl.remove();
|
|
1832
|
+
this.removeOutline(entry.target);
|
|
1733
1833
|
this.markers.delete(id);
|
|
1734
1834
|
}
|
|
1735
1835
|
}
|
|
@@ -1743,6 +1843,7 @@ var MarkerManager = class {
|
|
|
1743
1843
|
clear() {
|
|
1744
1844
|
for (const entry of this.markers.values()) {
|
|
1745
1845
|
entry.markerEl.remove();
|
|
1846
|
+
this.removeOutline(entry.target);
|
|
1746
1847
|
}
|
|
1747
1848
|
this.markers.clear();
|
|
1748
1849
|
this.counter = 0;
|
|
@@ -1754,6 +1855,15 @@ var MarkerManager = class {
|
|
|
1754
1855
|
}
|
|
1755
1856
|
this.clear();
|
|
1756
1857
|
}
|
|
1858
|
+
applyOutline(target, status) {
|
|
1859
|
+
const color = status === "pending" ? "#f97316" : "rgba(34, 197, 94, 0.5)";
|
|
1860
|
+
target.style.outline = `2px solid ${color}`;
|
|
1861
|
+
target.style.outlineOffset = "2px";
|
|
1862
|
+
}
|
|
1863
|
+
removeOutline(target) {
|
|
1864
|
+
target.style.outline = "";
|
|
1865
|
+
target.style.outlineOffset = "";
|
|
1866
|
+
}
|
|
1757
1867
|
updatePosition(id) {
|
|
1758
1868
|
const entry = this.markers.get(id);
|
|
1759
1869
|
if (!entry) return;
|
|
@@ -1805,16 +1915,17 @@ function hideToast() {
|
|
|
1805
1915
|
|
|
1806
1916
|
// src/ui/detached-panel.ts
|
|
1807
1917
|
var DetachedPanel = class {
|
|
1808
|
-
constructor(container, onDelete) {
|
|
1918
|
+
constructor(container, onDelete, position = "bottom-right") {
|
|
1809
1919
|
this.container = container;
|
|
1810
1920
|
this.onDelete = onDelete;
|
|
1921
|
+
this.position = position;
|
|
1811
1922
|
this.panelEl = null;
|
|
1812
1923
|
}
|
|
1813
1924
|
update(otherBreakpoint, detached) {
|
|
1814
1925
|
this.remove();
|
|
1815
1926
|
if (otherBreakpoint.length === 0 && detached.length === 0) return;
|
|
1816
1927
|
const panel = document.createElement("div");
|
|
1817
|
-
panel.className =
|
|
1928
|
+
panel.className = `remarq-detached-panel remarq-pos-${this.position}`;
|
|
1818
1929
|
if (otherBreakpoint.length > 0) {
|
|
1819
1930
|
this.renderSection(panel, `Other viewport (${otherBreakpoint.length})`, otherBreakpoint, "other");
|
|
1820
1931
|
}
|
|
@@ -1862,8 +1973,8 @@ var DetachedPanel = class {
|
|
|
1862
1973
|
deleteBtn.className = "remarq-detached-delete";
|
|
1863
1974
|
deleteBtn.textContent = "\xD7";
|
|
1864
1975
|
deleteBtn.addEventListener("click", () => {
|
|
1865
|
-
var
|
|
1866
|
-
(
|
|
1976
|
+
var _a3;
|
|
1977
|
+
(_a3 = this.onDelete) == null ? void 0 : _a3.call(this, ann.id);
|
|
1867
1978
|
});
|
|
1868
1979
|
item.appendChild(deleteBtn);
|
|
1869
1980
|
}
|
|
@@ -1878,6 +1989,76 @@ var DetachedPanel = class {
|
|
|
1878
1989
|
}
|
|
1879
1990
|
};
|
|
1880
1991
|
|
|
1992
|
+
// src/ui/shortcuts-modal.ts
|
|
1993
|
+
var _a2;
|
|
1994
|
+
var isMac2 = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test((_a2 = navigator.platform) != null ? _a2 : "");
|
|
1995
|
+
var modKey2 = isMac2 ? "\u2325" : "Alt";
|
|
1996
|
+
var SHORTCUTS = [
|
|
1997
|
+
{ key: `${modKey2}+I`, description: "Toggle inspect mode" },
|
|
1998
|
+
{ key: "S", description: "Toggle spacing overlay", context: "inspect" },
|
|
1999
|
+
{ key: "C", description: "Copy all annotations to clipboard", context: "inspect" },
|
|
2000
|
+
{ key: "Esc", description: "Exit inspect mode / close popup" },
|
|
2001
|
+
{ key: "?", description: "Show this help" },
|
|
2002
|
+
{ key: "Enter", description: "Submit annotation", context: "popup" },
|
|
2003
|
+
{ key: "Shift+Enter", description: "New line", context: "popup" }
|
|
2004
|
+
];
|
|
2005
|
+
var modalEl = null;
|
|
2006
|
+
var keyHandler = null;
|
|
2007
|
+
function showShortcutsModal(container) {
|
|
2008
|
+
if (modalEl) {
|
|
2009
|
+
hideShortcutsModal();
|
|
2010
|
+
return;
|
|
2011
|
+
}
|
|
2012
|
+
const backdrop = document.createElement("div");
|
|
2013
|
+
backdrop.className = "remarq-shortcuts-backdrop";
|
|
2014
|
+
const modal = document.createElement("div");
|
|
2015
|
+
modal.className = "remarq-shortcuts-modal";
|
|
2016
|
+
const title = document.createElement("div");
|
|
2017
|
+
title.className = "remarq-shortcuts-title";
|
|
2018
|
+
title.textContent = "Keyboard Shortcuts";
|
|
2019
|
+
modal.appendChild(title);
|
|
2020
|
+
for (const s of SHORTCUTS) {
|
|
2021
|
+
const row = document.createElement("div");
|
|
2022
|
+
row.className = "remarq-shortcuts-row";
|
|
2023
|
+
const key = document.createElement("kbd");
|
|
2024
|
+
key.className = "remarq-shortcuts-key";
|
|
2025
|
+
key.textContent = s.key;
|
|
2026
|
+
const desc = document.createElement("span");
|
|
2027
|
+
desc.textContent = s.description;
|
|
2028
|
+
row.appendChild(key);
|
|
2029
|
+
row.appendChild(desc);
|
|
2030
|
+
if ("context" in s && s.context) {
|
|
2031
|
+
const badge = document.createElement("span");
|
|
2032
|
+
badge.className = "remarq-shortcuts-context";
|
|
2033
|
+
badge.textContent = s.context;
|
|
2034
|
+
row.appendChild(badge);
|
|
2035
|
+
}
|
|
2036
|
+
modal.appendChild(row);
|
|
2037
|
+
}
|
|
2038
|
+
backdrop.appendChild(modal);
|
|
2039
|
+
container.appendChild(backdrop);
|
|
2040
|
+
modalEl = backdrop;
|
|
2041
|
+
backdrop.addEventListener("click", (e) => {
|
|
2042
|
+
if (e.target === backdrop) hideShortcutsModal();
|
|
2043
|
+
});
|
|
2044
|
+
keyHandler = (e) => {
|
|
2045
|
+
if (e.key === "Escape" || e.key === "?") {
|
|
2046
|
+
hideShortcutsModal();
|
|
2047
|
+
}
|
|
2048
|
+
};
|
|
2049
|
+
document.addEventListener("keydown", keyHandler);
|
|
2050
|
+
}
|
|
2051
|
+
function hideShortcutsModal() {
|
|
2052
|
+
if (modalEl) {
|
|
2053
|
+
modalEl.remove();
|
|
2054
|
+
modalEl = null;
|
|
2055
|
+
}
|
|
2056
|
+
if (keyHandler) {
|
|
2057
|
+
document.removeEventListener("keydown", keyHandler);
|
|
2058
|
+
keyHandler = null;
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
|
|
1881
2062
|
// src/spa.ts
|
|
1882
2063
|
var RouteObserver = class {
|
|
1883
2064
|
constructor() {
|
|
@@ -1945,10 +2126,10 @@ var refreshScheduled = false;
|
|
|
1945
2126
|
var savedCursor = "";
|
|
1946
2127
|
var elementCache = /* @__PURE__ */ new Map();
|
|
1947
2128
|
function describeTarget(el) {
|
|
1948
|
-
var
|
|
2129
|
+
var _a3, _b, _c, _d;
|
|
1949
2130
|
const parts = [];
|
|
1950
2131
|
if (el.id) parts.push(`#${el.id}`);
|
|
1951
|
-
const dataAnnotate = el.getAttribute((
|
|
2132
|
+
const dataAnnotate = el.getAttribute((_a3 = options.dataAttribute) != null ? _a3 : "data-annotate");
|
|
1952
2133
|
const dataTestId = el.getAttribute("data-testid") || el.getAttribute("data-test") || el.getAttribute("data-cy");
|
|
1953
2134
|
if (dataAnnotate) parts.push(`[${dataAnnotate}]`);
|
|
1954
2135
|
else if (dataTestId) parts.push(`[${dataTestId}]`);
|
|
@@ -2083,8 +2264,9 @@ function handleInspectHover(e) {
|
|
|
2083
2264
|
overlay.updateTooltipPosition(e.clientX, e.clientY);
|
|
2084
2265
|
}
|
|
2085
2266
|
function handleInspectKeydown(e) {
|
|
2086
|
-
var
|
|
2087
|
-
|
|
2267
|
+
var _a3, _b;
|
|
2268
|
+
if (options.shortcuts === false) return;
|
|
2269
|
+
const tag = (_a3 = e.target) == null ? void 0 : _a3.tagName;
|
|
2088
2270
|
if (tag === "INPUT" || tag === "TEXTAREA" || ((_b = e.target) == null ? void 0 : _b.isContentEditable)) return;
|
|
2089
2271
|
if (e.key === "Escape" && inspecting) {
|
|
2090
2272
|
setInspecting(false);
|
|
@@ -2096,13 +2278,20 @@ function handleInspectKeydown(e) {
|
|
|
2096
2278
|
toolbar.setSpacingActive(spacingMode);
|
|
2097
2279
|
if (!spacingMode) spacingOverlay.hide();
|
|
2098
2280
|
}
|
|
2099
|
-
if (e.key === "i") {
|
|
2281
|
+
if (e.key === "i" && e.altKey) {
|
|
2282
|
+
e.preventDefault();
|
|
2100
2283
|
setInspecting(!inspecting);
|
|
2101
2284
|
if (!inspecting) {
|
|
2102
2285
|
overlay.hide();
|
|
2103
2286
|
spacingOverlay.hide();
|
|
2104
2287
|
}
|
|
2105
2288
|
}
|
|
2289
|
+
if (e.key === "c" && inspecting) {
|
|
2290
|
+
copyToClipboard();
|
|
2291
|
+
}
|
|
2292
|
+
if (e.key === "?") {
|
|
2293
|
+
showShortcutsModal(themeManager.container);
|
|
2294
|
+
}
|
|
2106
2295
|
}
|
|
2107
2296
|
function setInspecting(value) {
|
|
2108
2297
|
if (value && !inspecting) {
|
|
@@ -2123,7 +2312,7 @@ function setInspecting(value) {
|
|
|
2123
2312
|
}
|
|
2124
2313
|
}
|
|
2125
2314
|
function handleMarkerClick(annotationId) {
|
|
2126
|
-
var
|
|
2315
|
+
var _a3;
|
|
2127
2316
|
const ann = storage.getAll().find((a) => a.id === annotationId);
|
|
2128
2317
|
if (!ann) return;
|
|
2129
2318
|
const el = resolveElement(ann);
|
|
@@ -2132,7 +2321,7 @@ function handleMarkerClick(annotationId) {
|
|
|
2132
2321
|
popup.showDetail(
|
|
2133
2322
|
{
|
|
2134
2323
|
tag: ann.fingerprint.tagName,
|
|
2135
|
-
text: (
|
|
2324
|
+
text: (_a3 = ann.fingerprint.textContent) != null ? _a3 : "",
|
|
2136
2325
|
comment: ann.comment,
|
|
2137
2326
|
status: ann.status
|
|
2138
2327
|
},
|
|
@@ -2156,6 +2345,21 @@ function handleMarkerClick(annotationId) {
|
|
|
2156
2345
|
onEdit: (newComment) => {
|
|
2157
2346
|
storage.update(ann.id, { comment: newComment });
|
|
2158
2347
|
refreshMarkers();
|
|
2348
|
+
},
|
|
2349
|
+
onCopy: () => {
|
|
2350
|
+
const fp = ann.fingerprint;
|
|
2351
|
+
const lines = [
|
|
2352
|
+
`[${ann.status}] "${ann.comment}"`,
|
|
2353
|
+
`Element: <${fp.tagName}>${fp.textContent ? ` "${fp.textContent}"` : ""}`,
|
|
2354
|
+
`Route: ${ann.route}`,
|
|
2355
|
+
`Viewport: ${ann.viewportBucket}px`
|
|
2356
|
+
];
|
|
2357
|
+
if (fp.sourceLocation) lines.push(`Source: ${fp.sourceLocation}`);
|
|
2358
|
+
navigator.clipboard.writeText(lines.join("\n")).then(() => {
|
|
2359
|
+
showToast(themeManager.container, "Annotation copied");
|
|
2360
|
+
}).catch(() => {
|
|
2361
|
+
console.warn("[web-remarq] Clipboard write failed");
|
|
2362
|
+
});
|
|
2159
2363
|
}
|
|
2160
2364
|
}
|
|
2161
2365
|
);
|
|
@@ -2166,7 +2370,7 @@ function generateMarkdown() {
|
|
|
2166
2370
|
if (!anns.length) return "";
|
|
2167
2371
|
const lines = [`## Annotations \u2014 ${route} (${anns.length})`, ""];
|
|
2168
2372
|
anns.forEach((ann, i) => {
|
|
2169
|
-
var
|
|
2373
|
+
var _a3, _b;
|
|
2170
2374
|
const fp = ann.fingerprint;
|
|
2171
2375
|
lines.push(`### ${i + 1}. [${ann.status}] "${ann.comment}"`);
|
|
2172
2376
|
let elDesc = `Element: <${fp.tagName}>`;
|
|
@@ -2197,7 +2401,7 @@ function generateMarkdown() {
|
|
|
2197
2401
|
if (fp.textContent) {
|
|
2198
2402
|
lines.push(`- \`"${fp.textContent}"\` \u2014 text content in templates`);
|
|
2199
2403
|
}
|
|
2200
|
-
if ((
|
|
2404
|
+
if ((_a3 = fp.cssModules) == null ? void 0 : _a3.length) {
|
|
2201
2405
|
for (const mod of fp.cssModules) {
|
|
2202
2406
|
lines.push(`- \`.${mod.localName}\` \u2014 in CSS Module file (likely \`${mod.moduleHint}.module.*\`)`);
|
|
2203
2407
|
lines.push(`- \`styles.${mod.localName}\` \u2014 in component JS/TS`);
|
|
@@ -2276,6 +2480,7 @@ function setupMutationObserver() {
|
|
|
2276
2480
|
}
|
|
2277
2481
|
var WebRemarq = {
|
|
2278
2482
|
init(opts) {
|
|
2483
|
+
var _a3;
|
|
2279
2484
|
if (initialized) return;
|
|
2280
2485
|
options = opts != null ? opts : {};
|
|
2281
2486
|
try {
|
|
@@ -2286,11 +2491,12 @@ var WebRemarq = {
|
|
|
2286
2491
|
spacingOverlay = new SpacingOverlay(themeManager.container);
|
|
2287
2492
|
popup = new Popup(themeManager.container);
|
|
2288
2493
|
markers = new MarkerManager(themeManager.container, handleMarkerClick);
|
|
2494
|
+
const position = (_a3 = options.position) != null ? _a3 : "bottom-right";
|
|
2289
2495
|
detachedPanel = new DetachedPanel(themeManager.container, (id) => {
|
|
2290
2496
|
elementCache.delete(id);
|
|
2291
2497
|
storage.remove(id);
|
|
2292
2498
|
refreshMarkers();
|
|
2293
|
-
});
|
|
2499
|
+
}, position);
|
|
2294
2500
|
toolbar = new Toolbar(themeManager.container, {
|
|
2295
2501
|
onInspect: () => setInspecting(!inspecting),
|
|
2296
2502
|
onSpacingToggle: () => {
|
|
@@ -2303,8 +2509,8 @@ var WebRemarq = {
|
|
|
2303
2509
|
onExportMd: exportMarkdown,
|
|
2304
2510
|
onExportJson: exportJSON,
|
|
2305
2511
|
onImport: () => {
|
|
2306
|
-
var
|
|
2307
|
-
const file = (
|
|
2512
|
+
var _a4;
|
|
2513
|
+
const file = (_a4 = toolbar.getFileInput().files) == null ? void 0 : _a4[0];
|
|
2308
2514
|
if (file) {
|
|
2309
2515
|
WebRemarq.import(file);
|
|
2310
2516
|
}
|
|
@@ -2315,8 +2521,9 @@ var WebRemarq = {
|
|
|
2315
2521
|
refreshMarkers();
|
|
2316
2522
|
showToast(themeManager.container, "All annotations cleared");
|
|
2317
2523
|
},
|
|
2318
|
-
onThemeToggle: () => themeManager.toggle()
|
|
2319
|
-
|
|
2524
|
+
onThemeToggle: () => themeManager.toggle(),
|
|
2525
|
+
onHelp: () => showShortcutsModal(themeManager.container)
|
|
2526
|
+
}, position);
|
|
2320
2527
|
if (storage.isMemoryOnly) {
|
|
2321
2528
|
toolbar.setMemoryWarning(true);
|
|
2322
2529
|
}
|
|
@@ -2346,6 +2553,7 @@ var WebRemarq = {
|
|
|
2346
2553
|
document.body.style.cursor = savedCursor;
|
|
2347
2554
|
}
|
|
2348
2555
|
hideToast();
|
|
2556
|
+
hideShortcutsModal();
|
|
2349
2557
|
destroyViewportListener();
|
|
2350
2558
|
unsubRoute == null ? void 0 : unsubRoute();
|
|
2351
2559
|
routeObserver == null ? void 0 : routeObserver.destroy();
|