@vite-plugin-opencode-assistant/components 1.0.18 → 1.0.20
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 +242 -31
- package/lib/@vite-plugin-opencode-assistant/components.es.js +219 -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,154 @@ 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
|
+
"nthchild"
|
|
848
|
+
],
|
|
849
|
+
combineWithinSelector: true,
|
|
850
|
+
combineBetweenSelectors: true,
|
|
851
|
+
maxCombinations: 100,
|
|
852
|
+
maxCandidates: 100,
|
|
853
|
+
blacklist: [(selectorValue) => {
|
|
854
|
+
const idMatch = selectorValue.match(/^#(.+)$/);
|
|
855
|
+
if (idMatch) return isDynamicId(idMatch[1]);
|
|
856
|
+
const classMatch = selectorValue.match(/^\.([a-zA-Z_-][\w-]*)$/);
|
|
857
|
+
if (classMatch) return isStateClass(classMatch[1]);
|
|
858
|
+
return false;
|
|
859
|
+
}]
|
|
860
|
+
});
|
|
861
|
+
} catch (e) {
|
|
862
|
+
const parts = [element.tagName.toLowerCase()];
|
|
863
|
+
const id = element.id;
|
|
864
|
+
if (id && !isDynamicId(id)) parts.push(`#${id}`);
|
|
865
|
+
const className = element.className;
|
|
866
|
+
if (typeof className === "string") {
|
|
867
|
+
const classes = filterStateClasses(className.trim().split(/\s+/).filter(Boolean)).slice(0, 2);
|
|
868
|
+
if (classes.length > 0) parts.push(`.${classes.join(".")}`);
|
|
869
|
+
} else {
|
|
870
|
+
const svgClass = className.baseVal;
|
|
871
|
+
if (svgClass) {
|
|
872
|
+
const classes = filterStateClasses(svgClass.trim().split(/\s+/).filter(Boolean)).slice(0, 2);
|
|
873
|
+
if (classes.length > 0) parts.push(`.${classes.join(".")}`);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
const name = element.getAttribute("name");
|
|
877
|
+
if (name) parts.push(`[name="${name}"]`);
|
|
878
|
+
const placeholder = element.getAttribute("placeholder");
|
|
879
|
+
if (placeholder) parts.push(`[placeholder="${placeholder.substring(0, 20)}"]`);
|
|
880
|
+
if (element.getAttribute("src")) parts.push(`[src]`);
|
|
881
|
+
const href = element.getAttribute("href");
|
|
882
|
+
if (href && href !== "#") parts.push(`[href]`);
|
|
883
|
+
return parts.join("");
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
function getFileInfoFromAttributes(element) {
|
|
887
|
+
const file = element.getAttribute("data-v-inspector-file");
|
|
888
|
+
if (file) {
|
|
889
|
+
const line = element.getAttribute("data-v-inspector-line");
|
|
890
|
+
const column = element.getAttribute("data-v-inspector-column");
|
|
891
|
+
return {
|
|
892
|
+
file,
|
|
893
|
+
line: line ? parseInt(line, 10) : null,
|
|
894
|
+
column: column ? parseInt(column, 10) : null
|
|
895
|
+
};
|
|
782
896
|
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
897
|
+
return null;
|
|
898
|
+
}
|
|
899
|
+
function getFileInfoFromVueInstance(element) {
|
|
900
|
+
var _a, _b, _c, _d;
|
|
901
|
+
const vue3Instance = element.__vueParentComponent;
|
|
902
|
+
if (vue3Instance) {
|
|
903
|
+
let current = vue3Instance;
|
|
904
|
+
while (current) {
|
|
905
|
+
const file = ((_a = current.type) == null ? void 0 : _a.__file) || ((_c = (_b = current.vnode) == null ? void 0 : _b.type) == null ? void 0 : _c.__file);
|
|
906
|
+
if (file) return {
|
|
907
|
+
file,
|
|
908
|
+
line: null,
|
|
909
|
+
column: null
|
|
910
|
+
};
|
|
911
|
+
current = current.parent;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
const vue2Instance = element.__vue__;
|
|
915
|
+
if (vue2Instance) {
|
|
916
|
+
let current = vue2Instance;
|
|
917
|
+
while (current) {
|
|
918
|
+
const file = (_d = current.$options) == null ? void 0 : _d.__file;
|
|
919
|
+
if (file) return {
|
|
920
|
+
file,
|
|
921
|
+
line: null,
|
|
922
|
+
column: null
|
|
923
|
+
};
|
|
924
|
+
current = current.$parent;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
return null;
|
|
928
|
+
}
|
|
929
|
+
function findFileInfo(element, inspector) {
|
|
930
|
+
var _a, _b;
|
|
931
|
+
let current = element;
|
|
932
|
+
let fallbackFileInfo = null;
|
|
933
|
+
while (current) {
|
|
934
|
+
const attrInfo = getFileInfoFromAttributes(current);
|
|
935
|
+
if (attrInfo && attrInfo.line !== null) return attrInfo;
|
|
936
|
+
if (attrInfo && !fallbackFileInfo) fallbackFileInfo = attrInfo;
|
|
937
|
+
const fakeEvent = {
|
|
938
|
+
clientX: 0,
|
|
939
|
+
clientY: 0,
|
|
940
|
+
target: current,
|
|
941
|
+
currentTarget: current
|
|
942
|
+
};
|
|
943
|
+
const { params } = inspector.getTargetNode(fakeEvent);
|
|
944
|
+
if (params && params.file) {
|
|
945
|
+
const info = {
|
|
946
|
+
file: params.file,
|
|
947
|
+
line: (_a = params.line) != null ? _a : null,
|
|
948
|
+
column: (_b = params.column) != null ? _b : null
|
|
949
|
+
};
|
|
950
|
+
if (info.line !== null) return info;
|
|
951
|
+
if (!fallbackFileInfo) fallbackFileInfo = info;
|
|
952
|
+
}
|
|
953
|
+
const vueInfo = getFileInfoFromVueInstance(current);
|
|
954
|
+
if (vueInfo && !fallbackFileInfo) fallbackFileInfo = vueInfo;
|
|
955
|
+
current = current.parentElement;
|
|
956
|
+
}
|
|
957
|
+
return fallbackFileInfo || {
|
|
958
|
+
file: null,
|
|
959
|
+
line: null,
|
|
960
|
+
column: null
|
|
961
|
+
};
|
|
791
962
|
}
|
|
792
963
|
function getPreciseElementAtPoint(x, y, boundary) {
|
|
793
964
|
var _a, _b;
|
|
@@ -804,7 +975,12 @@ function getPreciseElementAtPoint(x, y, boundary) {
|
|
|
804
975
|
if (el.closest("#vue-inspector-container")) continue;
|
|
805
976
|
if (el.closest(".opencode-widget")) continue;
|
|
806
977
|
if (el.hasAttribute("data-v-inspector-ignore")) continue;
|
|
807
|
-
if (boundary
|
|
978
|
+
if (boundary) {
|
|
979
|
+
if (boundary.contains(el) || el === boundary) {
|
|
980
|
+
element = el;
|
|
981
|
+
break;
|
|
982
|
+
}
|
|
983
|
+
} else {
|
|
808
984
|
element = el;
|
|
809
985
|
break;
|
|
810
986
|
}
|
|
@@ -834,13 +1010,31 @@ function useInspector(options) {
|
|
|
834
1010
|
});
|
|
835
1011
|
const INSPECTOR_CHECK_INTERVAL = 500;
|
|
836
1012
|
let inspectorCheckTimer = null;
|
|
837
|
-
function
|
|
1013
|
+
function handleMouseMoveCore(e) {
|
|
1014
|
+
var _a, _b;
|
|
838
1015
|
if (!options.selectMode.value) return;
|
|
839
1016
|
const inspector = window.__VUE_INSPECTOR__;
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
1017
|
+
let elementToHighlight = null;
|
|
1018
|
+
let fileInfo = {
|
|
1019
|
+
file: null,
|
|
1020
|
+
line: null,
|
|
1021
|
+
column: null
|
|
1022
|
+
};
|
|
1023
|
+
if (inspector) {
|
|
1024
|
+
const { targetNode, params } = inspector.getTargetNode(e);
|
|
1025
|
+
if (targetNode) {
|
|
1026
|
+
elementToHighlight = getPreciseElementAtPoint(e.clientX, e.clientY, targetNode) || targetNode;
|
|
1027
|
+
if (params && params.file) fileInfo = {
|
|
1028
|
+
file: params.file,
|
|
1029
|
+
line: (_a = params.line) != null ? _a : null,
|
|
1030
|
+
column: (_b = params.column) != null ? _b : null
|
|
1031
|
+
};
|
|
1032
|
+
else if (elementToHighlight) fileInfo = findFileInfo(elementToHighlight, inspector);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
if (!elementToHighlight) elementToHighlight = getPreciseElementAtPoint(e.clientX, e.clientY, null);
|
|
1036
|
+
if (elementToHighlight && !fileInfo.file) fileInfo = getFileInfoFromVueInstance(elementToHighlight) || fileInfo;
|
|
1037
|
+
if (elementToHighlight) {
|
|
844
1038
|
const rect = elementToHighlight.getBoundingClientRect();
|
|
845
1039
|
const widget = document.querySelector(".opencode-widget");
|
|
846
1040
|
let primary = "#3b82f6";
|
|
@@ -860,11 +1054,11 @@ function useInspector(options) {
|
|
|
860
1054
|
background: primaryBg
|
|
861
1055
|
};
|
|
862
1056
|
const description = getElementDescription(elementToHighlight);
|
|
863
|
-
const fileName =
|
|
1057
|
+
const fileName = fileInfo.file ? fileInfo.file.split("/").pop() : "";
|
|
864
1058
|
let lineInfo = "";
|
|
865
|
-
if (
|
|
866
|
-
lineInfo = `:${
|
|
867
|
-
if (
|
|
1059
|
+
if (fileInfo.line) {
|
|
1060
|
+
lineInfo = `:${fileInfo.line}`;
|
|
1061
|
+
if (fileInfo.column) lineInfo += `:${fileInfo.column}`;
|
|
868
1062
|
}
|
|
869
1063
|
tooltipContent.value = {
|
|
870
1064
|
description,
|
|
@@ -886,22 +1080,39 @@ function useInspector(options) {
|
|
|
886
1080
|
tooltipVisible.value = false;
|
|
887
1081
|
}
|
|
888
1082
|
}
|
|
1083
|
+
const handleMouseMove = throttle(handleMouseMoveCore, 16);
|
|
889
1084
|
function setupInspectorHook() {
|
|
890
1085
|
const inspector = window.__VUE_INSPECTOR__;
|
|
891
1086
|
if (!inspector || inspector.__opencode_hooked) return;
|
|
892
1087
|
const originalHandleClick = inspector.handleClick.bind(inspector);
|
|
893
1088
|
inspector.handleClick = function(e) {
|
|
894
|
-
var _a, _b
|
|
1089
|
+
var _a, _b;
|
|
895
1090
|
if (options.selectMode.value) {
|
|
1091
|
+
let elementToSelect = null;
|
|
1092
|
+
let fileInfo = {
|
|
1093
|
+
file: null,
|
|
1094
|
+
line: null,
|
|
1095
|
+
column: null
|
|
1096
|
+
};
|
|
896
1097
|
const { targetNode, params } = inspector.getTargetNode(e);
|
|
897
|
-
if (targetNode
|
|
898
|
-
|
|
1098
|
+
if (targetNode) {
|
|
1099
|
+
elementToSelect = getPreciseElementAtPoint(e.clientX, e.clientY, targetNode) || targetNode;
|
|
1100
|
+
if (params && params.file) fileInfo = {
|
|
1101
|
+
file: params.file,
|
|
1102
|
+
line: (_a = params.line) != null ? _a : null,
|
|
1103
|
+
column: (_b = params.column) != null ? _b : null
|
|
1104
|
+
};
|
|
1105
|
+
else if (elementToSelect) fileInfo = findFileInfo(elementToSelect, inspector);
|
|
1106
|
+
}
|
|
1107
|
+
if (!elementToSelect) elementToSelect = getPreciseElementAtPoint(e.clientX, e.clientY, null);
|
|
1108
|
+
if (elementToSelect && !fileInfo.file) fileInfo = getFileInfoFromVueInstance(elementToSelect) || fileInfo;
|
|
1109
|
+
if (elementToSelect) {
|
|
899
1110
|
const innerText = getDirectText(elementToSelect);
|
|
900
1111
|
const description = getElementDescription(elementToSelect);
|
|
901
1112
|
const elementInfo = {
|
|
902
|
-
filePath:
|
|
903
|
-
line:
|
|
904
|
-
column:
|
|
1113
|
+
filePath: fileInfo.file,
|
|
1114
|
+
line: fileInfo.line,
|
|
1115
|
+
column: fileInfo.column,
|
|
905
1116
|
innerText: (0, _vite_plugin_opencode_assistant_shared.truncate)(innerText, 200),
|
|
906
1117
|
description
|
|
907
1118
|
};
|
|
@@ -1468,7 +1679,7 @@ __vue_sfc__.render = __vue_render__;
|
|
|
1468
1679
|
var open_code_widget_default = __vue_sfc__;
|
|
1469
1680
|
//#endregion
|
|
1470
1681
|
//#region es/index.js
|
|
1471
|
-
var version = "1.0.
|
|
1682
|
+
var version = "1.0.20";
|
|
1472
1683
|
function install(app, options) {
|
|
1473
1684
|
[open_code_widget_default].forEach((item) => {
|
|
1474
1685
|
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,154 @@ 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
|
+
"nthchild"
|
|
821
|
+
],
|
|
822
|
+
combineWithinSelector: true,
|
|
823
|
+
combineBetweenSelectors: true,
|
|
824
|
+
maxCombinations: 100,
|
|
825
|
+
maxCandidates: 100,
|
|
826
|
+
blacklist: [(selectorValue) => {
|
|
827
|
+
const idMatch = selectorValue.match(/^#(.+)$/);
|
|
828
|
+
if (idMatch) return isDynamicId(idMatch[1]);
|
|
829
|
+
const classMatch = selectorValue.match(/^\.([a-zA-Z_-][\w-]*)$/);
|
|
830
|
+
if (classMatch) return isStateClass(classMatch[1]);
|
|
831
|
+
return false;
|
|
832
|
+
}]
|
|
833
|
+
});
|
|
834
|
+
} catch (e) {
|
|
835
|
+
const parts = [element.tagName.toLowerCase()];
|
|
836
|
+
const id = element.id;
|
|
837
|
+
if (id && !isDynamicId(id)) parts.push(`#${id}`);
|
|
838
|
+
const className = element.className;
|
|
839
|
+
if (typeof className === "string") {
|
|
840
|
+
const classes = filterStateClasses(className.trim().split(/\s+/).filter(Boolean)).slice(0, 2);
|
|
841
|
+
if (classes.length > 0) parts.push(`.${classes.join(".")}`);
|
|
842
|
+
} else {
|
|
843
|
+
const svgClass = className.baseVal;
|
|
844
|
+
if (svgClass) {
|
|
845
|
+
const classes = filterStateClasses(svgClass.trim().split(/\s+/).filter(Boolean)).slice(0, 2);
|
|
846
|
+
if (classes.length > 0) parts.push(`.${classes.join(".")}`);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
const name = element.getAttribute("name");
|
|
850
|
+
if (name) parts.push(`[name="${name}"]`);
|
|
851
|
+
const placeholder = element.getAttribute("placeholder");
|
|
852
|
+
if (placeholder) parts.push(`[placeholder="${placeholder.substring(0, 20)}"]`);
|
|
853
|
+
if (element.getAttribute("src")) parts.push(`[src]`);
|
|
854
|
+
const href = element.getAttribute("href");
|
|
855
|
+
if (href && href !== "#") parts.push(`[href]`);
|
|
856
|
+
return parts.join("");
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
function getFileInfoFromAttributes(element) {
|
|
860
|
+
const file = element.getAttribute("data-v-inspector-file");
|
|
861
|
+
if (file) {
|
|
862
|
+
const line = element.getAttribute("data-v-inspector-line");
|
|
863
|
+
const column = element.getAttribute("data-v-inspector-column");
|
|
864
|
+
return {
|
|
865
|
+
file,
|
|
866
|
+
line: line ? parseInt(line, 10) : null,
|
|
867
|
+
column: column ? parseInt(column, 10) : null
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
return null;
|
|
871
|
+
}
|
|
872
|
+
function getFileInfoFromVueInstance(element) {
|
|
873
|
+
var _a, _b, _c, _d;
|
|
874
|
+
const vue3Instance = element.__vueParentComponent;
|
|
875
|
+
if (vue3Instance) {
|
|
876
|
+
let current = vue3Instance;
|
|
877
|
+
while (current) {
|
|
878
|
+
const file = ((_a = current.type) == null ? void 0 : _a.__file) || ((_c = (_b = current.vnode) == null ? void 0 : _b.type) == null ? void 0 : _c.__file);
|
|
879
|
+
if (file) return {
|
|
880
|
+
file,
|
|
881
|
+
line: null,
|
|
882
|
+
column: null
|
|
883
|
+
};
|
|
884
|
+
current = current.parent;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
const vue2Instance = element.__vue__;
|
|
888
|
+
if (vue2Instance) {
|
|
889
|
+
let current = vue2Instance;
|
|
890
|
+
while (current) {
|
|
891
|
+
const file = (_d = current.$options) == null ? void 0 : _d.__file;
|
|
892
|
+
if (file) return {
|
|
893
|
+
file,
|
|
894
|
+
line: null,
|
|
895
|
+
column: null
|
|
896
|
+
};
|
|
897
|
+
current = current.$parent;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
return null;
|
|
901
|
+
}
|
|
902
|
+
function findFileInfo(element, inspector) {
|
|
903
|
+
var _a, _b;
|
|
904
|
+
let current = element;
|
|
905
|
+
let fallbackFileInfo = null;
|
|
906
|
+
while (current) {
|
|
907
|
+
const attrInfo = getFileInfoFromAttributes(current);
|
|
908
|
+
if (attrInfo && attrInfo.line !== null) return attrInfo;
|
|
909
|
+
if (attrInfo && !fallbackFileInfo) fallbackFileInfo = attrInfo;
|
|
910
|
+
const fakeEvent = {
|
|
911
|
+
clientX: 0,
|
|
912
|
+
clientY: 0,
|
|
913
|
+
target: current,
|
|
914
|
+
currentTarget: current
|
|
915
|
+
};
|
|
916
|
+
const { params } = inspector.getTargetNode(fakeEvent);
|
|
917
|
+
if (params && params.file) {
|
|
918
|
+
const info = {
|
|
919
|
+
file: params.file,
|
|
920
|
+
line: (_a = params.line) != null ? _a : null,
|
|
921
|
+
column: (_b = params.column) != null ? _b : null
|
|
922
|
+
};
|
|
923
|
+
if (info.line !== null) return info;
|
|
924
|
+
if (!fallbackFileInfo) fallbackFileInfo = info;
|
|
925
|
+
}
|
|
926
|
+
const vueInfo = getFileInfoFromVueInstance(current);
|
|
927
|
+
if (vueInfo && !fallbackFileInfo) fallbackFileInfo = vueInfo;
|
|
928
|
+
current = current.parentElement;
|
|
778
929
|
}
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
const href = element.getAttribute("href");
|
|
785
|
-
if (href && href !== "#") parts.push(`[href]`);
|
|
786
|
-
return parts.join("");
|
|
930
|
+
return fallbackFileInfo || {
|
|
931
|
+
file: null,
|
|
932
|
+
line: null,
|
|
933
|
+
column: null
|
|
934
|
+
};
|
|
787
935
|
}
|
|
788
936
|
function getPreciseElementAtPoint(x, y, boundary) {
|
|
789
937
|
var _a, _b;
|
|
@@ -800,7 +948,12 @@ function getPreciseElementAtPoint(x, y, boundary) {
|
|
|
800
948
|
if (el.closest("#vue-inspector-container")) continue;
|
|
801
949
|
if (el.closest(".opencode-widget")) continue;
|
|
802
950
|
if (el.hasAttribute("data-v-inspector-ignore")) continue;
|
|
803
|
-
if (boundary
|
|
951
|
+
if (boundary) {
|
|
952
|
+
if (boundary.contains(el) || el === boundary) {
|
|
953
|
+
element = el;
|
|
954
|
+
break;
|
|
955
|
+
}
|
|
956
|
+
} else {
|
|
804
957
|
element = el;
|
|
805
958
|
break;
|
|
806
959
|
}
|
|
@@ -830,13 +983,31 @@ function useInspector(options) {
|
|
|
830
983
|
});
|
|
831
984
|
const INSPECTOR_CHECK_INTERVAL = 500;
|
|
832
985
|
let inspectorCheckTimer = null;
|
|
833
|
-
function
|
|
986
|
+
function handleMouseMoveCore(e) {
|
|
987
|
+
var _a, _b;
|
|
834
988
|
if (!options.selectMode.value) return;
|
|
835
989
|
const inspector = window.__VUE_INSPECTOR__;
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
990
|
+
let elementToHighlight = null;
|
|
991
|
+
let fileInfo = {
|
|
992
|
+
file: null,
|
|
993
|
+
line: null,
|
|
994
|
+
column: null
|
|
995
|
+
};
|
|
996
|
+
if (inspector) {
|
|
997
|
+
const { targetNode, params } = inspector.getTargetNode(e);
|
|
998
|
+
if (targetNode) {
|
|
999
|
+
elementToHighlight = getPreciseElementAtPoint(e.clientX, e.clientY, targetNode) || targetNode;
|
|
1000
|
+
if (params && params.file) fileInfo = {
|
|
1001
|
+
file: params.file,
|
|
1002
|
+
line: (_a = params.line) != null ? _a : null,
|
|
1003
|
+
column: (_b = params.column) != null ? _b : null
|
|
1004
|
+
};
|
|
1005
|
+
else if (elementToHighlight) fileInfo = findFileInfo(elementToHighlight, inspector);
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
if (!elementToHighlight) elementToHighlight = getPreciseElementAtPoint(e.clientX, e.clientY, null);
|
|
1009
|
+
if (elementToHighlight && !fileInfo.file) fileInfo = getFileInfoFromVueInstance(elementToHighlight) || fileInfo;
|
|
1010
|
+
if (elementToHighlight) {
|
|
840
1011
|
const rect = elementToHighlight.getBoundingClientRect();
|
|
841
1012
|
const widget = document.querySelector(".opencode-widget");
|
|
842
1013
|
let primary = "#3b82f6";
|
|
@@ -856,11 +1027,11 @@ function useInspector(options) {
|
|
|
856
1027
|
background: primaryBg
|
|
857
1028
|
};
|
|
858
1029
|
const description = getElementDescription(elementToHighlight);
|
|
859
|
-
const fileName =
|
|
1030
|
+
const fileName = fileInfo.file ? fileInfo.file.split("/").pop() : "";
|
|
860
1031
|
let lineInfo = "";
|
|
861
|
-
if (
|
|
862
|
-
lineInfo = `:${
|
|
863
|
-
if (
|
|
1032
|
+
if (fileInfo.line) {
|
|
1033
|
+
lineInfo = `:${fileInfo.line}`;
|
|
1034
|
+
if (fileInfo.column) lineInfo += `:${fileInfo.column}`;
|
|
864
1035
|
}
|
|
865
1036
|
tooltipContent.value = {
|
|
866
1037
|
description,
|
|
@@ -882,22 +1053,39 @@ function useInspector(options) {
|
|
|
882
1053
|
tooltipVisible.value = false;
|
|
883
1054
|
}
|
|
884
1055
|
}
|
|
1056
|
+
const handleMouseMove = throttle(handleMouseMoveCore, 16);
|
|
885
1057
|
function setupInspectorHook() {
|
|
886
1058
|
const inspector = window.__VUE_INSPECTOR__;
|
|
887
1059
|
if (!inspector || inspector.__opencode_hooked) return;
|
|
888
1060
|
const originalHandleClick = inspector.handleClick.bind(inspector);
|
|
889
1061
|
inspector.handleClick = function(e) {
|
|
890
|
-
var _a, _b
|
|
1062
|
+
var _a, _b;
|
|
891
1063
|
if (options.selectMode.value) {
|
|
1064
|
+
let elementToSelect = null;
|
|
1065
|
+
let fileInfo = {
|
|
1066
|
+
file: null,
|
|
1067
|
+
line: null,
|
|
1068
|
+
column: null
|
|
1069
|
+
};
|
|
892
1070
|
const { targetNode, params } = inspector.getTargetNode(e);
|
|
893
|
-
if (targetNode
|
|
894
|
-
|
|
1071
|
+
if (targetNode) {
|
|
1072
|
+
elementToSelect = getPreciseElementAtPoint(e.clientX, e.clientY, targetNode) || targetNode;
|
|
1073
|
+
if (params && params.file) fileInfo = {
|
|
1074
|
+
file: params.file,
|
|
1075
|
+
line: (_a = params.line) != null ? _a : null,
|
|
1076
|
+
column: (_b = params.column) != null ? _b : null
|
|
1077
|
+
};
|
|
1078
|
+
else if (elementToSelect) fileInfo = findFileInfo(elementToSelect, inspector);
|
|
1079
|
+
}
|
|
1080
|
+
if (!elementToSelect) elementToSelect = getPreciseElementAtPoint(e.clientX, e.clientY, null);
|
|
1081
|
+
if (elementToSelect && !fileInfo.file) fileInfo = getFileInfoFromVueInstance(elementToSelect) || fileInfo;
|
|
1082
|
+
if (elementToSelect) {
|
|
895
1083
|
const innerText = getDirectText(elementToSelect);
|
|
896
1084
|
const description = getElementDescription(elementToSelect);
|
|
897
1085
|
const elementInfo = {
|
|
898
|
-
filePath:
|
|
899
|
-
line:
|
|
900
|
-
column:
|
|
1086
|
+
filePath: fileInfo.file,
|
|
1087
|
+
line: fileInfo.line,
|
|
1088
|
+
column: fileInfo.column,
|
|
901
1089
|
innerText: truncate(innerText, 200),
|
|
902
1090
|
description
|
|
903
1091
|
};
|
|
@@ -1464,7 +1652,7 @@ __vue_sfc__.render = __vue_render__;
|
|
|
1464
1652
|
var open_code_widget_default = __vue_sfc__;
|
|
1465
1653
|
//#endregion
|
|
1466
1654
|
//#region es/index.js
|
|
1467
|
-
var version = "1.0.
|
|
1655
|
+
var version = "1.0.20";
|
|
1468
1656
|
function install(app, options) {
|
|
1469
1657
|
[open_code_widget_default].forEach((item) => {
|
|
1470
1658
|
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.20";
|
|
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.20";
|
|
38
38
|
function install(app, options) {
|
|
39
39
|
const components = [
|
|
40
40
|
import_open_code_widget.default
|