@vite-plugin-opencode-assistant/components 1.0.18 → 1.0.19
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/es/index.d.ts +1 -1
- package/es/index.js +1 -1
- package/es/open-code-widget/composables/use-inspector.js +253 -35
- package/lib/@vite-plugin-opencode-assistant/components.cjs.js +243 -31
- package/lib/@vite-plugin-opencode-assistant/components.es.js +220 -31
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/open-code-widget/composables/use-inspector.js +263 -35
- package/lib/web-types.json +1 -1
- package/package.json +3 -2
|
@@ -2,8 +2,32 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
+
//#region \0rolldown/runtime.js
|
|
6
|
+
var __create = Object.create;
|
|
7
|
+
var __defProp$2 = Object.defineProperty;
|
|
8
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
11
|
+
var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
14
|
+
key = keys[i];
|
|
15
|
+
if (!__hasOwnProp$2.call(to, key) && key !== except) __defProp$2(to, key, {
|
|
16
|
+
get: ((k) => from[k]).bind(null, key),
|
|
17
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp$2(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
//#endregion
|
|
5
27
|
let vue = require("vue");
|
|
6
28
|
let _vite_plugin_opencode_assistant_shared = require("@vite-plugin-opencode-assistant/shared");
|
|
29
|
+
let css_selector_generator = require("css-selector-generator");
|
|
30
|
+
css_selector_generator = __toESM(css_selector_generator);
|
|
7
31
|
//#region es/open-code-widget/src/context.js
|
|
8
32
|
var CONTEXT_KEY = /* @__PURE__ */ Symbol("OpenCodeWidgetContext");
|
|
9
33
|
function provideOpenCodeWidgetContext(context) {
|
|
@@ -764,6 +788,21 @@ function useWidget(options) {
|
|
|
764
788
|
}
|
|
765
789
|
//#endregion
|
|
766
790
|
//#region es/open-code-widget/composables/use-inspector.js
|
|
791
|
+
function throttle(fn, delay) {
|
|
792
|
+
let lastCall = 0;
|
|
793
|
+
let rafId = null;
|
|
794
|
+
return ((...args) => {
|
|
795
|
+
const now = performance.now();
|
|
796
|
+
if (now - lastCall >= delay) {
|
|
797
|
+
lastCall = now;
|
|
798
|
+
fn(...args);
|
|
799
|
+
} else if (!rafId) rafId = requestAnimationFrame(() => {
|
|
800
|
+
rafId = null;
|
|
801
|
+
lastCall = performance.now();
|
|
802
|
+
fn(...args);
|
|
803
|
+
});
|
|
804
|
+
});
|
|
805
|
+
}
|
|
767
806
|
function getDirectText(element) {
|
|
768
807
|
let text = "";
|
|
769
808
|
for (let i = 0; i < element.childNodes.length; i++) {
|
|
@@ -772,22 +811,155 @@ function getDirectText(element) {
|
|
|
772
811
|
}
|
|
773
812
|
return text.trim();
|
|
774
813
|
}
|
|
814
|
+
var DYNAMIC_ID_PATTERN = /^(?:el-|:r[0-9]+:|radix-|uid-|ts-|uuid-|id-[a-f0-9]{4,}|.*[0-9]{4,}.*|.*-[a-f0-9]{6,}$)/i;
|
|
815
|
+
var STATE_CLASS_PATTERN = /^(?:hover|active|focus|focus-visible|focus-within|disabled|enabled|checked|selected|open|closed|loading|error|success|warning|hidden|visible|show|hide|current|expanded|collapsed|pressed|dragging|droppable|sortable|placeholder|transition|enter|leave|appear|move)$/i;
|
|
816
|
+
var STATE_CLASS_PREFIX_PATTERN = /^(?:is-|has-|was-|are-|can-|should-|will-|did-|does-|on-|off-|in-|out-|at-|to-|from-)/i;
|
|
817
|
+
function isDynamicId(id) {
|
|
818
|
+
if (!id) return false;
|
|
819
|
+
if (DYNAMIC_ID_PATTERN.test(id)) return true;
|
|
820
|
+
const digitCount = (id.match(/\d/g) || []).length;
|
|
821
|
+
if (digitCount > (id.match(/[a-zA-Z]/g) || []).length && digitCount >= 3) return true;
|
|
822
|
+
const dashParts = id.split("-");
|
|
823
|
+
if (dashParts.length >= 3) {
|
|
824
|
+
const lastPart = dashParts[dashParts.length - 1];
|
|
825
|
+
if (/^\d+$/.test(lastPart) || /^[a-f0-9]{4,}$/i.test(lastPart)) return true;
|
|
826
|
+
}
|
|
827
|
+
return false;
|
|
828
|
+
}
|
|
829
|
+
function isStateClass(className) {
|
|
830
|
+
if (!className) return false;
|
|
831
|
+
if (STATE_CLASS_PATTERN.test(className)) return true;
|
|
832
|
+
if (STATE_CLASS_PREFIX_PATTERN.test(className)) return true;
|
|
833
|
+
if (className.includes("-active") || className.includes("-hover") || className.includes("-focus")) return true;
|
|
834
|
+
if (/^(?:router-link|nuxt-link)/.test(className)) return true;
|
|
835
|
+
return false;
|
|
836
|
+
}
|
|
837
|
+
function filterStateClasses(classes) {
|
|
838
|
+
return classes.filter((cls) => !isStateClass(cls));
|
|
839
|
+
}
|
|
775
840
|
function getElementDescription(element) {
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
841
|
+
try {
|
|
842
|
+
return (0, css_selector_generator.default)(element, {
|
|
843
|
+
selectors: [
|
|
844
|
+
"id",
|
|
845
|
+
"class",
|
|
846
|
+
"tag",
|
|
847
|
+
"attribute",
|
|
848
|
+
"nthchild"
|
|
849
|
+
],
|
|
850
|
+
combineWithinSelector: true,
|
|
851
|
+
combineBetweenSelectors: true,
|
|
852
|
+
maxCombinations: 100,
|
|
853
|
+
maxCandidates: 100,
|
|
854
|
+
blacklist: [(selectorValue) => {
|
|
855
|
+
const idMatch = selectorValue.match(/^#(.+)$/);
|
|
856
|
+
if (idMatch) return isDynamicId(idMatch[1]);
|
|
857
|
+
const classMatch = selectorValue.match(/^\.([a-zA-Z_-][\w-]*)$/);
|
|
858
|
+
if (classMatch) return isStateClass(classMatch[1]);
|
|
859
|
+
return false;
|
|
860
|
+
}]
|
|
861
|
+
});
|
|
862
|
+
} catch (e) {
|
|
863
|
+
const parts = [element.tagName.toLowerCase()];
|
|
864
|
+
const id = element.id;
|
|
865
|
+
if (id && !isDynamicId(id)) parts.push(`#${id}`);
|
|
866
|
+
const className = element.className;
|
|
867
|
+
if (typeof className === "string") {
|
|
868
|
+
const classes = filterStateClasses(className.trim().split(/\s+/).filter(Boolean)).slice(0, 2);
|
|
869
|
+
if (classes.length > 0) parts.push(`.${classes.join(".")}`);
|
|
870
|
+
} else {
|
|
871
|
+
const svgClass = className.baseVal;
|
|
872
|
+
if (svgClass) {
|
|
873
|
+
const classes = filterStateClasses(svgClass.trim().split(/\s+/).filter(Boolean)).slice(0, 2);
|
|
874
|
+
if (classes.length > 0) parts.push(`.${classes.join(".")}`);
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
const name = element.getAttribute("name");
|
|
878
|
+
if (name) parts.push(`[name="${name}"]`);
|
|
879
|
+
const placeholder = element.getAttribute("placeholder");
|
|
880
|
+
if (placeholder) parts.push(`[placeholder="${placeholder.substring(0, 20)}"]`);
|
|
881
|
+
if (element.getAttribute("src")) parts.push(`[src]`);
|
|
882
|
+
const href = element.getAttribute("href");
|
|
883
|
+
if (href && href !== "#") parts.push(`[href]`);
|
|
884
|
+
return parts.join("");
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
function getFileInfoFromAttributes(element) {
|
|
888
|
+
const file = element.getAttribute("data-v-inspector-file");
|
|
889
|
+
if (file) {
|
|
890
|
+
const line = element.getAttribute("data-v-inspector-line");
|
|
891
|
+
const column = element.getAttribute("data-v-inspector-column");
|
|
892
|
+
return {
|
|
893
|
+
file,
|
|
894
|
+
line: line ? parseInt(line, 10) : null,
|
|
895
|
+
column: column ? parseInt(column, 10) : null
|
|
896
|
+
};
|
|
782
897
|
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
898
|
+
return null;
|
|
899
|
+
}
|
|
900
|
+
function getFileInfoFromVueInstance(element) {
|
|
901
|
+
var _a, _b, _c, _d;
|
|
902
|
+
const vue3Instance = element.__vueParentComponent;
|
|
903
|
+
if (vue3Instance) {
|
|
904
|
+
let current = vue3Instance;
|
|
905
|
+
while (current) {
|
|
906
|
+
const file = ((_a = current.type) == null ? void 0 : _a.__file) || ((_c = (_b = current.vnode) == null ? void 0 : _b.type) == null ? void 0 : _c.__file);
|
|
907
|
+
if (file) return {
|
|
908
|
+
file,
|
|
909
|
+
line: null,
|
|
910
|
+
column: null
|
|
911
|
+
};
|
|
912
|
+
current = current.parent;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
const vue2Instance = element.__vue__;
|
|
916
|
+
if (vue2Instance) {
|
|
917
|
+
let current = vue2Instance;
|
|
918
|
+
while (current) {
|
|
919
|
+
const file = (_d = current.$options) == null ? void 0 : _d.__file;
|
|
920
|
+
if (file) return {
|
|
921
|
+
file,
|
|
922
|
+
line: null,
|
|
923
|
+
column: null
|
|
924
|
+
};
|
|
925
|
+
current = current.$parent;
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
return null;
|
|
929
|
+
}
|
|
930
|
+
function findFileInfo(element, inspector) {
|
|
931
|
+
var _a, _b;
|
|
932
|
+
let current = element;
|
|
933
|
+
let fallbackFileInfo = null;
|
|
934
|
+
while (current) {
|
|
935
|
+
const attrInfo = getFileInfoFromAttributes(current);
|
|
936
|
+
if (attrInfo && attrInfo.line !== null) return attrInfo;
|
|
937
|
+
if (attrInfo && !fallbackFileInfo) fallbackFileInfo = attrInfo;
|
|
938
|
+
const fakeEvent = {
|
|
939
|
+
clientX: 0,
|
|
940
|
+
clientY: 0,
|
|
941
|
+
target: current,
|
|
942
|
+
currentTarget: current
|
|
943
|
+
};
|
|
944
|
+
const { params } = inspector.getTargetNode(fakeEvent);
|
|
945
|
+
if (params && params.file) {
|
|
946
|
+
const info = {
|
|
947
|
+
file: params.file,
|
|
948
|
+
line: (_a = params.line) != null ? _a : null,
|
|
949
|
+
column: (_b = params.column) != null ? _b : null
|
|
950
|
+
};
|
|
951
|
+
if (info.line !== null) return info;
|
|
952
|
+
if (!fallbackFileInfo) fallbackFileInfo = info;
|
|
953
|
+
}
|
|
954
|
+
const vueInfo = getFileInfoFromVueInstance(current);
|
|
955
|
+
if (vueInfo && !fallbackFileInfo) fallbackFileInfo = vueInfo;
|
|
956
|
+
current = current.parentElement;
|
|
957
|
+
}
|
|
958
|
+
return fallbackFileInfo || {
|
|
959
|
+
file: null,
|
|
960
|
+
line: null,
|
|
961
|
+
column: null
|
|
962
|
+
};
|
|
791
963
|
}
|
|
792
964
|
function getPreciseElementAtPoint(x, y, boundary) {
|
|
793
965
|
var _a, _b;
|
|
@@ -804,7 +976,12 @@ function getPreciseElementAtPoint(x, y, boundary) {
|
|
|
804
976
|
if (el.closest("#vue-inspector-container")) continue;
|
|
805
977
|
if (el.closest(".opencode-widget")) continue;
|
|
806
978
|
if (el.hasAttribute("data-v-inspector-ignore")) continue;
|
|
807
|
-
if (boundary
|
|
979
|
+
if (boundary) {
|
|
980
|
+
if (boundary.contains(el) || el === boundary) {
|
|
981
|
+
element = el;
|
|
982
|
+
break;
|
|
983
|
+
}
|
|
984
|
+
} else {
|
|
808
985
|
element = el;
|
|
809
986
|
break;
|
|
810
987
|
}
|
|
@@ -834,13 +1011,31 @@ function useInspector(options) {
|
|
|
834
1011
|
});
|
|
835
1012
|
const INSPECTOR_CHECK_INTERVAL = 500;
|
|
836
1013
|
let inspectorCheckTimer = null;
|
|
837
|
-
function
|
|
1014
|
+
function handleMouseMoveCore(e) {
|
|
1015
|
+
var _a, _b;
|
|
838
1016
|
if (!options.selectMode.value) return;
|
|
839
1017
|
const inspector = window.__VUE_INSPECTOR__;
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
1018
|
+
let elementToHighlight = null;
|
|
1019
|
+
let fileInfo = {
|
|
1020
|
+
file: null,
|
|
1021
|
+
line: null,
|
|
1022
|
+
column: null
|
|
1023
|
+
};
|
|
1024
|
+
if (inspector) {
|
|
1025
|
+
const { targetNode, params } = inspector.getTargetNode(e);
|
|
1026
|
+
if (targetNode) {
|
|
1027
|
+
elementToHighlight = getPreciseElementAtPoint(e.clientX, e.clientY, targetNode) || targetNode;
|
|
1028
|
+
if (params && params.file) fileInfo = {
|
|
1029
|
+
file: params.file,
|
|
1030
|
+
line: (_a = params.line) != null ? _a : null,
|
|
1031
|
+
column: (_b = params.column) != null ? _b : null
|
|
1032
|
+
};
|
|
1033
|
+
else if (elementToHighlight) fileInfo = findFileInfo(elementToHighlight, inspector);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
if (!elementToHighlight) elementToHighlight = getPreciseElementAtPoint(e.clientX, e.clientY, null);
|
|
1037
|
+
if (elementToHighlight && !fileInfo.file) fileInfo = getFileInfoFromVueInstance(elementToHighlight) || fileInfo;
|
|
1038
|
+
if (elementToHighlight) {
|
|
844
1039
|
const rect = elementToHighlight.getBoundingClientRect();
|
|
845
1040
|
const widget = document.querySelector(".opencode-widget");
|
|
846
1041
|
let primary = "#3b82f6";
|
|
@@ -860,11 +1055,11 @@ function useInspector(options) {
|
|
|
860
1055
|
background: primaryBg
|
|
861
1056
|
};
|
|
862
1057
|
const description = getElementDescription(elementToHighlight);
|
|
863
|
-
const fileName =
|
|
1058
|
+
const fileName = fileInfo.file ? fileInfo.file.split("/").pop() : "";
|
|
864
1059
|
let lineInfo = "";
|
|
865
|
-
if (
|
|
866
|
-
lineInfo = `:${
|
|
867
|
-
if (
|
|
1060
|
+
if (fileInfo.line) {
|
|
1061
|
+
lineInfo = `:${fileInfo.line}`;
|
|
1062
|
+
if (fileInfo.column) lineInfo += `:${fileInfo.column}`;
|
|
868
1063
|
}
|
|
869
1064
|
tooltipContent.value = {
|
|
870
1065
|
description,
|
|
@@ -886,22 +1081,39 @@ function useInspector(options) {
|
|
|
886
1081
|
tooltipVisible.value = false;
|
|
887
1082
|
}
|
|
888
1083
|
}
|
|
1084
|
+
const handleMouseMove = throttle(handleMouseMoveCore, 16);
|
|
889
1085
|
function setupInspectorHook() {
|
|
890
1086
|
const inspector = window.__VUE_INSPECTOR__;
|
|
891
1087
|
if (!inspector || inspector.__opencode_hooked) return;
|
|
892
1088
|
const originalHandleClick = inspector.handleClick.bind(inspector);
|
|
893
1089
|
inspector.handleClick = function(e) {
|
|
894
|
-
var _a, _b
|
|
1090
|
+
var _a, _b;
|
|
895
1091
|
if (options.selectMode.value) {
|
|
1092
|
+
let elementToSelect = null;
|
|
1093
|
+
let fileInfo = {
|
|
1094
|
+
file: null,
|
|
1095
|
+
line: null,
|
|
1096
|
+
column: null
|
|
1097
|
+
};
|
|
896
1098
|
const { targetNode, params } = inspector.getTargetNode(e);
|
|
897
|
-
if (targetNode
|
|
898
|
-
|
|
1099
|
+
if (targetNode) {
|
|
1100
|
+
elementToSelect = getPreciseElementAtPoint(e.clientX, e.clientY, targetNode) || targetNode;
|
|
1101
|
+
if (params && params.file) fileInfo = {
|
|
1102
|
+
file: params.file,
|
|
1103
|
+
line: (_a = params.line) != null ? _a : null,
|
|
1104
|
+
column: (_b = params.column) != null ? _b : null
|
|
1105
|
+
};
|
|
1106
|
+
else if (elementToSelect) fileInfo = findFileInfo(elementToSelect, inspector);
|
|
1107
|
+
}
|
|
1108
|
+
if (!elementToSelect) elementToSelect = getPreciseElementAtPoint(e.clientX, e.clientY, null);
|
|
1109
|
+
if (elementToSelect && !fileInfo.file) fileInfo = getFileInfoFromVueInstance(elementToSelect) || fileInfo;
|
|
1110
|
+
if (elementToSelect) {
|
|
899
1111
|
const innerText = getDirectText(elementToSelect);
|
|
900
1112
|
const description = getElementDescription(elementToSelect);
|
|
901
1113
|
const elementInfo = {
|
|
902
|
-
filePath:
|
|
903
|
-
line:
|
|
904
|
-
column:
|
|
1114
|
+
filePath: fileInfo.file,
|
|
1115
|
+
line: fileInfo.line,
|
|
1116
|
+
column: fileInfo.column,
|
|
905
1117
|
innerText: (0, _vite_plugin_opencode_assistant_shared.truncate)(innerText, 200),
|
|
906
1118
|
description
|
|
907
1119
|
};
|
|
@@ -1468,7 +1680,7 @@ __vue_sfc__.render = __vue_render__;
|
|
|
1468
1680
|
var open_code_widget_default = __vue_sfc__;
|
|
1469
1681
|
//#endregion
|
|
1470
1682
|
//#region es/index.js
|
|
1471
|
-
var version = "1.0.
|
|
1683
|
+
var version = "1.0.19";
|
|
1472
1684
|
function install(app, options) {
|
|
1473
1685
|
[open_code_widget_default].forEach((item) => {
|
|
1474
1686
|
if (item.install) app.use(item, options);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createStaticVNode, createVNode, defineComponent, inject, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, provide, ref, renderList, renderSlot, toDisplayString, toRef, useSlots, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
|
|
2
2
|
import { truncate } from "@vite-plugin-opencode-assistant/shared";
|
|
3
|
+
import getCssSelector from "css-selector-generator";
|
|
3
4
|
//#region es/open-code-widget/src/context.js
|
|
4
5
|
var CONTEXT_KEY = /* @__PURE__ */ Symbol("OpenCodeWidgetContext");
|
|
5
6
|
function provideOpenCodeWidgetContext(context) {
|
|
@@ -760,6 +761,21 @@ function useWidget(options) {
|
|
|
760
761
|
}
|
|
761
762
|
//#endregion
|
|
762
763
|
//#region es/open-code-widget/composables/use-inspector.js
|
|
764
|
+
function throttle(fn, delay) {
|
|
765
|
+
let lastCall = 0;
|
|
766
|
+
let rafId = null;
|
|
767
|
+
return ((...args) => {
|
|
768
|
+
const now = performance.now();
|
|
769
|
+
if (now - lastCall >= delay) {
|
|
770
|
+
lastCall = now;
|
|
771
|
+
fn(...args);
|
|
772
|
+
} else if (!rafId) rafId = requestAnimationFrame(() => {
|
|
773
|
+
rafId = null;
|
|
774
|
+
lastCall = performance.now();
|
|
775
|
+
fn(...args);
|
|
776
|
+
});
|
|
777
|
+
});
|
|
778
|
+
}
|
|
763
779
|
function getDirectText(element) {
|
|
764
780
|
let text = "";
|
|
765
781
|
for (let i = 0; i < element.childNodes.length; i++) {
|
|
@@ -768,22 +784,155 @@ function getDirectText(element) {
|
|
|
768
784
|
}
|
|
769
785
|
return text.trim();
|
|
770
786
|
}
|
|
787
|
+
var DYNAMIC_ID_PATTERN = /^(?:el-|:r[0-9]+:|radix-|uid-|ts-|uuid-|id-[a-f0-9]{4,}|.*[0-9]{4,}.*|.*-[a-f0-9]{6,}$)/i;
|
|
788
|
+
var STATE_CLASS_PATTERN = /^(?:hover|active|focus|focus-visible|focus-within|disabled|enabled|checked|selected|open|closed|loading|error|success|warning|hidden|visible|show|hide|current|expanded|collapsed|pressed|dragging|droppable|sortable|placeholder|transition|enter|leave|appear|move)$/i;
|
|
789
|
+
var STATE_CLASS_PREFIX_PATTERN = /^(?:is-|has-|was-|are-|can-|should-|will-|did-|does-|on-|off-|in-|out-|at-|to-|from-)/i;
|
|
790
|
+
function isDynamicId(id) {
|
|
791
|
+
if (!id) return false;
|
|
792
|
+
if (DYNAMIC_ID_PATTERN.test(id)) return true;
|
|
793
|
+
const digitCount = (id.match(/\d/g) || []).length;
|
|
794
|
+
if (digitCount > (id.match(/[a-zA-Z]/g) || []).length && digitCount >= 3) return true;
|
|
795
|
+
const dashParts = id.split("-");
|
|
796
|
+
if (dashParts.length >= 3) {
|
|
797
|
+
const lastPart = dashParts[dashParts.length - 1];
|
|
798
|
+
if (/^\d+$/.test(lastPart) || /^[a-f0-9]{4,}$/i.test(lastPart)) return true;
|
|
799
|
+
}
|
|
800
|
+
return false;
|
|
801
|
+
}
|
|
802
|
+
function isStateClass(className) {
|
|
803
|
+
if (!className) return false;
|
|
804
|
+
if (STATE_CLASS_PATTERN.test(className)) return true;
|
|
805
|
+
if (STATE_CLASS_PREFIX_PATTERN.test(className)) return true;
|
|
806
|
+
if (className.includes("-active") || className.includes("-hover") || className.includes("-focus")) return true;
|
|
807
|
+
if (/^(?:router-link|nuxt-link)/.test(className)) return true;
|
|
808
|
+
return false;
|
|
809
|
+
}
|
|
810
|
+
function filterStateClasses(classes) {
|
|
811
|
+
return classes.filter((cls) => !isStateClass(cls));
|
|
812
|
+
}
|
|
771
813
|
function getElementDescription(element) {
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
814
|
+
try {
|
|
815
|
+
return getCssSelector(element, {
|
|
816
|
+
selectors: [
|
|
817
|
+
"id",
|
|
818
|
+
"class",
|
|
819
|
+
"tag",
|
|
820
|
+
"attribute",
|
|
821
|
+
"nthchild"
|
|
822
|
+
],
|
|
823
|
+
combineWithinSelector: true,
|
|
824
|
+
combineBetweenSelectors: true,
|
|
825
|
+
maxCombinations: 100,
|
|
826
|
+
maxCandidates: 100,
|
|
827
|
+
blacklist: [(selectorValue) => {
|
|
828
|
+
const idMatch = selectorValue.match(/^#(.+)$/);
|
|
829
|
+
if (idMatch) return isDynamicId(idMatch[1]);
|
|
830
|
+
const classMatch = selectorValue.match(/^\.([a-zA-Z_-][\w-]*)$/);
|
|
831
|
+
if (classMatch) return isStateClass(classMatch[1]);
|
|
832
|
+
return false;
|
|
833
|
+
}]
|
|
834
|
+
});
|
|
835
|
+
} catch (e) {
|
|
836
|
+
const parts = [element.tagName.toLowerCase()];
|
|
837
|
+
const id = element.id;
|
|
838
|
+
if (id && !isDynamicId(id)) parts.push(`#${id}`);
|
|
839
|
+
const className = element.className;
|
|
840
|
+
if (typeof className === "string") {
|
|
841
|
+
const classes = filterStateClasses(className.trim().split(/\s+/).filter(Boolean)).slice(0, 2);
|
|
842
|
+
if (classes.length > 0) parts.push(`.${classes.join(".")}`);
|
|
843
|
+
} else {
|
|
844
|
+
const svgClass = className.baseVal;
|
|
845
|
+
if (svgClass) {
|
|
846
|
+
const classes = filterStateClasses(svgClass.trim().split(/\s+/).filter(Boolean)).slice(0, 2);
|
|
847
|
+
if (classes.length > 0) parts.push(`.${classes.join(".")}`);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
const name = element.getAttribute("name");
|
|
851
|
+
if (name) parts.push(`[name="${name}"]`);
|
|
852
|
+
const placeholder = element.getAttribute("placeholder");
|
|
853
|
+
if (placeholder) parts.push(`[placeholder="${placeholder.substring(0, 20)}"]`);
|
|
854
|
+
if (element.getAttribute("src")) parts.push(`[src]`);
|
|
855
|
+
const href = element.getAttribute("href");
|
|
856
|
+
if (href && href !== "#") parts.push(`[href]`);
|
|
857
|
+
return parts.join("");
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
function getFileInfoFromAttributes(element) {
|
|
861
|
+
const file = element.getAttribute("data-v-inspector-file");
|
|
862
|
+
if (file) {
|
|
863
|
+
const line = element.getAttribute("data-v-inspector-line");
|
|
864
|
+
const column = element.getAttribute("data-v-inspector-column");
|
|
865
|
+
return {
|
|
866
|
+
file,
|
|
867
|
+
line: line ? parseInt(line, 10) : null,
|
|
868
|
+
column: column ? parseInt(column, 10) : null
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
return null;
|
|
872
|
+
}
|
|
873
|
+
function getFileInfoFromVueInstance(element) {
|
|
874
|
+
var _a, _b, _c, _d;
|
|
875
|
+
const vue3Instance = element.__vueParentComponent;
|
|
876
|
+
if (vue3Instance) {
|
|
877
|
+
let current = vue3Instance;
|
|
878
|
+
while (current) {
|
|
879
|
+
const file = ((_a = current.type) == null ? void 0 : _a.__file) || ((_c = (_b = current.vnode) == null ? void 0 : _b.type) == null ? void 0 : _c.__file);
|
|
880
|
+
if (file) return {
|
|
881
|
+
file,
|
|
882
|
+
line: null,
|
|
883
|
+
column: null
|
|
884
|
+
};
|
|
885
|
+
current = current.parent;
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
const vue2Instance = element.__vue__;
|
|
889
|
+
if (vue2Instance) {
|
|
890
|
+
let current = vue2Instance;
|
|
891
|
+
while (current) {
|
|
892
|
+
const file = (_d = current.$options) == null ? void 0 : _d.__file;
|
|
893
|
+
if (file) return {
|
|
894
|
+
file,
|
|
895
|
+
line: null,
|
|
896
|
+
column: null
|
|
897
|
+
};
|
|
898
|
+
current = current.$parent;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
return null;
|
|
902
|
+
}
|
|
903
|
+
function findFileInfo(element, inspector) {
|
|
904
|
+
var _a, _b;
|
|
905
|
+
let current = element;
|
|
906
|
+
let fallbackFileInfo = null;
|
|
907
|
+
while (current) {
|
|
908
|
+
const attrInfo = getFileInfoFromAttributes(current);
|
|
909
|
+
if (attrInfo && attrInfo.line !== null) return attrInfo;
|
|
910
|
+
if (attrInfo && !fallbackFileInfo) fallbackFileInfo = attrInfo;
|
|
911
|
+
const fakeEvent = {
|
|
912
|
+
clientX: 0,
|
|
913
|
+
clientY: 0,
|
|
914
|
+
target: current,
|
|
915
|
+
currentTarget: current
|
|
916
|
+
};
|
|
917
|
+
const { params } = inspector.getTargetNode(fakeEvent);
|
|
918
|
+
if (params && params.file) {
|
|
919
|
+
const info = {
|
|
920
|
+
file: params.file,
|
|
921
|
+
line: (_a = params.line) != null ? _a : null,
|
|
922
|
+
column: (_b = params.column) != null ? _b : null
|
|
923
|
+
};
|
|
924
|
+
if (info.line !== null) return info;
|
|
925
|
+
if (!fallbackFileInfo) fallbackFileInfo = info;
|
|
926
|
+
}
|
|
927
|
+
const vueInfo = getFileInfoFromVueInstance(current);
|
|
928
|
+
if (vueInfo && !fallbackFileInfo) fallbackFileInfo = vueInfo;
|
|
929
|
+
current = current.parentElement;
|
|
778
930
|
}
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
const href = element.getAttribute("href");
|
|
785
|
-
if (href && href !== "#") parts.push(`[href]`);
|
|
786
|
-
return parts.join("");
|
|
931
|
+
return fallbackFileInfo || {
|
|
932
|
+
file: null,
|
|
933
|
+
line: null,
|
|
934
|
+
column: null
|
|
935
|
+
};
|
|
787
936
|
}
|
|
788
937
|
function getPreciseElementAtPoint(x, y, boundary) {
|
|
789
938
|
var _a, _b;
|
|
@@ -800,7 +949,12 @@ function getPreciseElementAtPoint(x, y, boundary) {
|
|
|
800
949
|
if (el.closest("#vue-inspector-container")) continue;
|
|
801
950
|
if (el.closest(".opencode-widget")) continue;
|
|
802
951
|
if (el.hasAttribute("data-v-inspector-ignore")) continue;
|
|
803
|
-
if (boundary
|
|
952
|
+
if (boundary) {
|
|
953
|
+
if (boundary.contains(el) || el === boundary) {
|
|
954
|
+
element = el;
|
|
955
|
+
break;
|
|
956
|
+
}
|
|
957
|
+
} else {
|
|
804
958
|
element = el;
|
|
805
959
|
break;
|
|
806
960
|
}
|
|
@@ -830,13 +984,31 @@ function useInspector(options) {
|
|
|
830
984
|
});
|
|
831
985
|
const INSPECTOR_CHECK_INTERVAL = 500;
|
|
832
986
|
let inspectorCheckTimer = null;
|
|
833
|
-
function
|
|
987
|
+
function handleMouseMoveCore(e) {
|
|
988
|
+
var _a, _b;
|
|
834
989
|
if (!options.selectMode.value) return;
|
|
835
990
|
const inspector = window.__VUE_INSPECTOR__;
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
991
|
+
let elementToHighlight = null;
|
|
992
|
+
let fileInfo = {
|
|
993
|
+
file: null,
|
|
994
|
+
line: null,
|
|
995
|
+
column: null
|
|
996
|
+
};
|
|
997
|
+
if (inspector) {
|
|
998
|
+
const { targetNode, params } = inspector.getTargetNode(e);
|
|
999
|
+
if (targetNode) {
|
|
1000
|
+
elementToHighlight = getPreciseElementAtPoint(e.clientX, e.clientY, targetNode) || targetNode;
|
|
1001
|
+
if (params && params.file) fileInfo = {
|
|
1002
|
+
file: params.file,
|
|
1003
|
+
line: (_a = params.line) != null ? _a : null,
|
|
1004
|
+
column: (_b = params.column) != null ? _b : null
|
|
1005
|
+
};
|
|
1006
|
+
else if (elementToHighlight) fileInfo = findFileInfo(elementToHighlight, inspector);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
if (!elementToHighlight) elementToHighlight = getPreciseElementAtPoint(e.clientX, e.clientY, null);
|
|
1010
|
+
if (elementToHighlight && !fileInfo.file) fileInfo = getFileInfoFromVueInstance(elementToHighlight) || fileInfo;
|
|
1011
|
+
if (elementToHighlight) {
|
|
840
1012
|
const rect = elementToHighlight.getBoundingClientRect();
|
|
841
1013
|
const widget = document.querySelector(".opencode-widget");
|
|
842
1014
|
let primary = "#3b82f6";
|
|
@@ -856,11 +1028,11 @@ function useInspector(options) {
|
|
|
856
1028
|
background: primaryBg
|
|
857
1029
|
};
|
|
858
1030
|
const description = getElementDescription(elementToHighlight);
|
|
859
|
-
const fileName =
|
|
1031
|
+
const fileName = fileInfo.file ? fileInfo.file.split("/").pop() : "";
|
|
860
1032
|
let lineInfo = "";
|
|
861
|
-
if (
|
|
862
|
-
lineInfo = `:${
|
|
863
|
-
if (
|
|
1033
|
+
if (fileInfo.line) {
|
|
1034
|
+
lineInfo = `:${fileInfo.line}`;
|
|
1035
|
+
if (fileInfo.column) lineInfo += `:${fileInfo.column}`;
|
|
864
1036
|
}
|
|
865
1037
|
tooltipContent.value = {
|
|
866
1038
|
description,
|
|
@@ -882,22 +1054,39 @@ function useInspector(options) {
|
|
|
882
1054
|
tooltipVisible.value = false;
|
|
883
1055
|
}
|
|
884
1056
|
}
|
|
1057
|
+
const handleMouseMove = throttle(handleMouseMoveCore, 16);
|
|
885
1058
|
function setupInspectorHook() {
|
|
886
1059
|
const inspector = window.__VUE_INSPECTOR__;
|
|
887
1060
|
if (!inspector || inspector.__opencode_hooked) return;
|
|
888
1061
|
const originalHandleClick = inspector.handleClick.bind(inspector);
|
|
889
1062
|
inspector.handleClick = function(e) {
|
|
890
|
-
var _a, _b
|
|
1063
|
+
var _a, _b;
|
|
891
1064
|
if (options.selectMode.value) {
|
|
1065
|
+
let elementToSelect = null;
|
|
1066
|
+
let fileInfo = {
|
|
1067
|
+
file: null,
|
|
1068
|
+
line: null,
|
|
1069
|
+
column: null
|
|
1070
|
+
};
|
|
892
1071
|
const { targetNode, params } = inspector.getTargetNode(e);
|
|
893
|
-
if (targetNode
|
|
894
|
-
|
|
1072
|
+
if (targetNode) {
|
|
1073
|
+
elementToSelect = getPreciseElementAtPoint(e.clientX, e.clientY, targetNode) || targetNode;
|
|
1074
|
+
if (params && params.file) fileInfo = {
|
|
1075
|
+
file: params.file,
|
|
1076
|
+
line: (_a = params.line) != null ? _a : null,
|
|
1077
|
+
column: (_b = params.column) != null ? _b : null
|
|
1078
|
+
};
|
|
1079
|
+
else if (elementToSelect) fileInfo = findFileInfo(elementToSelect, inspector);
|
|
1080
|
+
}
|
|
1081
|
+
if (!elementToSelect) elementToSelect = getPreciseElementAtPoint(e.clientX, e.clientY, null);
|
|
1082
|
+
if (elementToSelect && !fileInfo.file) fileInfo = getFileInfoFromVueInstance(elementToSelect) || fileInfo;
|
|
1083
|
+
if (elementToSelect) {
|
|
895
1084
|
const innerText = getDirectText(elementToSelect);
|
|
896
1085
|
const description = getElementDescription(elementToSelect);
|
|
897
1086
|
const elementInfo = {
|
|
898
|
-
filePath:
|
|
899
|
-
line:
|
|
900
|
-
column:
|
|
1087
|
+
filePath: fileInfo.file,
|
|
1088
|
+
line: fileInfo.line,
|
|
1089
|
+
column: fileInfo.column,
|
|
901
1090
|
innerText: truncate(innerText, 200),
|
|
902
1091
|
description
|
|
903
1092
|
};
|
|
@@ -1464,7 +1653,7 @@ __vue_sfc__.render = __vue_render__;
|
|
|
1464
1653
|
var open_code_widget_default = __vue_sfc__;
|
|
1465
1654
|
//#endregion
|
|
1466
1655
|
//#region es/index.js
|
|
1467
|
-
var version = "1.0.
|
|
1656
|
+
var version = "1.0.19";
|
|
1468
1657
|
function install(app, options) {
|
|
1469
1658
|
[open_code_widget_default].forEach((item) => {
|
|
1470
1659
|
if (item.install) app.use(item, options);
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import OpenCodeWidget from './open-code-widget';
|
|
2
2
|
import type { App } from 'vue';
|
|
3
|
-
declare const version = "1.0.
|
|
3
|
+
declare const version = "1.0.19";
|
|
4
4
|
declare function install(app: App<any>, options?: any): void;
|
|
5
5
|
export { install, version, OpenCodeWidget };
|
|
6
6
|
export default install;
|
package/lib/index.js
CHANGED
|
@@ -34,7 +34,7 @@ __export(lib_exports, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(lib_exports);
|
|
36
36
|
var import_open_code_widget = __toESM(require("./open-code-widget"));
|
|
37
|
-
const version = "1.0.
|
|
37
|
+
const version = "1.0.19";
|
|
38
38
|
function install(app, options) {
|
|
39
39
|
const components = [
|
|
40
40
|
import_open_code_widget.default
|