@howone/sdk 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +0 -17
- package/dist/index.d.ts +0 -17
- package/dist/index.js +102 -1237
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +102 -1237
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1578,7 +1578,6 @@ var ViteHMRDetector = class {
|
|
|
1578
1578
|
if (this.isInitialized) return;
|
|
1579
1579
|
this.setupViteErrorDetection();
|
|
1580
1580
|
this.isInitialized = true;
|
|
1581
|
-
console.log("[ViteHMRDetector] Vite HMR \u9519\u8BEF\u68C0\u6D4B\u5668\u521D\u59CB\u5316\u5B8C\u6210");
|
|
1582
1581
|
}
|
|
1583
1582
|
/**
|
|
1584
1583
|
* 销毁检测器
|
|
@@ -1629,10 +1628,8 @@ var ViteHMRDetector = class {
|
|
|
1629
1628
|
setTimeout(() => this.checkForCompileErrors(), 500);
|
|
1630
1629
|
});
|
|
1631
1630
|
hot.on("vite:beforeUpdate", () => {
|
|
1632
|
-
console.log("[ViteHMRDetector] HMR \u66F4\u65B0\u5F00\u59CB");
|
|
1633
1631
|
});
|
|
1634
1632
|
hot.on("vite:afterUpdate", () => {
|
|
1635
|
-
console.log("[ViteHMRDetector] HMR \u66F4\u65B0\u5B8C\u6210");
|
|
1636
1633
|
});
|
|
1637
1634
|
}
|
|
1638
1635
|
window.addEventListener("error", (event) => {
|
|
@@ -1670,7 +1667,6 @@ var ViteHMRDetector = class {
|
|
|
1670
1667
|
payload: errorPayload,
|
|
1671
1668
|
timestamp: Date.now()
|
|
1672
1669
|
});
|
|
1673
|
-
console.log("[ViteHMRDetector] Vite \u9519\u8BEF\u5DF2\u68C0\u6D4B\u5E76\u62A5\u544A:", errorPayload);
|
|
1674
1670
|
} catch (err) {
|
|
1675
1671
|
this.handleFallbackError(errorOverlay, err);
|
|
1676
1672
|
}
|
|
@@ -1943,20 +1939,16 @@ var HardRefreshManager = class {
|
|
|
1943
1939
|
clearedStorage: []
|
|
1944
1940
|
};
|
|
1945
1941
|
try {
|
|
1946
|
-
console.log("[HardRefreshManager] \u5F00\u59CB\u6267\u884C\u786C\u5237\u65B0...");
|
|
1947
1942
|
if (defaultOptions.clearCaches) {
|
|
1948
1943
|
const clearedCaches = await this.clearAllCaches();
|
|
1949
1944
|
result.clearedCaches = clearedCaches;
|
|
1950
|
-
console.log(`[HardRefreshManager] \u5DF2\u6E05\u9664 ${clearedCaches.length} \u4E2A\u7F13\u5B58`);
|
|
1951
1945
|
}
|
|
1952
1946
|
if (defaultOptions.unregisterServiceWorkers) {
|
|
1953
1947
|
const unregisteredCount = await this.unregisterServiceWorkers();
|
|
1954
1948
|
result.unregisteredWorkers = unregisteredCount;
|
|
1955
|
-
console.log(`[HardRefreshManager] \u5DF2\u6CE8\u9500 ${unregisteredCount} \u4E2A Service Worker`);
|
|
1956
1949
|
}
|
|
1957
1950
|
const clearedStorage = await this.clearStorage(defaultOptions);
|
|
1958
1951
|
result.clearedStorage = clearedStorage;
|
|
1959
|
-
console.log(`[HardRefreshManager] \u5DF2\u6E05\u9664\u5B58\u50A8: ${clearedStorage.join(", ")}`);
|
|
1960
1952
|
await this.forceReload(defaultOptions);
|
|
1961
1953
|
result.success = true;
|
|
1962
1954
|
return result;
|
|
@@ -2555,7 +2547,6 @@ var ComponentTreeGenerator = class {
|
|
|
2555
2547
|
maxTextLength: 100,
|
|
2556
2548
|
maxChildren: 50
|
|
2557
2549
|
};
|
|
2558
|
-
console.log("[ComponentTreeGenerator] \u7EC4\u4EF6\u6811\u751F\u6210\u5668\u521D\u59CB\u5316\u5B8C\u6210");
|
|
2559
2550
|
}
|
|
2560
2551
|
/** ----------------- 主要生成方法 ----------------- */
|
|
2561
2552
|
/**
|
|
@@ -2564,7 +2555,6 @@ var ComponentTreeGenerator = class {
|
|
|
2564
2555
|
generateComponentTree(rootElement) {
|
|
2565
2556
|
const startTime = Date.now();
|
|
2566
2557
|
const root = rootElement || document.body;
|
|
2567
|
-
console.log("[ComponentTreeGenerator] \u5F00\u59CB\u751F\u6210\u7EC4\u4EF6\u6811...");
|
|
2568
2558
|
const rootNode = this.generateNodeTree(root, 0);
|
|
2569
2559
|
const stats = this.calculateTreeStats(rootNode);
|
|
2570
2560
|
const componentTree = {
|
|
@@ -2585,7 +2575,6 @@ var ComponentTreeGenerator = class {
|
|
|
2585
2575
|
}
|
|
2586
2576
|
};
|
|
2587
2577
|
const generationTime = Date.now() - startTime;
|
|
2588
|
-
console.log(`[ComponentTreeGenerator] \u7EC4\u4EF6\u6811\u751F\u6210\u5B8C\u6210\uFF0C\u8017\u65F6 ${generationTime}ms\uFF0C\u8282\u70B9\u6570: ${stats.totalNodes}`);
|
|
2589
2578
|
return componentTree;
|
|
2590
2579
|
}
|
|
2591
2580
|
/**
|
|
@@ -2936,7 +2925,6 @@ var ComponentTreeGenerator = class {
|
|
|
2936
2925
|
*/
|
|
2937
2926
|
updateConfig(newConfig) {
|
|
2938
2927
|
this.config = { ...this.config, ...newConfig };
|
|
2939
|
-
console.log("[ComponentTreeGenerator] \u914D\u7F6E\u5DF2\u66F4\u65B0:", this.config);
|
|
2940
2928
|
}
|
|
2941
2929
|
/**
|
|
2942
2930
|
* 获取当前配置
|
|
@@ -2959,7 +2947,6 @@ var ComponentTreeGenerator = class {
|
|
|
2959
2947
|
* 销毁生成器
|
|
2960
2948
|
*/
|
|
2961
2949
|
destroy() {
|
|
2962
|
-
console.log("[ComponentTreeGenerator] \u7EC4\u4EF6\u6811\u751F\u6210\u5668\u5DF2\u9500\u6BC1");
|
|
2963
2950
|
}
|
|
2964
2951
|
};
|
|
2965
2952
|
|
|
@@ -3136,7 +3123,6 @@ var ErrorTracking = class {
|
|
|
3136
3123
|
this.viewDetector = null;
|
|
3137
3124
|
this.interactionTracking = null;
|
|
3138
3125
|
this.sendMessage = sendMessage;
|
|
3139
|
-
this.internalLog("log", "[ErrorTracking] \u9519\u8BEF\u8FFD\u8E2A\u6A21\u5757\u521D\u59CB\u5316\u5B8C\u6210");
|
|
3140
3126
|
}
|
|
3141
3127
|
/**
|
|
3142
3128
|
* 内部日志方法,避免被控制台拦截器捕获
|
|
@@ -3172,10 +3158,8 @@ var ErrorTracking = class {
|
|
|
3172
3158
|
this.setupConsoleInterception();
|
|
3173
3159
|
this.setupNetworkMonitoring();
|
|
3174
3160
|
this.initialized = true;
|
|
3175
|
-
this.internalLog("log", "[ErrorTracking] \u9519\u8BEF\u8FFD\u8E2A\u529F\u80FD\u5DF2\u542F\u7528");
|
|
3176
3161
|
setTimeout(() => {
|
|
3177
3162
|
this.fullyInitialized = true;
|
|
3178
|
-
this.internalLog("log", "[ErrorTracking] \u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u63A7\u5236\u53F0\u62E6\u622A\u5DF2\u9ED8\u8BA4\u542F\u7528");
|
|
3179
3163
|
}, 1e3);
|
|
3180
3164
|
}
|
|
3181
3165
|
/**
|
|
@@ -3200,7 +3184,6 @@ var ErrorTracking = class {
|
|
|
3200
3184
|
source: "unhandledrejection"
|
|
3201
3185
|
});
|
|
3202
3186
|
});
|
|
3203
|
-
this.internalLog("log", "[ErrorTracking] \u5168\u5C40\u9519\u8BEF\u76D1\u542C\u5668\u5DF2\u8BBE\u7F6E");
|
|
3204
3187
|
}
|
|
3205
3188
|
/**
|
|
3206
3189
|
* 设置控制台拦截
|
|
@@ -3224,7 +3207,6 @@ var ErrorTracking = class {
|
|
|
3224
3207
|
}
|
|
3225
3208
|
};
|
|
3226
3209
|
});
|
|
3227
|
-
this.internalLog("log", "[ErrorTracking] \u63A7\u5236\u53F0\u62E6\u622A\u5DF2\u8BBE\u7F6E");
|
|
3228
3210
|
}
|
|
3229
3211
|
/**
|
|
3230
3212
|
* 安全地将控制台输出转发到父窗口
|
|
@@ -3352,7 +3334,6 @@ var ErrorTracking = class {
|
|
|
3352
3334
|
throw error;
|
|
3353
3335
|
}
|
|
3354
3336
|
};
|
|
3355
|
-
this.internalLog("log", "[ErrorTracking] \u7F51\u7EDC\u76D1\u63A7\u5DF2\u8BBE\u7F6E");
|
|
3356
3337
|
}
|
|
3357
3338
|
/**
|
|
3358
3339
|
* 记录网络请求
|
|
@@ -3644,14 +3625,12 @@ var ErrorTracking = class {
|
|
|
3644
3625
|
*/
|
|
3645
3626
|
enableConsoleInterception() {
|
|
3646
3627
|
this.fullyInitialized = true;
|
|
3647
|
-
this.internalLog("log", "[ErrorTracking] \u624B\u52A8\u542F\u7528\u63A7\u5236\u53F0\u62E6\u622A");
|
|
3648
3628
|
}
|
|
3649
3629
|
/**
|
|
3650
3630
|
* 手动禁用控制台拦截
|
|
3651
3631
|
*/
|
|
3652
3632
|
disableConsoleInterception() {
|
|
3653
3633
|
this.fullyInitialized = false;
|
|
3654
|
-
this.internalLog("log", "[ErrorTracking] \u624B\u52A8\u7981\u7528\u63A7\u5236\u53F0\u62E6\u622A");
|
|
3655
3634
|
}
|
|
3656
3635
|
/**
|
|
3657
3636
|
* 销毁错误追踪
|
|
@@ -3663,10 +3642,32 @@ var ErrorTracking = class {
|
|
|
3663
3642
|
}
|
|
3664
3643
|
});
|
|
3665
3644
|
this.initialized = false;
|
|
3666
|
-
this.internalLog("log", "[ErrorTracking] \u9519\u8BEF\u8FFD\u8E2A\u6A21\u5757\u5DF2\u9500\u6BC1");
|
|
3667
3645
|
}
|
|
3668
3646
|
};
|
|
3669
3647
|
|
|
3648
|
+
// src/utils/unified-error-handler/utils/SelectorUtils.ts
|
|
3649
|
+
function getElementClasses(element) {
|
|
3650
|
+
const classAttr = element.getAttribute("class");
|
|
3651
|
+
if (classAttr && classAttr.trim().length > 0) {
|
|
3652
|
+
return dedupeAndClean(classAttr.split(/\s+/));
|
|
3653
|
+
}
|
|
3654
|
+
const anyEl = element;
|
|
3655
|
+
if (typeof anyEl.className === "string") {
|
|
3656
|
+
return dedupeAndClean(anyEl.className.split(/\s+/));
|
|
3657
|
+
}
|
|
3658
|
+
if (anyEl.className && typeof anyEl.className.baseVal === "string") {
|
|
3659
|
+
return dedupeAndClean(anyEl.className.baseVal.split(/\s+/));
|
|
3660
|
+
}
|
|
3661
|
+
if (anyEl.classList && anyEl.classList.length > 0) {
|
|
3662
|
+
return dedupeAndClean(Array.from(anyEl.classList));
|
|
3663
|
+
}
|
|
3664
|
+
return [];
|
|
3665
|
+
}
|
|
3666
|
+
function dedupeAndClean(arr) {
|
|
3667
|
+
const cleaned = arr.map((s) => s.trim()).filter(Boolean);
|
|
3668
|
+
return Array.from(new Set(cleaned));
|
|
3669
|
+
}
|
|
3670
|
+
|
|
3670
3671
|
// src/utils/unified-error-handler/features/InteractionTracking.ts
|
|
3671
3672
|
var InteractionTracking = class {
|
|
3672
3673
|
constructor(sendMessage) {
|
|
@@ -3690,7 +3691,6 @@ var InteractionTracking = class {
|
|
|
3690
3691
|
this.debounceTimers = /* @__PURE__ */ new Map();
|
|
3691
3692
|
this.eventListeners = [];
|
|
3692
3693
|
this.sendMessage = sendMessage;
|
|
3693
|
-
console.log("[InteractionTracking] \u4EA4\u4E92\u8FFD\u8E2A\u6A21\u5757\u521D\u59CB\u5316\u5B8C\u6210");
|
|
3694
3694
|
}
|
|
3695
3695
|
/** ----------------- 主要控制方法 ----------------- */
|
|
3696
3696
|
/**
|
|
@@ -3706,7 +3706,6 @@ var InteractionTracking = class {
|
|
|
3706
3706
|
title: document.title,
|
|
3707
3707
|
timestamp: Date.now()
|
|
3708
3708
|
});
|
|
3709
|
-
console.log("[InteractionTracking] \u4EA4\u4E92\u8FFD\u8E2A\u5DF2\u5F00\u59CB");
|
|
3710
3709
|
}
|
|
3711
3710
|
/**
|
|
3712
3711
|
* 停止追踪
|
|
@@ -3715,7 +3714,6 @@ var InteractionTracking = class {
|
|
|
3715
3714
|
if (!this.isTracking) return;
|
|
3716
3715
|
this.removeEventListeners();
|
|
3717
3716
|
this.isTracking = false;
|
|
3718
|
-
console.log("[InteractionTracking] \u4EA4\u4E92\u8FFD\u8E2A\u5DF2\u505C\u6B62");
|
|
3719
3717
|
}
|
|
3720
3718
|
/** ----------------- 事件监听器设置 ----------------- */
|
|
3721
3719
|
/**
|
|
@@ -4028,979 +4026,121 @@ var InteractionTracking = class {
|
|
|
4028
4026
|
*/
|
|
4029
4027
|
getElementSelector(element) {
|
|
4030
4028
|
if (element.id) return `#${element.id}`;
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
return `.${classes[0]}`;
|
|
4035
|
-
}
|
|
4029
|
+
const classes = getElementClasses(element);
|
|
4030
|
+
if (classes.length > 0) {
|
|
4031
|
+
return `.${classes[0]}`;
|
|
4036
4032
|
}
|
|
4037
4033
|
const dataTestId = element.getAttribute("data-testid");
|
|
4038
4034
|
if (dataTestId) return `[data-testid="${dataTestId}"]`;
|
|
4039
4035
|
const dataId = element.getAttribute("data-id");
|
|
4040
|
-
if (dataId) return `[data-id="${dataId}"]`;
|
|
4041
|
-
return element.tagName.toLowerCase();
|
|
4042
|
-
}
|
|
4043
|
-
/**
|
|
4044
|
-
* 检查是否为敏感输入
|
|
4045
|
-
*/
|
|
4046
|
-
isSensitiveInput(element) {
|
|
4047
|
-
if (!this.trackingConfig.sensitiveInputFilter) return false;
|
|
4048
|
-
const sensitiveTypes = ["password", "email", "tel", "ssn", "credit-card"];
|
|
4049
|
-
const sensitiveNames = ["password", "email", "phone", "ssn", "credit", "card", "cvv", "pin"];
|
|
4050
|
-
return sensitiveTypes.includes(element.type) || sensitiveNames.some(
|
|
4051
|
-
(name) => element.name?.toLowerCase().includes(name) || element.placeholder?.toLowerCase().includes(name) || element.id?.toLowerCase().includes(name)
|
|
4052
|
-
);
|
|
4053
|
-
}
|
|
4054
|
-
/**
|
|
4055
|
-
* 管理数组长度
|
|
4056
|
-
*/
|
|
4057
|
-
manageArrayLength(array, maxLength) {
|
|
4058
|
-
if (array.length > maxLength) {
|
|
4059
|
-
array.shift();
|
|
4060
|
-
}
|
|
4061
|
-
}
|
|
4062
|
-
/** ----------------- 公共接口方法 ----------------- */
|
|
4063
|
-
/**
|
|
4064
|
-
* 获取交互历史
|
|
4065
|
-
*/
|
|
4066
|
-
getInteractionHistory() {
|
|
4067
|
-
return [...this.interactions];
|
|
4068
|
-
}
|
|
4069
|
-
/**
|
|
4070
|
-
* 获取最近的交互记录
|
|
4071
|
-
*/
|
|
4072
|
-
getRecentInteractions(count = 8) {
|
|
4073
|
-
return this.interactions.slice(-count);
|
|
4074
|
-
}
|
|
4075
|
-
/**
|
|
4076
|
-
* 手动发送交互数据到父窗口(用于测试或特殊情况)
|
|
4077
|
-
*/
|
|
4078
|
-
sendInteractionData() {
|
|
4079
|
-
if (this.interactions.length === 0) return;
|
|
4080
|
-
this.sendMessage({
|
|
4081
|
-
type: "INTERACTION_EVENT",
|
|
4082
|
-
payload: {
|
|
4083
|
-
type: "summary",
|
|
4084
|
-
interactions: this.interactions,
|
|
4085
|
-
count: this.interactions.length,
|
|
4086
|
-
timeRange: {
|
|
4087
|
-
start: this.interactions[0]?.timestamp || Date.now(),
|
|
4088
|
-
end: this.interactions[this.interactions.length - 1]?.timestamp || Date.now()
|
|
4089
|
-
},
|
|
4090
|
-
summary: this.generateInteractionSummary()
|
|
4091
|
-
},
|
|
4092
|
-
timestamp: Date.now()
|
|
4093
|
-
});
|
|
4094
|
-
}
|
|
4095
|
-
/**
|
|
4096
|
-
* 生成交互摘要
|
|
4097
|
-
*/
|
|
4098
|
-
generateInteractionSummary() {
|
|
4099
|
-
const summary = {
|
|
4100
|
-
totalInteractions: this.interactions.length,
|
|
4101
|
-
typeCount: {},
|
|
4102
|
-
uniqueElements: /* @__PURE__ */ new Set(),
|
|
4103
|
-
timeSpan: 0
|
|
4104
|
-
};
|
|
4105
|
-
this.interactions.forEach((interaction) => {
|
|
4106
|
-
summary.typeCount[interaction.type] = (summary.typeCount[interaction.type] || 0) + 1;
|
|
4107
|
-
if (interaction.element) {
|
|
4108
|
-
summary.uniqueElements.add(interaction.element);
|
|
4109
|
-
}
|
|
4110
|
-
});
|
|
4111
|
-
if (this.interactions.length > 1) {
|
|
4112
|
-
summary.timeSpan = this.interactions[this.interactions.length - 1].timestamp - this.interactions[0].timestamp;
|
|
4113
|
-
}
|
|
4114
|
-
return {
|
|
4115
|
-
...summary,
|
|
4116
|
-
uniqueElements: Array.from(summary.uniqueElements),
|
|
4117
|
-
mostCommonType: Object.entries(summary.typeCount).sort(([, a], [, b]) => b - a)[0]?.[0] || "unknown"
|
|
4118
|
-
};
|
|
4119
|
-
}
|
|
4120
|
-
/**
|
|
4121
|
-
* 清除交互历史
|
|
4122
|
-
*/
|
|
4123
|
-
clearInteractionHistory() {
|
|
4124
|
-
this.interactions = [];
|
|
4125
|
-
}
|
|
4126
|
-
/**
|
|
4127
|
-
* 更新追踪配置
|
|
4128
|
-
*/
|
|
4129
|
-
updateConfig(newConfig) {
|
|
4130
|
-
this.trackingConfig = { ...this.trackingConfig, ...newConfig };
|
|
4131
|
-
if (this.isTracking) {
|
|
4132
|
-
this.removeEventListeners();
|
|
4133
|
-
this.setupEventListeners();
|
|
4134
|
-
}
|
|
4135
|
-
}
|
|
4136
|
-
/**
|
|
4137
|
-
* 获取追踪状态
|
|
4138
|
-
*/
|
|
4139
|
-
isTrackingActive() {
|
|
4140
|
-
return this.isTracking;
|
|
4141
|
-
}
|
|
4142
|
-
/**
|
|
4143
|
-
* 销毁交互追踪
|
|
4144
|
-
*/
|
|
4145
|
-
destroy() {
|
|
4146
|
-
this.stopTracking();
|
|
4147
|
-
this.interactions = [];
|
|
4148
|
-
console.log("[InteractionTracking] \u4EA4\u4E92\u8FFD\u8E2A\u6A21\u5757\u5DF2\u9500\u6BC1");
|
|
4149
|
-
}
|
|
4150
|
-
};
|
|
4151
|
-
|
|
4152
|
-
// src/utils/unified-error-handler/features/ElementSelector.ts
|
|
4153
|
-
var ElementSelector2 = class {
|
|
4154
|
-
constructor(sendMessage) {
|
|
4155
|
-
this.config = { ...DEFAULT_SELECTOR_CONFIG };
|
|
4156
|
-
this.isActive = false;
|
|
4157
|
-
this.highlightedElement = null;
|
|
4158
|
-
this.selectedElements = [];
|
|
4159
|
-
this.rootElement = null;
|
|
4160
|
-
this.tooltip = null;
|
|
4161
|
-
this.styleElement = null;
|
|
4162
|
-
this.eventListeners = [];
|
|
4163
|
-
this.lastClickTimestamp = 0;
|
|
4164
|
-
this.lastClickTarget = null;
|
|
4165
|
-
this.mousePosition = { x: 0, y: 0 };
|
|
4166
|
-
this.sendMessage = sendMessage;
|
|
4167
|
-
this.initializeSelector();
|
|
4168
|
-
}
|
|
4169
|
-
/** ----------------- 初始化方法 ----------------- */
|
|
4170
|
-
/**
|
|
4171
|
-
* 初始化选择器
|
|
4172
|
-
*/
|
|
4173
|
-
initializeSelector() {
|
|
4174
|
-
this.waitForRootElement();
|
|
4175
|
-
this.createTooltip();
|
|
4176
|
-
this.createStyles();
|
|
4177
|
-
}
|
|
4178
|
-
/**
|
|
4179
|
-
* 等待根元素加载
|
|
4180
|
-
*/
|
|
4181
|
-
async waitForRootElement() {
|
|
4182
|
-
const maxAttempts = 50;
|
|
4183
|
-
let attempts = 0;
|
|
4184
|
-
while (attempts < maxAttempts) {
|
|
4185
|
-
this.rootElement = document.querySelector("#root") || document.body;
|
|
4186
|
-
if (this.rootElement) {
|
|
4187
|
-
break;
|
|
4188
|
-
}
|
|
4189
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
4190
|
-
attempts++;
|
|
4191
|
-
}
|
|
4192
|
-
if (!this.rootElement) {
|
|
4193
|
-
this.rootElement = document.body;
|
|
4194
|
-
}
|
|
4195
|
-
}
|
|
4196
|
-
/**
|
|
4197
|
-
* 创建工具提示
|
|
4198
|
-
*/
|
|
4199
|
-
createTooltip() {
|
|
4200
|
-
this.tooltip = document.createElement("div");
|
|
4201
|
-
this.tooltip.className = "element-selector-tooltip";
|
|
4202
|
-
this.tooltip.setAttribute("role", "tooltip");
|
|
4203
|
-
this.tooltip.style.display = "none";
|
|
4204
|
-
document.body.appendChild(this.tooltip);
|
|
4205
|
-
}
|
|
4206
|
-
/**
|
|
4207
|
-
* 创建样式
|
|
4208
|
-
*/
|
|
4209
|
-
createStyles() {
|
|
4210
|
-
this.styleElement = document.createElement("style");
|
|
4211
|
-
this.styleElement.id = "element-selector-styles";
|
|
4212
|
-
this.styleElement.textContent = this.generateCSS();
|
|
4213
|
-
document.head.appendChild(this.styleElement);
|
|
4214
|
-
}
|
|
4215
|
-
/**
|
|
4216
|
-
* 生成 CSS 样式
|
|
4217
|
-
*/
|
|
4218
|
-
generateCSS() {
|
|
4219
|
-
return `
|
|
4220
|
-
.element-selector-tooltip {
|
|
4221
|
-
position: fixed;
|
|
4222
|
-
z-index: ${this.config.TOOLTIP_Z_INDEX};
|
|
4223
|
-
pointer-events: none;
|
|
4224
|
-
background-color: ${this.config.TOOLTIP_BACKGROUND};
|
|
4225
|
-
color: ${this.config.TOOLTIP_COLOR};
|
|
4226
|
-
padding: ${this.config.TOOLTIP_PADDING};
|
|
4227
|
-
border-radius: ${this.config.TOOLTIP_BORDER_RADIUS};
|
|
4228
|
-
font-size: ${this.config.TOOLTIP_FONT_SIZE};
|
|
4229
|
-
font-weight: bold;
|
|
4230
|
-
line-height: 1;
|
|
4231
|
-
white-space: nowrap;
|
|
4232
|
-
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
|
4233
|
-
transition: opacity 0.2s ease-in-out;
|
|
4234
|
-
margin: 0;
|
|
4235
|
-
}
|
|
4236
|
-
|
|
4237
|
-
[data-element-hovered] {
|
|
4238
|
-
position: relative;
|
|
4239
|
-
outline: ${this.config.HIGHLIGHT_BORDER_WIDTH} ${this.config.HIGHLIGHT_BORDER_STYLE} ${this.config.HIGHLIGHT_COLOR} !important;
|
|
4240
|
-
outline-offset: 0 !important;
|
|
4241
|
-
background-color: ${this.config.HIGHLIGHT_COLOR}20 !important;
|
|
4242
|
-
z-index: 9999;
|
|
4243
|
-
}
|
|
4244
|
-
|
|
4245
|
-
[data-element-selected] {
|
|
4246
|
-
position: relative;
|
|
4247
|
-
outline: ${this.config.SELECTED_BORDER_WIDTH} ${this.config.HIGHLIGHT_BORDER_STYLE} ${this.config.SELECTED_COLOR} !important;
|
|
4248
|
-
outline-offset: 3px !important;
|
|
4249
|
-
background-color: ${this.config.SELECTED_COLOR}15 !important;
|
|
4250
|
-
z-index: 9999;
|
|
4251
|
-
}
|
|
4252
|
-
|
|
4253
|
-
[data-element-selected][contenteditable] {
|
|
4254
|
-
outline: none !important;
|
|
4255
|
-
}
|
|
4256
|
-
|
|
4257
|
-
[data-element-hovered][data-full-width],
|
|
4258
|
-
[data-element-selected][data-full-width] {
|
|
4259
|
-
outline-offset: -5px !important;
|
|
4260
|
-
}
|
|
4261
|
-
|
|
4262
|
-
.element-selector-active {
|
|
4263
|
-
cursor: ${this.config.cursor} !important;
|
|
4264
|
-
}
|
|
4265
|
-
|
|
4266
|
-
.element-selector-active * {
|
|
4267
|
-
cursor: ${this.config.cursor} !important;
|
|
4268
|
-
}
|
|
4269
|
-
|
|
4270
|
-
/* \u963B\u6B62\u539F\u751F hover \u6548\u679C\u7684\u5168\u5C40\u6837\u5F0F */
|
|
4271
|
-
body.element-selector-active * {
|
|
4272
|
-
/* \u963B\u6B62\u539F\u751F CSS hover \u4F2A\u7C7B\u6548\u679C */
|
|
4273
|
-
transition: none !important;
|
|
4274
|
-
}
|
|
4275
|
-
|
|
4276
|
-
/* \u963B\u6B62\u6240\u6709 hover \u76F8\u5173\u7684 CSS \u4F2A\u7C7B\uFF0C\u4F46\u6392\u9664\u6211\u4EEC\u7684\u9009\u62E9\u5668\u5143\u7D20 */
|
|
4277
|
-
body.element-selector-active *:hover:not([data-element-selected]):not([data-element-hovered]) {
|
|
4278
|
-
background-color: inherit !important;
|
|
4279
|
-
color: inherit !important;
|
|
4280
|
-
border-color: inherit !important;
|
|
4281
|
-
box-shadow: inherit !important;
|
|
4282
|
-
transform: inherit !important;
|
|
4283
|
-
opacity: inherit !important;
|
|
4284
|
-
filter: inherit !important;
|
|
4285
|
-
}
|
|
4286
|
-
|
|
4287
|
-
/* \u786E\u4FDD\u6211\u4EEC\u7684\u9009\u62E9\u5668\u6837\u5F0F\u4F18\u5148\u7EA7\u6700\u9AD8 */
|
|
4288
|
-
body.element-selector-active [data-element-selected] {
|
|
4289
|
-
background-color: ${this.config.SELECTED_COLOR}15 !important;
|
|
4290
|
-
outline: ${this.config.SELECTED_BORDER_WIDTH} ${this.config.HIGHLIGHT_BORDER_STYLE} ${this.config.SELECTED_COLOR} !important;
|
|
4291
|
-
}
|
|
4292
|
-
|
|
4293
|
-
body.element-selector-active [data-element-hovered] {
|
|
4294
|
-
background-color: ${this.config.HIGHLIGHT_COLOR}20 !important;
|
|
4295
|
-
outline: ${this.config.HIGHLIGHT_BORDER_WIDTH} ${this.config.HIGHLIGHT_BORDER_STYLE} ${this.config.HIGHLIGHT_COLOR} !important;
|
|
4296
|
-
}
|
|
4297
|
-
|
|
4298
|
-
/* \u786E\u4FDD\u5DE5\u5177\u63D0\u793A\u4E0D\u53D7\u5F71\u54CD */
|
|
4299
|
-
body.element-selector-active .element-selector-tooltip {
|
|
4300
|
-
pointer-events: none !important;
|
|
4301
|
-
}
|
|
4302
|
-
`;
|
|
4303
|
-
}
|
|
4304
|
-
/** ----------------- 选择器状态管理 ----------------- */
|
|
4305
|
-
/**
|
|
4306
|
-
* 启用选择器
|
|
4307
|
-
*/
|
|
4308
|
-
enableSelector() {
|
|
4309
|
-
if (this.isActive) return;
|
|
4310
|
-
this.isActive = true;
|
|
4311
|
-
document.body.classList.add("element-selector-active");
|
|
4312
|
-
this.setupEventListeners();
|
|
4313
|
-
this.manageButtonStates(true);
|
|
4314
|
-
this.sendMessage({
|
|
4315
|
-
type: "SELECTOR_ENABLED",
|
|
4316
|
-
payload: { isActive: true }
|
|
4317
|
-
});
|
|
4318
|
-
}
|
|
4319
|
-
/**
|
|
4320
|
-
* 禁用选择器
|
|
4321
|
-
*/
|
|
4322
|
-
disableSelector() {
|
|
4323
|
-
if (!this.isActive) return;
|
|
4324
|
-
this.isActive = false;
|
|
4325
|
-
document.body.classList.remove("element-selector-active");
|
|
4326
|
-
this.removeEventListeners();
|
|
4327
|
-
this.clearHighlight();
|
|
4328
|
-
this.clearSelection();
|
|
4329
|
-
this.manageButtonStates(false);
|
|
4330
|
-
this.hideTooltip();
|
|
4331
|
-
this.sendMessage({
|
|
4332
|
-
type: "SELECTOR_DISABLED",
|
|
4333
|
-
payload: { isActive: false }
|
|
4334
|
-
});
|
|
4335
|
-
}
|
|
4336
|
-
/**
|
|
4337
|
-
* 切换选择器状态
|
|
4338
|
-
*/
|
|
4339
|
-
toggleSelector() {
|
|
4340
|
-
if (this.isActive) {
|
|
4341
|
-
this.disableSelector();
|
|
4342
|
-
} else {
|
|
4343
|
-
this.enableSelector();
|
|
4344
|
-
}
|
|
4345
|
-
}
|
|
4346
|
-
/**
|
|
4347
|
-
* 获取选择器状态
|
|
4348
|
-
*/
|
|
4349
|
-
getSelectorState() {
|
|
4350
|
-
return {
|
|
4351
|
-
isActive: this.isActive,
|
|
4352
|
-
highlightedElement: this.highlightedElement ? this.getElementInfo(this.highlightedElement) : null,
|
|
4353
|
-
selectedElements: this.selectedElements.map((el) => this.getElementInfo(el)),
|
|
4354
|
-
config: { ...this.config }
|
|
4355
|
-
};
|
|
4356
|
-
}
|
|
4357
|
-
/** ----------------- 事件监听器管理 ----------------- */
|
|
4358
|
-
/**
|
|
4359
|
-
* 设置事件监听器
|
|
4360
|
-
*/
|
|
4361
|
-
setupEventListeners() {
|
|
4362
|
-
this.addEventListenerWithCleanup(document, "mouseover", this.handleMouseOver.bind(this), { passive: true });
|
|
4363
|
-
this.addEventListenerWithCleanup(document, "mouseout", this.handleMouseOut.bind(this), { passive: true });
|
|
4364
|
-
this.addEventListenerWithCleanup(document, "mousemove", this.trackMousePosition.bind(this), { passive: true });
|
|
4365
|
-
this.addEventListenerWithCleanup(document, "click", this.handleClick.bind(this), { capture: true });
|
|
4366
|
-
this.addEventListenerWithCleanup(document, "dblclick", this.handleDoubleClick.bind(this), { capture: true });
|
|
4367
|
-
this.addEventListenerWithCleanup(window, "scroll", this.handleScroll.bind(this), { passive: true });
|
|
4368
|
-
this.addEventListenerWithCleanup(document, "keydown", this.handleKeyDown.bind(this));
|
|
4369
|
-
this.addEventListenerWithCleanup(document, "mousedown", this.preventFormInteraction.bind(this), { capture: true });
|
|
4370
|
-
this.addEventListenerWithCleanup(document, "submit", this.preventAllInteraction.bind(this), { capture: true });
|
|
4371
|
-
this.addEventListenerWithCleanup(document, "touchstart", this.preventAllInteraction.bind(this), { capture: true });
|
|
4372
|
-
this.addEventListenerWithCleanup(document, "touchend", this.preventAllInteraction.bind(this), { capture: true });
|
|
4373
|
-
}
|
|
4374
|
-
/**
|
|
4375
|
-
* 添加事件监听器并记录以便清理
|
|
4376
|
-
*/
|
|
4377
|
-
addEventListenerWithCleanup(element, event, handler, options) {
|
|
4378
|
-
element.addEventListener(event, handler, options);
|
|
4379
|
-
this.eventListeners.push({ element, event, handler, options });
|
|
4380
|
-
}
|
|
4381
|
-
/**
|
|
4382
|
-
* 移除所有事件监听器
|
|
4383
|
-
*/
|
|
4384
|
-
removeEventListeners() {
|
|
4385
|
-
this.eventListeners.forEach(({ element, event, handler }) => {
|
|
4386
|
-
element.removeEventListener(event, handler);
|
|
4387
|
-
});
|
|
4388
|
-
this.eventListeners = [];
|
|
4389
|
-
}
|
|
4390
|
-
/** ----------------- 事件处理方法 ----------------- */
|
|
4391
|
-
/**
|
|
4392
|
-
* 跟踪鼠标位置
|
|
4393
|
-
*/
|
|
4394
|
-
trackMousePosition(event) {
|
|
4395
|
-
this.mousePosition = { x: event.clientX, y: event.clientY };
|
|
4396
|
-
}
|
|
4397
|
-
/**
|
|
4398
|
-
* 处理鼠标悬停
|
|
4399
|
-
*/
|
|
4400
|
-
handleMouseOver(event) {
|
|
4401
|
-
if (!this.isActive) return;
|
|
4402
|
-
const target = event.target;
|
|
4403
|
-
if (!this.isSelectableElement(target)) return;
|
|
4404
|
-
this.highlightElement(target);
|
|
4405
|
-
this.updateTooltip(target);
|
|
4406
|
-
}
|
|
4407
|
-
/**
|
|
4408
|
-
* 处理鼠标离开
|
|
4409
|
-
*/
|
|
4410
|
-
handleMouseOut(event) {
|
|
4411
|
-
if (!this.isActive) return;
|
|
4412
|
-
this.clearHighlight();
|
|
4413
|
-
this.hideTooltip();
|
|
4414
|
-
}
|
|
4415
|
-
/**
|
|
4416
|
-
* 处理点击
|
|
4417
|
-
*/
|
|
4418
|
-
handleClick(event) {
|
|
4419
|
-
if (!this.isActive) return;
|
|
4420
|
-
const currentTimestamp = Date.now();
|
|
4421
|
-
const target = event.target;
|
|
4422
|
-
if (this.lastClickTarget === target && currentTimestamp - this.lastClickTimestamp < 100) {
|
|
4423
|
-
event.preventDefault();
|
|
4424
|
-
event.stopPropagation();
|
|
4425
|
-
return;
|
|
4426
|
-
}
|
|
4427
|
-
this.lastClickTimestamp = currentTimestamp;
|
|
4428
|
-
this.lastClickTarget = target;
|
|
4429
|
-
event.preventDefault();
|
|
4430
|
-
event.stopPropagation();
|
|
4431
|
-
if (!this.isSelectableElement(target)) return;
|
|
4432
|
-
if (event.metaKey || event.ctrlKey) {
|
|
4433
|
-
this.toggleElementSelection(target);
|
|
4434
|
-
} else {
|
|
4435
|
-
this.selectElement(target);
|
|
4436
|
-
}
|
|
4437
|
-
this.sendMessage({
|
|
4438
|
-
type: "ELEMENT_CLICKED",
|
|
4439
|
-
payload: {
|
|
4440
|
-
element: this.getElementInfo(target),
|
|
4441
|
-
isMultiSelect: event.metaKey || event.ctrlKey
|
|
4442
|
-
}
|
|
4443
|
-
});
|
|
4444
|
-
}
|
|
4445
|
-
/**
|
|
4446
|
-
* 处理双击
|
|
4447
|
-
*/
|
|
4448
|
-
handleDoubleClick(event) {
|
|
4449
|
-
if (!this.isActive) return;
|
|
4450
|
-
event.preventDefault();
|
|
4451
|
-
event.stopPropagation();
|
|
4452
|
-
const target = event.target;
|
|
4453
|
-
if (!this.isSelectableElement(target)) return;
|
|
4454
|
-
this.sendMessage({
|
|
4455
|
-
type: "ELEMENT_DOUBLE_CLICKED",
|
|
4456
|
-
payload: {
|
|
4457
|
-
element: this.getElementInfo(target)
|
|
4458
|
-
}
|
|
4459
|
-
});
|
|
4460
|
-
}
|
|
4461
|
-
/**
|
|
4462
|
-
* 处理滚动
|
|
4463
|
-
*/
|
|
4464
|
-
handleScroll() {
|
|
4465
|
-
if (!this.isActive) return;
|
|
4466
|
-
this.hideTooltip();
|
|
4467
|
-
}
|
|
4468
|
-
/**
|
|
4469
|
-
* 处理键盘事件
|
|
4470
|
-
*/
|
|
4471
|
-
handleKeyDown(event) {
|
|
4472
|
-
if (!this.isActive) return;
|
|
4473
|
-
const keyboardEvent = event;
|
|
4474
|
-
if (keyboardEvent.key === "Escape") {
|
|
4475
|
-
event.preventDefault();
|
|
4476
|
-
event.stopPropagation();
|
|
4477
|
-
this.disableSelector();
|
|
4478
|
-
}
|
|
4479
|
-
}
|
|
4480
|
-
/**
|
|
4481
|
-
* 阻止表单交互
|
|
4482
|
-
*/
|
|
4483
|
-
preventFormInteraction(event) {
|
|
4484
|
-
if (!this.isActive) return;
|
|
4485
|
-
const target = event.target;
|
|
4486
|
-
if (["input", "textarea", "select"].includes(target.tagName.toLowerCase())) {
|
|
4487
|
-
event.preventDefault();
|
|
4488
|
-
}
|
|
4489
|
-
}
|
|
4490
|
-
/**
|
|
4491
|
-
* 阻止所有交互
|
|
4492
|
-
*/
|
|
4493
|
-
preventAllInteraction(event) {
|
|
4494
|
-
if (this.isActive) {
|
|
4495
|
-
event.preventDefault();
|
|
4496
|
-
event.stopPropagation();
|
|
4497
|
-
return false;
|
|
4498
|
-
}
|
|
4499
|
-
}
|
|
4500
|
-
/** ----------------- 元素操作方法 ----------------- */
|
|
4501
|
-
/**
|
|
4502
|
-
* 高亮元素
|
|
4503
|
-
*/
|
|
4504
|
-
highlightElement(element) {
|
|
4505
|
-
this.clearHighlight();
|
|
4506
|
-
this.highlightedElement = element;
|
|
4507
|
-
element.setAttribute("data-element-hovered", "true");
|
|
4508
|
-
if (this.isFullWidthElement(element)) {
|
|
4509
|
-
element.setAttribute("data-full-width", "true");
|
|
4510
|
-
}
|
|
4511
|
-
}
|
|
4512
|
-
/**
|
|
4513
|
-
* 清除高亮
|
|
4514
|
-
*/
|
|
4515
|
-
clearHighlight() {
|
|
4516
|
-
if (this.highlightedElement) {
|
|
4517
|
-
this.highlightedElement.removeAttribute("data-element-hovered");
|
|
4518
|
-
this.highlightedElement.removeAttribute("data-full-width");
|
|
4519
|
-
this.highlightedElement = null;
|
|
4520
|
-
}
|
|
4521
|
-
}
|
|
4522
|
-
/**
|
|
4523
|
-
* 选择元素
|
|
4524
|
-
*/
|
|
4525
|
-
selectElement(element) {
|
|
4526
|
-
this.clearSelection();
|
|
4527
|
-
this.selectedElements = [element];
|
|
4528
|
-
element.setAttribute("data-element-selected", "true");
|
|
4529
|
-
if (this.isFullWidthElement(element)) {
|
|
4530
|
-
element.setAttribute("data-full-width", "true");
|
|
4531
|
-
}
|
|
4532
|
-
}
|
|
4533
|
-
/**
|
|
4534
|
-
* 切换元素选择状态
|
|
4535
|
-
*/
|
|
4536
|
-
toggleElementSelection(element) {
|
|
4537
|
-
const index = this.selectedElements.indexOf(element);
|
|
4538
|
-
if (index > -1) {
|
|
4539
|
-
this.selectedElements.splice(index, 1);
|
|
4540
|
-
element.removeAttribute("data-element-selected");
|
|
4541
|
-
element.removeAttribute("data-full-width");
|
|
4542
|
-
} else {
|
|
4543
|
-
this.selectedElements.push(element);
|
|
4544
|
-
element.setAttribute("data-element-selected", "true");
|
|
4545
|
-
if (this.isFullWidthElement(element)) {
|
|
4546
|
-
element.setAttribute("data-full-width", "true");
|
|
4547
|
-
}
|
|
4548
|
-
}
|
|
4549
|
-
}
|
|
4550
|
-
/**
|
|
4551
|
-
* 清除选择
|
|
4552
|
-
*/
|
|
4553
|
-
clearSelection() {
|
|
4554
|
-
this.selectedElements.forEach((element) => {
|
|
4555
|
-
element.removeAttribute("data-element-selected");
|
|
4556
|
-
element.removeAttribute("data-full-width");
|
|
4557
|
-
});
|
|
4558
|
-
this.selectedElements = [];
|
|
4559
|
-
}
|
|
4560
|
-
/** ----------------- 工具提示管理 ----------------- */
|
|
4561
|
-
/**
|
|
4562
|
-
* 更新工具提示
|
|
4563
|
-
*/
|
|
4564
|
-
updateTooltip(element) {
|
|
4565
|
-
if (!this.tooltip) return;
|
|
4566
|
-
const rect = element.getBoundingClientRect();
|
|
4567
|
-
const tagName = element.tagName.toLowerCase();
|
|
4568
|
-
this.tooltip.textContent = tagName;
|
|
4569
|
-
this.tooltip.style.display = "block";
|
|
4570
|
-
const isFullWidth = this.isFullWidthElement(element);
|
|
4571
|
-
if (isFullWidth) {
|
|
4572
|
-
this.tooltip.style.left = this.config.FULL_WIDTH_TOOLTIP_OFFSET + "px";
|
|
4573
|
-
this.tooltip.style.top = this.config.FULL_WIDTH_TOOLTIP_OFFSET + "px";
|
|
4574
|
-
} else {
|
|
4575
|
-
const top = Math.max(0, rect.top - 30);
|
|
4576
|
-
this.tooltip.style.left = `${Math.max(0, rect.left)}px`;
|
|
4577
|
-
this.tooltip.style.top = `${top}px`;
|
|
4578
|
-
}
|
|
4579
|
-
}
|
|
4580
|
-
/**
|
|
4581
|
-
* 隐藏工具提示
|
|
4582
|
-
*/
|
|
4583
|
-
hideTooltip() {
|
|
4584
|
-
if (this.tooltip) {
|
|
4585
|
-
this.tooltip.style.display = "none";
|
|
4586
|
-
}
|
|
4587
|
-
}
|
|
4588
|
-
/** ----------------- 按钮状态管理 ----------------- */
|
|
4589
|
-
/**
|
|
4590
|
-
* 管理按钮状态
|
|
4591
|
-
*/
|
|
4592
|
-
manageButtonStates(enable) {
|
|
4593
|
-
if (!this.rootElement) return;
|
|
4594
|
-
const buttons = this.rootElement.querySelectorAll('button, input[type="button"], input[type="submit"]');
|
|
4595
|
-
if (enable) {
|
|
4596
|
-
buttons.forEach((button) => {
|
|
4597
|
-
const btn = button;
|
|
4598
|
-
if (!btn.disabled) {
|
|
4599
|
-
btn.disabled = true;
|
|
4600
|
-
btn.setAttribute("data-selector-disabled", "true");
|
|
4601
|
-
}
|
|
4602
|
-
});
|
|
4603
|
-
} else {
|
|
4604
|
-
buttons.forEach((button) => {
|
|
4605
|
-
const btn = button;
|
|
4606
|
-
if (btn.hasAttribute("data-selector-disabled")) {
|
|
4607
|
-
btn.disabled = false;
|
|
4608
|
-
btn.removeAttribute("data-selector-disabled");
|
|
4609
|
-
}
|
|
4610
|
-
});
|
|
4611
|
-
}
|
|
4612
|
-
}
|
|
4613
|
-
/** ----------------- 新增的精确代码位置定位方法 ----------------- */
|
|
4614
|
-
/**
|
|
4615
|
-
* 检查元素是否有 howone ID
|
|
4616
|
-
*/
|
|
4617
|
-
hasHowoneId(element) {
|
|
4618
|
-
return element.hasAttribute("data-howone-id");
|
|
4619
|
-
}
|
|
4620
|
-
/**
|
|
4621
|
-
* 解析 howone ID
|
|
4622
|
-
*/
|
|
4623
|
-
parseHowoneId(element) {
|
|
4624
|
-
const howoneId = element.getAttribute("data-howone-id");
|
|
4625
|
-
if (!howoneId) return null;
|
|
4626
|
-
try {
|
|
4627
|
-
if (howoneId.includes(":")) {
|
|
4628
|
-
const parts = howoneId.split(":");
|
|
4629
|
-
if (parts.length >= 2) {
|
|
4630
|
-
return {
|
|
4631
|
-
filePath: parts[0],
|
|
4632
|
-
lineNumber: parseInt(parts[1], 10),
|
|
4633
|
-
col: parts[2] ? parseInt(parts[2], 10) : 0
|
|
4634
|
-
};
|
|
4635
|
-
}
|
|
4636
|
-
} else {
|
|
4637
|
-
const parsed = JSON.parse(howoneId);
|
|
4638
|
-
if (parsed.filePath && parsed.lineNumber) {
|
|
4639
|
-
return {
|
|
4640
|
-
filePath: parsed.filePath,
|
|
4641
|
-
lineNumber: parsed.lineNumber,
|
|
4642
|
-
col: parsed.col || 0
|
|
4643
|
-
};
|
|
4644
|
-
}
|
|
4645
|
-
}
|
|
4646
|
-
} catch (error) {
|
|
4647
|
-
console.warn("[ElementSelector] \u89E3\u6790 data-howone-id \u5931\u8D25:", error);
|
|
4648
|
-
}
|
|
4649
|
-
return null;
|
|
4650
|
-
}
|
|
4651
|
-
/**
|
|
4652
|
-
* 获取元素的代码位置
|
|
4653
|
-
*/
|
|
4654
|
-
getElementLocation(element) {
|
|
4655
|
-
return this.parseHowoneId(element);
|
|
4656
|
-
}
|
|
4657
|
-
/**
|
|
4658
|
-
* 提取元素数据(包含位置信息)
|
|
4659
|
-
*/
|
|
4660
|
-
extractElementData(element) {
|
|
4661
|
-
const location = this.getElementLocation(element);
|
|
4662
|
-
return {
|
|
4663
|
-
id: element.id || void 0,
|
|
4664
|
-
className: element.className || void 0,
|
|
4665
|
-
textContent: element.textContent?.trim().substring(0, 100) || void 0,
|
|
4666
|
-
filePath: location?.filePath,
|
|
4667
|
-
lineNumber: location?.lineNumber,
|
|
4668
|
-
col: location?.col,
|
|
4669
|
-
elementType: element.tagName.toLowerCase(),
|
|
4670
|
-
attrs: this.getElementAttributes(element)
|
|
4671
|
-
};
|
|
4672
|
-
}
|
|
4673
|
-
/**
|
|
4674
|
-
* 根据代码位置查找元素
|
|
4675
|
-
*/
|
|
4676
|
-
findElementsByLocation(filePath, lineNumber) {
|
|
4677
|
-
const elements = [];
|
|
4678
|
-
const elementsWithHowoneId = this.rootElement?.querySelectorAll("[data-howone-id]") || [];
|
|
4679
|
-
elementsWithHowoneId.forEach((element) => {
|
|
4680
|
-
const location = this.getElementLocation(element);
|
|
4681
|
-
if (location && location.filePath === filePath && location.lineNumber === lineNumber) {
|
|
4682
|
-
elements.push(element);
|
|
4683
|
-
}
|
|
4684
|
-
});
|
|
4685
|
-
return elements;
|
|
4686
|
-
}
|
|
4687
|
-
/**
|
|
4688
|
-
* 获取指定坐标位置的元素
|
|
4689
|
-
*/
|
|
4690
|
-
getElementAtPoint(x, y) {
|
|
4691
|
-
const originalDisplay = this.tooltip?.style.display;
|
|
4692
|
-
if (this.tooltip) {
|
|
4693
|
-
this.tooltip.style.display = "none";
|
|
4694
|
-
}
|
|
4695
|
-
const element = document.elementFromPoint(x, y);
|
|
4696
|
-
if (this.tooltip && originalDisplay) {
|
|
4697
|
-
this.tooltip.style.display = originalDisplay;
|
|
4698
|
-
}
|
|
4699
|
-
return element;
|
|
4700
|
-
}
|
|
4701
|
-
/** ----------------- 元素编辑功能 ----------------- */
|
|
4702
|
-
/**
|
|
4703
|
-
* 设置元素内容
|
|
4704
|
-
*/
|
|
4705
|
-
setElementContent(selector, content) {
|
|
4706
|
-
try {
|
|
4707
|
-
const element = document.querySelector(selector);
|
|
4708
|
-
if (!element) return false;
|
|
4709
|
-
if (element.tagName.toLowerCase() === "input" || element.tagName.toLowerCase() === "textarea") {
|
|
4710
|
-
element.value = content;
|
|
4711
|
-
} else {
|
|
4712
|
-
element.textContent = content;
|
|
4713
|
-
}
|
|
4714
|
-
this.sendMessage({
|
|
4715
|
-
type: "ELEMENT_CONTENT_UPDATED",
|
|
4716
|
-
payload: {
|
|
4717
|
-
selector,
|
|
4718
|
-
content,
|
|
4719
|
-
element: this.getElementInfo(element)
|
|
4720
|
-
}
|
|
4721
|
-
});
|
|
4722
|
-
return true;
|
|
4723
|
-
} catch (error) {
|
|
4724
|
-
console.error("[ElementSelector] \u8BBE\u7F6E\u5143\u7D20\u5185\u5BB9\u5931\u8D25:", error);
|
|
4725
|
-
return false;
|
|
4726
|
-
}
|
|
4727
|
-
}
|
|
4728
|
-
/**
|
|
4729
|
-
* 设置元素属性
|
|
4730
|
-
*/
|
|
4731
|
-
setElementAttributes(selector, attributes) {
|
|
4732
|
-
try {
|
|
4733
|
-
const element = document.querySelector(selector);
|
|
4734
|
-
if (!element) return false;
|
|
4735
|
-
Object.entries(attributes).forEach(([key, value]) => {
|
|
4736
|
-
if (value === null || value === void 0) {
|
|
4737
|
-
element.removeAttribute(key);
|
|
4738
|
-
} else {
|
|
4739
|
-
element.setAttribute(key, value);
|
|
4740
|
-
}
|
|
4741
|
-
});
|
|
4742
|
-
this.sendMessage({
|
|
4743
|
-
type: "ELEMENT_ATTRIBUTES_UPDATED",
|
|
4744
|
-
payload: {
|
|
4745
|
-
selector,
|
|
4746
|
-
attributes,
|
|
4747
|
-
element: this.getElementInfo(element)
|
|
4748
|
-
}
|
|
4749
|
-
});
|
|
4750
|
-
return true;
|
|
4751
|
-
} catch (error) {
|
|
4752
|
-
console.error("[ElementSelector] \u8BBE\u7F6E\u5143\u7D20\u5C5E\u6027\u5931\u8D25:", error);
|
|
4753
|
-
return false;
|
|
4754
|
-
}
|
|
4755
|
-
}
|
|
4756
|
-
/**
|
|
4757
|
-
* 复制元素
|
|
4758
|
-
*/
|
|
4759
|
-
duplicateElement(selector) {
|
|
4760
|
-
try {
|
|
4761
|
-
const element = document.querySelector(selector);
|
|
4762
|
-
if (!element || !element.parentNode) return false;
|
|
4763
|
-
const clonedElement = element.cloneNode(true);
|
|
4764
|
-
clonedElement.removeAttribute("data-blnk-id");
|
|
4765
|
-
element.parentNode.insertBefore(clonedElement, element.nextSibling);
|
|
4766
|
-
this.sendMessage({
|
|
4767
|
-
type: "ELEMENT_DUPLICATED",
|
|
4768
|
-
payload: {
|
|
4769
|
-
originalSelector: selector,
|
|
4770
|
-
duplicatedElement: this.getElementInfo(clonedElement)
|
|
4771
|
-
}
|
|
4772
|
-
});
|
|
4773
|
-
return true;
|
|
4774
|
-
} catch (error) {
|
|
4775
|
-
console.error("[ElementSelector] \u590D\u5236\u5143\u7D20\u5931\u8D25:", error);
|
|
4776
|
-
return false;
|
|
4777
|
-
}
|
|
4778
|
-
}
|
|
4779
|
-
/**
|
|
4780
|
-
* 启用文本编辑
|
|
4781
|
-
*/
|
|
4782
|
-
enableTextEditing(selector) {
|
|
4783
|
-
try {
|
|
4784
|
-
const element = document.querySelector(selector);
|
|
4785
|
-
if (!element) return false;
|
|
4786
|
-
element.setAttribute("contenteditable", "true");
|
|
4787
|
-
element.setAttribute("data-editing", "true");
|
|
4788
|
-
element.focus();
|
|
4789
|
-
const handleEditComplete = () => {
|
|
4790
|
-
element.removeAttribute("contenteditable");
|
|
4791
|
-
element.removeAttribute("data-editing");
|
|
4792
|
-
element.removeEventListener("blur", handleEditComplete);
|
|
4793
|
-
element.removeEventListener("keydown", handleKeyDown);
|
|
4794
|
-
this.sendMessage({
|
|
4795
|
-
type: "ELEMENT_TEXT_UPDATED",
|
|
4796
|
-
payload: {
|
|
4797
|
-
selector,
|
|
4798
|
-
content: element.textContent || "",
|
|
4799
|
-
element: this.getElementInfo(element)
|
|
4800
|
-
}
|
|
4801
|
-
});
|
|
4802
|
-
};
|
|
4803
|
-
const handleKeyDown = (event) => {
|
|
4804
|
-
const keyboardEvent = event;
|
|
4805
|
-
if (keyboardEvent.key === "Enter" && !keyboardEvent.shiftKey) {
|
|
4806
|
-
event.preventDefault();
|
|
4807
|
-
handleEditComplete();
|
|
4808
|
-
} else if (keyboardEvent.key === "Escape") {
|
|
4809
|
-
event.preventDefault();
|
|
4810
|
-
handleEditComplete();
|
|
4811
|
-
}
|
|
4812
|
-
};
|
|
4813
|
-
element.addEventListener("blur", handleEditComplete);
|
|
4814
|
-
element.addEventListener("keydown", handleKeyDown);
|
|
4815
|
-
return true;
|
|
4816
|
-
} catch (error) {
|
|
4817
|
-
console.error("[ElementSelector] \u542F\u7528\u6587\u672C\u7F16\u8F91\u5931\u8D25:", error);
|
|
4818
|
-
return false;
|
|
4819
|
-
}
|
|
4820
|
-
}
|
|
4821
|
-
/** ----------------- 高级交互功能 ----------------- */
|
|
4822
|
-
/**
|
|
4823
|
-
* 获取父元素
|
|
4824
|
-
*/
|
|
4825
|
-
getParentElement(selector) {
|
|
4826
|
-
try {
|
|
4827
|
-
const element = document.querySelector(selector);
|
|
4828
|
-
return element?.parentElement || null;
|
|
4829
|
-
} catch (error) {
|
|
4830
|
-
console.error("[ElementSelector] \u83B7\u53D6\u7236\u5143\u7D20\u5931\u8D25:", error);
|
|
4831
|
-
return null;
|
|
4832
|
-
}
|
|
4833
|
-
}
|
|
4834
|
-
/**
|
|
4835
|
-
* 外部悬停控制 - 通过选择器悬停元素
|
|
4836
|
-
*/
|
|
4837
|
-
hoverElementBySelector(selector) {
|
|
4838
|
-
try {
|
|
4839
|
-
const element = document.querySelector(selector);
|
|
4840
|
-
if (!element) return false;
|
|
4841
|
-
this.highlightElement(element);
|
|
4842
|
-
this.updateTooltip(element);
|
|
4843
|
-
return true;
|
|
4844
|
-
} catch (error) {
|
|
4845
|
-
console.error("[ElementSelector] \u5916\u90E8\u60AC\u505C\u63A7\u5236\u5931\u8D25:", error);
|
|
4846
|
-
return false;
|
|
4847
|
-
}
|
|
4036
|
+
if (dataId) return `[data-id="${dataId}"]`;
|
|
4037
|
+
return element.tagName.toLowerCase();
|
|
4848
4038
|
}
|
|
4849
4039
|
/**
|
|
4850
|
-
*
|
|
4040
|
+
* 检查是否为敏感输入
|
|
4851
4041
|
*/
|
|
4852
|
-
|
|
4853
|
-
this.
|
|
4854
|
-
|
|
4042
|
+
isSensitiveInput(element) {
|
|
4043
|
+
if (!this.trackingConfig.sensitiveInputFilter) return false;
|
|
4044
|
+
const sensitiveTypes = ["password", "email", "tel", "ssn", "credit-card"];
|
|
4045
|
+
const sensitiveNames = ["password", "email", "phone", "ssn", "credit", "card", "cvv", "pin"];
|
|
4046
|
+
return sensitiveTypes.includes(element.type) || sensitiveNames.some(
|
|
4047
|
+
(name) => element.name?.toLowerCase().includes(name) || element.placeholder?.toLowerCase().includes(name) || element.id?.toLowerCase().includes(name)
|
|
4048
|
+
);
|
|
4855
4049
|
}
|
|
4856
|
-
/** ----------------- 辅助方法 ----------------- */
|
|
4857
4050
|
/**
|
|
4858
|
-
*
|
|
4051
|
+
* 管理数组长度
|
|
4859
4052
|
*/
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
return Math.abs(rect.width - window.innerWidth) < 5;
|
|
4864
|
-
} catch (error) {
|
|
4865
|
-
console.warn("[ElementSelector] \u68C0\u67E5\u5168\u5BBD\u5143\u7D20\u5931\u8D25:", error);
|
|
4866
|
-
return false;
|
|
4053
|
+
manageArrayLength(array, maxLength) {
|
|
4054
|
+
if (array.length > maxLength) {
|
|
4055
|
+
array.shift();
|
|
4867
4056
|
}
|
|
4868
4057
|
}
|
|
4058
|
+
/** ----------------- 公共接口方法 ----------------- */
|
|
4869
4059
|
/**
|
|
4870
|
-
*
|
|
4060
|
+
* 获取交互历史
|
|
4871
4061
|
*/
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
return false;
|
|
4875
|
-
}
|
|
4876
|
-
if (this.hasHowoneId(element)) {
|
|
4877
|
-
return true;
|
|
4878
|
-
}
|
|
4879
|
-
if (element.id === "howone-element-tooltip" || element.classList.contains("howone-tooltip")) {
|
|
4880
|
-
return false;
|
|
4881
|
-
}
|
|
4882
|
-
const tagName = element.tagName.toLowerCase();
|
|
4883
|
-
if (["script", "style", "meta", "link", "title"].includes(tagName)) {
|
|
4884
|
-
return false;
|
|
4885
|
-
}
|
|
4886
|
-
return true;
|
|
4062
|
+
getInteractionHistory() {
|
|
4063
|
+
return [...this.interactions];
|
|
4887
4064
|
}
|
|
4888
4065
|
/**
|
|
4889
|
-
*
|
|
4066
|
+
* 获取最近的交互记录
|
|
4890
4067
|
*/
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
return {
|
|
4894
|
-
tagName: element.tagName.toLowerCase(),
|
|
4895
|
-
id: element.id || void 0,
|
|
4896
|
-
className: element.className || void 0,
|
|
4897
|
-
textContent: element.textContent?.trim().substring(0, 100) || void 0,
|
|
4898
|
-
attributes: this.getElementAttributes(element),
|
|
4899
|
-
selector: this.getElementSelector(element),
|
|
4900
|
-
boundingRect: element.getBoundingClientRect(),
|
|
4901
|
-
location: location || void 0
|
|
4902
|
-
};
|
|
4068
|
+
getRecentInteractions(count = 8) {
|
|
4069
|
+
return this.interactions.slice(-count);
|
|
4903
4070
|
}
|
|
4904
4071
|
/**
|
|
4905
|
-
*
|
|
4072
|
+
* 手动发送交互数据到父窗口(用于测试或特殊情况)
|
|
4906
4073
|
*/
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4074
|
+
sendInteractionData() {
|
|
4075
|
+
if (this.interactions.length === 0) return;
|
|
4076
|
+
this.sendMessage({
|
|
4077
|
+
type: "INTERACTION_EVENT",
|
|
4078
|
+
payload: {
|
|
4079
|
+
type: "summary",
|
|
4080
|
+
interactions: this.interactions,
|
|
4081
|
+
count: this.interactions.length,
|
|
4082
|
+
timeRange: {
|
|
4083
|
+
start: this.interactions[0]?.timestamp || Date.now(),
|
|
4084
|
+
end: this.interactions[this.interactions.length - 1]?.timestamp || Date.now()
|
|
4085
|
+
},
|
|
4086
|
+
summary: this.generateInteractionSummary()
|
|
4087
|
+
},
|
|
4088
|
+
timestamp: Date.now()
|
|
4915
4089
|
});
|
|
4916
|
-
return attrs;
|
|
4917
4090
|
}
|
|
4918
4091
|
/**
|
|
4919
|
-
*
|
|
4092
|
+
* 生成交互摘要
|
|
4920
4093
|
*/
|
|
4921
|
-
|
|
4922
|
-
const
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
}
|
|
4933
|
-
if (element.className) {
|
|
4934
|
-
const classes = element.className.split(" ").filter((c) => c.trim());
|
|
4935
|
-
if (classes.length > 0) {
|
|
4936
|
-
return `.${classes[0]}`;
|
|
4094
|
+
generateInteractionSummary() {
|
|
4095
|
+
const summary = {
|
|
4096
|
+
totalInteractions: this.interactions.length,
|
|
4097
|
+
typeCount: {},
|
|
4098
|
+
uniqueElements: /* @__PURE__ */ new Set(),
|
|
4099
|
+
timeSpan: 0
|
|
4100
|
+
};
|
|
4101
|
+
this.interactions.forEach((interaction) => {
|
|
4102
|
+
summary.typeCount[interaction.type] = (summary.typeCount[interaction.type] || 0) + 1;
|
|
4103
|
+
if (interaction.element) {
|
|
4104
|
+
summary.uniqueElements.add(interaction.element);
|
|
4937
4105
|
}
|
|
4106
|
+
});
|
|
4107
|
+
if (this.interactions.length > 1) {
|
|
4108
|
+
summary.timeSpan = this.interactions[this.interactions.length - 1].timestamp - this.interactions[0].timestamp;
|
|
4938
4109
|
}
|
|
4939
|
-
return
|
|
4110
|
+
return {
|
|
4111
|
+
...summary,
|
|
4112
|
+
uniqueElements: Array.from(summary.uniqueElements),
|
|
4113
|
+
mostCommonType: Object.entries(summary.typeCount).sort(([, a], [, b]) => b - a)[0]?.[0] || "unknown"
|
|
4114
|
+
};
|
|
4940
4115
|
}
|
|
4941
|
-
/** ----------------- 公共接口方法 ----------------- */
|
|
4942
4116
|
/**
|
|
4943
|
-
*
|
|
4117
|
+
* 清除交互历史
|
|
4944
4118
|
*/
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
if (element) {
|
|
4948
|
-
this.highlightElement(element);
|
|
4949
|
-
}
|
|
4119
|
+
clearInteractionHistory() {
|
|
4120
|
+
this.interactions = [];
|
|
4950
4121
|
}
|
|
4951
4122
|
/**
|
|
4952
|
-
*
|
|
4123
|
+
* 更新追踪配置
|
|
4953
4124
|
*/
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
if (
|
|
4957
|
-
this.
|
|
4125
|
+
updateConfig(newConfig) {
|
|
4126
|
+
this.trackingConfig = { ...this.trackingConfig, ...newConfig };
|
|
4127
|
+
if (this.isTracking) {
|
|
4128
|
+
this.removeEventListeners();
|
|
4129
|
+
this.setupEventListeners();
|
|
4958
4130
|
}
|
|
4959
4131
|
}
|
|
4960
4132
|
/**
|
|
4961
|
-
*
|
|
4962
|
-
*/
|
|
4963
|
-
updateSelectedElements(elements) {
|
|
4964
|
-
this.clearSelection();
|
|
4965
|
-
elements.forEach((elementData) => {
|
|
4966
|
-
const element = this.findElementByData(elementData);
|
|
4967
|
-
if (element) {
|
|
4968
|
-
this.selectedElements.push(element);
|
|
4969
|
-
element.setAttribute("data-element-selected", "true");
|
|
4970
|
-
if (this.isFullWidthElement(element)) {
|
|
4971
|
-
element.setAttribute("data-full-width", "true");
|
|
4972
|
-
}
|
|
4973
|
-
}
|
|
4974
|
-
});
|
|
4975
|
-
}
|
|
4976
|
-
/**
|
|
4977
|
-
* 根据数据查找元素
|
|
4133
|
+
* 获取追踪状态
|
|
4978
4134
|
*/
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
return document.querySelector(`[data-blnk-id="${elementData.blinkId}"]`);
|
|
4982
|
-
}
|
|
4983
|
-
if (elementData.id) {
|
|
4984
|
-
return document.getElementById(elementData.id);
|
|
4985
|
-
}
|
|
4986
|
-
if (elementData.selector) {
|
|
4987
|
-
return document.querySelector(elementData.selector);
|
|
4988
|
-
}
|
|
4989
|
-
return null;
|
|
4135
|
+
isTrackingActive() {
|
|
4136
|
+
return this.isTracking;
|
|
4990
4137
|
}
|
|
4991
4138
|
/**
|
|
4992
|
-
*
|
|
4139
|
+
* 销毁交互追踪
|
|
4993
4140
|
*/
|
|
4994
4141
|
destroy() {
|
|
4995
|
-
this.
|
|
4996
|
-
|
|
4997
|
-
this.tooltip.remove();
|
|
4998
|
-
this.tooltip = null;
|
|
4999
|
-
}
|
|
5000
|
-
if (this.styleElement) {
|
|
5001
|
-
this.styleElement.remove();
|
|
5002
|
-
this.styleElement = null;
|
|
5003
|
-
}
|
|
4142
|
+
this.stopTracking();
|
|
4143
|
+
this.interactions = [];
|
|
5004
4144
|
}
|
|
5005
4145
|
};
|
|
5006
4146
|
|
|
@@ -5014,7 +4154,6 @@ var getOriginalConsole2 = () => window.__originalConsole || {
|
|
|
5014
4154
|
};
|
|
5015
4155
|
var MessageBridge = class {
|
|
5016
4156
|
constructor(sendMessage) {
|
|
5017
|
-
this.elementSelector = null;
|
|
5018
4157
|
this.componentTreeGenerator = null;
|
|
5019
4158
|
this.messageSender = createDefaultMessageSender({
|
|
5020
4159
|
addTimestamp: true,
|
|
@@ -5022,15 +4161,8 @@ var MessageBridge = class {
|
|
|
5022
4161
|
});
|
|
5023
4162
|
this.sendMessage = sendMessage || this.messageSender.createSendFunction();
|
|
5024
4163
|
this.setupMessageListener();
|
|
5025
|
-
console.log("[MessageBridge] \u6D88\u606F\u6865\u63A5\u5668\u521D\u59CB\u5316\u5B8C\u6210");
|
|
5026
4164
|
}
|
|
5027
4165
|
/** ----------------- 依赖注入方法 ----------------- */
|
|
5028
|
-
/**
|
|
5029
|
-
* 设置元素选择器
|
|
5030
|
-
*/
|
|
5031
|
-
setElementSelector(elementSelector2) {
|
|
5032
|
-
this.elementSelector = elementSelector2;
|
|
5033
|
-
}
|
|
5034
4166
|
/**
|
|
5035
4167
|
* 设置组件树生成器
|
|
5036
4168
|
*/
|
|
@@ -5068,32 +4200,6 @@ var MessageBridge = class {
|
|
|
5068
4200
|
try {
|
|
5069
4201
|
const { type, payload } = message;
|
|
5070
4202
|
switch (type) {
|
|
5071
|
-
// 选择器相关消息
|
|
5072
|
-
case "TOGGLE_SELECTOR":
|
|
5073
|
-
this.handleToggleSelector(payload);
|
|
5074
|
-
break;
|
|
5075
|
-
case "ENABLE_SELECTOR":
|
|
5076
|
-
this.handleEnableElementSelector();
|
|
5077
|
-
break;
|
|
5078
|
-
case "DISABLE_SELECTOR":
|
|
5079
|
-
this.handleDisableElementSelector();
|
|
5080
|
-
break;
|
|
5081
|
-
case "GET_SELECTOR_STATE":
|
|
5082
|
-
this.handleGetSelectorState();
|
|
5083
|
-
break;
|
|
5084
|
-
// 元素操作消息
|
|
5085
|
-
case "HOVER_ELEMENT_BY_ID":
|
|
5086
|
-
this.handleHoverElementById(payload);
|
|
5087
|
-
break;
|
|
5088
|
-
case "UNHOVER_ELEMENT_BY_ID":
|
|
5089
|
-
this.handleUnhoverElementById(payload);
|
|
5090
|
-
break;
|
|
5091
|
-
case "HOVER_ELEMENT_REQUESTED":
|
|
5092
|
-
this.handleHoverElementRequested(payload);
|
|
5093
|
-
break;
|
|
5094
|
-
case "UNHOVER_ELEMENT_REQUESTED":
|
|
5095
|
-
this.handleUnhoverElementRequested(payload);
|
|
5096
|
-
break;
|
|
5097
4203
|
case "SET_ELEMENT_CONTENT":
|
|
5098
4204
|
this.handleSetElementContent(payload);
|
|
5099
4205
|
break;
|
|
@@ -5106,28 +4212,6 @@ var MessageBridge = class {
|
|
|
5106
4212
|
case "EDIT_TEXT_REQUESTED":
|
|
5107
4213
|
this.handleEditTextRequested(payload);
|
|
5108
4214
|
break;
|
|
5109
|
-
case "UPDATE_SELECTED_ELEMENTS":
|
|
5110
|
-
this.handleUpdateSelectedElements(payload);
|
|
5111
|
-
break;
|
|
5112
|
-
// 新增的消息类型
|
|
5113
|
-
case "GET_ELEMENT_AT_POINT":
|
|
5114
|
-
this.handleGetElementAtPoint(payload);
|
|
5115
|
-
break;
|
|
5116
|
-
case "FIND_ELEMENTS_BY_LOCATION":
|
|
5117
|
-
this.handleFindElementsByLocation(payload);
|
|
5118
|
-
break;
|
|
5119
|
-
case "SET_ELEMENT_ATTRIBUTES":
|
|
5120
|
-
this.handleSetElementAttributes(payload);
|
|
5121
|
-
break;
|
|
5122
|
-
case "ENABLE_TEXT_EDITING":
|
|
5123
|
-
this.handleEnableTextEditing(payload);
|
|
5124
|
-
break;
|
|
5125
|
-
case "HOVER_ELEMENT_BY_SELECTOR":
|
|
5126
|
-
this.handleHoverElementBySelector(payload);
|
|
5127
|
-
break;
|
|
5128
|
-
case "UNHOVER_ELEMENT":
|
|
5129
|
-
this.handleUnhoverElement();
|
|
5130
|
-
break;
|
|
5131
4215
|
// 组件树相关消息
|
|
5132
4216
|
case "REQUEST_COMPONENT_TREE":
|
|
5133
4217
|
this.handleRequestComponentTree();
|
|
@@ -5155,79 +4239,7 @@ var MessageBridge = class {
|
|
|
5155
4239
|
});
|
|
5156
4240
|
}
|
|
5157
4241
|
}
|
|
5158
|
-
/** ----------------- 选择器相关消息处理 ----------------- */
|
|
5159
|
-
/**
|
|
5160
|
-
* 处理切换选择器
|
|
5161
|
-
*/
|
|
5162
|
-
handleToggleSelector(payload) {
|
|
5163
|
-
if (!this.elementSelector) return;
|
|
5164
|
-
const shouldActivate = !!payload;
|
|
5165
|
-
if (shouldActivate) {
|
|
5166
|
-
this.elementSelector.enableSelector();
|
|
5167
|
-
} else {
|
|
5168
|
-
this.elementSelector.disableSelector();
|
|
5169
|
-
}
|
|
5170
|
-
}
|
|
5171
|
-
/**
|
|
5172
|
-
* 处理获取选择器状态
|
|
5173
|
-
*/
|
|
5174
|
-
handleGetSelectorState() {
|
|
5175
|
-
if (!this.elementSelector) return;
|
|
5176
|
-
const state = this.elementSelector.getSelectorState();
|
|
5177
|
-
this.sendMessage({
|
|
5178
|
-
type: "SELECTOR_EVENT",
|
|
5179
|
-
payload: {
|
|
5180
|
-
type: "state_response",
|
|
5181
|
-
...state
|
|
5182
|
-
},
|
|
5183
|
-
timestamp: Date.now()
|
|
5184
|
-
});
|
|
5185
|
-
}
|
|
5186
|
-
/**
|
|
5187
|
-
* 处理启用元素选择器
|
|
5188
|
-
*/
|
|
5189
|
-
handleEnableElementSelector() {
|
|
5190
|
-
if (!this.elementSelector) return;
|
|
5191
|
-
this.elementSelector.enableSelector();
|
|
5192
|
-
}
|
|
5193
|
-
/**
|
|
5194
|
-
* 处理禁用元素选择器
|
|
5195
|
-
*/
|
|
5196
|
-
handleDisableElementSelector() {
|
|
5197
|
-
if (!this.elementSelector) return;
|
|
5198
|
-
this.elementSelector.disableSelector();
|
|
5199
|
-
}
|
|
5200
4242
|
/** ----------------- 元素操作消息处理 ----------------- */
|
|
5201
|
-
/**
|
|
5202
|
-
* 处理通过 ID 高亮元素
|
|
5203
|
-
*/
|
|
5204
|
-
handleHoverElementById(payload) {
|
|
5205
|
-
if (!this.elementSelector || !payload?.id) return;
|
|
5206
|
-
const selector = `#${payload.id}`;
|
|
5207
|
-
this.elementSelector.highlightElementBySelector(selector);
|
|
5208
|
-
}
|
|
5209
|
-
/**
|
|
5210
|
-
* 处理通过 ID 取消高亮元素
|
|
5211
|
-
*/
|
|
5212
|
-
handleUnhoverElementById(payload) {
|
|
5213
|
-
if (!this.elementSelector || !payload?.id) return;
|
|
5214
|
-
const selector = `#${payload.id}`;
|
|
5215
|
-
this.elementSelector.unhighlightElementBySelector(selector);
|
|
5216
|
-
}
|
|
5217
|
-
/**
|
|
5218
|
-
* 处理高亮元素请求
|
|
5219
|
-
*/
|
|
5220
|
-
handleHoverElementRequested(payload) {
|
|
5221
|
-
if (!this.elementSelector || !payload?.selector) return;
|
|
5222
|
-
this.elementSelector.highlightElementBySelector(payload.selector);
|
|
5223
|
-
}
|
|
5224
|
-
/**
|
|
5225
|
-
* 处理取消高亮元素请求
|
|
5226
|
-
*/
|
|
5227
|
-
handleUnhoverElementRequested(payload) {
|
|
5228
|
-
if (!this.elementSelector || !payload?.selector) return;
|
|
5229
|
-
this.elementSelector.unhighlightElementBySelector(payload.selector);
|
|
5230
|
-
}
|
|
5231
4243
|
/**
|
|
5232
4244
|
* 处理设置元素内容
|
|
5233
4245
|
*/
|
|
@@ -5331,22 +4343,6 @@ var MessageBridge = class {
|
|
|
5331
4343
|
element.addEventListener("blur", handleBlur);
|
|
5332
4344
|
}
|
|
5333
4345
|
}
|
|
5334
|
-
/**
|
|
5335
|
-
* 处理更新选中元素
|
|
5336
|
-
*/
|
|
5337
|
-
handleUpdateSelectedElements(payload) {
|
|
5338
|
-
if (!this.elementSelector || !Array.isArray(payload)) return;
|
|
5339
|
-
this.elementSelector.updateSelectedElements(payload);
|
|
5340
|
-
this.sendMessage({
|
|
5341
|
-
type: "ELEMENT_EVENT",
|
|
5342
|
-
payload: {
|
|
5343
|
-
type: "selected_elements_updated",
|
|
5344
|
-
selectedElements: payload,
|
|
5345
|
-
count: payload.length
|
|
5346
|
-
},
|
|
5347
|
-
timestamp: Date.now()
|
|
5348
|
-
});
|
|
5349
|
-
}
|
|
5350
4346
|
/** ----------------- 组件树相关消息处理 ----------------- */
|
|
5351
4347
|
/**
|
|
5352
4348
|
* 处理请求组件树
|
|
@@ -5470,11 +4466,9 @@ var MessageBridge = class {
|
|
|
5470
4466
|
if (dataTestId) return `[data-testid="${dataTestId}"]`;
|
|
5471
4467
|
const dataHowoneId = element.getAttribute("data-howone-id");
|
|
5472
4468
|
if (dataHowoneId) return `[data-howone-id="${dataHowoneId}"]`;
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
return `.${classes[0]}`;
|
|
5477
|
-
}
|
|
4469
|
+
const classes = getElementClasses(element);
|
|
4470
|
+
if (classes.length > 0) {
|
|
4471
|
+
return `.${classes[0]}`;
|
|
5478
4472
|
}
|
|
5479
4473
|
return element.tagName.toLowerCase();
|
|
5480
4474
|
}
|
|
@@ -5502,106 +4496,6 @@ var MessageBridge = class {
|
|
|
5502
4496
|
timestamp: Date.now()
|
|
5503
4497
|
});
|
|
5504
4498
|
}
|
|
5505
|
-
/** ----------------- 新增的消息处理方法 ----------------- */
|
|
5506
|
-
/**
|
|
5507
|
-
* 处理获取鼠标位置的元素
|
|
5508
|
-
*/
|
|
5509
|
-
handleGetElementAtPoint(payload) {
|
|
5510
|
-
if (!this.elementSelector) return;
|
|
5511
|
-
const element = this.elementSelector.getElementAtPoint(payload?.x, payload?.y);
|
|
5512
|
-
this.sendMessage({
|
|
5513
|
-
type: "ELEMENT_EVENT",
|
|
5514
|
-
payload: {
|
|
5515
|
-
type: "at_point_response",
|
|
5516
|
-
element: element ? this.getElementInfo(element) : null,
|
|
5517
|
-
coordinates: { x: payload?.x, y: payload?.y }
|
|
5518
|
-
},
|
|
5519
|
-
timestamp: Date.now()
|
|
5520
|
-
});
|
|
5521
|
-
}
|
|
5522
|
-
/**
|
|
5523
|
-
* 处理根据位置查找元素
|
|
5524
|
-
*/
|
|
5525
|
-
handleFindElementsByLocation(payload) {
|
|
5526
|
-
if (!this.elementSelector || !payload?.filePath || !payload?.lineNumber) return;
|
|
5527
|
-
const elements = this.elementSelector.findElementsByLocation(payload.filePath, payload.lineNumber);
|
|
5528
|
-
this.sendMessage({
|
|
5529
|
-
type: "ELEMENT_EVENT",
|
|
5530
|
-
payload: {
|
|
5531
|
-
type: "elements_by_location_response",
|
|
5532
|
-
elements: elements.map((el) => this.getElementInfo(el)),
|
|
5533
|
-
location: {
|
|
5534
|
-
filePath: payload.filePath,
|
|
5535
|
-
lineNumber: payload.lineNumber
|
|
5536
|
-
}
|
|
5537
|
-
},
|
|
5538
|
-
timestamp: Date.now()
|
|
5539
|
-
});
|
|
5540
|
-
}
|
|
5541
|
-
/**
|
|
5542
|
-
* 处理设置元素属性(新版本)
|
|
5543
|
-
*/
|
|
5544
|
-
handleSetElementAttributes(payload) {
|
|
5545
|
-
if (!this.elementSelector || !payload?.selector || !payload?.attributes) return;
|
|
5546
|
-
const success = this.elementSelector.setElementAttributes(payload.selector, payload.attributes);
|
|
5547
|
-
this.sendMessage({
|
|
5548
|
-
type: "ELEMENT_EVENT",
|
|
5549
|
-
payload: {
|
|
5550
|
-
type: "attributes_set_response",
|
|
5551
|
-
success,
|
|
5552
|
-
selector: payload.selector,
|
|
5553
|
-
attributes: payload.attributes
|
|
5554
|
-
},
|
|
5555
|
-
timestamp: Date.now()
|
|
5556
|
-
});
|
|
5557
|
-
}
|
|
5558
|
-
/**
|
|
5559
|
-
* 处理启用文本编辑
|
|
5560
|
-
*/
|
|
5561
|
-
handleEnableTextEditing(payload) {
|
|
5562
|
-
if (!this.elementSelector || !payload?.selector) return;
|
|
5563
|
-
const success = this.elementSelector.enableTextEditing(payload.selector);
|
|
5564
|
-
this.sendMessage({
|
|
5565
|
-
type: "ELEMENT_EVENT",
|
|
5566
|
-
payload: {
|
|
5567
|
-
type: "text_editing_enabled_response",
|
|
5568
|
-
success,
|
|
5569
|
-
selector: payload.selector
|
|
5570
|
-
},
|
|
5571
|
-
timestamp: Date.now()
|
|
5572
|
-
});
|
|
5573
|
-
}
|
|
5574
|
-
/**
|
|
5575
|
-
* 处理通过选择器悬停元素
|
|
5576
|
-
*/
|
|
5577
|
-
handleHoverElementBySelector(payload) {
|
|
5578
|
-
if (!this.elementSelector || !payload?.selector) return;
|
|
5579
|
-
const success = this.elementSelector.hoverElementBySelector(payload.selector);
|
|
5580
|
-
this.sendMessage({
|
|
5581
|
-
type: "ELEMENT_EVENT",
|
|
5582
|
-
payload: {
|
|
5583
|
-
type: "hovered_by_selector_response",
|
|
5584
|
-
success,
|
|
5585
|
-
selector: payload.selector
|
|
5586
|
-
},
|
|
5587
|
-
timestamp: Date.now()
|
|
5588
|
-
});
|
|
5589
|
-
}
|
|
5590
|
-
/**
|
|
5591
|
-
* 处理取消悬停元素
|
|
5592
|
-
*/
|
|
5593
|
-
handleUnhoverElement() {
|
|
5594
|
-
if (!this.elementSelector) return;
|
|
5595
|
-
this.elementSelector.unhoverElement();
|
|
5596
|
-
this.sendMessage({
|
|
5597
|
-
type: "ELEMENT_EVENT",
|
|
5598
|
-
payload: {
|
|
5599
|
-
type: "unhovered_response",
|
|
5600
|
-
success: true
|
|
5601
|
-
},
|
|
5602
|
-
timestamp: Date.now()
|
|
5603
|
-
});
|
|
5604
|
-
}
|
|
5605
4499
|
/** ----------------- 统一消息发送管理方法 ----------------- */
|
|
5606
4500
|
/**
|
|
5607
4501
|
* 获取统一的消息发送器实例
|
|
@@ -5635,7 +4529,6 @@ var MessageBridge = class {
|
|
|
5635
4529
|
window.removeEventListener("message", this.messageListener);
|
|
5636
4530
|
this.messageListener = void 0;
|
|
5637
4531
|
}
|
|
5638
|
-
console.log("[MessageBridge] \u6D88\u606F\u6865\u63A5\u5668\u5DF2\u9500\u6BC1");
|
|
5639
4532
|
}
|
|
5640
4533
|
};
|
|
5641
4534
|
|
|
@@ -5670,7 +4563,6 @@ var ErrorHandler = class {
|
|
|
5670
4563
|
const sendMessage = this.messageSender.createSendFunction();
|
|
5671
4564
|
this.errorTracking = new ErrorTracking(sendMessage);
|
|
5672
4565
|
this.interactionTracking = new InteractionTracking(sendMessage);
|
|
5673
|
-
this.elementSelector = new ElementSelector2(sendMessage);
|
|
5674
4566
|
this.messageBridge = new MessageBridge();
|
|
5675
4567
|
this.viewDetector = new ViewDetector();
|
|
5676
4568
|
this.hardRefreshManager = new HardRefreshManager(GLOBAL_CONFIG.ALLOWED_ORIGINS);
|
|
@@ -5735,7 +4627,6 @@ var ErrorHandler = class {
|
|
|
5735
4627
|
* 设置模块间的协作
|
|
5736
4628
|
*/
|
|
5737
4629
|
setupModuleIntegration() {
|
|
5738
|
-
this.messageBridge.setElementSelector(this.elementSelector);
|
|
5739
4630
|
this.messageBridge.setComponentTreeGenerator(this.componentTreeGenerator);
|
|
5740
4631
|
this.errorTracking.setViewDetector(this.viewDetector);
|
|
5741
4632
|
this.errorTracking.setInteractionTracking(this.interactionTracking);
|
|
@@ -5812,12 +4703,6 @@ var ErrorHandler = class {
|
|
|
5812
4703
|
getErrorStats() {
|
|
5813
4704
|
return this.errorTracking.getErrorStats();
|
|
5814
4705
|
}
|
|
5815
|
-
/**
|
|
5816
|
-
* 获取选择器状态
|
|
5817
|
-
*/
|
|
5818
|
-
getSelectorState() {
|
|
5819
|
-
return this.elementSelector.getSelectorState();
|
|
5820
|
-
}
|
|
5821
4706
|
/**
|
|
5822
4707
|
* 获取交互历史
|
|
5823
4708
|
*/
|
|
@@ -5851,24 +4736,6 @@ var ErrorHandler = class {
|
|
|
5851
4736
|
isViteEnvironment() {
|
|
5852
4737
|
return ViteHMRDetector.isViteEnvironment();
|
|
5853
4738
|
}
|
|
5854
|
-
/**
|
|
5855
|
-
* 启用元素选择器
|
|
5856
|
-
*/
|
|
5857
|
-
enableElementSelector() {
|
|
5858
|
-
this.elementSelector.enableSelector();
|
|
5859
|
-
}
|
|
5860
|
-
/**
|
|
5861
|
-
* 禁用元素选择器
|
|
5862
|
-
*/
|
|
5863
|
-
disableElementSelector() {
|
|
5864
|
-
this.elementSelector.disableSelector();
|
|
5865
|
-
}
|
|
5866
|
-
/**
|
|
5867
|
-
* 切换元素选择器状态
|
|
5868
|
-
*/
|
|
5869
|
-
toggleElementSelector() {
|
|
5870
|
-
this.elementSelector.toggleSelector();
|
|
5871
|
-
}
|
|
5872
4739
|
/**
|
|
5873
4740
|
* 更新配置
|
|
5874
4741
|
*/
|
|
@@ -5882,7 +4749,6 @@ var ErrorHandler = class {
|
|
|
5882
4749
|
try {
|
|
5883
4750
|
this.errorTracking.destroy();
|
|
5884
4751
|
this.interactionTracking.destroy();
|
|
5885
|
-
this.elementSelector.destroy();
|
|
5886
4752
|
this.messageBridge.destroy();
|
|
5887
4753
|
if (this.viteHMRDetector) {
|
|
5888
4754
|
this.viteHMRDetector.destroy();
|
|
@@ -5913,7 +4779,6 @@ var ErrorHandler = class {
|
|
|
5913
4779
|
errorStats: this.getErrorStats(),
|
|
5914
4780
|
currentView: this.getCurrentView(),
|
|
5915
4781
|
interactionHistory: this.getInteractionHistory(),
|
|
5916
|
-
selectorState: this.getSelectorState(),
|
|
5917
4782
|
isViteEnvironment: this.isViteEnvironment(),
|
|
5918
4783
|
timestamp: Date.now()
|
|
5919
4784
|
};
|
|
@@ -7095,7 +5960,7 @@ function createClient(opts) {
|
|
|
7095
5960
|
function makeRequestFromBase(base) {
|
|
7096
5961
|
return new request_default({
|
|
7097
5962
|
baseURL: base,
|
|
7098
|
-
timeout:
|
|
5963
|
+
timeout: 3e5,
|
|
7099
5964
|
interceptors: {
|
|
7100
5965
|
requestInterceptor: (config) => {
|
|
7101
5966
|
config.headers = config.headers || {};
|