@howone/sdk 0.2.2 → 0.2.4

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.js CHANGED
@@ -768,17 +768,13 @@ var LoginForm = ({
768
768
  const [codeSent, setCodeSent] = (0, import_react2.useState)(false);
769
769
  const [loginError, setLoginError] = (0, import_react2.useState)(null);
770
770
  const googleLogin = async () => {
771
- console.log("Google login clicked");
772
771
  };
773
772
  const githubLogin = async () => {
774
- console.log("GitHub login clicked");
775
773
  };
776
774
  const sendEmailCode = async (email2) => {
777
- console.log("Send code to:", email2, "for app:", appName);
778
775
  setCodeSent(true);
779
776
  };
780
777
  const loginWithEmail = async (email2, code2) => {
781
- console.log("Login with email:", email2, "code:", code2);
782
778
  if (onLoginSuccess) onLoginSuccess();
783
779
  };
784
780
  const clearError = () => {
@@ -1225,11 +1221,9 @@ var ElementSelectorProvider = ({ children }) => {
1225
1221
  type: "ELEMENT_SELECTION_CANCELLED"
1226
1222
  }, "*");
1227
1223
  }
1228
- console.log("\u{1F6AB} \u5143\u7D20\u9009\u62E9\u5DF2\u53D6\u6D88 (ESC)");
1229
1224
  }, []);
1230
1225
  const handleSelect = (0, import_react7.useCallback)((data) => {
1231
1226
  sendElementSelectionToParent(data);
1232
- console.log("\u{1F3AF} \u5143\u7D20\u5DF2\u9009\u4E2D:", data.element.tagName, data.sourceLocation?.file);
1233
1227
  }, []);
