@spotpatch/runtime 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -7
- package/dist/index.cjs +603 -376
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -15
- package/dist/index.d.ts +2 -15
- package/dist/index.js +601 -374
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -3,9 +3,9 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (
|
|
6
|
+
var __export = (target2, all) => {
|
|
7
7
|
for (var name in all)
|
|
8
|
-
__defProp(
|
|
8
|
+
__defProp(target2, name, { get: all[name], enumerable: true });
|
|
9
9
|
};
|
|
10
10
|
var __copyProps = (to, from, except, desc) => {
|
|
11
11
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
@@ -31,45 +31,46 @@ var import_shared9 = require("@spotpatch/shared");
|
|
|
31
31
|
|
|
32
32
|
// src/annotation/create-annotation.ts
|
|
33
33
|
var import_shared = require("@spotpatch/shared");
|
|
34
|
-
function freezeSource(
|
|
34
|
+
function freezeSource(source2, code2) {
|
|
35
35
|
return Object.freeze({
|
|
36
|
-
...
|
|
37
|
-
...
|
|
36
|
+
...source2,
|
|
37
|
+
...source2.relativePath === void 0 && code2 !== void 0 ? { relativePath: code2.relativePath } : {}
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
|
-
function freezeReact(
|
|
40
|
+
function freezeReact(react2) {
|
|
41
41
|
return Object.freeze({
|
|
42
|
-
...
|
|
43
|
-
componentStack: Object.freeze([...
|
|
44
|
-
...
|
|
42
|
+
...react2,
|
|
43
|
+
componentStack: Object.freeze([...react2.componentStack]),
|
|
44
|
+
...react2.source === void 0 ? {} : { source: freezeSource(react2.source) }
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
|
-
function freezeElement(
|
|
47
|
+
function freezeElement(element2) {
|
|
48
48
|
return Object.freeze({
|
|
49
|
-
...
|
|
50
|
-
rect: Object.freeze({ ...
|
|
49
|
+
...element2,
|
|
50
|
+
rect: Object.freeze({ ...element2.rect })
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
|
-
function freezeStyles(
|
|
53
|
+
function freezeStyles(styles2) {
|
|
54
54
|
return Object.freeze({
|
|
55
|
-
...
|
|
56
|
-
classNames: Object.freeze([...
|
|
55
|
+
...styles2,
|
|
56
|
+
classNames: Object.freeze([...styles2.classNames]),
|
|
57
57
|
matchedRules: Object.freeze(
|
|
58
|
-
|
|
58
|
+
styles2.matchedRules.map((rule) => Object.freeze({ ...rule }))
|
|
59
59
|
),
|
|
60
|
-
computed: Object.freeze({ ...
|
|
61
|
-
warnings: Object.freeze([...
|
|
60
|
+
computed: Object.freeze({ ...styles2.computed }),
|
|
61
|
+
warnings: Object.freeze([...styles2.warnings])
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
|
-
function freezeTarget(
|
|
64
|
+
function freezeTarget(target2) {
|
|
65
65
|
return Object.freeze({
|
|
66
|
-
instruction:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
instruction: target2.instruction.trim(),
|
|
67
|
+
...target2.page === void 0 ? {} : { page: Object.freeze({ ...target2.page }) },
|
|
68
|
+
source: freezeSource(target2.source, target2.code),
|
|
69
|
+
react: freezeReact(target2.react),
|
|
70
|
+
element: freezeElement(target2.element),
|
|
71
|
+
styles: freezeStyles(target2.styles),
|
|
72
|
+
...target2.code === void 0 ? {} : { code: Object.freeze({ ...target2.code }) },
|
|
73
|
+
warnings: Object.freeze([...target2.warnings])
|
|
73
74
|
});
|
|
74
75
|
}
|
|
75
76
|
function createAnnotation(input) {
|
|
@@ -78,7 +79,7 @@ function createAnnotation(input) {
|
|
|
78
79
|
`SpotPatch annotations require between 1 and ${String(import_shared.MAX_ANNOTATION_TARGETS)} targets.`
|
|
79
80
|
);
|
|
80
81
|
}
|
|
81
|
-
const instructions = input.targets.map((
|
|
82
|
+
const instructions = input.targets.map((target2) => target2.instruction.trim());
|
|
82
83
|
if (instructions.some(
|
|
83
84
|
(instruction) => instruction.length === 0 || instruction.length > import_shared.MAX_TARGET_INSTRUCTION_CHARACTERS
|
|
84
85
|
) || instructions.reduce((total, instruction) => total + instruction.length, 0) > import_shared.MAX_ANNOTATION_INSTRUCTION_CHARACTERS) {
|
|
@@ -265,10 +266,10 @@ var MAX_EVENT_LINE_BYTES = 1e5;
|
|
|
265
266
|
var MAX_EVENT_STREAM_BYTES = 4e6;
|
|
266
267
|
var RuntimeApiError = class extends Error {
|
|
267
268
|
code;
|
|
268
|
-
constructor(
|
|
269
|
+
constructor(code2) {
|
|
269
270
|
super("SpotPatch local API request failed.");
|
|
270
271
|
this.name = "RuntimeApiError";
|
|
271
|
-
this.code =
|
|
272
|
+
this.code = code2;
|
|
272
273
|
}
|
|
273
274
|
};
|
|
274
275
|
function isRecord2(value) {
|
|
@@ -340,9 +341,9 @@ async function readBoundedText(response, maximumBytes) {
|
|
|
340
341
|
reader.releaseLock();
|
|
341
342
|
}
|
|
342
343
|
}
|
|
343
|
-
function parseJson(
|
|
344
|
+
function parseJson(text2) {
|
|
344
345
|
try {
|
|
345
|
-
return JSON.parse(
|
|
346
|
+
return JSON.parse(text2);
|
|
346
347
|
} catch {
|
|
347
348
|
throw new RuntimeApiError();
|
|
348
349
|
}
|
|
@@ -385,13 +386,13 @@ function omitBrowserCodeContext(request) {
|
|
|
385
386
|
...request,
|
|
386
387
|
annotation: {
|
|
387
388
|
...request.annotation,
|
|
388
|
-
targets: request.annotation.targets.map((
|
|
389
|
-
instruction:
|
|
390
|
-
source:
|
|
391
|
-
react:
|
|
392
|
-
element:
|
|
393
|
-
styles:
|
|
394
|
-
warnings:
|
|
389
|
+
targets: request.annotation.targets.map((target2) => ({
|
|
390
|
+
instruction: target2.instruction,
|
|
391
|
+
source: target2.source,
|
|
392
|
+
react: target2.react,
|
|
393
|
+
element: target2.element,
|
|
394
|
+
styles: target2.styles,
|
|
395
|
+
warnings: target2.warnings
|
|
395
396
|
}))
|
|
396
397
|
}
|
|
397
398
|
};
|
|
@@ -682,12 +683,12 @@ function contextCharacterCount(classNames, inlineStyle, rules, computed, warning
|
|
|
682
683
|
function stylesheetSource(sheet, baseUrl) {
|
|
683
684
|
return sheet.href === null ? void 0 : (0, import_shared4.sanitizeUrl)(sheet.href, baseUrl);
|
|
684
685
|
}
|
|
685
|
-
function collectMatchedRules(
|
|
686
|
+
function collectMatchedRules(element2, rules, source2, inheritedConditions, output, warnings) {
|
|
686
687
|
for (const rule of rules) {
|
|
687
688
|
if (isStyleRule(rule)) {
|
|
688
689
|
let matches = false;
|
|
689
690
|
try {
|
|
690
|
-
matches =
|
|
691
|
+
matches = element2.matches(rule.selectorText);
|
|
691
692
|
} catch {
|
|
692
693
|
warnings.add(CSS_COLLECTION_WARNINGS.selector);
|
|
693
694
|
continue;
|
|
@@ -697,7 +698,7 @@ function collectMatchedRules(element, rules, source, inheritedConditions, output
|
|
|
697
698
|
Object.freeze({
|
|
698
699
|
selector: sanitizeCssText(rule.selectorText),
|
|
699
700
|
declarations: sanitizeCssText(rule.style.cssText),
|
|
700
|
-
...
|
|
701
|
+
...source2 === void 0 ? {} : { source: source2 },
|
|
701
702
|
...inheritedConditions.length === 0 ? {} : { media: inheritedConditions.join(" and ") }
|
|
702
703
|
})
|
|
703
704
|
);
|
|
@@ -707,9 +708,9 @@ function collectMatchedRules(element, rules, source, inheritedConditions, output
|
|
|
707
708
|
if (isGroupingRule(rule)) {
|
|
708
709
|
const condition = groupingCondition(rule);
|
|
709
710
|
collectMatchedRules(
|
|
710
|
-
|
|
711
|
+
element2,
|
|
711
712
|
rule.cssRules,
|
|
712
|
-
|
|
713
|
+
source2,
|
|
713
714
|
condition === void 0 ? inheritedConditions : [...inheritedConditions, condition],
|
|
714
715
|
output,
|
|
715
716
|
warnings
|
|
@@ -717,11 +718,11 @@ function collectMatchedRules(element, rules, source, inheritedConditions, output
|
|
|
717
718
|
}
|
|
718
719
|
}
|
|
719
720
|
}
|
|
720
|
-
function collectComputedStyle(
|
|
721
|
+
function collectComputedStyle(element2, getComputedStyle) {
|
|
721
722
|
if (getComputedStyle === void 0) {
|
|
722
723
|
return {};
|
|
723
724
|
}
|
|
724
|
-
const declaration = getComputedStyle(
|
|
725
|
+
const declaration = getComputedStyle(element2);
|
|
725
726
|
const computed = {};
|
|
726
727
|
for (const property of COMPUTED_STYLE_PROPERTIES) {
|
|
727
728
|
const value = sanitizeCssText(declaration.getPropertyValue(property).trim());
|
|
@@ -859,11 +860,11 @@ function escapeHtml(value) {
|
|
|
859
860
|
function isPreservedAttribute(name) {
|
|
860
861
|
return SAFE_ATTRIBUTE_NAMES.has(name) || name.startsWith("aria-") || name === "data-testid";
|
|
861
862
|
}
|
|
862
|
-
function openingTag(
|
|
863
|
-
const tagName =
|
|
863
|
+
function openingTag(element2) {
|
|
864
|
+
const tagName = element2.tagName.toLowerCase();
|
|
864
865
|
const attributes = [];
|
|
865
|
-
const baseUrl =
|
|
866
|
-
for (const attribute of
|
|
866
|
+
const baseUrl = element2.ownerDocument.baseURI;
|
|
867
|
+
for (const attribute of element2.attributes) {
|
|
867
868
|
const name = attribute.name.toLowerCase();
|
|
868
869
|
if (!isPreservedAttribute(name)) {
|
|
869
870
|
continue;
|
|
@@ -878,28 +879,28 @@ function openingTag(element) {
|
|
|
878
879
|
function normalizedText(value) {
|
|
879
880
|
return (0, import_shared4.redactSensitiveText)(value).replaceAll(/\s+/gu, " ").trim();
|
|
880
881
|
}
|
|
881
|
-
function serializeElement(
|
|
882
|
+
function serializeElement(element2, depth, state, lines) {
|
|
882
883
|
if (state.nodeCount >= DOM_COLLECTION_LIMITS.maxNodes) {
|
|
883
884
|
state.truncated = true;
|
|
884
885
|
return;
|
|
885
886
|
}
|
|
886
887
|
state.nodeCount += 1;
|
|
887
888
|
const indent = " ".repeat(depth);
|
|
888
|
-
const tagName =
|
|
889
|
-
lines.push(`${indent}${openingTag(
|
|
889
|
+
const tagName = element2.tagName.toLowerCase();
|
|
890
|
+
lines.push(`${indent}${openingTag(element2)}`);
|
|
890
891
|
if (VOID_ELEMENT_NAMES.has(tagName)) {
|
|
891
892
|
return;
|
|
892
893
|
}
|
|
893
|
-
for (const child of
|
|
894
|
+
for (const child of element2.childNodes) {
|
|
894
895
|
if (state.nodeCount >= DOM_COLLECTION_LIMITS.maxNodes) {
|
|
895
896
|
state.truncated = true;
|
|
896
897
|
break;
|
|
897
898
|
}
|
|
898
899
|
if (child.nodeType === 3) {
|
|
899
|
-
const
|
|
900
|
-
if (
|
|
900
|
+
const text2 = normalizedText(child.textContent ?? "");
|
|
901
|
+
if (text2.length > 0) {
|
|
901
902
|
state.nodeCount += 1;
|
|
902
|
-
const truncated =
|
|
903
|
+
const truncated = text2.length <= DOM_COLLECTION_LIMITS.maxTextCharacters ? text2 : `${text2.slice(0, DOM_COLLECTION_LIMITS.maxTextCharacters)}\u2026`;
|
|
903
904
|
lines.push(`${" ".repeat(depth + 1)}${escapeHtml(truncated)}`);
|
|
904
905
|
}
|
|
905
906
|
continue;
|
|
@@ -918,9 +919,9 @@ function serializeElement(element, depth, state, lines) {
|
|
|
918
919
|
}
|
|
919
920
|
lines.push(`${indent}</${tagName}>`);
|
|
920
921
|
}
|
|
921
|
-
function parentContext(
|
|
922
|
+
function parentContext(element2) {
|
|
922
923
|
const parents = [];
|
|
923
|
-
let parent =
|
|
924
|
+
let parent = element2.parentElement;
|
|
924
925
|
while (parent !== null && parents.length < DOM_COLLECTION_LIMITS.maxParentDepth) {
|
|
925
926
|
parents.push(openingTag(parent));
|
|
926
927
|
parent = parent.parentElement;
|
|
@@ -941,26 +942,26 @@ function escapeCssIdentifier(value) {
|
|
|
941
942
|
function escapeCssAttribute(value) {
|
|
942
943
|
return value.replaceAll("\\", "\\\\").replaceAll('"', '\\"');
|
|
943
944
|
}
|
|
944
|
-
function selectorSegment(
|
|
945
|
-
const tagName =
|
|
946
|
-
if (
|
|
947
|
-
return `${tagName}#${escapeCssIdentifier(
|
|
945
|
+
function selectorSegment(element2) {
|
|
946
|
+
const tagName = element2.tagName.toLowerCase();
|
|
947
|
+
if (element2.id.length > 0) {
|
|
948
|
+
return `${tagName}#${escapeCssIdentifier(element2.id)}`;
|
|
948
949
|
}
|
|
949
|
-
const testId =
|
|
950
|
+
const testId = element2.getAttribute("data-testid");
|
|
950
951
|
if (testId !== null && testId.length > 0) {
|
|
951
952
|
return `${tagName}[data-testid="${escapeCssAttribute(testId)}"]`;
|
|
952
953
|
}
|
|
953
|
-
const classes = Array.from(
|
|
954
|
-
const sameTagSiblings =
|
|
955
|
-
(sibling) => sibling.tagName ===
|
|
954
|
+
const classes = Array.from(element2.classList).slice(0, 2).map((name) => `.${escapeCssIdentifier(name)}`).join("");
|
|
955
|
+
const sameTagSiblings = element2.parentElement === null ? [] : Array.from(element2.parentElement.children).filter(
|
|
956
|
+
(sibling) => sibling.tagName === element2.tagName
|
|
956
957
|
);
|
|
957
|
-
const position = sameTagSiblings.indexOf(
|
|
958
|
+
const position = sameTagSiblings.indexOf(element2);
|
|
958
959
|
const nth = sameTagSiblings.length > 1 && position >= 0 ? `:nth-of-type(${String(position + 1)})` : "";
|
|
959
960
|
return `${tagName}${classes}${nth}`;
|
|
960
961
|
}
|
|
961
|
-
function createSelector(
|
|
962
|
+
function createSelector(element2) {
|
|
962
963
|
const segments = [];
|
|
963
|
-
let current =
|
|
964
|
+
let current = element2;
|
|
964
965
|
while (current !== null && segments.length < 5) {
|
|
965
966
|
const segment = selectorSegment(current);
|
|
966
967
|
segments.unshift(segment);
|
|
@@ -979,15 +980,15 @@ function collectElementContext(options) {
|
|
|
979
980
|
if (parents.length > 0) {
|
|
980
981
|
lines.push("<!-- Parent context: nearest first -->", ...parents);
|
|
981
982
|
}
|
|
982
|
-
const
|
|
983
|
+
const text2 = normalizedText(options.element.textContent);
|
|
983
984
|
const rect = options.element.getBoundingClientRect();
|
|
984
985
|
const role = options.element.getAttribute("role");
|
|
985
986
|
return Object.freeze({
|
|
986
987
|
tagName: options.element.tagName.toLowerCase(),
|
|
987
988
|
selector: createSelector(options.element),
|
|
988
989
|
sanitizedHtml: truncateContext(lines.join("\n"), options.maxCharacters),
|
|
989
|
-
...
|
|
990
|
-
textPreview:
|
|
990
|
+
...text2.length === 0 ? {} : {
|
|
991
|
+
textPreview: text2.length <= DOM_COLLECTION_LIMITS.maxTextCharacters ? text2 : `${text2.slice(0, DOM_COLLECTION_LIMITS.maxTextCharacters)}\u2026`
|
|
991
992
|
},
|
|
992
993
|
...role === null ? {} : { role },
|
|
993
994
|
rect: Object.freeze({
|
|
@@ -1006,11 +1007,11 @@ function isApplePlatform(platform) {
|
|
|
1006
1007
|
function normalizedKey(key) {
|
|
1007
1008
|
return key.toLowerCase();
|
|
1008
1009
|
}
|
|
1009
|
-
function isTextEntryTarget(
|
|
1010
|
-
if (!(
|
|
1010
|
+
function isTextEntryTarget(target2) {
|
|
1011
|
+
if (!(target2 instanceof Element)) {
|
|
1011
1012
|
return false;
|
|
1012
1013
|
}
|
|
1013
|
-
return
|
|
1014
|
+
return target2 instanceof HTMLInputElement || target2 instanceof HTMLTextAreaElement || target2 instanceof HTMLSelectElement || target2.closest("[contenteditable]:not([contenteditable='false'])") !== null;
|
|
1014
1015
|
}
|
|
1015
1016
|
function matchesShortcut(event, shortcut, platform) {
|
|
1016
1017
|
const tokens = shortcut.split("+").map((token) => token.trim().toLowerCase()).filter((token) => token.length > 0);
|
|
@@ -1060,15 +1061,15 @@ function unionRects(rects) {
|
|
|
1060
1061
|
height: bottom - top
|
|
1061
1062
|
});
|
|
1062
1063
|
}
|
|
1063
|
-
function getElementRect(
|
|
1064
|
-
const display = view.getComputedStyle(
|
|
1064
|
+
function getElementRect(element2, view) {
|
|
1065
|
+
const display = view.getComputedStyle(element2).display;
|
|
1065
1066
|
if (display.startsWith("inline")) {
|
|
1066
|
-
const lineBoxRect = unionRects(Array.from(
|
|
1067
|
+
const lineBoxRect = unionRects(Array.from(element2.getClientRects()));
|
|
1067
1068
|
if (lineBoxRect !== void 0) {
|
|
1068
1069
|
return lineBoxRect;
|
|
1069
1070
|
}
|
|
1070
1071
|
}
|
|
1071
|
-
return toElementRect(
|
|
1072
|
+
return toElementRect(element2.getBoundingClientRect());
|
|
1072
1073
|
}
|
|
1073
1074
|
|
|
1074
1075
|
// src/ui/ui-constants.ts
|
|
@@ -1079,32 +1080,32 @@ var UI_Z_INDEX = Object.freeze({
|
|
|
1079
1080
|
});
|
|
1080
1081
|
|
|
1081
1082
|
// src/picker/hit-test.ts
|
|
1082
|
-
function isInsideSpotPatchUI(
|
|
1083
|
-
if (
|
|
1083
|
+
function isInsideSpotPatchUI(element2) {
|
|
1084
|
+
if (element2.closest(`[${UI_MARKER_ATTRIBUTE}]`) !== null) {
|
|
1084
1085
|
return true;
|
|
1085
1086
|
}
|
|
1086
|
-
const root =
|
|
1087
|
+
const root = element2.getRootNode();
|
|
1087
1088
|
return root instanceof ShadowRoot && root.host.hasAttribute(UI_MARKER_ATTRIBUTE);
|
|
1088
1089
|
}
|
|
1089
|
-
function hasVisibleArea(
|
|
1090
|
-
const style = view.getComputedStyle(
|
|
1090
|
+
function hasVisibleArea(element2, view) {
|
|
1091
|
+
const style = view.getComputedStyle(element2);
|
|
1091
1092
|
if (style.display === "none" || style.visibility === "hidden") {
|
|
1092
1093
|
return false;
|
|
1093
1094
|
}
|
|
1094
|
-
const rect =
|
|
1095
|
+
const rect = element2.getBoundingClientRect();
|
|
1095
1096
|
return rect.width > 0 && rect.height > 0;
|
|
1096
1097
|
}
|
|
1097
|
-
function isDocumentRoot(
|
|
1098
|
-
return
|
|
1098
|
+
function isDocumentRoot(element2) {
|
|
1099
|
+
return element2.tagName === "HTML" || element2.tagName === "BODY";
|
|
1099
1100
|
}
|
|
1100
1101
|
function pickElementAt(document, view, clientX, clientY) {
|
|
1101
1102
|
const visibleCandidates = document.elementsFromPoint(clientX, clientY).filter(
|
|
1102
|
-
(
|
|
1103
|
+
(element2) => !isInsideSpotPatchUI(element2) && hasVisibleArea(element2, view)
|
|
1103
1104
|
);
|
|
1104
|
-
return visibleCandidates.find((
|
|
1105
|
+
return visibleCandidates.find((element2) => !isDocumentRoot(element2)) ?? visibleCandidates[0];
|
|
1105
1106
|
}
|
|
1106
|
-
function isSpotPatchUIEventTarget(
|
|
1107
|
-
return
|
|
1107
|
+
function isSpotPatchUIEventTarget(target2) {
|
|
1108
|
+
return target2 instanceof Element && isInsideSpotPatchUI(target2);
|
|
1108
1109
|
}
|
|
1109
1110
|
|
|
1110
1111
|
// src/prompt/prompt-composer.ts
|
|
@@ -1183,10 +1184,10 @@ function fenced(language, value) {
|
|
|
1183
1184
|
${value}
|
|
1184
1185
|
${fence}`;
|
|
1185
1186
|
}
|
|
1186
|
-
function sourceLocation(
|
|
1187
|
-
const path =
|
|
1188
|
-
const line =
|
|
1189
|
-
const column =
|
|
1187
|
+
function sourceLocation(target2, messages) {
|
|
1188
|
+
const path = target2.code?.relativePath ?? target2.source.relativePath;
|
|
1189
|
+
const line = target2.source.line;
|
|
1190
|
+
const column = target2.source.column;
|
|
1190
1191
|
if (path === void 0) {
|
|
1191
1192
|
return messages.unavailable;
|
|
1192
1193
|
}
|
|
@@ -1205,10 +1206,10 @@ function renderRule(rule) {
|
|
|
1205
1206
|
}`;
|
|
1206
1207
|
return [...metadata, body].join("\n");
|
|
1207
1208
|
}
|
|
1208
|
-
function renderStyles(
|
|
1209
|
+
function renderStyles(target2, rules, messages) {
|
|
1209
1210
|
const metadata = [
|
|
1210
|
-
|
|
1211
|
-
|
|
1211
|
+
target2.styles.classNames.length === 0 ? void 0 : `/* classes: ${target2.styles.classNames.map(sanitizeCssText).join(" ")} */`,
|
|
1212
|
+
target2.styles.inlineStyle === void 0 ? void 0 : `/* inline: ${sanitizeCssText(target2.styles.inlineStyle)} */`
|
|
1212
1213
|
].filter((line) => line !== void 0);
|
|
1213
1214
|
const blocks = [...metadata, ...rules.map(renderRule)];
|
|
1214
1215
|
return blocks.length === 0 ? messages.unavailable : fenced("css", blocks.join("\n\n"));
|
|
@@ -1221,41 +1222,47 @@ function renderComputed(entries, messages) {
|
|
|
1221
1222
|
).join("\n")
|
|
1222
1223
|
);
|
|
1223
1224
|
}
|
|
1224
|
-
function renderTarget(
|
|
1225
|
+
function renderTarget(target2, draft, index, messages) {
|
|
1225
1226
|
const reactLines = [
|
|
1226
|
-
`- ${messages.adapter}: ${
|
|
1227
|
-
...
|
|
1228
|
-
...
|
|
1229
|
-
`- ${messages.component}: ${(0, import_shared4.redactSensitiveText)(
|
|
1227
|
+
`- ${messages.adapter}: ${target2.react.supported ? messages.supported : messages.unsupported}`,
|
|
1228
|
+
...target2.react.version === void 0 ? [] : [`- ${messages.reactVersion}: ${(0, import_shared4.redactSensitiveText)(target2.react.version)}`],
|
|
1229
|
+
...target2.react.componentName === void 0 ? [] : [
|
|
1230
|
+
`- ${messages.component}: ${(0, import_shared4.redactSensitiveText)(target2.react.componentName)}`
|
|
1230
1231
|
],
|
|
1231
1232
|
...draft.reactStack.length === 0 ? [] : [
|
|
1232
1233
|
`- ${messages.stack}: ${draft.reactStack.map(import_shared4.redactSensitiveText).join(" > ")}`
|
|
1233
1234
|
]
|
|
1234
1235
|
];
|
|
1235
|
-
const
|
|
1236
|
+
const code2 = target2.code === void 0 || draft.codeLines.length === 0 ? messages.unavailable : `- ${messages.boundary}: ${target2.code.boundary}
|
|
1236
1237
|
|
|
1237
1238
|
${fenced(
|
|
1238
|
-
|
|
1239
|
+
target2.code.language,
|
|
1239
1240
|
(0, import_shared4.redactSensitiveText)(draft.codeLines.join("\n"))
|
|
1240
1241
|
)}`;
|
|
1241
1242
|
return [
|
|
1242
1243
|
`### ${messages.target(index + 1)}`,
|
|
1243
1244
|
`#### ${messages.requestedChange}`,
|
|
1244
1245
|
draft.instruction,
|
|
1246
|
+
...target2.page === void 0 ? [] : [
|
|
1247
|
+
`#### ${messages.pageEnvironment}`,
|
|
1248
|
+
`- ${messages.url}: <${(0, import_shared4.sanitizeUrl)(target2.page.url, target2.page.url)}>
|
|
1249
|
+
- ${messages.pathname}: ${(0, import_shared4.redactSensitiveText)(target2.page.pathname)}
|
|
1250
|
+
- ${messages.title}: ${(0, import_shared4.redactSensitiveText)(target2.page.title) || messages.unavailable}`
|
|
1251
|
+
],
|
|
1245
1252
|
`#### ${messages.reactContext}`,
|
|
1246
1253
|
reactLines.join("\n"),
|
|
1247
1254
|
`#### ${messages.source}`,
|
|
1248
|
-
`- ${messages.file}: ${sourceLocation(
|
|
1249
|
-
- ${messages.origin}: ${
|
|
1250
|
-
- ${messages.confidence}: ${
|
|
1255
|
+
`- ${messages.file}: ${sourceLocation(target2, messages)}
|
|
1256
|
+
- ${messages.origin}: ${target2.source.origin}
|
|
1257
|
+
- ${messages.confidence}: ${target2.source.confidence}`,
|
|
1251
1258
|
`#### ${messages.element}`,
|
|
1252
1259
|
fenced("html", (0, import_shared4.redactSensitiveText)(draft.dom)),
|
|
1253
1260
|
`#### ${messages.styles}`,
|
|
1254
|
-
renderStyles(
|
|
1261
|
+
renderStyles(target2, draft.matchedRules, messages),
|
|
1255
1262
|
`#### ${messages.computedStyles}`,
|
|
1256
1263
|
renderComputed(draft.computedEntries, messages),
|
|
1257
1264
|
`#### ${messages.code}`,
|
|
1258
|
-
|
|
1265
|
+
code2,
|
|
1259
1266
|
`#### ${messages.warnings}`,
|
|
1260
1267
|
draft.warnings.length === 0 ? `- ${messages.none}` : draft.warnings.map((warning) => `- ${(0, import_shared4.redactSensitiveText)(warning)}`).join("\n")
|
|
1261
1268
|
].join("\n\n");
|
|
@@ -1271,19 +1278,19 @@ function renderPrompt(annotation, draft) {
|
|
|
1271
1278
|
- ${messages.viewport}: ${String(annotation.page.viewportWidth)} \xD7 ${String(annotation.page.viewportHeight)}
|
|
1272
1279
|
- ${messages.devicePixelRatio}: ${String(annotation.page.devicePixelRatio)}`,
|
|
1273
1280
|
`## ${messages.selectedTargets(annotation.targets.length)}`,
|
|
1274
|
-
annotation.targets.map((
|
|
1281
|
+
annotation.targets.map((target2, index) => {
|
|
1275
1282
|
const targetDraft = draft.targets[index];
|
|
1276
1283
|
if (targetDraft === void 0) {
|
|
1277
1284
|
throw new RangeError("Prompt target draft is missing.");
|
|
1278
1285
|
}
|
|
1279
|
-
return renderTarget(
|
|
1286
|
+
return renderTarget(target2, targetDraft, index, messages);
|
|
1280
1287
|
}).join("\n\n"),
|
|
1281
1288
|
`## ${messages.modificationRequirements}`,
|
|
1282
1289
|
messages.modificationConstraint
|
|
1283
1290
|
].join("\n\n");
|
|
1284
1291
|
}
|
|
1285
|
-
function shrinkCode(
|
|
1286
|
-
if (draft.codeLines.length === 0 ||
|
|
1292
|
+
function shrinkCode(target2, draft) {
|
|
1293
|
+
if (draft.codeLines.length === 0 || target2.code === void 0) {
|
|
1287
1294
|
return false;
|
|
1288
1295
|
}
|
|
1289
1296
|
if (draft.codeLines.length === 1) {
|
|
@@ -1295,9 +1302,9 @@ function shrinkCode(target, draft) {
|
|
|
1295
1302
|
}
|
|
1296
1303
|
return true;
|
|
1297
1304
|
}
|
|
1298
|
-
const selectedLine =
|
|
1299
|
-
const firstDistance = Math.abs(
|
|
1300
|
-
const lastLine =
|
|
1305
|
+
const selectedLine = target2.source.line ?? target2.code.startLine;
|
|
1306
|
+
const firstDistance = Math.abs(target2.code.startLine - selectedLine);
|
|
1307
|
+
const lastLine = target2.code.startLine + draft.codeLines.length - 1;
|
|
1301
1308
|
const lastDistance = Math.abs(lastLine - selectedLine);
|
|
1302
1309
|
if (lastDistance >= firstDistance) {
|
|
1303
1310
|
draft.codeLines.pop();
|
|
@@ -1306,15 +1313,15 @@ function shrinkCode(target, draft) {
|
|
|
1306
1313
|
}
|
|
1307
1314
|
return true;
|
|
1308
1315
|
}
|
|
1309
|
-
function createTargetDraft(
|
|
1316
|
+
function createTargetDraft(target2) {
|
|
1310
1317
|
return {
|
|
1311
|
-
instruction: (0, import_shared4.redactSensitiveText)(
|
|
1312
|
-
reactStack: [...
|
|
1313
|
-
dom:
|
|
1314
|
-
matchedRules: [...
|
|
1315
|
-
computedEntries: Object.entries(
|
|
1316
|
-
codeLines:
|
|
1317
|
-
warnings: Array.from(/* @__PURE__ */ new Set([...
|
|
1318
|
+
instruction: (0, import_shared4.redactSensitiveText)(target2.instruction.trim()),
|
|
1319
|
+
reactStack: [...target2.react.componentStack],
|
|
1320
|
+
dom: target2.element.sanitizedHtml,
|
|
1321
|
+
matchedRules: [...target2.styles.matchedRules],
|
|
1322
|
+
computedEntries: Object.entries(target2.styles.computed),
|
|
1323
|
+
codeLines: target2.code?.excerpt.split(/\r?\n/u) ?? [],
|
|
1324
|
+
warnings: Array.from(/* @__PURE__ */ new Set([...target2.styles.warnings, ...target2.warnings]))
|
|
1318
1325
|
};
|
|
1319
1326
|
}
|
|
1320
1327
|
function createDraft(annotation) {
|
|
@@ -1343,9 +1350,9 @@ function shrinkTargetsFairly(annotation, draft, cursor) {
|
|
|
1343
1350
|
for (const operation of operations) {
|
|
1344
1351
|
for (let offset = 0; offset < annotation.targets.length; offset += 1) {
|
|
1345
1352
|
const index = (cursor + offset) % annotation.targets.length;
|
|
1346
|
-
const
|
|
1353
|
+
const target2 = annotation.targets[index];
|
|
1347
1354
|
const targetDraft = draft.targets[index];
|
|
1348
|
-
if (
|
|
1355
|
+
if (target2 !== void 0 && targetDraft !== void 0 && operation(target2, targetDraft)) {
|
|
1349
1356
|
return (index + 1) % annotation.targets.length;
|
|
1350
1357
|
}
|
|
1351
1358
|
}
|
|
@@ -1354,15 +1361,15 @@ function shrinkTargetsFairly(annotation, draft, cursor) {
|
|
|
1354
1361
|
}
|
|
1355
1362
|
function renderCompactPrompt(annotation, draft) {
|
|
1356
1363
|
const messages = PROMPT_MESSAGES[annotation.locale];
|
|
1357
|
-
const targets = annotation.targets.map((
|
|
1364
|
+
const targets = annotation.targets.map((target2, index) => {
|
|
1358
1365
|
const targetDraft = draft.targets[index];
|
|
1359
|
-
const component =
|
|
1366
|
+
const component = target2.react.componentName;
|
|
1360
1367
|
return [
|
|
1361
1368
|
`### ${messages.target(index + 1)}`,
|
|
1362
|
-
`- ${messages.requestedChange}: ${targetDraft?.instruction ?? (0, import_shared4.redactSensitiveText)(
|
|
1363
|
-
`- ${messages.file}: ${sourceLocation(
|
|
1369
|
+
`- ${messages.requestedChange}: ${targetDraft?.instruction ?? (0, import_shared4.redactSensitiveText)(target2.instruction)}`,
|
|
1370
|
+
`- ${messages.file}: ${sourceLocation(target2, messages)}`,
|
|
1364
1371
|
...component === void 0 ? [] : [`- ${messages.component}: ${(0, import_shared4.redactSensitiveText)(component)}`],
|
|
1365
|
-
`- ${messages.element}: ${(0, import_shared4.redactSensitiveText)(openingTag2(targetDraft?.dom ??
|
|
1372
|
+
`- ${messages.element}: ${(0, import_shared4.redactSensitiveText)(openingTag2(targetDraft?.dom ?? target2.element.sanitizedHtml, messages.unavailable))}`
|
|
1366
1373
|
].join("\n");
|
|
1367
1374
|
});
|
|
1368
1375
|
return [
|
|
@@ -1420,7 +1427,10 @@ var STATES = Object.freeze({
|
|
|
1420
1427
|
});
|
|
1421
1428
|
var INITIAL_RUNTIME_STATE = STATES.idle;
|
|
1422
1429
|
function reduceIdle(event) {
|
|
1423
|
-
|
|
1430
|
+
if (event.type === "ACTIVATE") {
|
|
1431
|
+
return STATES.inspecting;
|
|
1432
|
+
}
|
|
1433
|
+
return event.type === "RESTORE" ? STATES.selected : STATES.idle;
|
|
1424
1434
|
}
|
|
1425
1435
|
function reduceInspecting(event) {
|
|
1426
1436
|
switch (event.type) {
|
|
@@ -1472,17 +1482,132 @@ function reduceRuntimeState(state, event) {
|
|
|
1472
1482
|
}
|
|
1473
1483
|
}
|
|
1474
1484
|
|
|
1485
|
+
// src/state/selection-session.ts
|
|
1486
|
+
var STORAGE_PREFIX = "spotpatch:selection:";
|
|
1487
|
+
var SNAPSHOT_VERSION = 1;
|
|
1488
|
+
var MAX_SNAPSHOT_CHARACTERS = 1e6;
|
|
1489
|
+
function record(value) {
|
|
1490
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
1491
|
+
}
|
|
1492
|
+
function text(value) {
|
|
1493
|
+
return typeof value === "string";
|
|
1494
|
+
}
|
|
1495
|
+
function optionalText(value) {
|
|
1496
|
+
return value === void 0 || text(value);
|
|
1497
|
+
}
|
|
1498
|
+
function strings(value) {
|
|
1499
|
+
return Array.isArray(value) && value.length <= 256 && value.every(text);
|
|
1500
|
+
}
|
|
1501
|
+
function finiteNumber(value) {
|
|
1502
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
1503
|
+
}
|
|
1504
|
+
function optionalNumber(value) {
|
|
1505
|
+
return value === void 0 || finiteNumber(value);
|
|
1506
|
+
}
|
|
1507
|
+
function source(value) {
|
|
1508
|
+
const item = record(value);
|
|
1509
|
+
return item !== void 0 && text(item.origin) && text(item.confidence) && optionalText(item.fileId) && optionalText(item.relativePath) && optionalNumber(item.line) && optionalNumber(item.column);
|
|
1510
|
+
}
|
|
1511
|
+
function react(value) {
|
|
1512
|
+
const item = record(value);
|
|
1513
|
+
return item !== void 0 && typeof item.supported === "boolean" && optionalText(item.version) && optionalText(item.componentName) && strings(item.componentStack) && (item.source === void 0 || source(item.source));
|
|
1514
|
+
}
|
|
1515
|
+
function page(value) {
|
|
1516
|
+
const item = record(value);
|
|
1517
|
+
return item !== void 0 && text(item.url) && text(item.pathname) && text(item.title) && finiteNumber(item.viewportWidth) && finiteNumber(item.viewportHeight) && finiteNumber(item.devicePixelRatio);
|
|
1518
|
+
}
|
|
1519
|
+
function element(value) {
|
|
1520
|
+
const item = record(value);
|
|
1521
|
+
const rect = record(item?.rect);
|
|
1522
|
+
return item !== void 0 && text(item.tagName) && text(item.selector) && text(item.sanitizedHtml) && optionalText(item.textPreview) && optionalText(item.role) && rect !== void 0 && finiteNumber(rect.x) && finiteNumber(rect.y) && finiteNumber(rect.width) && finiteNumber(rect.height);
|
|
1523
|
+
}
|
|
1524
|
+
function styles(value) {
|
|
1525
|
+
const item = record(value);
|
|
1526
|
+
const computed = record(item?.computed);
|
|
1527
|
+
return item !== void 0 && strings(item.classNames) && optionalText(item.inlineStyle) && Array.isArray(item.matchedRules) && item.matchedRules.length <= 256 && item.matchedRules.every((value2) => {
|
|
1528
|
+
const rule = record(value2);
|
|
1529
|
+
return rule !== void 0 && text(rule.selector) && text(rule.declarations) && optionalText(rule.source) && optionalText(rule.media);
|
|
1530
|
+
}) && computed !== void 0 && Object.values(computed).every(text) && strings(item.warnings);
|
|
1531
|
+
}
|
|
1532
|
+
function code(value) {
|
|
1533
|
+
const item = record(value);
|
|
1534
|
+
return item !== void 0 && text(item.relativePath) && text(item.language) && finiteNumber(item.startLine) && finiteNumber(item.endLine) && text(item.excerpt) && text(item.boundary);
|
|
1535
|
+
}
|
|
1536
|
+
function target(value) {
|
|
1537
|
+
const item = record(value);
|
|
1538
|
+
return item !== void 0 && text(item.id) && text(item.instruction) && page(item.page) && source(item.source) && react(item.react) && element(item.element) && styles(item.styles) && (item.code === void 0 || code(item.code));
|
|
1539
|
+
}
|
|
1540
|
+
function parseSnapshot(value, maximumTargets) {
|
|
1541
|
+
const item = record(value);
|
|
1542
|
+
if (item?.version !== SNAPSHOT_VERSION || typeof item.open !== "boolean" || !Number.isSafeInteger(item.sequence) || Number(item.sequence) < 0 || item.activeTargetId !== void 0 && typeof item.activeTargetId !== "string" || !Array.isArray(item.targets) || item.targets.length === 0 || item.targets.length > maximumTargets || !item.targets.every(target)) {
|
|
1543
|
+
return void 0;
|
|
1544
|
+
}
|
|
1545
|
+
const targets = item.targets;
|
|
1546
|
+
const ids = targets.map(({ id }) => id);
|
|
1547
|
+
if (new Set(ids).size !== ids.length || item.activeTargetId !== void 0 && !ids.includes(item.activeTargetId)) {
|
|
1548
|
+
return void 0;
|
|
1549
|
+
}
|
|
1550
|
+
return {
|
|
1551
|
+
...item.activeTargetId === void 0 ? {} : { activeTargetId: item.activeTargetId },
|
|
1552
|
+
open: item.open,
|
|
1553
|
+
sequence: Number(item.sequence),
|
|
1554
|
+
targets
|
|
1555
|
+
};
|
|
1556
|
+
}
|
|
1557
|
+
function createSelectionSession(window, sessionId, maximumTargets) {
|
|
1558
|
+
const key = `${STORAGE_PREFIX}${sessionId}`;
|
|
1559
|
+
let storage;
|
|
1560
|
+
try {
|
|
1561
|
+
storage = window.sessionStorage;
|
|
1562
|
+
} catch {
|
|
1563
|
+
storage = void 0;
|
|
1564
|
+
}
|
|
1565
|
+
return Object.freeze({
|
|
1566
|
+
clear() {
|
|
1567
|
+
try {
|
|
1568
|
+
storage?.removeItem(key);
|
|
1569
|
+
} catch {
|
|
1570
|
+
}
|
|
1571
|
+
},
|
|
1572
|
+
load() {
|
|
1573
|
+
let serialized;
|
|
1574
|
+
try {
|
|
1575
|
+
serialized = storage?.getItem(key) ?? null;
|
|
1576
|
+
} catch {
|
|
1577
|
+
return void 0;
|
|
1578
|
+
}
|
|
1579
|
+
if (serialized === null || serialized.length > MAX_SNAPSHOT_CHARACTERS) {
|
|
1580
|
+
return void 0;
|
|
1581
|
+
}
|
|
1582
|
+
try {
|
|
1583
|
+
return parseSnapshot(JSON.parse(serialized), maximumTargets);
|
|
1584
|
+
} catch {
|
|
1585
|
+
return void 0;
|
|
1586
|
+
}
|
|
1587
|
+
},
|
|
1588
|
+
save(snapshot) {
|
|
1589
|
+
try {
|
|
1590
|
+
storage?.setItem(
|
|
1591
|
+
key,
|
|
1592
|
+
JSON.stringify({ version: SNAPSHOT_VERSION, ...snapshot })
|
|
1593
|
+
);
|
|
1594
|
+
} catch {
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
});
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1475
1600
|
// src/source/source-resolver.ts
|
|
1476
1601
|
var import_shared5 = require("@spotpatch/shared");
|
|
1477
1602
|
var EMPTY_REACT_CONTEXT = Object.freeze({
|
|
1478
1603
|
supported: false,
|
|
1479
1604
|
componentStack: Object.freeze([])
|
|
1480
1605
|
});
|
|
1481
|
-
function directMarker(
|
|
1482
|
-
return (0, import_shared5.parseSourceMarker)(
|
|
1606
|
+
function directMarker(element2) {
|
|
1607
|
+
return (0, import_shared5.parseSourceMarker)(element2.getAttribute(import_shared5.SOURCE_MARKER_ATTRIBUTE));
|
|
1483
1608
|
}
|
|
1484
|
-
function ancestorMarker(
|
|
1485
|
-
let ancestor =
|
|
1609
|
+
function ancestorMarker(element2) {
|
|
1610
|
+
let ancestor = element2.parentElement;
|
|
1486
1611
|
while (ancestor !== null) {
|
|
1487
1612
|
const marker = directMarker(ancestor);
|
|
1488
1613
|
if (marker !== void 0) {
|
|
@@ -1504,21 +1629,21 @@ function markerSource(marker, origin, confidence) {
|
|
|
1504
1629
|
function unknownSource() {
|
|
1505
1630
|
return Object.freeze({ origin: "none", confidence: "unknown" });
|
|
1506
1631
|
}
|
|
1507
|
-
function sourceRefToMarker(
|
|
1508
|
-
return
|
|
1509
|
-
fileId:
|
|
1510
|
-
line:
|
|
1511
|
-
column:
|
|
1632
|
+
function sourceRefToMarker(source2) {
|
|
1633
|
+
return source2.fileId === void 0 || source2.line === void 0 || source2.column === void 0 ? void 0 : Object.freeze({
|
|
1634
|
+
fileId: source2.fileId,
|
|
1635
|
+
line: source2.line,
|
|
1636
|
+
column: source2.column
|
|
1512
1637
|
});
|
|
1513
1638
|
}
|
|
1514
1639
|
function createSourceResolver(options) {
|
|
1515
1640
|
let adapterEnabled = true;
|
|
1516
|
-
function inspectReact(
|
|
1641
|
+
function inspectReact(element2) {
|
|
1517
1642
|
if (!adapterEnabled) {
|
|
1518
1643
|
return EMPTY_REACT_CONTEXT;
|
|
1519
1644
|
}
|
|
1520
1645
|
try {
|
|
1521
|
-
return options.adapter.inspect(
|
|
1646
|
+
return options.adapter.inspect(element2);
|
|
1522
1647
|
} catch {
|
|
1523
1648
|
adapterEnabled = false;
|
|
1524
1649
|
options.onAdapterError?.();
|
|
@@ -1526,26 +1651,26 @@ function createSourceResolver(options) {
|
|
|
1526
1651
|
}
|
|
1527
1652
|
}
|
|
1528
1653
|
return Object.freeze({
|
|
1529
|
-
resolve(
|
|
1530
|
-
const marker = directMarker(
|
|
1531
|
-
const
|
|
1654
|
+
resolve(element2) {
|
|
1655
|
+
const marker = directMarker(element2);
|
|
1656
|
+
const react2 = inspectReact(element2);
|
|
1532
1657
|
if (marker !== void 0) {
|
|
1533
1658
|
return Object.freeze({
|
|
1534
|
-
react,
|
|
1659
|
+
react: react2,
|
|
1535
1660
|
source: markerSource(marker, "jsx-host", "exact")
|
|
1536
1661
|
});
|
|
1537
1662
|
}
|
|
1538
|
-
if (
|
|
1539
|
-
return Object.freeze({ react, source:
|
|
1663
|
+
if (react2.source !== void 0) {
|
|
1664
|
+
return Object.freeze({ react: react2, source: react2.source });
|
|
1540
1665
|
}
|
|
1541
|
-
const nearestAncestor = ancestorMarker(
|
|
1666
|
+
const nearestAncestor = ancestorMarker(element2);
|
|
1542
1667
|
if (nearestAncestor !== void 0) {
|
|
1543
1668
|
return Object.freeze({
|
|
1544
|
-
react,
|
|
1669
|
+
react: react2,
|
|
1545
1670
|
source: markerSource(nearestAncestor, "dom-ancestor", "approximate")
|
|
1546
1671
|
});
|
|
1547
1672
|
}
|
|
1548
|
-
return Object.freeze({ react, source: unknownSource() });
|
|
1673
|
+
return Object.freeze({ react: react2, source: unknownSource() });
|
|
1549
1674
|
},
|
|
1550
1675
|
dispose() {
|
|
1551
1676
|
adapterEnabled = false;
|
|
@@ -1559,9 +1684,9 @@ var import_shared7 = require("@spotpatch/shared");
|
|
|
1559
1684
|
|
|
1560
1685
|
// src/ui/dom.ts
|
|
1561
1686
|
function createMarkedElement(document, tagName) {
|
|
1562
|
-
const
|
|
1563
|
-
|
|
1564
|
-
return
|
|
1687
|
+
const element2 = document.createElement(tagName);
|
|
1688
|
+
element2.setAttribute(UI_MARKER_ATTRIBUTE, "");
|
|
1689
|
+
return element2;
|
|
1565
1690
|
}
|
|
1566
1691
|
function createButton(document, label, className = "") {
|
|
1567
1692
|
const button = createMarkedElement(document, "button");
|
|
@@ -2178,68 +2303,81 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
2178
2303
|
});
|
|
2179
2304
|
}
|
|
2180
2305
|
|
|
2306
|
+
// src/ui/brand-mark-content.ts
|
|
2307
|
+
var BRAND_MARK_CONTENT = `
|
|
2308
|
+
<defs>
|
|
2309
|
+
<linearGradient id="locator-gradient" x1="76" y1="92" x2="436" y2="374" gradientUnits="userSpaceOnUse">
|
|
2310
|
+
<stop offset="0" stop-color="#B61CFF" />
|
|
2311
|
+
<stop offset="0.38" stop-color="#6D35FF" />
|
|
2312
|
+
<stop offset="0.72" stop-color="#168EFF" />
|
|
2313
|
+
<stop offset="1" stop-color="#00D9E9" />
|
|
2314
|
+
</linearGradient>
|
|
2315
|
+
<linearGradient id="left-code-gradient" x1="165" y1="166" x2="236" y2="258" gradientUnits="userSpaceOnUse">
|
|
2316
|
+
<stop stop-color="#A51EFF" />
|
|
2317
|
+
<stop offset="1" stop-color="#653BFF" />
|
|
2318
|
+
</linearGradient>
|
|
2319
|
+
<linearGradient id="right-code-gradient" x1="276" y1="166" x2="347" y2="258" gradientUnits="userSpaceOnUse">
|
|
2320
|
+
<stop stop-color="#158DFF" />
|
|
2321
|
+
<stop offset="1" stop-color="#00D8E9" />
|
|
2322
|
+
</linearGradient>
|
|
2323
|
+
<linearGradient id="bolt-gradient" x1="270" y1="111" x2="252" y2="365" gradientUnits="userSpaceOnUse">
|
|
2324
|
+
<stop stop-color="#6840FF" />
|
|
2325
|
+
<stop offset="0.48" stop-color="#257BFF" />
|
|
2326
|
+
<stop offset="1" stop-color="#00CBEF" />
|
|
2327
|
+
</linearGradient>
|
|
2328
|
+
</defs>
|
|
2329
|
+
<path
|
|
2330
|
+
fill="url(#locator-gradient)"
|
|
2331
|
+
fill-rule="evenodd"
|
|
2332
|
+
clip-rule="evenodd"
|
|
2333
|
+
d="M256 52C345.47 52 418 124.53 418 214C418 267.55 391.98 316.24 354.04 348.02L256 468L157.96 348.02C120.02 316.24 94 267.55 94 214C94 124.53 166.53 52 256 52ZM256 88C186.41 88 130 144.41 130 214C130 258.2 152.76 297.08 187.2 319.57L256 403.8L324.8 319.57C359.24 297.08 382 258.2 382 214C382 144.41 325.59 88 256 88Z"
|
|
2334
|
+
/>
|
|
2335
|
+
<rect x="238" y="20" width="36" height="84" rx="4" fill="url(#locator-gradient)" />
|
|
2336
|
+
<rect x="62" y="196" width="84" height="36" rx="4" fill="url(#locator-gradient)" />
|
|
2337
|
+
<rect x="366" y="196" width="84" height="36" rx="4" fill="url(#locator-gradient)" />
|
|
2338
|
+
<path
|
|
2339
|
+
d="M213.5 160L158 211.5L213.5 263L238 236.5L211 211.5L238 186.5L213.5 160Z"
|
|
2340
|
+
fill="url(#left-code-gradient)"
|
|
2341
|
+
/>
|
|
2342
|
+
<path
|
|
2343
|
+
d="M298.5 160L354 211.5L298.5 263L274 236.5L301 211.5L274 186.5L298.5 160Z"
|
|
2344
|
+
fill="url(#right-code-gradient)"
|
|
2345
|
+
/>
|
|
2346
|
+
<path
|
|
2347
|
+
d="M283 108L232 212L266 253L238 369L302 237L267 198L283 108Z"
|
|
2348
|
+
fill="url(#bolt-gradient)"
|
|
2349
|
+
/>
|
|
2350
|
+
`;
|
|
2351
|
+
|
|
2181
2352
|
// src/ui/brand-mark.ts
|
|
2182
2353
|
var SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
2354
|
+
function resolveBrandMarkContent(override) {
|
|
2355
|
+
if (override !== void 0) {
|
|
2356
|
+
return { content: override, viewBox: "0 0 512 512" };
|
|
2357
|
+
}
|
|
2358
|
+
const injected = typeof __SPOTPATCH_BRAND_MARK_CONTENT__ === "string" ? __SPOTPATCH_BRAND_MARK_CONTENT__ : void 0;
|
|
2359
|
+
if (typeof injected === "string") {
|
|
2360
|
+
return { content: injected, viewBox: "0 0 512 512" };
|
|
2361
|
+
}
|
|
2362
|
+
return true ? { content: BRAND_MARK_CONTENT, viewBox: "0 0 512 512" } : { content: FALLBACK_BRAND_MARK_CONTENT, viewBox: "0 0 1 1" };
|
|
2363
|
+
}
|
|
2183
2364
|
function svgElement(document, tagName, attributes) {
|
|
2184
|
-
const
|
|
2365
|
+
const element2 = document.createElementNS(SVG_NAMESPACE, tagName);
|
|
2185
2366
|
for (const [name, value] of Object.entries(attributes)) {
|
|
2186
|
-
|
|
2367
|
+
element2.setAttribute(name, value);
|
|
2187
2368
|
}
|
|
2188
|
-
return
|
|
2369
|
+
return element2;
|
|
2189
2370
|
}
|
|
2190
|
-
function createBrandMark(document) {
|
|
2371
|
+
function createBrandMark(document, content) {
|
|
2372
|
+
const resolved = resolveBrandMarkContent(content);
|
|
2191
2373
|
const svg = svgElement(document, "svg", {
|
|
2374
|
+
xmlns: SVG_NAMESPACE,
|
|
2192
2375
|
class: "spotpatch-brand-mark",
|
|
2193
|
-
viewBox:
|
|
2376
|
+
viewBox: resolved.viewBox,
|
|
2194
2377
|
"aria-hidden": "true",
|
|
2195
2378
|
focusable: "false"
|
|
2196
2379
|
});
|
|
2197
|
-
|
|
2198
|
-
const gradient = svgElement(document, "linearGradient", {
|
|
2199
|
-
id: "spotpatch-brand-gradient",
|
|
2200
|
-
x1: "35",
|
|
2201
|
-
y1: "42",
|
|
2202
|
-
x2: "184",
|
|
2203
|
-
y2: "176",
|
|
2204
|
-
gradientUnits: "userSpaceOnUse"
|
|
2205
|
-
});
|
|
2206
|
-
gradient.append(
|
|
2207
|
-
svgElement(document, "stop", { offset: "0", "stop-color": "#7c22ff" }),
|
|
2208
|
-
svgElement(document, "stop", { offset: ".52", "stop-color": "#4a69ff" }),
|
|
2209
|
-
svgElement(document, "stop", { offset: "1", "stop-color": "#06d9ef" })
|
|
2210
|
-
);
|
|
2211
|
-
definitions.append(gradient);
|
|
2212
|
-
const commonStroke = {
|
|
2213
|
-
fill: "none",
|
|
2214
|
-
stroke: "url(#spotpatch-brand-gradient)",
|
|
2215
|
-
"stroke-linecap": "square",
|
|
2216
|
-
"stroke-linejoin": "miter"
|
|
2217
|
-
};
|
|
2218
|
-
const outer = svgElement(document, "path", {
|
|
2219
|
-
d: "M106 42C67 42 43 68 43 105c0 36 24 61 63 96 39-35 63-60 63-96 0-37-24-63-63-63Z",
|
|
2220
|
-
...commonStroke,
|
|
2221
|
-
"stroke-width": "14"
|
|
2222
|
-
});
|
|
2223
|
-
const topStem = svgElement(document, "path", {
|
|
2224
|
-
d: "M106 25v42",
|
|
2225
|
-
...commonStroke,
|
|
2226
|
-
"stroke-width": "14"
|
|
2227
|
-
});
|
|
2228
|
-
const sideStems = svgElement(document, "path", {
|
|
2229
|
-
d: "M35 109h20m102 0h38",
|
|
2230
|
-
...commonStroke,
|
|
2231
|
-
"stroke-width": "13"
|
|
2232
|
-
});
|
|
2233
|
-
const brackets = svgElement(document, "path", {
|
|
2234
|
-
d: "m94 89-18 19 18 17m39-36 18 19-18 17",
|
|
2235
|
-
...commonStroke,
|
|
2236
|
-
"stroke-width": "9"
|
|
2237
|
-
});
|
|
2238
|
-
const bolt = svgElement(document, "path", {
|
|
2239
|
-
d: "m119 61-20 45 15 11-13 47 30-56-16-12 4-35Z",
|
|
2240
|
-
fill: "url(#spotpatch-brand-gradient)"
|
|
2241
|
-
});
|
|
2242
|
-
svg.append(definitions, outer, topStem, sideStems, brackets, bolt);
|
|
2380
|
+
svg.innerHTML = resolved.content;
|
|
2243
2381
|
return svg;
|
|
2244
2382
|
}
|
|
2245
2383
|
|
|
@@ -2254,32 +2392,32 @@ function clamp(value, minimum, maximum) {
|
|
|
2254
2392
|
function calculateDialogPlacement({
|
|
2255
2393
|
dialogHeight,
|
|
2256
2394
|
dialogWidth,
|
|
2257
|
-
target,
|
|
2395
|
+
target: target2,
|
|
2258
2396
|
viewportHeight,
|
|
2259
2397
|
viewportWidth
|
|
2260
2398
|
}) {
|
|
2261
2399
|
const maxLeft = viewportWidth - dialogWidth - VIEWPORT_MARGIN;
|
|
2262
2400
|
const maxTop = viewportHeight - dialogHeight - VIEWPORT_MARGIN;
|
|
2263
|
-
const targetCenterX =
|
|
2264
|
-
const targetCenterY =
|
|
2401
|
+
const targetCenterX = target2.x + target2.width / 2;
|
|
2402
|
+
const targetCenterY = target2.y + target2.height / 2;
|
|
2265
2403
|
const centeredLeft = clamp(targetCenterX - dialogWidth / 2, VIEWPORT_MARGIN, maxLeft);
|
|
2266
2404
|
const centeredTop = clamp(targetCenterY - dialogHeight / 2, VIEWPORT_MARGIN, maxTop);
|
|
2267
2405
|
let left = centeredLeft;
|
|
2268
2406
|
let top = centeredTop;
|
|
2269
2407
|
let mode = "viewport";
|
|
2270
|
-
if (
|
|
2408
|
+
if (target2.width >= dialogWidth + TARGET_INSET * 2 && target2.height >= dialogHeight + TARGET_INSET * 2) {
|
|
2271
2409
|
mode = "center";
|
|
2272
|
-
} else if (
|
|
2273
|
-
top =
|
|
2410
|
+
} else if (target2.y - dialogHeight - TARGET_GAP >= VIEWPORT_MARGIN) {
|
|
2411
|
+
top = target2.y - dialogHeight - TARGET_GAP;
|
|
2274
2412
|
mode = "above";
|
|
2275
|
-
} else if (
|
|
2276
|
-
top =
|
|
2413
|
+
} else if (target2.y + target2.height + TARGET_GAP + dialogHeight <= viewportHeight - VIEWPORT_MARGIN) {
|
|
2414
|
+
top = target2.y + target2.height + TARGET_GAP;
|
|
2277
2415
|
mode = "below";
|
|
2278
|
-
} else if (
|
|
2279
|
-
left =
|
|
2416
|
+
} else if (target2.x + target2.width + TARGET_GAP + dialogWidth <= viewportWidth - VIEWPORT_MARGIN) {
|
|
2417
|
+
left = target2.x + target2.width + TARGET_GAP;
|
|
2280
2418
|
mode = "right";
|
|
2281
|
-
} else if (
|
|
2282
|
-
left =
|
|
2419
|
+
} else if (target2.x - dialogWidth - TARGET_GAP >= VIEWPORT_MARGIN) {
|
|
2420
|
+
left = target2.x - dialogWidth - TARGET_GAP;
|
|
2283
2421
|
mode = "left";
|
|
2284
2422
|
}
|
|
2285
2423
|
return Object.freeze({
|
|
@@ -2596,7 +2734,7 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2596
2734
|
noSelectable: "No selectable element was found.",
|
|
2597
2735
|
allTargetsRemoved: "All targets were removed. Choose an element to continue.",
|
|
2598
2736
|
targetRemoved: "Selected target removed.",
|
|
2599
|
-
|
|
2737
|
+
detachedTargetPreserved: "The page element was unloaded; its collected context remains selected.",
|
|
2600
2738
|
contextWarning: "Browser context collection completed with a warning.",
|
|
2601
2739
|
contextCollected: "Browser context collected.",
|
|
2602
2740
|
editorOpening: "Opening source\u2026",
|
|
@@ -2732,7 +2870,7 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2732
2870
|
noSelectable: "\u5F53\u524D\u4F4D\u7F6E\u6CA1\u6709\u53EF\u9009\u62E9\u7684\u5143\u7D20\u3002",
|
|
2733
2871
|
allTargetsRemoved: "\u5DF2\u79FB\u9664\u5168\u90E8\u76EE\u6807\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u5143\u7D20\u3002",
|
|
2734
2872
|
targetRemoved: "\u5DF2\u79FB\u9664\u9009\u4E2D\u76EE\u6807\u3002",
|
|
2735
|
-
|
|
2873
|
+
detachedTargetPreserved: "\u9875\u9762\u5143\u7D20\u5DF2\u5378\u8F7D\uFF0C\u5DF2\u91C7\u96C6\u7684\u4E0A\u4E0B\u6587\u4ECD\u4FDD\u7559\u5728\u9009\u62E9\u4E2D\u3002",
|
|
2736
2874
|
contextWarning: "\u6D4F\u89C8\u5668\u4E0A\u4E0B\u6587\u91C7\u96C6\u5B8C\u6210\uFF0C\u4F46\u5B58\u5728\u8B66\u544A\u3002",
|
|
2737
2875
|
contextCollected: "\u6D4F\u89C8\u5668\u4E0A\u4E0B\u6587\u91C7\u96C6\u5B8C\u6210\u3002",
|
|
2738
2876
|
editorOpening: "\u6B63\u5728\u6253\u5F00\u6E90\u7801\u2026\u2026",
|
|
@@ -3627,11 +3765,11 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3627
3765
|
editorFeedback.textContent = state === "opening" ? messages.announcements.editorOpening : state === "success" ? messages.announcements.editorOpened : state === "error" ? messages.announcements.editorFailed : "";
|
|
3628
3766
|
placeDialog();
|
|
3629
3767
|
}
|
|
3630
|
-
function statusText(
|
|
3631
|
-
if (
|
|
3768
|
+
function statusText(target2) {
|
|
3769
|
+
if (target2.status === "ready") {
|
|
3632
3770
|
return messages.targets.statusReady;
|
|
3633
3771
|
}
|
|
3634
|
-
return
|
|
3772
|
+
return target2.status === "warning" ? messages.targets.statusPartial : messages.targets.statusCollecting;
|
|
3635
3773
|
}
|
|
3636
3774
|
function instructionInput(targetId) {
|
|
3637
3775
|
const inputs = targetList.querySelectorAll(
|
|
@@ -3648,14 +3786,14 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3648
3786
|
const focusedTargetId = focusedInstruction?.dataset.targetInstructionId;
|
|
3649
3787
|
const selectionStart = focusedInstruction?.selectionStart;
|
|
3650
3788
|
const selectionEnd = focusedInstruction?.selectionEnd;
|
|
3651
|
-
currentTargets = targets.map((
|
|
3789
|
+
currentTargets = targets.map((target2) => Object.freeze({ ...target2 }));
|
|
3652
3790
|
currentMaximum = maximum;
|
|
3653
3791
|
targetList.replaceChildren();
|
|
3654
3792
|
const completeCount = targets.filter(
|
|
3655
|
-
(
|
|
3793
|
+
(target2) => target2.instruction.trim().length > 0
|
|
3656
3794
|
).length;
|
|
3657
3795
|
const instructionCharacters = targets.reduce(
|
|
3658
|
-
(total,
|
|
3796
|
+
(total, target2) => total + target2.instruction.trim().length,
|
|
3659
3797
|
0
|
|
3660
3798
|
);
|
|
3661
3799
|
targetCount.textContent = messages.targets.count(targets.length, maximum);
|
|
@@ -3675,18 +3813,18 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3675
3813
|
addTargetButton.disabled = !editingEnabled || targets.length >= maximum;
|
|
3676
3814
|
addTargetButton.title = targets.length >= maximum ? messages.targets.limitTitle(maximum) : messages.targets.addTitle;
|
|
3677
3815
|
targetLabel.textContent = targets.length === 1 ? targets[0]?.label ?? messages.context.selectedElement : messages.context.selectedCount(targets.length);
|
|
3678
|
-
for (const [index,
|
|
3816
|
+
for (const [index, target2] of targets.entries()) {
|
|
3679
3817
|
const item = createMarkedElement(document, "div");
|
|
3680
3818
|
item.className = "spotpatch-target-item";
|
|
3681
|
-
item.dataset.active = String(
|
|
3682
|
-
item.dataset.status =
|
|
3683
|
-
item.dataset.targetId =
|
|
3819
|
+
item.dataset.active = String(target2.active);
|
|
3820
|
+
item.dataset.status = target2.status;
|
|
3821
|
+
item.dataset.targetId = target2.id;
|
|
3684
3822
|
const targetSummary = createMarkedElement(document, "div");
|
|
3685
3823
|
targetSummary.className = "spotpatch-target-summary";
|
|
3686
3824
|
const select = createButton(document, "", "spotpatch-target-select");
|
|
3687
|
-
select.dataset.activateTargetId =
|
|
3825
|
+
select.dataset.activateTargetId = target2.id;
|
|
3688
3826
|
select.setAttribute("aria-label", messages.targets.activate(index + 1));
|
|
3689
|
-
select.setAttribute("aria-expanded", String(
|
|
3827
|
+
select.setAttribute("aria-expanded", String(target2.active));
|
|
3690
3828
|
const number = createMarkedElement(document, "span");
|
|
3691
3829
|
number.className = "spotpatch-target-index";
|
|
3692
3830
|
number.textContent = String(index + 1);
|
|
@@ -3694,54 +3832,54 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3694
3832
|
copy.className = "spotpatch-target-copy";
|
|
3695
3833
|
const name = createMarkedElement(document, "span");
|
|
3696
3834
|
name.className = "spotpatch-target-name";
|
|
3697
|
-
name.textContent =
|
|
3698
|
-
const
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
copy.append(name,
|
|
3702
|
-
const instructionComplete =
|
|
3835
|
+
name.textContent = target2.label;
|
|
3836
|
+
const source2 = createMarkedElement(document, "span");
|
|
3837
|
+
source2.className = "spotpatch-target-source";
|
|
3838
|
+
source2.textContent = `${statusText(target2)} \xB7 ${target2.source}`;
|
|
3839
|
+
copy.append(name, source2);
|
|
3840
|
+
const instructionComplete = target2.instruction.trim().length > 0;
|
|
3703
3841
|
const state = createMarkedElement(document, "span");
|
|
3704
3842
|
state.className = "spotpatch-target-state";
|
|
3705
3843
|
state.dataset.complete = String(instructionComplete);
|
|
3706
3844
|
state.textContent = instructionComplete ? messages.targets.instructionReady : messages.targets.instructionMissing;
|
|
3707
3845
|
select.append(number, copy, state);
|
|
3708
3846
|
const open = createButton(document, "\u2197", "spotpatch-target-open");
|
|
3709
|
-
open.dataset.openTargetId =
|
|
3710
|
-
open.disabled = !
|
|
3847
|
+
open.dataset.openTargetId = target2.id;
|
|
3848
|
+
open.disabled = !target2.canOpenEditor;
|
|
3711
3849
|
open.setAttribute("aria-label", messages.actions.openTarget(index + 1));
|
|
3712
3850
|
open.title = messages.actions.openTarget(index + 1);
|
|
3713
3851
|
const remove = createButton(document, "\xD7", "spotpatch-target-remove");
|
|
3714
|
-
remove.dataset.removeTargetId =
|
|
3852
|
+
remove.dataset.removeTargetId = target2.id;
|
|
3715
3853
|
remove.disabled = !editingEnabled;
|
|
3716
3854
|
remove.setAttribute("aria-label", messages.targets.remove(index + 1));
|
|
3717
3855
|
remove.title = messages.targets.removeTitle;
|
|
3718
3856
|
targetSummary.append(select, open, remove);
|
|
3719
3857
|
item.append(targetSummary);
|
|
3720
|
-
if (
|
|
3858
|
+
if (target2.active) {
|
|
3721
3859
|
const editor = createMarkedElement(document, "label");
|
|
3722
3860
|
editor.className = "spotpatch-target-editor";
|
|
3723
3861
|
const editorHead = createMarkedElement(document, "span");
|
|
3724
3862
|
editorHead.className = "spotpatch-target-editor-head";
|
|
3725
3863
|
const editorLabel = createMarkedElement(document, "span");
|
|
3726
3864
|
editorLabel.className = "spotpatch-target-editor-label";
|
|
3727
|
-
editorLabel.textContent = messages.targets.instructionLabel(
|
|
3865
|
+
editorLabel.textContent = messages.targets.instructionLabel(target2.label);
|
|
3728
3866
|
const characterCount = createMarkedElement(document, "span");
|
|
3729
3867
|
characterCount.className = "spotpatch-target-editor-count";
|
|
3730
3868
|
characterCount.textContent = messages.targets.instructionCount(
|
|
3731
|
-
|
|
3869
|
+
target2.instruction.length,
|
|
3732
3870
|
import_shared7.MAX_TARGET_INSTRUCTION_CHARACTERS
|
|
3733
3871
|
);
|
|
3734
3872
|
editorHead.append(editorLabel, characterCount);
|
|
3735
3873
|
const input = createMarkedElement(document, "textarea");
|
|
3736
3874
|
input.rows = 4;
|
|
3737
3875
|
input.maxLength = import_shared7.MAX_TARGET_INSTRUCTION_CHARACTERS;
|
|
3738
|
-
input.value =
|
|
3876
|
+
input.value = target2.instruction;
|
|
3739
3877
|
input.placeholder = messages.targets.instructionPlaceholder;
|
|
3740
3878
|
input.disabled = !editingEnabled;
|
|
3741
|
-
input.dataset.targetInstructionId =
|
|
3879
|
+
input.dataset.targetInstructionId = target2.id;
|
|
3742
3880
|
input.setAttribute(
|
|
3743
3881
|
"aria-label",
|
|
3744
|
-
messages.targets.instructionLabel(
|
|
3882
|
+
messages.targets.instructionLabel(target2.label)
|
|
3745
3883
|
);
|
|
3746
3884
|
editor.append(editorHead, input);
|
|
3747
3885
|
item.append(editor);
|
|
@@ -3758,7 +3896,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3758
3896
|
}
|
|
3759
3897
|
function updateTargetInstruction(targetId, instruction) {
|
|
3760
3898
|
currentTargets = currentTargets.map(
|
|
3761
|
-
(
|
|
3899
|
+
(target2) => target2.id === targetId ? Object.freeze({ ...target2, instruction }) : target2
|
|
3762
3900
|
);
|
|
3763
3901
|
const item = Array.from(
|
|
3764
3902
|
targetList.querySelectorAll(".spotpatch-target-item")
|
|
@@ -3780,11 +3918,11 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3780
3918
|
);
|
|
3781
3919
|
}
|
|
3782
3920
|
targetComplete.textContent = messages.targets.complete(
|
|
3783
|
-
currentTargets.filter((
|
|
3921
|
+
currentTargets.filter((target2) => target2.instruction.trim().length > 0).length,
|
|
3784
3922
|
currentTargets.length
|
|
3785
3923
|
);
|
|
3786
3924
|
const instructionCharacters = currentTargets.reduce(
|
|
3787
|
-
(total,
|
|
3925
|
+
(total, target2) => total + target2.instruction.trim().length,
|
|
3788
3926
|
0
|
|
3789
3927
|
);
|
|
3790
3928
|
const instructionLimitExceeded = instructionCharacters > import_shared7.MAX_ANNOTATION_INSTRUCTION_CHARACTERS;
|
|
@@ -3799,18 +3937,18 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3799
3937
|
}
|
|
3800
3938
|
function showSelectionHighlights(targets) {
|
|
3801
3939
|
selectionHighlights.replaceChildren();
|
|
3802
|
-
activeSelectionRect = targets.find((
|
|
3940
|
+
activeSelectionRect = targets.find((target2) => target2.active)?.rect;
|
|
3803
3941
|
currentRect = activeSelectionRect;
|
|
3804
|
-
for (const [index,
|
|
3942
|
+
for (const [index, target2] of targets.entries()) {
|
|
3805
3943
|
const box = createMarkedElement(document, "div");
|
|
3806
3944
|
box.className = "spotpatch-selection-highlight";
|
|
3807
|
-
box.dataset.targetId =
|
|
3808
|
-
box.dataset.active = String(
|
|
3809
|
-
box.style.transform = `translate(${String(
|
|
3810
|
-
box.style.width = `${String(
|
|
3811
|
-
box.style.height = `${String(
|
|
3945
|
+
box.dataset.targetId = target2.id;
|
|
3946
|
+
box.dataset.active = String(target2.active);
|
|
3947
|
+
box.style.transform = `translate(${String(target2.rect.x)}px, ${String(target2.rect.y)}px)`;
|
|
3948
|
+
box.style.width = `${String(target2.rect.width)}px`;
|
|
3949
|
+
box.style.height = `${String(target2.rect.height)}px`;
|
|
3812
3950
|
const label = createMarkedElement(document, "span");
|
|
3813
|
-
label.textContent = `${String(index + 1)} \xB7 ${
|
|
3951
|
+
label.textContent = `${String(index + 1)} \xB7 ${target2.label}`;
|
|
3814
3952
|
box.append(label);
|
|
3815
3953
|
selectionHighlights.append(box);
|
|
3816
3954
|
}
|
|
@@ -3842,8 +3980,8 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3842
3980
|
}
|
|
3843
3981
|
function updateContextOverview(summaryText) {
|
|
3844
3982
|
const summaryMessages = messages.summary;
|
|
3845
|
-
const
|
|
3846
|
-
sourcePeek.textContent =
|
|
3983
|
+
const source2 = summaryLine(summaryText, summaryMessages.source);
|
|
3984
|
+
sourcePeek.textContent = source2 ?? messages.diagnostics.noExactSource;
|
|
3847
3985
|
const browserReady = `${summaryMessages.browserContext}: ${summaryMessages.collectionStatuses.ready}`;
|
|
3848
3986
|
const browserLoading = `${summaryMessages.browserContext}: ${summaryMessages.collectionStatuses.loading}`;
|
|
3849
3987
|
const browserFailed = `${summaryMessages.browserContext}: ${summaryMessages.collectionStatuses.failed}`;
|
|
@@ -4120,7 +4258,7 @@ function sourceLocation2(resolution, context, messages) {
|
|
|
4120
4258
|
function createSelectionSummary(input, messages) {
|
|
4121
4259
|
const lines = [
|
|
4122
4260
|
`SpotPatch: ${input.spotPatchVersion}`,
|
|
4123
|
-
|
|
4261
|
+
`${input.framework === "next" ? "Next.js" : "Vite"}: ${input.frameworkVersion}`,
|
|
4124
4262
|
`${messages.source}: ${sourceLocation2(input.resolution, input.code, messages)}`,
|
|
4125
4263
|
`${messages.confidence}: ${input.resolution.source.confidence} (${messages.confidenceLabels[input.resolution.source.confidence]})`,
|
|
4126
4264
|
`${messages.origin}: ${input.resolution.source.origin}`
|
|
@@ -4552,25 +4690,25 @@ var EMPTY_STYLE_CONTEXT = Object.freeze({
|
|
|
4552
4690
|
computed: Object.freeze({}),
|
|
4553
4691
|
warnings: Object.freeze(["CSS context collection failed."])
|
|
4554
4692
|
});
|
|
4555
|
-
function elementLabel(
|
|
4556
|
-
const id =
|
|
4557
|
-
const className = Array.from(
|
|
4558
|
-
return `<${
|
|
4559
|
-
}
|
|
4560
|
-
function sourceLabel(
|
|
4561
|
-
const path =
|
|
4562
|
-
const line =
|
|
4563
|
-
const column =
|
|
4693
|
+
function elementLabel(element2) {
|
|
4694
|
+
const id = element2.id.length > 0 ? `#${element2.id}` : "";
|
|
4695
|
+
const className = Array.from(element2.classList).slice(0, 2).map((name) => `.${name}`).join("");
|
|
4696
|
+
return `<${element2.tagName.toLowerCase()}${id}${className}>`;
|
|
4697
|
+
}
|
|
4698
|
+
function sourceLabel(target2, unavailable) {
|
|
4699
|
+
const path = target2.code?.relativePath ?? target2.resolution.source.relativePath;
|
|
4700
|
+
const line = target2.resolution.source.line;
|
|
4701
|
+
const column = target2.resolution.source.column;
|
|
4564
4702
|
if (path === void 0) {
|
|
4565
4703
|
return unavailable;
|
|
4566
4704
|
}
|
|
4567
4705
|
return `${path}${line === void 0 ? "" : `:${String(line)}`}${column === void 0 ? "" : `:${String(column)}`}`;
|
|
4568
4706
|
}
|
|
4569
|
-
function targetStatus(
|
|
4570
|
-
if (
|
|
4707
|
+
function targetStatus(target2) {
|
|
4708
|
+
if (target2.apiStatus === "failed" || target2.collectionStatus === "failed") {
|
|
4571
4709
|
return "warning";
|
|
4572
4710
|
}
|
|
4573
|
-
if (
|
|
4711
|
+
if (target2.apiStatus === "loading" || target2.collectionStatus === "loading") {
|
|
4574
4712
|
return "loading";
|
|
4575
4713
|
}
|
|
4576
4714
|
return "ready";
|
|
@@ -4597,6 +4735,8 @@ function createController(config, dependencies = {}) {
|
|
|
4597
4735
|
const clipboard = dependencies.clipboard ?? resolveClipboardWriter(browser.window.navigator);
|
|
4598
4736
|
const createId = dependencies.createId ?? (() => createBrowserAnnotationId(browser.window));
|
|
4599
4737
|
const now = dependencies.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
4738
|
+
const selectionSession = dependencies.selectionSession ?? createSelectionSession(browser.window, config.sessionId, config.maxTargets);
|
|
4739
|
+
const restoredSelection = selectionSession.load();
|
|
4600
4740
|
const sourceResolver = createSourceResolver({
|
|
4601
4741
|
adapter: dependencies.reactAdapter ?? (0, import_react_adapter.createReact18Adapter)({
|
|
4602
4742
|
maxComponentDepth: config.budget.maxComponentDepth
|
|
@@ -4614,9 +4754,26 @@ function createController(config, dependencies = {}) {
|
|
|
4614
4754
|
let mounted = false;
|
|
4615
4755
|
let animationFrame;
|
|
4616
4756
|
let lastPointer;
|
|
4617
|
-
let targets =
|
|
4618
|
-
|
|
4619
|
-
|
|
4757
|
+
let targets = restoredSelection?.targets.map((target2) => {
|
|
4758
|
+
const marker = sourceRefToMarker(target2.source);
|
|
4759
|
+
return {
|
|
4760
|
+
id: target2.id,
|
|
4761
|
+
resolution: Object.freeze({ source: target2.source, react: target2.react }),
|
|
4762
|
+
apiStatus: marker === void 0 ? "not-required" : target2.code === void 0 ? "failed" : "connected",
|
|
4763
|
+
code: target2.code,
|
|
4764
|
+
collectionStatus: "ready",
|
|
4765
|
+
element: void 0,
|
|
4766
|
+
elementContext: target2.element,
|
|
4767
|
+
instruction: target2.instruction,
|
|
4768
|
+
marker,
|
|
4769
|
+
page: target2.page,
|
|
4770
|
+
styles: target2.styles
|
|
4771
|
+
};
|
|
4772
|
+
}) ?? [];
|
|
4773
|
+
let activeTargetId = restoredSelection?.activeTargetId;
|
|
4774
|
+
let targetSequence = restoredSelection?.sequence ?? 0;
|
|
4775
|
+
let selectionOpen = restoredSelection?.open ?? false;
|
|
4776
|
+
let workflowSelectionActive = false;
|
|
4620
4777
|
let sessionRevision = 0;
|
|
4621
4778
|
let editorRequestRevision = 0;
|
|
4622
4779
|
let addingTarget = false;
|
|
@@ -4631,50 +4788,83 @@ function createController(config, dependencies = {}) {
|
|
|
4631
4788
|
view.renderStatus(state.status);
|
|
4632
4789
|
}
|
|
4633
4790
|
function activeTarget() {
|
|
4634
|
-
return targets.find((
|
|
4791
|
+
return targets.find((target2) => target2.id === activeTargetId) ?? targets.at(-1);
|
|
4792
|
+
}
|
|
4793
|
+
function snapshotTarget(target2) {
|
|
4794
|
+
if (target2.elementContext === void 0 || target2.styles === void 0) {
|
|
4795
|
+
return void 0;
|
|
4796
|
+
}
|
|
4797
|
+
return {
|
|
4798
|
+
id: target2.id,
|
|
4799
|
+
instruction: target2.instruction,
|
|
4800
|
+
page: target2.page,
|
|
4801
|
+
source: target2.resolution.source,
|
|
4802
|
+
react: target2.resolution.react,
|
|
4803
|
+
element: target2.elementContext,
|
|
4804
|
+
styles: target2.styles,
|
|
4805
|
+
...target2.code === void 0 ? {} : { code: target2.code }
|
|
4806
|
+
};
|
|
4635
4807
|
}
|
|
4636
|
-
function
|
|
4637
|
-
|
|
4808
|
+
function persistSelection() {
|
|
4809
|
+
const persistedTargets = targets.flatMap((target2) => {
|
|
4810
|
+
const snapshot = snapshotTarget(target2);
|
|
4811
|
+
return snapshot === void 0 ? [] : [snapshot];
|
|
4812
|
+
});
|
|
4813
|
+
if (persistedTargets.length === 0) {
|
|
4814
|
+
selectionSession.clear();
|
|
4815
|
+
return;
|
|
4816
|
+
}
|
|
4817
|
+
const persistedIds = new Set(persistedTargets.map(({ id }) => id));
|
|
4818
|
+
selectionSession.save({
|
|
4819
|
+
...activeTargetId !== void 0 && persistedIds.has(activeTargetId) ? { activeTargetId } : {},
|
|
4820
|
+
open: selectionOpen,
|
|
4821
|
+
sequence: targetSequence,
|
|
4822
|
+
targets: persistedTargets
|
|
4823
|
+
});
|
|
4824
|
+
}
|
|
4825
|
+
function targetIsCurrent(target2, revision) {
|
|
4826
|
+
return mounted && revision === sessionRevision && state.status !== "idle" && targets.includes(target2);
|
|
4638
4827
|
}
|
|
4639
4828
|
function canPreview() {
|
|
4640
4829
|
const instructionCharacters = targets.reduce(
|
|
4641
|
-
(total,
|
|
4830
|
+
(total, target2) => total + target2.instruction.trim().length,
|
|
4642
4831
|
0
|
|
4643
4832
|
);
|
|
4644
4833
|
return targets.length > 0 && instructionCharacters <= import_shared9.MAX_ANNOTATION_INSTRUCTION_CHARACTERS && targets.every(
|
|
4645
|
-
(
|
|
4834
|
+
(target2) => target2.instruction.trim().length > 0 && target2.elementContext !== void 0 && target2.styles !== void 0 && target2.apiStatus !== "loading"
|
|
4646
4835
|
);
|
|
4647
4836
|
}
|
|
4648
4837
|
function selectionSummary() {
|
|
4649
4838
|
const messages = view.messages().summary;
|
|
4650
|
-
return targets.map((
|
|
4839
|
+
return targets.map((target2, index) => {
|
|
4651
4840
|
const summary = createSelectionSummary(
|
|
4652
4841
|
{
|
|
4653
|
-
resolution:
|
|
4654
|
-
...
|
|
4655
|
-
...
|
|
4656
|
-
apiStatus:
|
|
4657
|
-
collectionStatus:
|
|
4658
|
-
|
|
4659
|
-
|
|
4842
|
+
resolution: target2.resolution,
|
|
4843
|
+
...target2.code === void 0 ? {} : { code: target2.code },
|
|
4844
|
+
...target2.styles === void 0 ? {} : { styles: target2.styles },
|
|
4845
|
+
apiStatus: target2.apiStatus,
|
|
4846
|
+
collectionStatus: target2.collectionStatus,
|
|
4847
|
+
framework: config.framework,
|
|
4848
|
+
frameworkVersion: config.frameworkVersion,
|
|
4849
|
+
spotPatchVersion: config.spotPatchVersion
|
|
4660
4850
|
},
|
|
4661
4851
|
messages
|
|
4662
4852
|
);
|
|
4663
|
-
return `${messages.target(index + 1,
|
|
4853
|
+
return `${messages.target(index + 1, target2.id === activeTargetId)}
|
|
4664
4854
|
${summary}`;
|
|
4665
4855
|
}).join("\n\n");
|
|
4666
4856
|
}
|
|
4667
4857
|
function refreshHighlights() {
|
|
4668
|
-
const highlights = targets.flatMap((
|
|
4669
|
-
if (!
|
|
4858
|
+
const highlights = targets.flatMap((target2) => {
|
|
4859
|
+
if (!target2.element?.isConnected) {
|
|
4670
4860
|
return [];
|
|
4671
4861
|
}
|
|
4672
4862
|
return [
|
|
4673
4863
|
{
|
|
4674
|
-
id:
|
|
4675
|
-
label: elementLabel(
|
|
4676
|
-
rect: getElementRect(
|
|
4677
|
-
active:
|
|
4864
|
+
id: target2.id,
|
|
4865
|
+
label: elementLabel(target2.element),
|
|
4866
|
+
rect: getElementRect(target2.element, browser.window),
|
|
4867
|
+
active: target2.id === activeTargetId
|
|
4678
4868
|
}
|
|
4679
4869
|
];
|
|
4680
4870
|
});
|
|
@@ -4689,14 +4879,14 @@ ${summary}`;
|
|
|
4689
4879
|
return;
|
|
4690
4880
|
}
|
|
4691
4881
|
view.renderTargets(
|
|
4692
|
-
targets.map((
|
|
4693
|
-
id:
|
|
4694
|
-
label:
|
|
4695
|
-
source: sourceLabel(
|
|
4696
|
-
canOpenEditor:
|
|
4697
|
-
status: targetStatus(
|
|
4698
|
-
active:
|
|
4699
|
-
instruction:
|
|
4882
|
+
targets.map((target2) => ({
|
|
4883
|
+
id: target2.id,
|
|
4884
|
+
label: target2.resolution.react.componentName ?? (target2.element === void 0 ? target2.elementContext?.tagName ?? "Element" : elementLabel(target2.element)),
|
|
4885
|
+
source: sourceLabel(target2, view.messages().context.sourceUnavailable),
|
|
4886
|
+
canOpenEditor: target2.marker !== void 0,
|
|
4887
|
+
status: targetStatus(target2),
|
|
4888
|
+
active: target2.id === activeTargetId,
|
|
4889
|
+
instruction: target2.instruction
|
|
4700
4890
|
})),
|
|
4701
4891
|
config.maxTargets
|
|
4702
4892
|
);
|
|
@@ -4714,21 +4904,22 @@ ${summary}`;
|
|
|
4714
4904
|
if (!canPreview()) {
|
|
4715
4905
|
return void 0;
|
|
4716
4906
|
}
|
|
4717
|
-
const annotationTargets = targets.map((
|
|
4718
|
-
if (
|
|
4907
|
+
const annotationTargets = targets.map((target2) => {
|
|
4908
|
+
if (target2.elementContext === void 0 || target2.styles === void 0) {
|
|
4719
4909
|
throw new Error("SpotPatch attempted to compose an incomplete target.");
|
|
4720
4910
|
}
|
|
4721
4911
|
const warnings = [
|
|
4722
|
-
...
|
|
4723
|
-
...
|
|
4912
|
+
...target2.apiStatus === "failed" ? ["Source context could not be loaded."] : [],
|
|
4913
|
+
...target2.collectionStatus === "failed" ? ["Part of the browser context could not be collected."] : []
|
|
4724
4914
|
];
|
|
4725
4915
|
return {
|
|
4726
|
-
instruction:
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4916
|
+
instruction: target2.instruction.trim(),
|
|
4917
|
+
page: target2.page,
|
|
4918
|
+
source: target2.resolution.source,
|
|
4919
|
+
react: target2.resolution.react,
|
|
4920
|
+
element: target2.elementContext,
|
|
4921
|
+
styles: target2.styles,
|
|
4922
|
+
...target2.code === void 0 ? {} : { code: target2.code },
|
|
4732
4923
|
warnings
|
|
4733
4924
|
};
|
|
4734
4925
|
});
|
|
@@ -4740,8 +4931,8 @@ ${summary}`;
|
|
|
4740
4931
|
targets: annotationTargets
|
|
4741
4932
|
});
|
|
4742
4933
|
}
|
|
4743
|
-
function showElementHighlight(
|
|
4744
|
-
view.showHighlight(getElementRect(
|
|
4934
|
+
function showElementHighlight(element2) {
|
|
4935
|
+
view.showHighlight(getElementRect(element2, browser.window), elementLabel(element2));
|
|
4745
4936
|
}
|
|
4746
4937
|
function restoreFocus() {
|
|
4747
4938
|
if (previousFocus?.isConnected === true) {
|
|
@@ -4763,10 +4954,13 @@ ${summary}`;
|
|
|
4763
4954
|
resizeObserver?.disconnect();
|
|
4764
4955
|
targets = [];
|
|
4765
4956
|
activeTargetId = void 0;
|
|
4957
|
+
selectionOpen = false;
|
|
4958
|
+
workflowSelectionActive = false;
|
|
4766
4959
|
addingTarget = false;
|
|
4767
4960
|
previewPrompt = "";
|
|
4768
4961
|
view.hideSelection();
|
|
4769
4962
|
view.hideSelectionHighlights();
|
|
4963
|
+
selectionSession.clear();
|
|
4770
4964
|
restoreFocus();
|
|
4771
4965
|
}
|
|
4772
4966
|
function close() {
|
|
@@ -4778,7 +4972,11 @@ ${summary}`;
|
|
|
4778
4972
|
transition({ type: "BACK" });
|
|
4779
4973
|
transition({ type: "CLOSE" });
|
|
4780
4974
|
}
|
|
4781
|
-
|
|
4975
|
+
selectionOpen = false;
|
|
4976
|
+
persistSelection();
|
|
4977
|
+
view.hideSelection();
|
|
4978
|
+
view.hideSelectionHighlights();
|
|
4979
|
+
restoreFocus();
|
|
4782
4980
|
view.hideHighlight();
|
|
4783
4981
|
}
|
|
4784
4982
|
function cancelAddTarget() {
|
|
@@ -4802,6 +5000,18 @@ ${summary}`;
|
|
|
4802
5000
|
close();
|
|
4803
5001
|
return;
|
|
4804
5002
|
}
|
|
5003
|
+
if (targets.length > 0) {
|
|
5004
|
+
selectionOpen = true;
|
|
5005
|
+
transition({ type: "RESTORE" });
|
|
5006
|
+
if (!workflowSelectionActive) {
|
|
5007
|
+
agentWorkflow.beginSelection();
|
|
5008
|
+
workflowSelectionActive = true;
|
|
5009
|
+
}
|
|
5010
|
+
refreshSelectionView(true);
|
|
5011
|
+
view.focusTargetInstruction(activeTargetId);
|
|
5012
|
+
persistSelection();
|
|
5013
|
+
return;
|
|
5014
|
+
}
|
|
4805
5015
|
transition({ type: "ACTIVATE" });
|
|
4806
5016
|
view.hideSelection();
|
|
4807
5017
|
view.announce(view.messages().announcements.selectionEnabled);
|
|
@@ -4835,12 +5045,13 @@ ${summary}`;
|
|
|
4835
5045
|
sessionRevision += 1;
|
|
4836
5046
|
clearCollectionTimers();
|
|
4837
5047
|
resizeObserver?.disconnect();
|
|
4838
|
-
for (const
|
|
4839
|
-
|
|
5048
|
+
for (const target2 of targets) {
|
|
5049
|
+
target2.element = void 0;
|
|
4840
5050
|
}
|
|
4841
5051
|
view.hideHighlight();
|
|
4842
5052
|
view.hideSelectionHighlights();
|
|
4843
5053
|
refreshSelectionView();
|
|
5054
|
+
selectionSession.clear();
|
|
4844
5055
|
view.announce(view.messages().announcements.appliedTargetsDetached);
|
|
4845
5056
|
}
|
|
4846
5057
|
const agentWorkflow = createAgentWorkflow({
|
|
@@ -4853,8 +5064,8 @@ ${summary}`;
|
|
|
4853
5064
|
},
|
|
4854
5065
|
view
|
|
4855
5066
|
});
|
|
4856
|
-
async function loadSourceContext(
|
|
4857
|
-
const marker =
|
|
5067
|
+
async function loadSourceContext(target2, revision) {
|
|
5068
|
+
const marker = target2.marker;
|
|
4858
5069
|
if (marker === void 0) {
|
|
4859
5070
|
return;
|
|
4860
5071
|
}
|
|
@@ -4865,16 +5076,18 @@ ${summary}`;
|
|
|
4865
5076
|
column: marker.column,
|
|
4866
5077
|
maxLines: config.budget.maxCodeLines
|
|
4867
5078
|
});
|
|
4868
|
-
if (targetIsCurrent(
|
|
4869
|
-
|
|
4870
|
-
|
|
5079
|
+
if (targetIsCurrent(target2, revision)) {
|
|
5080
|
+
target2.code = context;
|
|
5081
|
+
target2.apiStatus = "connected";
|
|
5082
|
+
persistSelection();
|
|
4871
5083
|
refreshSelectionView();
|
|
4872
5084
|
view.announce(view.messages().announcements.sourceLoaded);
|
|
4873
5085
|
}
|
|
4874
5086
|
} catch (error) {
|
|
4875
|
-
if (targetIsCurrent(
|
|
4876
|
-
|
|
4877
|
-
|
|
5087
|
+
if (targetIsCurrent(target2, revision)) {
|
|
5088
|
+
target2.code = void 0;
|
|
5089
|
+
target2.apiStatus = "failed";
|
|
5090
|
+
persistSelection();
|
|
4878
5091
|
refreshSelectionView();
|
|
4879
5092
|
view.announce(view.messages().announcements.sourceFailed);
|
|
4880
5093
|
if (config.debug && !(error instanceof DOMException && error.name === "AbortError")) {
|
|
@@ -4883,61 +5096,62 @@ ${summary}`;
|
|
|
4883
5096
|
}
|
|
4884
5097
|
}
|
|
4885
5098
|
}
|
|
4886
|
-
function scheduleBrowserContextCollection(
|
|
4887
|
-
const
|
|
4888
|
-
if (
|
|
5099
|
+
function scheduleBrowserContextCollection(target2, revision) {
|
|
5100
|
+
const element2 = target2.element;
|
|
5101
|
+
if (element2 === void 0) {
|
|
4889
5102
|
return;
|
|
4890
5103
|
}
|
|
4891
5104
|
const timer = browser.window.setTimeout(() => {
|
|
4892
|
-
collectionTimers.delete(
|
|
4893
|
-
if (!targetIsCurrent(
|
|
5105
|
+
collectionTimers.delete(target2.id);
|
|
5106
|
+
if (!targetIsCurrent(target2, revision)) {
|
|
4894
5107
|
return;
|
|
4895
5108
|
}
|
|
4896
5109
|
let failed = false;
|
|
4897
5110
|
try {
|
|
4898
|
-
|
|
4899
|
-
element,
|
|
5111
|
+
target2.elementContext = collectElementContext({
|
|
5112
|
+
element: element2,
|
|
4900
5113
|
maxCharacters: config.budget.domCharacters
|
|
4901
5114
|
});
|
|
4902
5115
|
} catch {
|
|
4903
|
-
|
|
5116
|
+
target2.elementContext = void 0;
|
|
4904
5117
|
failed = true;
|
|
4905
5118
|
}
|
|
4906
5119
|
try {
|
|
4907
|
-
|
|
5120
|
+
target2.styles = collectStyleContext({
|
|
4908
5121
|
document: browser.document,
|
|
4909
|
-
element,
|
|
5122
|
+
element: element2,
|
|
4910
5123
|
maxCharacters: config.budget.cssCharacters
|
|
4911
5124
|
});
|
|
4912
5125
|
} catch {
|
|
4913
|
-
|
|
5126
|
+
target2.styles = EMPTY_STYLE_CONTEXT;
|
|
4914
5127
|
failed = true;
|
|
4915
5128
|
}
|
|
4916
|
-
|
|
5129
|
+
target2.collectionStatus = failed ? "failed" : "ready";
|
|
5130
|
+
persistSelection();
|
|
4917
5131
|
refreshSelectionView();
|
|
4918
5132
|
view.announce(
|
|
4919
5133
|
failed ? view.messages().announcements.contextWarning : view.messages().announcements.contextCollected
|
|
4920
5134
|
);
|
|
4921
|
-
if (config.debug &&
|
|
5135
|
+
if (config.debug && target2.styles.warnings.length > 0) {
|
|
4922
5136
|
console.warn(
|
|
4923
|
-
`[spotpatch:runtime] CSS collection completed with ${String(
|
|
5137
|
+
`[spotpatch:runtime] CSS collection completed with ${String(target2.styles.warnings.length)} warning(s).`
|
|
4924
5138
|
);
|
|
4925
5139
|
}
|
|
4926
5140
|
}, 0);
|
|
4927
|
-
collectionTimers.set(
|
|
5141
|
+
collectionTimers.set(target2.id, timer);
|
|
4928
5142
|
}
|
|
4929
|
-
function duplicateTarget(
|
|
5143
|
+
function duplicateTarget(element2, marker) {
|
|
4930
5144
|
if (marker !== void 0) {
|
|
4931
5145
|
return targets.find(
|
|
4932
|
-
(
|
|
5146
|
+
(target2) => target2.marker?.fileId === marker.fileId && target2.marker.line === marker.line && target2.marker.column === marker.column
|
|
4933
5147
|
);
|
|
4934
5148
|
}
|
|
4935
|
-
return targets.find((
|
|
5149
|
+
return targets.find((target2) => target2.element === element2);
|
|
4936
5150
|
}
|
|
4937
|
-
function selectElement(
|
|
4938
|
-
const resolution = sourceResolver.resolve(
|
|
5151
|
+
function selectElement(element2) {
|
|
5152
|
+
const resolution = sourceResolver.resolve(element2);
|
|
4939
5153
|
const marker = sourceRefToMarker(resolution.source);
|
|
4940
|
-
const duplicate = duplicateTarget(
|
|
5154
|
+
const duplicate = duplicateTarget(element2, marker);
|
|
4941
5155
|
if (duplicate !== void 0) {
|
|
4942
5156
|
activeTargetId = duplicate.id;
|
|
4943
5157
|
addingTarget = false;
|
|
@@ -4961,13 +5175,15 @@ ${summary}`;
|
|
|
4961
5175
|
previousFocus = browser.document.activeElement instanceof HTMLElement ? browser.document.activeElement : void 0;
|
|
4962
5176
|
previewPrompt = "";
|
|
4963
5177
|
agentWorkflow.beginSelection();
|
|
5178
|
+
workflowSelectionActive = true;
|
|
4964
5179
|
}
|
|
4965
5180
|
targetSequence += 1;
|
|
4966
|
-
const
|
|
5181
|
+
const target2 = {
|
|
4967
5182
|
id: `target-${String(targetSequence)}`,
|
|
4968
|
-
element,
|
|
5183
|
+
element: element2,
|
|
4969
5184
|
resolution,
|
|
4970
5185
|
marker,
|
|
5186
|
+
page: collectPageContext(browser.document, browser.window),
|
|
4971
5187
|
code: void 0,
|
|
4972
5188
|
elementContext: void 0,
|
|
4973
5189
|
styles: void 0,
|
|
@@ -4975,18 +5191,19 @@ ${summary}`;
|
|
|
4975
5191
|
apiStatus: marker === void 0 ? "not-required" : "loading",
|
|
4976
5192
|
collectionStatus: "loading"
|
|
4977
5193
|
};
|
|
4978
|
-
targets.push(
|
|
4979
|
-
activeTargetId =
|
|
5194
|
+
targets.push(target2);
|
|
5195
|
+
activeTargetId = target2.id;
|
|
4980
5196
|
addingTarget = false;
|
|
4981
5197
|
const revision = sessionRevision;
|
|
4982
5198
|
transition({ type: "SELECT" });
|
|
4983
5199
|
view.hideHighlight();
|
|
4984
|
-
resizeObserver?.observe(
|
|
5200
|
+
resizeObserver?.observe(element2);
|
|
4985
5201
|
refreshSelectionView(true);
|
|
4986
|
-
|
|
4987
|
-
|
|
5202
|
+
selectionOpen = true;
|
|
5203
|
+
view.focusTargetInstruction(target2.id);
|
|
5204
|
+
scheduleBrowserContextCollection(target2, revision);
|
|
4988
5205
|
if (marker !== void 0) {
|
|
4989
|
-
void loadSourceContext(
|
|
5206
|
+
void loadSourceContext(target2, revision);
|
|
4990
5207
|
} else {
|
|
4991
5208
|
view.announce(
|
|
4992
5209
|
resolution.source.confidence === "probable" ? view.messages().announcements.sourceProbable : view.messages().announcements.sourceMissing
|
|
@@ -5060,7 +5277,7 @@ ${summary}`;
|
|
|
5060
5277
|
if (state.status !== "selected" && state.status !== "inspecting") {
|
|
5061
5278
|
return;
|
|
5062
5279
|
}
|
|
5063
|
-
const index = targets.findIndex((
|
|
5280
|
+
const index = targets.findIndex((target2) => target2.id === targetId);
|
|
5064
5281
|
if (index < 0) {
|
|
5065
5282
|
return;
|
|
5066
5283
|
}
|
|
@@ -5086,10 +5303,12 @@ ${summary}`;
|
|
|
5086
5303
|
}
|
|
5087
5304
|
view.hideSelectionTemporarily();
|
|
5088
5305
|
view.hideSelectionHighlights();
|
|
5306
|
+
selectionSession.clear();
|
|
5089
5307
|
view.announce(view.messages().announcements.allTargetsRemoved);
|
|
5090
5308
|
return;
|
|
5091
5309
|
}
|
|
5092
5310
|
refreshSelectionView();
|
|
5311
|
+
persistSelection();
|
|
5093
5312
|
view.announce(view.messages().announcements.targetRemoved);
|
|
5094
5313
|
}
|
|
5095
5314
|
function refreshSelectedGeometry() {
|
|
@@ -5097,24 +5316,24 @@ ${summary}`;
|
|
|
5097
5316
|
return;
|
|
5098
5317
|
}
|
|
5099
5318
|
const disconnected = targets.filter(
|
|
5100
|
-
(
|
|
5319
|
+
(target2) => target2.element !== void 0 && !target2.element.isConnected
|
|
5101
5320
|
);
|
|
5102
5321
|
if (disconnected.length > 0) {
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
}
|
|
5109
|
-
if (targets.length > 0) {
|
|
5110
|
-
view.announce(view.messages().announcements.detachedTargetRemoved);
|
|
5322
|
+
for (const target2 of disconnected) {
|
|
5323
|
+
if (target2.element !== void 0) {
|
|
5324
|
+
resizeObserver?.unobserve(target2.element);
|
|
5325
|
+
target2.element = void 0;
|
|
5326
|
+
}
|
|
5111
5327
|
}
|
|
5328
|
+
refreshSelectionView();
|
|
5329
|
+
persistSelection();
|
|
5330
|
+
view.announce(view.messages().announcements.detachedTargetPreserved);
|
|
5112
5331
|
return;
|
|
5113
5332
|
}
|
|
5114
5333
|
refreshHighlights();
|
|
5115
5334
|
}
|
|
5116
5335
|
function handleOpenEditor(targetId) {
|
|
5117
|
-
const current = targetId === void 0 ? activeTarget() : targets.find((
|
|
5336
|
+
const current = targetId === void 0 ? activeTarget() : targets.find((target2) => target2.id === targetId);
|
|
5118
5337
|
if (state.status !== "selected" || current?.marker === void 0) {
|
|
5119
5338
|
return;
|
|
5120
5339
|
}
|
|
@@ -5146,13 +5365,14 @@ ${summary}`;
|
|
|
5146
5365
|
return;
|
|
5147
5366
|
}
|
|
5148
5367
|
const targetId = event.target.dataset.targetInstructionId;
|
|
5149
|
-
const
|
|
5150
|
-
if (
|
|
5368
|
+
const target2 = targets.find((candidate) => candidate.id === targetId);
|
|
5369
|
+
if (target2 === void 0) {
|
|
5151
5370
|
return;
|
|
5152
5371
|
}
|
|
5153
|
-
|
|
5154
|
-
view.updateTargetInstruction(
|
|
5372
|
+
target2.instruction = event.target.value;
|
|
5373
|
+
view.updateTargetInstruction(target2.id, target2.instruction);
|
|
5155
5374
|
view.setPreviewEnabled(canPreview());
|
|
5375
|
+
persistSelection();
|
|
5156
5376
|
}
|
|
5157
5377
|
function handleOpenEditorButtonClick() {
|
|
5158
5378
|
handleOpenEditor();
|
|
@@ -5245,7 +5465,7 @@ ${summary}`;
|
|
|
5245
5465
|
"button[data-activate-target-id]"
|
|
5246
5466
|
);
|
|
5247
5467
|
const targetId = activateButton?.dataset.activateTargetId;
|
|
5248
|
-
if (state.status !== "selected" || targetId === void 0 || !targets.some((
|
|
5468
|
+
if (state.status !== "selected" || targetId === void 0 || !targets.some((target2) => target2.id === targetId)) {
|
|
5249
5469
|
return;
|
|
5250
5470
|
}
|
|
5251
5471
|
activeTargetId = targetId;
|
|
@@ -5303,6 +5523,12 @@ ${summary}`;
|
|
|
5303
5523
|
subtree: true
|
|
5304
5524
|
});
|
|
5305
5525
|
}
|
|
5526
|
+
if (selectionOpen && targets.length > 0) {
|
|
5527
|
+
transition({ type: "RESTORE" });
|
|
5528
|
+
agentWorkflow.beginSelection();
|
|
5529
|
+
workflowSelectionActive = true;
|
|
5530
|
+
refreshSelectionView(true);
|
|
5531
|
+
}
|
|
5306
5532
|
if (config.debug) {
|
|
5307
5533
|
console.info(`[spotpatch:runtime] Mounted. Shortcut: ${config.shortcut}.`);
|
|
5308
5534
|
}
|
|
@@ -5360,6 +5586,7 @@ ${summary}`;
|
|
|
5360
5586
|
animationFrame = void 0;
|
|
5361
5587
|
}
|
|
5362
5588
|
clearCollectionTimers();
|
|
5589
|
+
persistSelection();
|
|
5363
5590
|
resizeObserver?.disconnect();
|
|
5364
5591
|
mutationObserver?.disconnect();
|
|
5365
5592
|
resizeObserver = void 0;
|
|
@@ -5382,10 +5609,10 @@ ${summary}`;
|
|
|
5382
5609
|
// src/controller/bootstrap.ts
|
|
5383
5610
|
var RUNTIME_INSTANCE_KEY = "__spotpatchRuntime__";
|
|
5384
5611
|
function bootstrapSpotPatch(config) {
|
|
5385
|
-
const
|
|
5386
|
-
|
|
5612
|
+
const target2 = globalThis;
|
|
5613
|
+
target2[RUNTIME_INSTANCE_KEY]?.dispose();
|
|
5387
5614
|
const controller = createController(config);
|
|
5388
|
-
|
|
5615
|
+
target2[RUNTIME_INSTANCE_KEY] = controller;
|
|
5389
5616
|
controller.mount();
|
|
5390
5617
|
}
|
|
5391
5618
|
// Annotate the CommonJS export names for ESM import in node:
|