1234
1228
  (0, import_react7.useEffect)(() => {
1235
1229
  const handleStartSelection = () => {
@@ -1584,7 +1578,6 @@ var ViteHMRDetector = class {
1584
1578
  if (this.isInitialized) return;
1585
1579
  this.setupViteErrorDetection();
1586
1580
  this.isInitialized = true;
1587
- console.log("[ViteHMRDetector] Vite HMR \u9519\u8BEF\u68C0\u6D4B\u5668\u521D\u59CB\u5316\u5B8C\u6210");
1588
1581
  }
1589
1582
  /**
1590
1583
  * 销毁检测器
@@ -1635,10 +1628,8 @@ var ViteHMRDetector = class {
1635
1628
  setTimeout(() => this.checkForCompileErrors(), 500);
1636
1629
  });
1637
1630
  hot.on("vite:beforeUpdate", () => {
1638
- console.log("[ViteHMRDetector] HMR \u66F4\u65B0\u5F00\u59CB");
1639
1631
  });
1640
1632
  hot.on("vite:afterUpdate", () => {
1641
- console.log("[ViteHMRDetector] HMR \u66F4\u65B0\u5B8C\u6210");
1642
1633
  });
1643
1634
  }
1644
1635
  window.addEventListener("error", (event) => {
@@ -1676,7 +1667,6 @@ var ViteHMRDetector = class {
1676
1667
  payload: errorPayload,
1677
1668
  timestamp: Date.now()
1678
1669
  });
1679
- console.log("[ViteHMRDetector] Vite \u9519\u8BEF\u5DF2\u68C0\u6D4B\u5E76\u62A5\u544A:", errorPayload);
1680
1670
  } catch (err) {
1681
1671
  this.handleFallbackError(errorOverlay, err);
1682
1672
  }
@@ -1949,20 +1939,16 @@ var HardRefreshManager = class {
1949
1939
  clearedStorage: []
1950
1940
  };
1951
1941
  try {
1952
- console.log("[HardRefreshManager] \u5F00\u59CB\u6267\u884C\u786C\u5237\u65B0...");
1953
1942
  if (defaultOptions.clearCaches) {
1954
1943
  const clearedCaches = await this.clearAllCaches();
1955
1944
  result.clearedCaches = clearedCaches;
1956
- console.log(`[HardRefreshManager] \u5DF2\u6E05\u9664 ${clearedCaches.length} \u4E2A\u7F13\u5B58`);
1957
1945
  }
1958
1946
  if (defaultOptions.unregisterServiceWorkers) {
1959
1947
  const unregisteredCount = await this.unregisterServiceWorkers();
1960
1948
  result.unregisteredWorkers = unregisteredCount;
1961
- console.log(`[HardRefreshManager] \u5DF2\u6CE8\u9500 ${unregisteredCount} \u4E2A Service Worker`);
1962
1949
  }
1963
1950
  const clearedStorage = await this.clearStorage(defaultOptions);
1964
1951
  result.clearedStorage = clearedStorage;
1965
- console.log(`[HardRefreshManager] \u5DF2\u6E05\u9664\u5B58\u50A8: ${clearedStorage.join(", ")}`);
1966
1952
  await this.forceReload(defaultOptions);
1967
1953
  result.success = true;
1968
1954
  return result;
@@ -2561,7 +2547,6 @@ var ComponentTreeGenerator = class {
2561
2547
  maxTextLength: 100,
2562
2548
  maxChildren: 50
2563
2549
  };
2564
- console.log("[ComponentTreeGenerator] \u7EC4\u4EF6\u6811\u751F\u6210\u5668\u521D\u59CB\u5316\u5B8C\u6210");
2565
2550
  }
2566
2551
  /** ----------------- 主要生成方法 ----------------- */
2567
2552
  /**
@@ -2570,7 +2555,6 @@ var ComponentTreeGenerator = class {
2570
2555
  generateComponentTree(rootElement) {
2571
2556
  const startTime = Date.now();
2572
2557
  const root = rootElement || document.body;
2573
- console.log("[ComponentTreeGenerator] \u5F00\u59CB\u751F\u6210\u7EC4\u4EF6\u6811...");
2574
2558
  const rootNode = this.generateNodeTree(root, 0);
2575
2559
  const stats = this.calculateTreeStats(rootNode);
2576
2560
  const componentTree = {
@@ -2591,7 +2575,6 @@ var ComponentTreeGenerator = class {
2591
2575
  }
2592
2576
  };
2593
2577
  const generationTime = Date.now() - startTime;
2594
- console.log(`[ComponentTreeGenerator] \u7EC4\u4EF6\u6811\u751F\u6210\u5B8C\u6210\uFF0C\u8017\u65F6 ${generationTime}ms\uFF0C\u8282\u70B9\u6570: ${stats.totalNodes}`);
2595
2578
  return componentTree;
2596
2579
  }
2597
2580
  /**
@@ -2942,7 +2925,6 @@ var ComponentTreeGenerator = class {
2942
2925
  */
2943
2926
  updateConfig(newConfig) {
2944
2927
  this.config = { ...this.config, ...newConfig };
2945
- console.log("[ComponentTreeGenerator] \u914D\u7F6E\u5DF2\u66F4\u65B0:", this.config);
2946
2928
  }
2947
2929
  /**
2948
2930
  * 获取当前配置
@@ -2965,7 +2947,6 @@ var ComponentTreeGenerator = class {
2965
2947
  * 销毁生成器
2966
2948
  */
2967
2949
  destroy() {
2968
- console.log("[ComponentTreeGenerator] \u7EC4\u4EF6\u6811\u751F\u6210\u5668\u5DF2\u9500\u6BC1");
2969
2950
  }
2970
2951
  };
2971
2952
 
@@ -3142,7 +3123,6 @@ var ErrorTracking = class {
3142
3123
  this.viewDetector = null;
3143
3124
  this.interactionTracking = null;
3144
3125
  this.sendMessage = sendMessage;
3145
- this.internalLog("log", "[ErrorTracking] \u9519\u8BEF\u8FFD\u8E2A\u6A21\u5757\u521D\u59CB\u5316\u5B8C\u6210");
3146
3126
  }
3147
3127
  /**
3148
3128
  * 内部日志方法,避免被控制台拦截器捕获
@@ -3178,10 +3158,8 @@ var ErrorTracking = class {
3178
3158
  this.setupConsoleInterception();
3179
3159
  this.setupNetworkMonitoring();
3180
3160
  this.initialized = true;
3181
- this.internalLog("log", "[ErrorTracking] \u9519\u8BEF\u8FFD\u8E2A\u529F\u80FD\u5DF2\u542F\u7528");
3182
3161
  setTimeout(() => {
3183
3162
  this.fullyInitialized = true;
3184
- this.internalLog("log", "[ErrorTracking] \u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u63A7\u5236\u53F0\u62E6\u622A\u5DF2\u9ED8\u8BA4\u542F\u7528");
3185
3163
  }, 1e3);
3186
3164
  }
3187
3165
  /**
@@ -3206,7 +3184,6 @@ var ErrorTracking = class {
3206
3184
  source: "unhandledrejection"
3207
3185
  });
3208
3186
  });
3209
- this.internalLog("log", "[ErrorTracking] \u5168\u5C40\u9519\u8BEF\u76D1\u542C\u5668\u5DF2\u8BBE\u7F6E");
3210
3187
  }
3211
3188
  /**
3212
3189
  * 设置控制台拦截
@@ -3230,7 +3207,6 @@ var ErrorTracking = class {
3230
3207
  }
3231
3208
  };
3232
3209
  });
3233
- this.internalLog("log", "[ErrorTracking] \u63A7\u5236\u53F0\u62E6\u622A\u5DF2\u8BBE\u7F6E");
3234
3210
  }
3235
3211
  /**
3236
3212
  * 安全地将控制台输出转发到父窗口
@@ -3250,6 +3226,20 @@ var ErrorTracking = class {
3250
3226
  const fileInfo = this.extractFileInfoFromStack(fullStack);
3251
3227
  const serializedArgs = args.map((arg) => DeepSerializer.quickSerialize(arg));
3252
3228
  const message = serializedArgs.map((arg) => typeof arg === "string" ? arg : JSON.stringify(arg, null, 2)).join(" ") + (stack ? "\n" + stack : "");
3229
+ const lowerMessage = message.toLowerCase();
3230
+ const isFromVite = (fileInfo.filename || "").toLowerCase().includes("vite") || lowerMessage.includes("@vite") || lowerMessage.includes("vite") || lowerMessage.includes("hmr");
3231
+ const ignoreVitePatterns = [
3232
+ /\[vite\]\s*hot updated/i,
3233
+ /\[vite\]\s*connected/i,
3234
+ /\[vite\]\s*connecting/i,
3235
+ /\bhot updated\b/i,
3236
+ /\bhmr\b.*\bupdated\b/i
3237
+ ];
3238
+ if (isFromVite && ignoreVitePatterns.some((re) => re.test(lowerMessage))) {
3239
+ return;
3240
+ }
3241
+ const hasErrorKeywords = /\b(error|failed|overlay|compile|exception)\b/.test(lowerMessage);
3242
+ const isViteHMRNonError = isFromVite && !hasErrorKeywords;
3253
3243
  if (method === "error") {
3254
3244
  const globalError = {
3255
3245
  id: `console-error-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
@@ -3266,9 +3256,11 @@ var ErrorTracking = class {
3266
3256
  pagePath: window.location.pathname + window.location.search + window.location.hash,
3267
3257
  interactionTrail: [...window.__AUTO_ENGINEER_INTERACTION_TRAIL__ || []]
3268
3258
  };
3269
- window.__AUTO_ENGINEER_ERRORS__ = window.__AUTO_ENGINEER_ERRORS__ || [];
3270
- window.__AUTO_ENGINEER_ERRORS__.push(globalError);
3271
- this.manageArrayLength(window.__AUTO_ENGINEER_ERRORS__, ERROR_CONFIG.MAX_ERRORS);
3259
+ if (!isViteHMRNonError) {
3260
+ window.__AUTO_ENGINEER_ERRORS__ = window.__AUTO_ENGINEER_ERRORS__ || [];
3261
+ window.__AUTO_ENGINEER_ERRORS__.push(globalError);
3262
+ this.manageArrayLength(window.__AUTO_ENGINEER_ERRORS__, ERROR_CONFIG.MAX_ERRORS);
3263
+ }
3272
3264
  }
3273
3265
  const consoleLevelMap = {
3274
3266
  log: "info",
@@ -3280,7 +3272,7 @@ var ErrorTracking = class {
3280
3272
  this.sendMessage({
3281
3273
  type: "CONSOLE_EVENT",
3282
3274
  payload: {
3283
- type: consoleLevelMap[method] === "info" ? "info" : consoleLevelMap[method] === "warning" ? "warning" : "error",
3275
+ type: consoleLevelMap[method] === "info" ? "info" : consoleLevelMap[method] === "warning" ? "warning" : consoleLevelMap[method] === "debug" ? "debug" : "error",
3284
3276
  message,
3285
3277
  logged_at: (/* @__PURE__ */ new Date()).toISOString(),
3286
3278
  filename: fileInfo.filename,
@@ -3301,19 +3293,47 @@ var ErrorTracking = class {
3301
3293
  * 设置网络监控
3302
3294
  */
3303
3295
  setupNetworkMonitoring() {
3296
+ const self = this;
3304
3297
  const originalFetch = window.fetch;
3305
3298
  window.fetch = async (...args) => {
3306
3299
  const startTime = Date.now();
3307
3300
  try {
3308
3301
  const response = await originalFetch(...args);
3309
- this.logNetworkRequest(args, response, Date.now() - startTime);
3302
+ self.logNetworkRequest(args, response, Date.now() - startTime);
3310
3303
  return response;
3311
3304
  } catch (error) {
3312
- this.logNetworkError(args, error, Date.now() - startTime);
3305
+ const duration = Date.now() - startTime;
3306
+ const message = error && (error.message || String(error));
3307
+ const match = typeof message === "string" ? message.match(/^HTTP\s+(\d+):\s*(.*)$/i) : null;
3308
+ if (match) {
3309
+ const status = Number(match[1]);
3310
+ const statusText = match[2] || "";
3311
+ const stack = new Error().stack;
3312
+ const fileInfo = self.extractFileInfoFromStack(stack);
3313
+ self.sendMessage({
3314
+ type: "NETWORK_EVENT",
3315
+ payload: {
3316
+ type: "request_error",
3317
+ url: args[0],
3318
+ method: args[1]?.method || "GET",
3319
+ status,
3320
+ statusText,
3321
+ filename: fileInfo.filename,
3322
+ lineno: fileInfo.lineno,
3323
+ colno: fileInfo.colno,
3324
+ duration,
3325
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
3326
+ pageUrl: window.location.href,
3327
+ interactionTrail: self.getRecentInteractions()
3328
+ },
3329
+ timestamp: Date.now()
3330
+ });
3331
+ } else {
3332
+ self.logNetworkError(args, error, duration);
3333
+ }
3313
3334
  throw error;
3314
3335
  }
3315
3336
  };
3316
- this.internalLog("log", "[ErrorTracking] \u7F51\u7EDC\u76D1\u63A7\u5DF2\u8BBE\u7F6E");
3317
3337
  }
3318
3338
  /**
3319
3339
  * 记录网络请求
@@ -3605,14 +3625,12 @@ var ErrorTracking = class {
3605
3625
  */
3606
3626
  enableConsoleInterception() {
3607
3627
  this.fullyInitialized = true;
3608
- this.internalLog("log", "[ErrorTracking] \u624B\u52A8\u542F\u7528\u63A7\u5236\u53F0\u62E6\u622A");
3609
3628
  }
3610
3629
  /**
3611
3630
  * 手动禁用控制台拦截
3612
3631
  */
3613
3632
  disableConsoleInterception() {
3614
3633
  this.fullyInitialized = false;
3615
- this.internalLog("log", "[ErrorTracking] \u624B\u52A8\u7981\u7528\u63A7\u5236\u53F0\u62E6\u622A");
3616
3634
  }
3617
3635
  /**
3618
3636
  * 销毁错误追踪
@@ -3624,10 +3642,32 @@ var ErrorTracking = class {
3624
3642
  }
3625
3643
  });
3626
3644
  this.initialized = false;
3627
- this.internalLog("log", "[ErrorTracking] \u9519\u8BEF\u8FFD\u8E2A\u6A21\u5757\u5DF2\u9500\u6BC1");
3628
3645
  }
3629
3646
  };
3630
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
+
3631
3671
  // src/utils/unified-error-handler/features/InteractionTracking.ts
3632
3672
  var InteractionTracking = class {
3633
3673
  constructor(sendMessage) {
@@ -3651,7 +3691,6 @@ var InteractionTracking = class {
3651
3691
  this.debounceTimers = /* @__PURE__ */ new Map();
3652
3692
  this.eventListeners = [];
3653
3693
  this.sendMessage = sendMessage;
3654
- console.log("[InteractionTracking] \u4EA4\u4E92\u8FFD\u8E2A\u6A21\u5757\u521D\u59CB\u5316\u5B8C\u6210");
3655
3694
  }
3656
3695
  /** ----------------- 主要控制方法 ----------------- */
3657
3696
  /**
@@ -3667,7 +3706,6 @@ var InteractionTracking = class {
3667
3706
  title: document.title,
3668
3707
  timestamp: Date.now()
3669
3708
  });
3670
- console.log("[InteractionTracking] \u4EA4\u4E92\u8FFD\u8E2A\u5DF2\u5F00\u59CB");
3671
3709
  }
3672
3710
  /**
3673
3711
  * 停止追踪
@@ -3676,7 +3714,6 @@ var InteractionTracking = class {
3676
3714
  if (!this.isTracking) return;
3677
3715
  this.removeEventListeners();
3678
3716
  this.isTracking = false;
3679
- console.log("[InteractionTracking] \u4EA4\u4E92\u8FFD\u8E2A\u5DF2\u505C\u6B62");
3680
3717
  }
3681
3718
  /** ----------------- 事件监听器设置 ----------------- */
3682
3719
  /**
@@ -3989,11 +4026,9 @@ var InteractionTracking = class {
3989
4026
  */
3990
4027
  getElementSelector(element) {
3991
4028
  if (element.id) return `#${element.id}`;
3992
- if (element.className) {
3993
- const classes = element.className.split(" ").filter((c) => c.trim());
3994
- if (classes.length > 0) {
3995
- return `.${classes[0]}`;
3996
- }
4029
+ const classes = getElementClasses(element);
4030
+ if (classes.length > 0) {
4031
+ return `.${classes[0]}`;
3997
4032
  }
3998
4033
  const dataTestId = element.getAttribute("data-testid");
3999
4034
  if (dataTestId) return `[data-testid="${dataTestId}"]`;
@@ -4106,1244 +4141,240 @@ var InteractionTracking = class {
4106
4141
  destroy() {
4107
4142
  this.stopTracking();
4108
4143
  this.interactions = [];
4109
- console.log("[InteractionTracking] \u4EA4\u4E92\u8FFD\u8E2A\u6A21\u5757\u5DF2\u9500\u6BC1");
4110
4144
  }
4111
4145
  };
4112
4146
 
4113
- // src/utils/unified-error-handler/features/ElementSelector.ts
4114
- var ElementSelector2 = class {
4147
+ // src/utils/unified-error-handler/features/MessageBridge.ts
4148
+ var getOriginalConsole2 = () => window.__originalConsole || {
4149
+ log: console.log.bind(console),
4150
+ warn: console.warn.bind(console),
4151
+ error: console.error.bind(console),
4152
+ info: console.info.bind(console),
4153
+ debug: console.debug.bind(console)
4154
+ };
4155
+ var MessageBridge = class {
4115
4156
  constructor(sendMessage) {
4116
- this.config = { ...DEFAULT_SELECTOR_CONFIG };
4117
- this.isActive = false;
4118
- this.highlightedElement = null;
4119
- this.selectedElements = [];
4120
- this.rootElement = null;
4121
- this.tooltip = null;
4122
- this.styleElement = null;
4123
- this.eventListeners = [];
4124
- this.lastClickTimestamp = 0;
4125
- this.lastClickTarget = null;
4126
- this.mousePosition = { x: 0, y: 0 };
4127
- this.sendMessage = sendMessage;
4128
- this.initializeSelector();
4157
+ this.componentTreeGenerator = null;
4158
+ this.messageSender = createDefaultMessageSender({
4159
+ addTimestamp: true,
4160
+ enableDebugLog: false
4161
+ });
4162
+ this.sendMessage = sendMessage || this.messageSender.createSendFunction();
4163
+ this.setupMessageListener();
4129
4164
  }
4130
- /** ----------------- 初始化方法 ----------------- */
4165
+ /** ----------------- 依赖注入方法 ----------------- */
4131
4166
  /**
4132
- * 初始化选择器
4167
+ * 设置组件树生成器
4133
4168
  */
4134
- initializeSelector() {
4135
- this.waitForRootElement();
4136
- this.createTooltip();
4137
- this.createStyles();
4138
- console.log("[ElementSelector] \u5143\u7D20\u9009\u62E9\u5668\u521D\u59CB\u5316\u5B8C\u6210");
4169
+ setComponentTreeGenerator(componentTreeGenerator) {
4170
+ this.componentTreeGenerator = componentTreeGenerator;
4139
4171
  }
4172
+ /** ----------------- 消息监听设置 ----------------- */
4140
4173
  /**
4141
- * 等待根元素加载
4174
+ * 设置消息监听器
4142
4175
  */
4143
- async waitForRootElement() {
4144
- const maxAttempts = 50;
4145
- let attempts = 0;
4146
- while (attempts < maxAttempts) {
4147
- this.rootElement = document.querySelector("#root") || document.body;
4148
- if (this.rootElement) {
4149
- break;
4176
+ setupMessageListener() {
4177
+ this.messageListener = (event) => {
4178
+ if (!this.isOriginAllowed(event.origin)) {
4179
+ return;
4150
4180
  }
4151
- await new Promise((resolve) => setTimeout(resolve, 100));
4152
- attempts++;
4153
- }
4154
- if (!this.rootElement) {
4155
- this.rootElement = document.body;
4156
- }
4157
- }
4158
- /**
4159
- * 创建工具提示
4160
- */
4161
- createTooltip() {
4162
- this.tooltip = document.createElement("div");
4163
- this.tooltip.className = "element-selector-tooltip";
4164
- this.tooltip.setAttribute("role", "tooltip");
4165
- this.tooltip.style.display = "none";
4166
- document.body.appendChild(this.tooltip);
4181
+ if (event.data && typeof event.data === "object" && event.data.type) {
4182
+ this.handleMessage(event.data);
4183
+ }
4184
+ };
4185
+ window.addEventListener("message", this.messageListener);
4167
4186
  }
4168
4187
  /**
4169
- * 创建样式
4188
+ * 检查来源是否被允许
4170
4189
  */
4171
- createStyles() {
4172
- this.styleElement = document.createElement("style");
4173
- this.styleElement.id = "element-selector-styles";
4174
- this.styleElement.textContent = this.generateCSS();
4175
- document.head.appendChild(this.styleElement);
4190
+ isOriginAllowed(origin) {
4191
+ return GLOBAL_CONFIG.ALLOWED_ORIGINS.some(
4192
+ (allowedOrigin) => origin.includes(allowedOrigin.replace("https://", "").replace("http://", ""))
4193
+ );
4176
4194
  }
4195
+ /** ----------------- 主要消息处理方法 ----------------- */
4177
4196
  /**
4178
- * 生成 CSS 样式
4197
+ * 处理消息
4179
4198
  */
4180
- generateCSS() {
4181
- return `
4182
- .element-selector-tooltip {
4183
- position: fixed;
4184
- z-index: ${this.config.TOOLTIP_Z_INDEX};
4185
- pointer-events: none;
4186
- background-color: ${this.config.TOOLTIP_BACKGROUND};
4187
- color: ${this.config.TOOLTIP_COLOR};
4188
- padding: ${this.config.TOOLTIP_PADDING};
4189
- border-radius: ${this.config.TOOLTIP_BORDER_RADIUS};
4190
- font-size: ${this.config.TOOLTIP_FONT_SIZE};
4191
- font-weight: bold;
4192
- line-height: 1;
4193
- white-space: nowrap;
4194
- box-shadow: 0 2px 4px rgba(0,0,0,0.2);
4195
- transition: opacity 0.2s ease-in-out;
4196
- margin: 0;
4197
- }
4198
-
4199
- [data-element-hovered] {
4200
- position: relative;
4201
- outline: ${this.config.HIGHLIGHT_BORDER_WIDTH} ${this.config.HIGHLIGHT_BORDER_STYLE} ${this.config.HIGHLIGHT_COLOR} !important;
4202
- outline-offset: 0 !important;
4203
- background-color: ${this.config.HIGHLIGHT_COLOR}20 !important;
4204
- z-index: 9999;
4205
- }
4206
-
4207
- [data-element-selected] {
4208
- position: relative;
4209
- outline: ${this.config.SELECTED_BORDER_WIDTH} ${this.config.HIGHLIGHT_BORDER_STYLE} ${this.config.SELECTED_COLOR} !important;
4210
- outline-offset: 3px !important;
4211
- background-color: ${this.config.SELECTED_COLOR}15 !important;
4212
- z-index: 9999;
4213
- }
4214
-
4215
- [data-element-selected][contenteditable] {
4216
- outline: none !important;
4217
- }
4218
-
4219
- [data-element-hovered][data-full-width],
4220
- [data-element-selected][data-full-width] {
4221
- outline-offset: -5px !important;
4222
- }
4223
-
4224
- .element-selector-active {
4225
- cursor: ${this.config.cursor} !important;
4226
- }
4227
-
4228
- .element-selector-active * {
4229
- cursor: ${this.config.cursor} !important;
4230
- }
4231
-
4232
- /* \u963B\u6B62\u539F\u751F hover \u6548\u679C\u7684\u5168\u5C40\u6837\u5F0F */
4233
- body.element-selector-active * {
4234
- /* \u963B\u6B62\u539F\u751F CSS hover \u4F2A\u7C7B\u6548\u679C */
4235
- transition: none !important;
4236
- }
4237
-
4238
- /* \u963B\u6B62\u6240\u6709 hover \u76F8\u5173\u7684 CSS \u4F2A\u7C7B\uFF0C\u4F46\u6392\u9664\u6211\u4EEC\u7684\u9009\u62E9\u5668\u5143\u7D20 */
4239
- body.element-selector-active *:hover:not([data-element-selected]):not([data-element-hovered]) {
4240
- background-color: inherit !important;
4241
- color: inherit !important;
4242
- border-color: inherit !important;
4243
- box-shadow: inherit !important;
4244
- transform: inherit !important;
4245
- opacity: inherit !important;
4246
- filter: inherit !important;
4247
- }
4248
-
4249
- /* \u786E\u4FDD\u6211\u4EEC\u7684\u9009\u62E9\u5668\u6837\u5F0F\u4F18\u5148\u7EA7\u6700\u9AD8 */
4250
- body.element-selector-active [data-element-selected] {
4251
- background-color: ${this.config.SELECTED_COLOR}15 !important;
4252
- outline: ${this.config.SELECTED_BORDER_WIDTH} ${this.config.HIGHLIGHT_BORDER_STYLE} ${this.config.SELECTED_COLOR} !important;
4253
- }
4254
-
4255
- body.element-selector-active [data-element-hovered] {
4256
- background-color: ${this.config.HIGHLIGHT_COLOR}20 !important;
4257
- outline: ${this.config.HIGHLIGHT_BORDER_WIDTH} ${this.config.HIGHLIGHT_BORDER_STYLE} ${this.config.HIGHLIGHT_COLOR} !important;
4258
- }
4259
-
4260
- /* \u786E\u4FDD\u5DE5\u5177\u63D0\u793A\u4E0D\u53D7\u5F71\u54CD */
4261
- body.element-selector-active .element-selector-tooltip {
4262
- pointer-events: none !important;
4199
+ handleMessage(message) {
4200
+ try {
4201
+ const { type, payload } = message;
4202
+ switch (type) {
4203
+ case "SET_ELEMENT_CONTENT":
4204
+ this.handleSetElementContent(payload);
4205
+ break;
4206
+ case "SET_ELEMENT_ATTRS":
4207
+ this.handleSetElementAttrs(payload);
4208
+ break;
4209
+ case "DUPLICATE_ELEMENT_REQUESTED":
4210
+ this.handleDuplicateElementRequested(payload);
4211
+ break;
4212
+ case "EDIT_TEXT_REQUESTED":
4213
+ this.handleEditTextRequested(payload);
4214
+ break;
4215
+ // 组件树相关消息
4216
+ case "REQUEST_COMPONENT_TREE":
4217
+ this.handleRequestComponentTree();
4218
+ break;
4219
+ case "GET_PARENT_ELEMENT":
4220
+ this.handleGetParentElement(payload);
4221
+ break;
4222
+ // 样式相关消息
4223
+ case "SET_STYLESHEET":
4224
+ this.handleSetStylesheet(payload);
4225
+ break;
4226
+ default:
4227
+ break;
4263
4228
  }
4264
- `;
4229
+ } catch (error) {
4230
+ console.error("[MessageBridge] \u5904\u7406\u6D88\u606F\u5931\u8D25:", error);
4231
+ this.sendMessage({
4232
+ type: "ERROR_EVENT",
4233
+ payload: {
4234
+ type: "message_handling",
4235
+ originalMessage: message,
4236
+ error: error instanceof Error ? error.message : String(error)
4237
+ },
4238
+ timestamp: Date.now()
4239
+ });
4240
+ }
4265
4241
  }
4266
- /** ----------------- 选择器状态管理 ----------------- */
4242
+ /** ----------------- 元素操作消息处理 ----------------- */
4267
4243
  /**
4268
- * 启用选择器
4244
+ * 处理设置元素内容
4269
4245
  */
4270
- enableSelector() {
4271
- if (this.isActive) return;
4272
- this.isActive = true;
4273
- document.body.classList.add("element-selector-active");
4274
- this.setupEventListeners();
4275
- this.manageButtonStates(true);
4276
- console.log("[ElementSelector] \u9009\u62E9\u5668\u5DF2\u542F\u7528");
4246
+ handleSetElementContent(payload) {
4247
+ if (!payload?.selector || !payload?.content) return;
4248
+ const elements = document.querySelectorAll(payload.selector);
4249
+ elements.forEach((element) => {
4250
+ if (element instanceof HTMLElement) {
4251
+ element.innerHTML = payload.content;
4252
+ }
4253
+ });
4277
4254
  this.sendMessage({
4278
- type: "SELECTOR_ENABLED",
4279
- payload: { isActive: true }
4255
+ type: "ELEMENT_EVENT",
4256
+ payload: {
4257
+ type: "content_updated",
4258
+ selector: payload.selector,
4259
+ content: payload.content,
4260
+ elementsUpdated: elements.length
4261
+ },
4262
+ timestamp: Date.now()
4280
4263
  });
4281
4264
  }
4282
4265
  /**
4283
- * 禁用选择器
4266
+ * 处理设置元素属性
4284
4267
  */
4285
- disableSelector() {
4286
- if (!this.isActive) return;
4287
- this.isActive = false;
4288
- document.body.classList.remove("element-selector-active");
4289
- this.removeEventListeners();
4290
- this.clearHighlight();
4291
- this.clearSelection();
4292
- this.manageButtonStates(false);
4293
- this.hideTooltip();
4294
- console.log("[ElementSelector] \u9009\u62E9\u5668\u5DF2\u7981\u7528");
4268
+ handleSetElementAttrs(payload) {
4269
+ if (!payload?.selector || !payload?.attrs) return;
4270
+ const elements = document.querySelectorAll(payload.selector);
4271
+ elements.forEach((element) => {
4272
+ Object.entries(payload.attrs).forEach(([key, value]) => {
4273
+ element.setAttribute(key, String(value));
4274
+ });
4275
+ });
4295
4276
  this.sendMessage({
4296
- type: "SELECTOR_DISABLED",
4297
- payload: { isActive: false }
4277
+ type: "ELEMENT_EVENT",
4278
+ payload: {
4279
+ type: "attrs_updated",
4280
+ selector: payload.selector,
4281
+ attrs: payload.attrs,
4282
+ elementsUpdated: elements.length
4283
+ },
4284
+ timestamp: Date.now()
4298
4285
  });
4299
4286
  }
4300
4287
  /**
4301
- * 切换选择器状态
4288
+ * 处理复制元素请求
4302
4289
  */
4303
- toggleSelector() {
4304
- if (this.isActive) {
4305
- this.disableSelector();
4306
- } else {
4307
- this.enableSelector();
4290
+ handleDuplicateElementRequested(payload) {
4291
+ if (!payload?.selector) return;
4292
+ const element = document.querySelector(payload.selector);
4293
+ if (element && element.parentElement) {
4294
+ const clone = element.cloneNode(true);
4295
+ clone.setAttribute("data-duplicated", "true");
4296
+ element.parentElement.appendChild(clone);
4297
+ this.sendMessage({
4298
+ type: "ELEMENT_EVENT",
4299
+ payload: {
4300
+ type: "duplicated",
4301
+ originalSelector: payload.selector,
4302
+ duplicatedElement: this.getElementInfo(clone)
4303
+ },
4304
+ timestamp: Date.now()
4305
+ });
4308
4306
  }
4309
4307
  }
4310
4308
  /**
4311
- * 获取选择器状态
4312
- */
4313
- getSelectorState() {
4314
- return {
4315
- isActive: this.isActive,
4316
- highlightedElement: this.highlightedElement ? this.getElementInfo(this.highlightedElement) : null,
4317
- selectedElements: this.selectedElements.map((el) => this.getElementInfo(el)),
4318
- config: { ...this.config }
4319
- };
4320
- }
4321
- /** ----------------- 事件监听器管理 ----------------- */
4322
- /**
4323
- * 设置事件监听器
4309
+ * 处理编辑文本请求
4324
4310
  */
4325
- setupEventListeners() {
4326
- this.addEventListenerWithCleanup(document, "mouseover", this.handleMouseOver.bind(this), { passive: true });
4327
- this.addEventListenerWithCleanup(document, "mouseout", this.handleMouseOut.bind(this), { passive: true });
4328
- this.addEventListenerWithCleanup(document, "mousemove", this.trackMousePosition.bind(this), { passive: true });
4329
- this.addEventListenerWithCleanup(document, "click", this.handleClick.bind(this), { capture: true });
4330
- this.addEventListenerWithCleanup(document, "dblclick", this.handleDoubleClick.bind(this), { capture: true });
4331
- this.addEventListenerWithCleanup(window, "scroll", this.handleScroll.bind(this), { passive: true });
4332
- this.addEventListenerWithCleanup(document, "keydown", this.handleKeyDown.bind(this));
4333
- this.addEventListenerWithCleanup(document, "mousedown", this.preventFormInteraction.bind(this), { capture: true });
4334
- this.addEventListenerWithCleanup(document, "submit", this.preventAllInteraction.bind(this), { capture: true });
4335
- this.addEventListenerWithCleanup(document, "touchstart", this.preventAllInteraction.bind(this), { capture: true });
4336
- this.addEventListenerWithCleanup(document, "touchend", this.preventAllInteraction.bind(this), { capture: true });
4311
+ handleEditTextRequested(payload) {
4312
+ if (!payload?.selector) return;
4313
+ const element = document.querySelector(payload.selector);
4314
+ if (element instanceof HTMLElement) {
4315
+ element.setAttribute("contenteditable", "true");
4316
+ element.focus();
4317
+ const handleInput = () => {
4318
+ this.sendMessage({
4319
+ type: "ELEMENT_EVENT",
4320
+ payload: {
4321
+ type: "text_updated",
4322
+ selector: payload.selector,
4323
+ content: element.innerText
4324
+ },
4325
+ timestamp: Date.now()
4326
+ });
4327
+ };
4328
+ const handleBlur = () => {
4329
+ element.removeAttribute("contenteditable");
4330
+ element.removeEventListener("input", handleInput);
4331
+ element.removeEventListener("blur", handleBlur);
4332
+ this.sendMessage({
4333
+ type: "ELEMENT_EVENT",
4334
+ payload: {
4335
+ type: "edit_completed",
4336
+ selector: payload.selector,
4337
+ finalContent: element.innerText
4338
+ },
4339
+ timestamp: Date.now()
4340
+ });
4341
+ };
4342
+ element.addEventListener("input", handleInput);
4343
+ element.addEventListener("blur", handleBlur);
4344
+ }
4337
4345
  }
4346
+ /** ----------------- 组件树相关消息处理 ----------------- */
4338
4347
  /**
4339
- * 添加事件监听器并记录以便清理
4348
+ * 处理请求组件树
4340
4349
  */
4341
- addEventListenerWithCleanup(element, event, handler, options) {
4342
- element.addEventListener(event, handler, options);
4343
- this.eventListeners.push({ element, event, handler, options });
4350
+ handleRequestComponentTree() {
4351
+ if (!this.componentTreeGenerator) return;
4352
+ try {
4353
+ const rootElement = document.querySelector("#root") || document.body;
4354
+ const componentTree = this.componentTreeGenerator.generateComponentTree(rootElement);
4355
+ this.sendMessage({
4356
+ type: "COMPONENT_EVENT",
4357
+ payload: {
4358
+ type: "tree_response",
4359
+ ...componentTree
4360
+ },
4361
+ timestamp: Date.now()
4362
+ });
4363
+ } catch (error) {
4364
+ const originalConsole = getOriginalConsole2();
4365
+ originalConsole.error("[MessageBridge] \u751F\u6210\u7EC4\u4EF6\u6811\u5931\u8D25:", error);
4366
+ this.sendMessage({
4367
+ type: "COMPONENT_EVENT",
4368
+ payload: {
4369
+ type: "tree_error",
4370
+ error: error instanceof Error ? error.message : String(error)
4371
+ },
4372
+ timestamp: Date.now()
4373
+ });
4374
+ }
4344
4375
  }
4345
4376
  /**
4346
- * 移除所有事件监听器
4347
- */
4348
- removeEventListeners() {
4349
- this.eventListeners.forEach(({ element, event, handler }) => {
4350
- element.removeEventListener(event, handler);
4351
- });
4352
- this.eventListeners = [];
4353
- }
4354
- /** ----------------- 事件处理方法 ----------------- */
4355
- /**
4356
- * 跟踪鼠标位置
4357
- */
4358
- trackMousePosition(event) {
4359
- this.mousePosition = { x: event.clientX, y: event.clientY };
4360
- }
4361
- /**
4362
- * 处理鼠标悬停
4363
- */
4364
- handleMouseOver(event) {
4365
- if (!this.isActive) return;
4366
- const target = event.target;
4367
- if (!this.isSelectableElement(target)) return;
4368
- this.highlightElement(target);
4369
- this.updateTooltip(target);
4370
- }
4371
- /**
4372
- * 处理鼠标离开
4373
- */
4374
- handleMouseOut(event) {
4375
- if (!this.isActive) return;
4376
- this.clearHighlight();
4377
- this.hideTooltip();
4378
- }
4379
- /**
4380
- * 处理点击
4381
- */
4382
- handleClick(event) {
4383
- if (!this.isActive) return;
4384
- const currentTimestamp = Date.now();
4385
- const target = event.target;
4386
- if (this.lastClickTarget === target && currentTimestamp - this.lastClickTimestamp < 100) {
4387
- event.preventDefault();
4388
- event.stopPropagation();
4389
- return;
4390
- }
4391
- this.lastClickTimestamp = currentTimestamp;
4392
- this.lastClickTarget = target;
4393
- event.preventDefault();
4394
- event.stopPropagation();
4395
- if (!this.isSelectableElement(target)) return;
4396
- if (event.metaKey || event.ctrlKey) {
4397
- this.toggleElementSelection(target);
4398
- } else {
4399
- this.selectElement(target);
4400
- }
4401
- this.sendMessage({
4402
- type: "ELEMENT_CLICKED",
4403
- payload: {
4404
- element: this.getElementInfo(target),
4405
- isMultiSelect: event.metaKey || event.ctrlKey
4406
- }
4407
- });
4408
- }
4409
- /**
4410
- * 处理双击
4411
- */
4412
- handleDoubleClick(event) {
4413
- if (!this.isActive) return;
4414
- event.preventDefault();
4415
- event.stopPropagation();
4416
- const target = event.target;
4417
- if (!this.isSelectableElement(target)) return;
4418
- this.sendMessage({
4419
- type: "ELEMENT_DOUBLE_CLICKED",
4420
- payload: {
4421
- element: this.getElementInfo(target)
4422
- }
4423
- });
4424
- }
4425
- /**
4426
- * 处理滚动
4427
- */
4428
- handleScroll() {
4429
- if (!this.isActive) return;
4430
- this.hideTooltip();
4431
- }
4432
- /**
4433
- * 处理键盘事件
4434
- */
4435
- handleKeyDown(event) {
4436
- if (!this.isActive) return;
4437
- const keyboardEvent = event;
4438
- if (keyboardEvent.key === "Escape") {
4439
- event.preventDefault();
4440
- event.stopPropagation();
4441
- this.disableSelector();
4442
- }
4443
- }
4444
- /**
4445
- * 阻止表单交互
4446
- */
4447
- preventFormInteraction(event) {
4448
- if (!this.isActive) return;
4449
- const target = event.target;
4450
- if (["input", "textarea", "select"].includes(target.tagName.toLowerCase())) {
4451
- event.preventDefault();
4452
- }
4453
- }
4454
- /**
4455
- * 阻止所有交互
4456
- */
4457
- preventAllInteraction(event) {
4458
- if (this.isActive) {
4459
- event.preventDefault();
4460
- event.stopPropagation();
4461
- return false;
4462
- }
4463
- }
4464
- /** ----------------- 元素操作方法 ----------------- */
4465
- /**
4466
- * 高亮元素
4467
- */
4468
- highlightElement(element) {
4469
- this.clearHighlight();
4470
- this.highlightedElement = element;
4471
- element.setAttribute("data-element-hovered", "true");
4472
- if (this.isFullWidthElement(element)) {
4473
- element.setAttribute("data-full-width", "true");
4474
- }
4475
- }
4476
- /**
4477
- * 清除高亮
4478
- */
4479
- clearHighlight() {
4480
- if (this.highlightedElement) {
4481
- this.highlightedElement.removeAttribute("data-element-hovered");
4482
- this.highlightedElement.removeAttribute("data-full-width");
4483
- this.highlightedElement = null;
4484
- }
4485
- }
4486
- /**
4487
- * 选择元素
4488
- */
4489
- selectElement(element) {
4490
- this.clearSelection();
4491
- this.selectedElements = [element];
4492
- element.setAttribute("data-element-selected", "true");
4493
- if (this.isFullWidthElement(element)) {
4494
- element.setAttribute("data-full-width", "true");
4495
- }
4496
- }
4497
- /**
4498
- * 切换元素选择状态
4499
- */
4500
- toggleElementSelection(element) {
4501
- const index = this.selectedElements.indexOf(element);
4502
- if (index > -1) {
4503
- this.selectedElements.splice(index, 1);
4504
- element.removeAttribute("data-element-selected");
4505
- element.removeAttribute("data-full-width");
4506
- } else {
4507
- this.selectedElements.push(element);
4508
- element.setAttribute("data-element-selected", "true");
4509
- if (this.isFullWidthElement(element)) {
4510
- element.setAttribute("data-full-width", "true");
4511
- }
4512
- }
4513
- }
4514
- /**
4515
- * 清除选择
4516
- */
4517
- clearSelection() {
4518
- this.selectedElements.forEach((element) => {
4519
- element.removeAttribute("data-element-selected");
4520
- element.removeAttribute("data-full-width");
4521
- });
4522
- this.selectedElements = [];
4523
- }
4524
- /** ----------------- 工具提示管理 ----------------- */
4525
- /**
4526
- * 更新工具提示
4527
- */
4528
- updateTooltip(element) {
4529
- if (!this.tooltip) return;
4530
- const rect = element.getBoundingClientRect();
4531
- const tagName = element.tagName.toLowerCase();
4532
- this.tooltip.textContent = tagName;
4533
- this.tooltip.style.display = "block";
4534
- const isFullWidth = this.isFullWidthElement(element);
4535
- if (isFullWidth) {
4536
- this.tooltip.style.left = this.config.FULL_WIDTH_TOOLTIP_OFFSET + "px";
4537
- this.tooltip.style.top = this.config.FULL_WIDTH_TOOLTIP_OFFSET + "px";
4538
- } else {
4539
- const top = Math.max(0, rect.top - 30);
4540
- this.tooltip.style.left = `${Math.max(0, rect.left)}px`;
4541
- this.tooltip.style.top = `${top}px`;
4542
- }
4543
- }
4544
- /**
4545
- * 隐藏工具提示
4546
- */
4547
- hideTooltip() {
4548
- if (this.tooltip) {
4549
- this.tooltip.style.display = "none";
4550
- }
4551
- }
4552
- /** ----------------- 按钮状态管理 ----------------- */
4553
- /**
4554
- * 管理按钮状态
4555
- */
4556
- manageButtonStates(enable) {
4557
- if (!this.rootElement) return;
4558
- const buttons = this.rootElement.querySelectorAll('button, input[type="button"], input[type="submit"]');
4559
- if (enable) {
4560
- buttons.forEach((button) => {
4561
- const btn = button;
4562
- if (!btn.disabled) {
4563
- btn.disabled = true;
4564
- btn.setAttribute("data-selector-disabled", "true");
4565
- }
4566
- });
4567
- } else {
4568
- buttons.forEach((button) => {
4569
- const btn = button;
4570
- if (btn.hasAttribute("data-selector-disabled")) {
4571
- btn.disabled = false;
4572
- btn.removeAttribute("data-selector-disabled");
4573
- }
4574
- });
4575
- }
4576
- }
4577
- /** ----------------- 新增的精确代码位置定位方法 ----------------- */
4578
- /**
4579
- * 检查元素是否有 howone ID
4580
- */
4581
- hasHowoneId(element) {
4582
- return element.hasAttribute("data-howone-id");
4583
- }
4584
- /**
4585
- * 解析 howone ID
4586
- */
4587
- parseHowoneId(element) {
4588
- const howoneId = element.getAttribute("data-howone-id");
4589
- if (!howoneId) return null;
4590
- try {
4591
- if (howoneId.includes(":")) {
4592
- const parts = howoneId.split(":");
4593
- if (parts.length >= 2) {
4594
- return {
4595
- filePath: parts[0],
4596
- lineNumber: parseInt(parts[1], 10),
4597
- col: parts[2] ? parseInt(parts[2], 10) : 0
4598
- };
4599
- }
4600
- } else {
4601
- const parsed = JSON.parse(howoneId);
4602
- if (parsed.filePath && parsed.lineNumber) {
4603
- return {
4604
- filePath: parsed.filePath,
4605
- lineNumber: parsed.lineNumber,
4606
- col: parsed.col || 0
4607
- };
4608
- }
4609
- }
4610
- } catch (error) {
4611
- console.warn("[ElementSelector] \u89E3\u6790 data-howone-id \u5931\u8D25:", error);
4612
- }
4613
- return null;
4614
- }
4615
- /**
4616
- * 获取元素的代码位置
4617
- */
4618
- getElementLocation(element) {
4619
- return this.parseHowoneId(element);
4620
- }
4621
- /**
4622
- * 提取元素数据(包含位置信息)
4623
- */
4624
- extractElementData(element) {
4625
- const location = this.getElementLocation(element);
4626
- return {
4627
- id: element.id || void 0,
4628
- className: element.className || void 0,
4629
- textContent: element.textContent?.trim().substring(0, 100) || void 0,
4630
- filePath: location?.filePath,
4631
- lineNumber: location?.lineNumber,
4632
- col: location?.col,
4633
- elementType: element.tagName.toLowerCase(),
4634
- attrs: this.getElementAttributes(element)
4635
- };
4636
- }
4637
- /**
4638
- * 根据代码位置查找元素
4639
- */
4640
- findElementsByLocation(filePath, lineNumber) {
4641
- const elements = [];
4642
- const elementsWithHowoneId = this.rootElement?.querySelectorAll("[data-howone-id]") || [];
4643
- elementsWithHowoneId.forEach((element) => {
4644
- const location = this.getElementLocation(element);
4645
- if (location && location.filePath === filePath && location.lineNumber === lineNumber) {
4646
- elements.push(element);
4647
- }
4648
- });
4649
- return elements;
4650
- }
4651
- /**
4652
- * 获取指定坐标位置的元素
4653
- */
4654
- getElementAtPoint(x, y) {
4655
- const originalDisplay = this.tooltip?.style.display;
4656
- if (this.tooltip) {
4657
- this.tooltip.style.display = "none";
4658
- }
4659
- const element = document.elementFromPoint(x, y);
4660
- if (this.tooltip && originalDisplay) {
4661
- this.tooltip.style.display = originalDisplay;
4662
- }
4663
- return element;
4664
- }
4665
- /** ----------------- 元素编辑功能 ----------------- */
4666
- /**
4667
- * 设置元素内容
4668
- */
4669
- setElementContent(selector, content) {
4670
- try {
4671
- const element = document.querySelector(selector);
4672
- if (!element) return false;
4673
- if (element.tagName.toLowerCase() === "input" || element.tagName.toLowerCase() === "textarea") {
4674
- element.value = content;
4675
- } else {
4676
- element.textContent = content;
4677
- }
4678
- this.sendMessage({
4679
- type: "ELEMENT_CONTENT_UPDATED",
4680
- payload: {
4681
- selector,
4682
- content,
4683
- element: this.getElementInfo(element)
4684
- }
4685
- });
4686
- return true;
4687
- } catch (error) {
4688
- console.error("[ElementSelector] \u8BBE\u7F6E\u5143\u7D20\u5185\u5BB9\u5931\u8D25:", error);
4689
- return false;
4690
- }
4691
- }
4692
- /**
4693
- * 设置元素属性
4694
- */
4695
- setElementAttributes(selector, attributes) {
4696
- try {
4697
- const element = document.querySelector(selector);
4698
- if (!element) return false;
4699
- Object.entries(attributes).forEach(([key, value]) => {
4700
- if (value === null || value === void 0) {
4701
- element.removeAttribute(key);
4702
- } else {
4703
- element.setAttribute(key, value);
4704
- }
4705
- });
4706
- this.sendMessage({
4707
- type: "ELEMENT_ATTRIBUTES_UPDATED",
4708
- payload: {
4709
- selector,
4710
- attributes,
4711
- element: this.getElementInfo(element)
4712
- }
4713
- });
4714
- return true;
4715
- } catch (error) {
4716
- console.error("[ElementSelector] \u8BBE\u7F6E\u5143\u7D20\u5C5E\u6027\u5931\u8D25:", error);
4717
- return false;
4718
- }
4719
- }
4720
- /**
4721
- * 复制元素
4722
- */
4723
- duplicateElement(selector) {
4724
- try {
4725
- const element = document.querySelector(selector);
4726
- if (!element || !element.parentNode) return false;
4727
- const clonedElement = element.cloneNode(true);
4728
- clonedElement.removeAttribute("data-blnk-id");
4729
- element.parentNode.insertBefore(clonedElement, element.nextSibling);
4730
- this.sendMessage({
4731
- type: "ELEMENT_DUPLICATED",
4732
- payload: {
4733
- originalSelector: selector,
4734
- duplicatedElement: this.getElementInfo(clonedElement)
4735
- }
4736
- });
4737
- return true;
4738
- } catch (error) {
4739
- console.error("[ElementSelector] \u590D\u5236\u5143\u7D20\u5931\u8D25:", error);
4740
- return false;
4741
- }
4742
- }
4743
- /**
4744
- * 启用文本编辑
4745
- */
4746
- enableTextEditing(selector) {
4747
- try {
4748
- const element = document.querySelector(selector);
4749
- if (!element) return false;
4750
- element.setAttribute("contenteditable", "true");
4751
- element.setAttribute("data-editing", "true");
4752
- element.focus();
4753
- const handleEditComplete = () => {
4754
- element.removeAttribute("contenteditable");
4755
- element.removeAttribute("data-editing");
4756
- element.removeEventListener("blur", handleEditComplete);
4757
- element.removeEventListener("keydown", handleKeyDown);
4758
- this.sendMessage({
4759
- type: "ELEMENT_TEXT_UPDATED",
4760
- payload: {
4761
- selector,
4762
- content: element.textContent || "",
4763
- element: this.getElementInfo(element)
4764
- }
4765
- });
4766
- };
4767
- const handleKeyDown = (event) => {
4768
- const keyboardEvent = event;
4769
- if (keyboardEvent.key === "Enter" && !keyboardEvent.shiftKey) {
4770
- event.preventDefault();
4771
- handleEditComplete();
4772
- } else if (keyboardEvent.key === "Escape") {
4773
- event.preventDefault();
4774
- handleEditComplete();
4775
- }
4776
- };
4777
- element.addEventListener("blur", handleEditComplete);
4778
- element.addEventListener("keydown", handleKeyDown);
4779
- return true;
4780
- } catch (error) {
4781
- console.error("[ElementSelector] \u542F\u7528\u6587\u672C\u7F16\u8F91\u5931\u8D25:", error);
4782
- return false;
4783
- }
4784
- }
4785
- /** ----------------- 高级交互功能 ----------------- */
4786
- /**
4787
- * 获取父元素
4788
- */
4789
- getParentElement(selector) {
4790
- try {
4791
- const element = document.querySelector(selector);
4792
- return element?.parentElement || null;
4793
- } catch (error) {
4794
- console.error("[ElementSelector] \u83B7\u53D6\u7236\u5143\u7D20\u5931\u8D25:", error);
4795
- return null;
4796
- }
4797
- }
4798
- /**
4799
- * 外部悬停控制 - 通过选择器悬停元素
4800
- */
4801
- hoverElementBySelector(selector) {
4802
- try {
4803
- const element = document.querySelector(selector);
4804
- if (!element) return false;
4805
- this.highlightElement(element);
4806
- this.updateTooltip(element);
4807
- return true;
4808
- } catch (error) {
4809
- console.error("[ElementSelector] \u5916\u90E8\u60AC\u505C\u63A7\u5236\u5931\u8D25:", error);
4810
- return false;
4811
- }
4812
- }
4813
- /**
4814
- * 外部悬停控制 - 取消悬停
4815
- */
4816
- unhoverElement() {
4817
- this.clearHighlight();
4818
- this.hideTooltip();
4819
- }
4820
- /** ----------------- 辅助方法 ----------------- */
4821
- /**
4822
- * 检查元素是否为全宽元素
4823
- */
4824
- isFullWidthElement(element) {
4825
- try {
4826
- const rect = element.getBoundingClientRect();
4827
- return Math.abs(rect.width - window.innerWidth) < 5;
4828
- } catch (error) {
4829
- console.warn("[ElementSelector] \u68C0\u67E5\u5168\u5BBD\u5143\u7D20\u5931\u8D25:", error);
4830
- return false;
4831
- }
4832
- }
4833
- /**
4834
- * 检查元素是否可选择
4835
- */
4836
- isSelectableElement(element) {
4837
- if (!element || element === document.body || element === document.documentElement) {
4838
- return false;
4839
- }
4840
- if (this.hasHowoneId(element)) {
4841
- return true;
4842
- }
4843
- if (element.id === "howone-element-tooltip" || element.classList.contains("howone-tooltip")) {
4844
- return false;
4845
- }
4846
- const tagName = element.tagName.toLowerCase();
4847
- if (["script", "style", "meta", "link", "title"].includes(tagName)) {
4848
- return false;
4849
- }
4850
- return true;
4851
- }
4852
- /**
4853
- * 获取元素信息
4854
- */
4855
- getElementInfo(element) {
4856
- const location = this.getElementLocation(element);
4857
- return {
4858
- tagName: element.tagName.toLowerCase(),
4859
- id: element.id || void 0,
4860
- className: element.className || void 0,
4861
- textContent: element.textContent?.trim().substring(0, 100) || void 0,
4862
- attributes: this.getElementAttributes(element),
4863
- selector: this.getElementSelector(element),
4864
- boundingRect: element.getBoundingClientRect(),
4865
- location: location || void 0
4866
- };
4867
- }
4868
- /**
4869
- * 获取元素属性
4870
- */
4871
- getElementAttributes(element) {
4872
- const attrs = {};
4873
- const importantAttrs = ["id", "class", "data-testid", "data-howone-id", "data-component-path", "data-blnk-id", "href", "src", "type", "name"];
4874
- importantAttrs.forEach((attr) => {
4875
- const value = element.getAttribute(attr);
4876
- if (value) {
4877
- attrs[attr] = value;
4878
- }
4879
- });
4880
- return attrs;
4881
- }
4882
- /**
4883
- * 获取元素选择器
4884
- */
4885
- getElementSelector(element) {
4886
- const howoneId = element.getAttribute("data-howone-id");
4887
- if (howoneId) {
4888
- return `[data-howone-id="${howoneId}"]`;
4889
- }
4890
- if (element.id) {
4891
- return `#${element.id}`;
4892
- }
4893
- const dataTestId = element.getAttribute("data-testid");
4894
- if (dataTestId) {
4895
- return `[data-testid="${dataTestId}"]`;
4896
- }
4897
- if (element.className) {
4898
- const classes = element.className.split(" ").filter((c) => c.trim());
4899
- if (classes.length > 0) {
4900
- return `.${classes[0]}`;
4901
- }
4902
- }
4903
- return element.tagName.toLowerCase();
4904
- }
4905
- /** ----------------- 公共接口方法 ----------------- */
4906
- /**
4907
- * 通过选择器高亮元素
4908
- */
4909
- highlightElementBySelector(selector) {
4910
- const element = document.querySelector(selector);
4911
- if (element) {
4912
- this.highlightElement(element);
4913
- }
4914
- }
4915
- /**
4916
- * 通过选择器取消高亮元素
4917
- */
4918
- unhighlightElementBySelector(selector) {
4919
- const element = document.querySelector(selector);
4920
- if (element && element === this.highlightedElement) {
4921
- this.clearHighlight();
4922
- }
4923
- }
4924
- /**
4925
- * 更新选中的元素
4926
- */
4927
- updateSelectedElements(elements) {
4928
- this.clearSelection();
4929
- elements.forEach((elementData) => {
4930
- const element = this.findElementByData(elementData);
4931
- if (element) {
4932
- this.selectedElements.push(element);
4933
- element.setAttribute("data-element-selected", "true");
4934
- if (this.isFullWidthElement(element)) {
4935
- element.setAttribute("data-full-width", "true");
4936
- }
4937
- }
4938
- });
4939
- }
4940
- /**
4941
- * 根据数据查找元素
4942
- */
4943
- findElementByData(elementData) {
4944
- if (elementData.blinkId) {
4945
- return document.querySelector(`[data-blnk-id="${elementData.blinkId}"]`);
4946
- }
4947
- if (elementData.id) {
4948
- return document.getElementById(elementData.id);
4949
- }
4950
- if (elementData.selector) {
4951
- return document.querySelector(elementData.selector);
4952
- }
4953
- return null;
4954
- }
4955
- /**
4956
- * 销毁选择器
4957
- */
4958
- destroy() {
4959
- this.disableSelector();
4960
- if (this.tooltip) {
4961
- this.tooltip.remove();
4962
- this.tooltip = null;
4963
- }
4964
- if (this.styleElement) {
4965
- this.styleElement.remove();
4966
- this.styleElement = null;
4967
- }
4968
- console.log("[ElementSelector] \u5143\u7D20\u9009\u62E9\u5668\u5DF2\u9500\u6BC1");
4969
- }
4970
- };
4971
-
4972
- // src/utils/unified-error-handler/features/MessageBridge.ts
4973
- var getOriginalConsole2 = () => window.__originalConsole || {
4974
- log: console.log.bind(console),
4975
- warn: console.warn.bind(console),
4976
- error: console.error.bind(console),
4977
- info: console.info.bind(console),
4978
- debug: console.debug.bind(console)
4979
- };
4980
- var MessageBridge = class {
4981
- constructor(sendMessage) {
4982
- this.elementSelector = null;
4983
- this.componentTreeGenerator = null;
4984
- this.messageSender = createDefaultMessageSender({
4985
- addTimestamp: true,
4986
- enableDebugLog: false
4987
- });
4988
- this.sendMessage = sendMessage || this.messageSender.createSendFunction();
4989
- this.setupMessageListener();
4990
- console.log("[MessageBridge] \u6D88\u606F\u6865\u63A5\u5668\u521D\u59CB\u5316\u5B8C\u6210");
4991
- }
4992
- /** ----------------- 依赖注入方法 ----------------- */
4993
- /**
4994
- * 设置元素选择器
4995
- */
4996
- setElementSelector(elementSelector2) {
4997
- this.elementSelector = elementSelector2;
4998
- }
4999
- /**
5000
- * 设置组件树生成器
5001
- */
5002
- setComponentTreeGenerator(componentTreeGenerator) {
5003
- this.componentTreeGenerator = componentTreeGenerator;
5004
- }
5005
- /** ----------------- 消息监听设置 ----------------- */
5006
- /**
5007
- * 设置消息监听器
5008
- */
5009
- setupMessageListener() {
5010
- this.messageListener = (event) => {
5011
- if (!this.isOriginAllowed(event.origin)) {
5012
- return;
5013
- }
5014
- if (event.data && typeof event.data === "object" && event.data.type) {
5015
- this.handleMessage(event.data);
5016
- }
5017
- };
5018
- window.addEventListener("message", this.messageListener);
5019
- }
5020
- /**
5021
- * 检查来源是否被允许
5022
- */
5023
- isOriginAllowed(origin) {
5024
- return GLOBAL_CONFIG.ALLOWED_ORIGINS.some(
5025
- (allowedOrigin) => origin.includes(allowedOrigin.replace("https://", "").replace("http://", ""))
5026
- );
5027
- }
5028
- /** ----------------- 主要消息处理方法 ----------------- */
5029
- /**
5030
- * 处理消息
5031
- */
5032
- handleMessage(message) {
5033
- try {
5034
- const { type, payload } = message;
5035
- switch (type) {
5036
- // 选择器相关消息
5037
- case "TOGGLE_SELECTOR":
5038
- this.handleToggleSelector(payload);
5039
- break;
5040
- case "ENABLE_SELECTOR":
5041
- this.handleEnableElementSelector();
5042
- break;
5043
- case "DISABLE_SELECTOR":
5044
- this.handleDisableElementSelector();
5045
- break;
5046
- case "GET_SELECTOR_STATE":
5047
- this.handleGetSelectorState();
5048
- break;
5049
- // 元素操作消息
5050
- case "HOVER_ELEMENT_BY_ID":
5051
- this.handleHoverElementById(payload);
5052
- break;
5053
- case "UNHOVER_ELEMENT_BY_ID":
5054
- this.handleUnhoverElementById(payload);
5055
- break;
5056
- case "HOVER_ELEMENT_REQUESTED":
5057
- this.handleHoverElementRequested(payload);
5058
- break;
5059
- case "UNHOVER_ELEMENT_REQUESTED":
5060
- this.handleUnhoverElementRequested(payload);
5061
- break;
5062
- case "SET_ELEMENT_CONTENT":
5063
- this.handleSetElementContent(payload);
5064
- break;
5065
- case "SET_ELEMENT_ATTRS":
5066
- this.handleSetElementAttrs(payload);
5067
- break;
5068
- case "DUPLICATE_ELEMENT_REQUESTED":
5069
- this.handleDuplicateElementRequested(payload);
5070
- break;
5071
- case "EDIT_TEXT_REQUESTED":
5072
- this.handleEditTextRequested(payload);
5073
- break;
5074
- case "UPDATE_SELECTED_ELEMENTS":
5075
- this.handleUpdateSelectedElements(payload);
5076
- break;
5077
- // 新增的消息类型
5078
- case "GET_ELEMENT_AT_POINT":
5079
- this.handleGetElementAtPoint(payload);
5080
- break;
5081
- case "FIND_ELEMENTS_BY_LOCATION":
5082
- this.handleFindElementsByLocation(payload);
5083
- break;
5084
- case "SET_ELEMENT_ATTRIBUTES":
5085
- this.handleSetElementAttributes(payload);
5086
- break;
5087
- case "ENABLE_TEXT_EDITING":
5088
- this.handleEnableTextEditing(payload);
5089
- break;
5090
- case "HOVER_ELEMENT_BY_SELECTOR":
5091
- this.handleHoverElementBySelector(payload);
5092
- break;
5093
- case "UNHOVER_ELEMENT":
5094
- this.handleUnhoverElement();
5095
- break;
5096
- // 组件树相关消息
5097
- case "REQUEST_COMPONENT_TREE":
5098
- this.handleRequestComponentTree();
5099
- break;
5100
- case "GET_PARENT_ELEMENT":
5101
- this.handleGetParentElement(payload);
5102
- break;
5103
- // 样式相关消息
5104
- case "SET_STYLESHEET":
5105
- this.handleSetStylesheet(payload);
5106
- break;
5107
- default:
5108
- break;
5109
- }
5110
- } catch (error) {
5111
- console.error("[MessageBridge] \u5904\u7406\u6D88\u606F\u5931\u8D25:", error);
5112
- this.sendMessage({
5113
- type: "ERROR_EVENT",
5114
- payload: {
5115
- type: "message_handling",
5116
- originalMessage: message,
5117
- error: error instanceof Error ? error.message : String(error)
5118
- },
5119
- timestamp: Date.now()
5120
- });
5121
- }
5122
- }
5123
- /** ----------------- 选择器相关消息处理 ----------------- */
5124
- /**
5125
- * 处理切换选择器
5126
- */
5127
- handleToggleSelector(payload) {
5128
- if (!this.elementSelector) return;
5129
- const shouldActivate = !!payload;
5130
- if (shouldActivate) {
5131
- this.elementSelector.enableSelector();
5132
- } else {
5133
- this.elementSelector.disableSelector();
5134
- }
5135
- }
5136
- /**
5137
- * 处理获取选择器状态
5138
- */
5139
- handleGetSelectorState() {
5140
- if (!this.elementSelector) return;
5141
- const state = this.elementSelector.getSelectorState();
5142
- this.sendMessage({
5143
- type: "SELECTOR_EVENT",
5144
- payload: {
5145
- type: "state_response",
5146
- ...state
5147
- },
5148
- timestamp: Date.now()
5149
- });
5150
- }
5151
- /**
5152
- * 处理启用元素选择器
5153
- */
5154
- handleEnableElementSelector() {
5155
- if (!this.elementSelector) return;
5156
- this.elementSelector.enableSelector();
5157
- }
5158
- /**
5159
- * 处理禁用元素选择器
5160
- */
5161
- handleDisableElementSelector() {
5162
- if (!this.elementSelector) return;
5163
- this.elementSelector.disableSelector();
5164
- }
5165
- /** ----------------- 元素操作消息处理 ----------------- */
5166
- /**
5167
- * 处理通过 ID 高亮元素
5168
- */
5169
- handleHoverElementById(payload) {
5170
- if (!this.elementSelector || !payload?.id) return;
5171
- const selector = `#${payload.id}`;
5172
- this.elementSelector.highlightElementBySelector(selector);
5173
- }
5174
- /**
5175
- * 处理通过 ID 取消高亮元素
5176
- */
5177
- handleUnhoverElementById(payload) {
5178
- if (!this.elementSelector || !payload?.id) return;
5179
- const selector = `#${payload.id}`;
5180
- this.elementSelector.unhighlightElementBySelector(selector);
5181
- }
5182
- /**
5183
- * 处理高亮元素请求
5184
- */
5185
- handleHoverElementRequested(payload) {
5186
- if (!this.elementSelector || !payload?.selector) return;
5187
- this.elementSelector.highlightElementBySelector(payload.selector);
5188
- }
5189
- /**
5190
- * 处理取消高亮元素请求
5191
- */
5192
- handleUnhoverElementRequested(payload) {
5193
- if (!this.elementSelector || !payload?.selector) return;
5194
- this.elementSelector.unhighlightElementBySelector(payload.selector);
5195
- }
5196
- /**
5197
- * 处理设置元素内容
5198
- */
5199
- handleSetElementContent(payload) {
5200
- if (!payload?.selector || !payload?.content) return;
5201
- const elements = document.querySelectorAll(payload.selector);
5202
- elements.forEach((element) => {
5203
- if (element instanceof HTMLElement) {
5204
- element.innerHTML = payload.content;
5205
- }
5206
- });
5207
- this.sendMessage({
5208
- type: "ELEMENT_EVENT",
5209
- payload: {
5210
- type: "content_updated",
5211
- selector: payload.selector,
5212
- content: payload.content,
5213
- elementsUpdated: elements.length
5214
- },
5215
- timestamp: Date.now()
5216
- });
5217
- }
5218
- /**
5219
- * 处理设置元素属性
5220
- */
5221
- handleSetElementAttrs(payload) {
5222
- if (!payload?.selector || !payload?.attrs) return;
5223
- const elements = document.querySelectorAll(payload.selector);
5224
- elements.forEach((element) => {
5225
- Object.entries(payload.attrs).forEach(([key, value]) => {
5226
- element.setAttribute(key, String(value));
5227
- });
5228
- });
5229
- this.sendMessage({
5230
- type: "ELEMENT_EVENT",
5231
- payload: {
5232
- type: "attrs_updated",
5233
- selector: payload.selector,
5234
- attrs: payload.attrs,
5235
- elementsUpdated: elements.length
5236
- },
5237
- timestamp: Date.now()
5238
- });
5239
- }
5240
- /**
5241
- * 处理复制元素请求
5242
- */
5243
- handleDuplicateElementRequested(payload) {
5244
- if (!payload?.selector) return;
5245
- const element = document.querySelector(payload.selector);
5246
- if (element && element.parentElement) {
5247
- const clone = element.cloneNode(true);
5248
- clone.setAttribute("data-duplicated", "true");
5249
- element.parentElement.appendChild(clone);
5250
- this.sendMessage({
5251
- type: "ELEMENT_EVENT",
5252
- payload: {
5253
- type: "duplicated",
5254
- originalSelector: payload.selector,
5255
- duplicatedElement: this.getElementInfo(clone)
5256
- },
5257
- timestamp: Date.now()
5258
- });
5259
- }
5260
- }
5261
- /**
5262
- * 处理编辑文本请求
5263
- */
5264
- handleEditTextRequested(payload) {
5265
- if (!payload?.selector) return;
5266
- const element = document.querySelector(payload.selector);
5267
- if (element instanceof HTMLElement) {
5268
- element.setAttribute("contenteditable", "true");
5269
- element.focus();
5270
- const handleInput = () => {
5271
- this.sendMessage({
5272
- type: "ELEMENT_EVENT",
5273
- payload: {
5274
- type: "text_updated",
5275
- selector: payload.selector,
5276
- content: element.innerText
5277
- },
5278
- timestamp: Date.now()
5279
- });
5280
- };
5281
- const handleBlur = () => {
5282
- element.removeAttribute("contenteditable");
5283
- element.removeEventListener("input", handleInput);
5284
- element.removeEventListener("blur", handleBlur);
5285
- this.sendMessage({
5286
- type: "ELEMENT_EVENT",
5287
- payload: {
5288
- type: "edit_completed",
5289
- selector: payload.selector,
5290
- finalContent: element.innerText
5291
- },
5292
- timestamp: Date.now()
5293
- });
5294
- };
5295
- element.addEventListener("input", handleInput);
5296
- element.addEventListener("blur", handleBlur);
5297
- }
5298
- }
5299
- /**
5300
- * 处理更新选中元素
5301
- */
5302
- handleUpdateSelectedElements(payload) {
5303
- if (!this.elementSelector || !Array.isArray(payload)) return;
5304
- this.elementSelector.updateSelectedElements(payload);
5305
- this.sendMessage({
5306
- type: "ELEMENT_EVENT",
5307
- payload: {
5308
- type: "selected_elements_updated",
5309
- selectedElements: payload,
5310
- count: payload.length
5311
- },
5312
- timestamp: Date.now()
5313
- });
5314
- }
5315
- /** ----------------- 组件树相关消息处理 ----------------- */
5316
- /**
5317
- * 处理请求组件树
5318
- */
5319
- handleRequestComponentTree() {
5320
- if (!this.componentTreeGenerator) return;
5321
- try {
5322
- const rootElement = document.querySelector("#root") || document.body;
5323
- const componentTree = this.componentTreeGenerator.generateComponentTree(rootElement);
5324
- this.sendMessage({
5325
- type: "COMPONENT_EVENT",
5326
- payload: {
5327
- type: "tree_response",
5328
- ...componentTree
5329
- },
5330
- timestamp: Date.now()
5331
- });
5332
- } catch (error) {
5333
- const originalConsole = getOriginalConsole2();
5334
- originalConsole.error("[MessageBridge] \u751F\u6210\u7EC4\u4EF6\u6811\u5931\u8D25:", error);
5335
- this.sendMessage({
5336
- type: "COMPONENT_EVENT",
5337
- payload: {
5338
- type: "tree_error",
5339
- error: error instanceof Error ? error.message : String(error)
5340
- },
5341
- timestamp: Date.now()
5342
- });
5343
- }
5344
- }
5345
- /**
5346
- * 处理获取父元素
4377
+ * 处理获取父元素
5347
4378
  */
5348
4379
  handleGetParentElement(payload) {
5349
4380
  if (!payload?.selector) return;
@@ -5435,11 +4466,9 @@ var MessageBridge = class {
5435
4466
  if (dataTestId) return `[data-testid="${dataTestId}"]`;
5436
4467
  const dataHowoneId = element.getAttribute("data-howone-id");
5437
4468
  if (dataHowoneId) return `[data-howone-id="${dataHowoneId}"]`;
5438
- if (element.className) {
5439
- const classes = element.className.split(" ").filter((c) => c.trim());
5440
- if (classes.length > 0) {
5441
- return `.${classes[0]}`;
5442
- }
4469
+ const classes = getElementClasses(element);
4470
+ if (classes.length > 0) {
4471
+ return `.${classes[0]}`;
5443
4472
  }
5444
4473
  return element.tagName.toLowerCase();
5445
4474
  }
@@ -5467,106 +4496,6 @@ var MessageBridge = class {
5467
4496
  timestamp: Date.now()
5468
4497
  });
5469
4498
  }
5470
- /** ----------------- 新增的消息处理方法 ----------------- */
5471
- /**
5472
- * 处理获取鼠标位置的元素
5473
- */
5474
- handleGetElementAtPoint(payload) {
5475
- if (!this.elementSelector) return;
5476
- const element = this.elementSelector.getElementAtPoint(payload?.x, payload?.y);
5477
- this.sendMessage({
5478
- type: "ELEMENT_EVENT",
5479
- payload: {
5480
- type: "at_point_response",
5481
- element: element ? this.getElementInfo(element) : null,
5482
- coordinates: { x: payload?.x, y: payload?.y }
5483
- },
5484
- timestamp: Date.now()
5485
- });
5486
- }
5487
- /**
5488
- * 处理根据位置查找元素
5489
- */
5490
- handleFindElementsByLocation(payload) {
5491
- if (!this.elementSelector || !payload?.filePath || !payload?.lineNumber) return;
5492
- const elements = this.elementSelector.findElementsByLocation(payload.filePath, payload.lineNumber);
5493
- this.sendMessage({
5494
- type: "ELEMENT_EVENT",
5495
- payload: {
5496
- type: "elements_by_location_response",
5497
- elements: elements.map((el) => this.getElementInfo(el)),
5498
- location: {
5499
- filePath: payload.filePath,
5500
- lineNumber: payload.lineNumber
5501
- }
5502
- },
5503
- timestamp: Date.now()
5504
- });
5505
- }
5506
- /**
5507
- * 处理设置元素属性(新版本)
5508
- */
5509
- handleSetElementAttributes(payload) {
5510
- if (!this.elementSelector || !payload?.selector || !payload?.attributes) return;
5511
- const success = this.elementSelector.setElementAttributes(payload.selector, payload.attributes);
5512
- this.sendMessage({
5513
- type: "ELEMENT_EVENT",
5514
- payload: {
5515
- type: "attributes_set_response",
5516
- success,
5517
- selector: payload.selector,
5518
- attributes: payload.attributes
5519
- },
5520
- timestamp: Date.now()
5521
- });
5522
- }
5523
- /**
5524
- * 处理启用文本编辑
5525
- */
5526
- handleEnableTextEditing(payload) {
5527
- if (!this.elementSelector || !payload?.selector) return;
5528
- const success = this.elementSelector.enableTextEditing(payload.selector);
5529
- this.sendMessage({
5530
- type: "ELEMENT_EVENT",
5531
- payload: {
5532
- type: "text_editing_enabled_response",
5533
- success,
5534
- selector: payload.selector
5535
- },
5536
- timestamp: Date.now()
5537
- });
5538
- }
5539
- /**
5540
- * 处理通过选择器悬停元素
5541
- */
5542
- handleHoverElementBySelector(payload) {
5543
- if (!this.elementSelector || !payload?.selector) return;
5544
- const success = this.elementSelector.hoverElementBySelector(payload.selector);
5545
- this.sendMessage({
5546
- type: "ELEMENT_EVENT",
5547
- payload: {
5548
- type: "hovered_by_selector_response",
5549
- success,
5550
- selector: payload.selector
5551
- },
5552
- timestamp: Date.now()
5553
- });
5554
- }
5555
- /**
5556
- * 处理取消悬停元素
5557
- */
5558
- handleUnhoverElement() {
5559
- if (!this.elementSelector) return;
5560
- this.elementSelector.unhoverElement();
5561
- this.sendMessage({
5562
- type: "ELEMENT_EVENT",
5563
- payload: {
5564
- type: "unhovered_response",
5565
- success: true
5566
- },
5567
- timestamp: Date.now()
5568
- });
5569
- }
5570
4499
  /** ----------------- 统一消息发送管理方法 ----------------- */
5571
4500
  /**
5572
4501
  * 获取统一的消息发送器实例
@@ -5600,7 +4529,6 @@ var MessageBridge = class {
5600
4529
  window.removeEventListener("message", this.messageListener);
5601
4530
  this.messageListener = void 0;
5602
4531
  }
5603
- console.log("[MessageBridge] \u6D88\u606F\u6865\u63A5\u5668\u5DF2\u9500\u6BC1");
5604
4532
  }
5605
4533
  };
5606
4534
 
@@ -5628,7 +4556,6 @@ var ErrorHandler = class {
5628
4556
  enableInteractionTracking: true
5629
4557
  };
5630
4558
  this.config = { ...this.config, ...options };
5631
- console.log("[ErrorHandler] \u5F00\u59CB\u521D\u59CB\u5316\u7EDF\u4E00\u9519\u8BEF\u5904\u7406\u5668...");
5632
4559
  this.messageSender = createDefaultMessageSender({
5633
4560
  addTimestamp: true,
5634
4561
  enableDebugLog: false
@@ -5636,16 +4563,13 @@ var ErrorHandler = class {
5636
4563
  const sendMessage = this.messageSender.createSendFunction();
5637
4564
  this.errorTracking = new ErrorTracking(sendMessage);
5638
4565
  this.interactionTracking = new InteractionTracking(sendMessage);
5639
- this.elementSelector = new ElementSelector2(sendMessage);
5640
4566
  this.messageBridge = new MessageBridge();
5641
4567
  this.viewDetector = new ViewDetector();
5642
4568
  this.hardRefreshManager = new HardRefreshManager(GLOBAL_CONFIG.ALLOWED_ORIGINS);
5643
4569
  this.componentTreeGenerator = new ComponentTreeGenerator();
5644
4570
  if (this.config.enableViteHMR && ViteHMRDetector.isViteEnvironment()) {
5645
4571
  this.viteHMRDetector = new ViteHMRDetector(sendMessage);
5646
- console.log("[ErrorHandler] Vite HMR \u68C0\u6D4B\u5668\u5DF2\u521D\u59CB\u5316");
5647
4572
  }
5648
- console.log("[ErrorHandler] \u6A21\u5757\u521D\u59CB\u5316\u5B8C\u6210");
5649
4573
  }
5650
4574
  /** ----------------- 主要初始化方法 ----------------- */
5651
4575
  /**
@@ -5657,12 +4581,10 @@ var ErrorHandler = class {
5657
4581
  return;
5658
4582
  }
5659
4583
  try {
5660
- console.log("[ErrorHandler] \u5F00\u59CB\u521D\u59CB\u5316\u5404\u4E2A\u6A21\u5757...");
5661
4584
  this.initializeCore();
5662
4585
  this.setupModuleIntegration();
5663
4586
  this.enableFeatures();
5664
4587
  this.initialized = true;
5665
- console.log("[ErrorHandler] \u521D\u59CB\u5316\u5B8C\u6210");
5666
4588
  } catch (error) {
5667
4589
  console.error("[ErrorHandler] \u521D\u59CB\u5316\u5931\u8D25:", error);
5668
4590
  throw error;
@@ -5675,7 +4597,6 @@ var ErrorHandler = class {
5675
4597
  this.initializeGlobalState();
5676
4598
  this.setupDebugEndpoint();
5677
4599
  this.errorTracking.initialize();
5678
- console.log("[ErrorHandler] \u6838\u5FC3\u529F\u80FD\u521D\u59CB\u5316\u5B8C\u6210");
5679
4600
  }
5680
4601
  /**
5681
4602
  * 初始化全局状态
@@ -5687,7 +4608,6 @@ var ErrorHandler = class {
5687
4608
  if (!window.__AUTO_ENGINEER_INTERACTION_TRAIL__) {
5688
4609
  window.__AUTO_ENGINEER_INTERACTION_TRAIL__ = [];
5689
4610
  }
5690
- console.log("[ErrorHandler] \u5168\u5C40\u72B6\u6001\u521D\u59CB\u5316\u5B8C\u6210");
5691
4611
  }
5692
4612
  /**
5693
4613
  * 设置调试端点
@@ -5707,28 +4627,22 @@ var ErrorHandler = class {
5707
4627
  * 设置模块间的协作
5708
4628
  */
5709
4629
  setupModuleIntegration() {
5710
- this.messageBridge.setElementSelector(this.elementSelector);
5711
4630
  this.messageBridge.setComponentTreeGenerator(this.componentTreeGenerator);
5712
4631
  this.errorTracking.setViewDetector(this.viewDetector);
5713
4632
  this.errorTracking.setInteractionTracking(this.interactionTracking);
5714
- console.log("[ErrorHandler] \u6A21\u5757\u96C6\u6210\u8BBE\u7F6E\u5B8C\u6210");
5715
4633
  }
5716
4634
  /**
5717
4635
  * 启用功能模块
5718
4636
  */
5719
4637
  enableFeatures() {
5720
- console.log("[ErrorHandler] \u542F\u7528\u529F\u80FD\u6A21\u5757...");
5721
4638
  if (this.config.enableInteractionTracking) {
5722
4639
  this.interactionTracking.startTracking();
5723
- console.log("[ErrorHandler] \u4EA4\u4E92\u8FFD\u8E2A\u5DF2\u542F\u7528");
5724
4640
  }
5725
4641
  if (this.viteHMRDetector) {
5726
4642
  this.viteHMRDetector.initialize();
5727
- console.log("[ErrorHandler] Vite HMR \u68C0\u6D4B\u5668\u5DF2\u542F\u7528");
5728
4643
  }
5729
4644
  this.handleHardRefreshLogic();
5730
4645
  this.setupViewDetection();
5731
- console.log("[ErrorHandler] \u529F\u80FD\u6A21\u5757\u542F\u7528\u5B8C\u6210");
5732
4646
  }
5733
4647
  /**
5734
4648
  * 处理硬刷新逻辑
@@ -5737,7 +4651,6 @@ var ErrorHandler = class {
5737
4651
  HardRefreshManager.cleanupRefreshParams();
5738
4652
  const refreshStats = HardRefreshManager.getRefreshStats();
5739
4653
  if (refreshStats.isHardRefresh) {
5740
- console.log("[ErrorHandler] \u68C0\u6D4B\u5230\u786C\u5237\u65B0:", refreshStats);
5741
4654
  this.messageSender.send({
5742
4655
  type: "SYSTEM_EVENT",
5743
4656
  payload: {
@@ -5758,7 +4671,6 @@ var ErrorHandler = class {
5758
4671
  const currentView = this.viewDetector.getCurrentViewInfo();
5759
4672
  if (currentView.title !== lastViewTitle) {
5760
4673
  lastViewTitle = currentView.title;
5761
- console.log("[ErrorHandler] \u89C6\u56FE\u53D8\u5316:", currentView);
5762
4674
  }
5763
4675
  };
5764
4676
  setInterval(checkViewChange, 1e3);
@@ -5791,12 +4703,6 @@ var ErrorHandler = class {
5791
4703
  getErrorStats() {
5792
4704
  return this.errorTracking.getErrorStats();
5793
4705
  }
5794
- /**
5795
- * 获取选择器状态
5796
- */
5797
- getSelectorState() {
5798
- return this.elementSelector.getSelectorState();
5799
- }
5800
4706
  /**
5801
4707
  * 获取交互历史
5802
4708
  */
@@ -5830,30 +4736,11 @@ var ErrorHandler = class {
5830
4736
  isViteEnvironment() {
5831
4737
  return ViteHMRDetector.isViteEnvironment();
5832
4738
  }
5833
- /**
5834
- * 启用元素选择器
5835
- */
5836
- enableElementSelector() {
5837
- this.elementSelector.enableSelector();
5838
- }
5839
- /**
5840
- * 禁用元素选择器
5841
- */
5842
- disableElementSelector() {
5843
- this.elementSelector.disableSelector();
5844
- }
5845
- /**
5846
- * 切换元素选择器状态
5847
- */
5848
- toggleElementSelector() {
5849
- this.elementSelector.toggleSelector();
5850
- }
5851
4739
  /**
5852
4740
  * 更新配置
5853
4741
  */
5854
4742
  updateConfig(newConfig) {
5855
4743
  this.config = { ...this.config, ...newConfig };
5856
- console.log("[ErrorHandler] \u914D\u7F6E\u5DF2\u66F4\u65B0:", this.config);
5857
4744
  }
5858
4745
  /**
5859
4746
  * 销毁错误处理器
@@ -5862,7 +4749,6 @@ var ErrorHandler = class {
5862
4749
  try {
5863
4750
  this.errorTracking.destroy();
5864
4751
  this.interactionTracking.destroy();
5865
- this.elementSelector.destroy();
5866
4752
  this.messageBridge.destroy();
5867
4753
  if (this.viteHMRDetector) {
5868
4754
  this.viteHMRDetector.destroy();
@@ -5872,7 +4758,6 @@ var ErrorHandler = class {
5872
4758
  this.viewDetector.clearCache();
5873
4759
  }
5874
4760
  this.initialized = false;
5875
- console.log("[ErrorHandler] \u5DF2\u9500\u6BC1");
5876
4761
  } catch (error) {
5877
4762
  const originalConsole = getOriginalConsole3();
5878
4763
  originalConsole.error("[ErrorHandler] \u9500\u6BC1\u65F6\u53D1\u751F\u9519\u8BEF:", error);
@@ -5894,7 +4779,6 @@ var ErrorHandler = class {
5894
4779
  errorStats: this.getErrorStats(),
5895
4780
  currentView: this.getCurrentView(),
5896
4781
  interactionHistory: this.getInteractionHistory(),
5897
- selectorState: this.getSelectorState(),
5898
4782
  isViteEnvironment: this.isViteEnvironment(),
5899
4783
  timestamp: Date.now()
5900
4784
  };
@@ -5918,7 +4802,6 @@ var import_jsx_runtime7 = require("react/jsx-runtime");
5918
4802
  var globalErrorHandler = null;
5919
4803
  var initializeErrorHandler = () => {
5920
4804
  if (!globalErrorHandler) {
5921
- console.log("[HowOneProvider] \u5728\u6A21\u5757\u9876\u5C42\u521D\u59CB\u5316\u9519\u8BEF\u5904\u7406\u5668...");
5922
4805
  globalErrorHandler = new ErrorHandler({
5923
4806
  enableViteHMR: true,
5924
4807
  enableElementSelector: true,
@@ -5926,7 +4809,6 @@ var initializeErrorHandler = () => {
5926
4809
  });
5927
4810
  globalErrorHandler.init();
5928
4811
  window.__ERROR_HANDLER__ = globalErrorHandler;
5929
- console.log("[HowOneProvider] \u9519\u8BEF\u5904\u7406\u5668\u5DF2\u5728\u6A21\u5757\u9876\u5C42\u521D\u59CB\u5316\u5B8C\u6210");
5930
4812
  }
5931
4813
  return globalErrorHandler;
5932
4814
  };
@@ -5954,7 +4836,6 @@ var HowOneProvider = ({
5954
4836
  urlToken = hashParams.get("access_token") || hashParams.get("token");
5955
4837
  }
5956
4838
  if (urlToken) {
5957
- console.log("[HowOneProvider] Token captured from URL, storing to localStorage...");
5958
4839
  setToken(urlToken);
5959
4840
  setTokenState(urlToken);
5960
4841
  setUser(parseUserFromToken(urlToken));
@@ -5964,7 +4845,6 @@ var HowOneProvider = ({
5964
4845
  const newSearch = params.toString();
5965
4846
  const newUrl = window.location.pathname + (newSearch ? "?" + newSearch : "");
5966
4847
  window.history.replaceState({}, "", newUrl);
5967
- console.log("[HowOneProvider] Token stored successfully, URL cleaned");
5968
4848
  }
5969
4849
  } catch (e) {
5970
4850
  console.error("[HowOneProvider] Failed to capture token from URL:", e);
@@ -5979,7 +4859,6 @@ var HowOneProvider = ({
5979
4859
  if (redirectOnUnauthenticated && !token && !user) {
5980
4860
  const currentUrl = new URL(window.location.href);
5981
4861
  if (!currentUrl.pathname.includes("/auth")) {
5982
- console.log("[HowOneProvider] No token found, redirecting to auth page...");
5983
4862
  try {
5984
4863
  const authUrlObj = new URL(authUrl);
5985
4864
  const redirectUri = window.location.href;
@@ -5987,7 +4866,6 @@ var HowOneProvider = ({
5987
4866
  if (projectId) {
5988
4867
  authUrlObj.searchParams.set("project_id", projectId);
5989
4868
  }
5990
- console.log("[HowOneProvider] Redirecting to:", authUrlObj.toString());
5991
4869
  window.location.href = authUrlObj.toString();
5992
4870
  } catch (error) {
5993
4871
  console.error("[HowOneProvider] Failed to build auth URL:", error);
@@ -7267,7 +6145,6 @@ var SimpleErrorHandler = class {
7267
6145
  this.setupErrorListeners();
7268
6146
  this.setupCompatibility();
7269
6147
  this.initialized = true;
7270
- console.log("[\u7B80\u5316\u9519\u8BEF\u5904\u7406] \u521D\u59CB\u5316\u5B8C\u6210");
7271
6148
  }
7272
6149
  /**
7273
6150
  * 设置错误监听器