@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.mjs CHANGED
@@ -697,17 +697,13 @@ var LoginForm = ({
697
697
  const [codeSent, setCodeSent] = useState2(false);
698
698
  const [loginError, setLoginError] = useState2(null);
699
699
  const googleLogin = async () => {
700
- console.log("Google login clicked");
701
700
  };
702
701
  const githubLogin = async () => {
703
- console.log("GitHub login clicked");
704
702
  };
705
703
  const sendEmailCode = async (email2) => {
706
- console.log("Send code to:", email2, "for app:", appName);
707
704
  setCodeSent(true);
708
705
  };
709
706
  const loginWithEmail = async (email2, code2) => {
710
- console.log("Login with email:", email2, "code:", code2);
711
707
  if (onLoginSuccess) onLoginSuccess();
712
708
  };
713
709
  const clearError = () => {
@@ -1154,11 +1150,9 @@ var ElementSelectorProvider = ({ children }) => {
1154
1150
  type: "ELEMENT_SELECTION_CANCELLED"
1155
1151
  }, "*");
1156
1152
  }
1157
- console.log("\u{1F6AB} \u5143\u7D20\u9009\u62E9\u5DF2\u53D6\u6D88 (ESC)");
1158
1153
  }, []);
1159
1154
  const handleSelect = useCallback3((data) => {
1160
1155
  sendElementSelectionToParent(data);
1161
- console.log("\u{1F3AF} \u5143\u7D20\u5DF2\u9009\u4E2D:", data.element.tagName, data.sourceLocation?.file);
1162
1156
  }, []);
1163
1157
  useEffect5(() => {
1164
1158
  const handleStartSelection = () => {
@@ -1513,7 +1507,6 @@ var ViteHMRDetector = class {
1513
1507
  if (this.isInitialized) return;
1514
1508
  this.setupViteErrorDetection();
1515
1509
  this.isInitialized = true;
1516
- console.log("[ViteHMRDetector] Vite HMR \u9519\u8BEF\u68C0\u6D4B\u5668\u521D\u59CB\u5316\u5B8C\u6210");
1517
1510
  }
1518
1511
  /**
1519
1512
  * 销毁检测器
@@ -1564,10 +1557,8 @@ var ViteHMRDetector = class {
1564
1557
  setTimeout(() => this.checkForCompileErrors(), 500);
1565
1558
  });
1566
1559
  hot.on("vite:beforeUpdate", () => {
1567
- console.log("[ViteHMRDetector] HMR \u66F4\u65B0\u5F00\u59CB");
1568
1560
  });
1569
1561
  hot.on("vite:afterUpdate", () => {
1570
- console.log("[ViteHMRDetector] HMR \u66F4\u65B0\u5B8C\u6210");
1571
1562
  });
1572
1563
  }
1573
1564
  window.addEventListener("error", (event) => {
@@ -1605,7 +1596,6 @@ var ViteHMRDetector = class {
1605
1596
  payload: errorPayload,
1606
1597
  timestamp: Date.now()
1607
1598
  });
1608
- console.log("[ViteHMRDetector] Vite \u9519\u8BEF\u5DF2\u68C0\u6D4B\u5E76\u62A5\u544A:", errorPayload);
1609
1599
  } catch (err) {
1610
1600
  this.handleFallbackError(errorOverlay, err);
1611
1601
  }
@@ -1878,20 +1868,16 @@ var HardRefreshManager = class {
1878
1868
  clearedStorage: []
1879
1869
  };
1880
1870
  try {
1881
- console.log("[HardRefreshManager] \u5F00\u59CB\u6267\u884C\u786C\u5237\u65B0...");
1882
1871
  if (defaultOptions.clearCaches) {
1883
1872
  const clearedCaches = await this.clearAllCaches();
1884
1873
  result.clearedCaches = clearedCaches;
1885
- console.log(`[HardRefreshManager] \u5DF2\u6E05\u9664 ${clearedCaches.length} \u4E2A\u7F13\u5B58`);
1886
1874
  }
1887
1875
  if (defaultOptions.unregisterServiceWorkers) {
1888
1876
  const unregisteredCount = await this.unregisterServiceWorkers();
1889
1877
  result.unregisteredWorkers = unregisteredCount;
1890
- console.log(`[HardRefreshManager] \u5DF2\u6CE8\u9500 ${unregisteredCount} \u4E2A Service Worker`);
1891
1878
  }
1892
1879
  const clearedStorage = await this.clearStorage(defaultOptions);
1893
1880
  result.clearedStorage = clearedStorage;
1894
- console.log(`[HardRefreshManager] \u5DF2\u6E05\u9664\u5B58\u50A8: ${clearedStorage.join(", ")}`);
1895
1881
  await this.forceReload(defaultOptions);
1896
1882
  result.success = true;
1897
1883
  return result;
@@ -2490,7 +2476,6 @@ var ComponentTreeGenerator = class {
2490
2476
  maxTextLength: 100,
2491
2477
  maxChildren: 50
2492
2478
  };
2493
- console.log("[ComponentTreeGenerator] \u7EC4\u4EF6\u6811\u751F\u6210\u5668\u521D\u59CB\u5316\u5B8C\u6210");
2494
2479
  }
2495
2480
  /** ----------------- 主要生成方法 ----------------- */
2496
2481
  /**
@@ -2499,7 +2484,6 @@ var ComponentTreeGenerator = class {
2499
2484
  generateComponentTree(rootElement) {
2500
2485
  const startTime = Date.now();
2501
2486
  const root = rootElement || document.body;
2502
- console.log("[ComponentTreeGenerator] \u5F00\u59CB\u751F\u6210\u7EC4\u4EF6\u6811...");
2503
2487
  const rootNode = this.generateNodeTree(root, 0);
2504
2488
  const stats = this.calculateTreeStats(rootNode);
2505
2489
  const componentTree = {
@@ -2520,7 +2504,6 @@ var ComponentTreeGenerator = class {
2520
2504
  }
2521
2505
  };
2522
2506
  const generationTime = Date.now() - startTime;
2523
- console.log(`[ComponentTreeGenerator] \u7EC4\u4EF6\u6811\u751F\u6210\u5B8C\u6210\uFF0C\u8017\u65F6 ${generationTime}ms\uFF0C\u8282\u70B9\u6570: ${stats.totalNodes}`);
2524
2507
  return componentTree;
2525
2508
  }
2526
2509
  /**
@@ -2871,7 +2854,6 @@ var ComponentTreeGenerator = class {
2871
2854
  */
2872
2855
  updateConfig(newConfig) {
2873
2856
  this.config = { ...this.config, ...newConfig };
2874
- console.log("[ComponentTreeGenerator] \u914D\u7F6E\u5DF2\u66F4\u65B0:", this.config);
2875
2857
  }
2876
2858
  /**
2877
2859
  * 获取当前配置
@@ -2894,7 +2876,6 @@ var ComponentTreeGenerator = class {
2894
2876
  * 销毁生成器
2895
2877
  */
2896
2878
  destroy() {
2897
- console.log("[ComponentTreeGenerator] \u7EC4\u4EF6\u6811\u751F\u6210\u5668\u5DF2\u9500\u6BC1");
2898
2879
  }
2899
2880
  };
2900
2881
 
@@ -3071,7 +3052,6 @@ var ErrorTracking = class {
3071
3052
  this.viewDetector = null;
3072
3053
  this.interactionTracking = null;
3073
3054
  this.sendMessage = sendMessage;
3074
- this.internalLog("log", "[ErrorTracking] \u9519\u8BEF\u8FFD\u8E2A\u6A21\u5757\u521D\u59CB\u5316\u5B8C\u6210");
3075
3055
  }
3076
3056
  /**
3077
3057
  * 内部日志方法,避免被控制台拦截器捕获
@@ -3107,10 +3087,8 @@ var ErrorTracking = class {
3107
3087
  this.setupConsoleInterception();
3108
3088
  this.setupNetworkMonitoring();
3109
3089
  this.initialized = true;
3110
- this.internalLog("log", "[ErrorTracking] \u9519\u8BEF\u8FFD\u8E2A\u529F\u80FD\u5DF2\u542F\u7528");
3111
3090
  setTimeout(() => {
3112
3091
  this.fullyInitialized = true;
3113
- this.internalLog("log", "[ErrorTracking] \u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u63A7\u5236\u53F0\u62E6\u622A\u5DF2\u9ED8\u8BA4\u542F\u7528");
3114
3092
  }, 1e3);
3115
3093
  }
3116
3094
  /**
@@ -3135,7 +3113,6 @@ var ErrorTracking = class {
3135
3113
  source: "unhandledrejection"
3136
3114
  });
3137
3115
  });
3138
- this.internalLog("log", "[ErrorTracking] \u5168\u5C40\u9519\u8BEF\u76D1\u542C\u5668\u5DF2\u8BBE\u7F6E");
3139
3116
  }
3140
3117
  /**
3141
3118
  * 设置控制台拦截
@@ -3159,7 +3136,6 @@ var ErrorTracking = class {
3159
3136
  }
3160
3137
  };
3161
3138
  });
3162
- this.internalLog("log", "[ErrorTracking] \u63A7\u5236\u53F0\u62E6\u622A\u5DF2\u8BBE\u7F6E");
3163
3139
  }
3164
3140
  /**
3165
3141
  * 安全地将控制台输出转发到父窗口
@@ -3179,6 +3155,20 @@ var ErrorTracking = class {
3179
3155
  const fileInfo = this.extractFileInfoFromStack(fullStack);
3180
3156
  const serializedArgs = args.map((arg) => DeepSerializer.quickSerialize(arg));
3181
3157
  const message = serializedArgs.map((arg) => typeof arg === "string" ? arg : JSON.stringify(arg, null, 2)).join(" ") + (stack ? "\n" + stack : "");
3158
+ const lowerMessage = message.toLowerCase();
3159
+ const isFromVite = (fileInfo.filename || "").toLowerCase().includes("vite") || lowerMessage.includes("@vite") || lowerMessage.includes("vite") || lowerMessage.includes("hmr");
3160
+ const ignoreVitePatterns = [
3161
+ /\[vite\]\s*hot updated/i,
3162
+ /\[vite\]\s*connected/i,
3163
+ /\[vite\]\s*connecting/i,
3164
+ /\bhot updated\b/i,
3165
+ /\bhmr\b.*\bupdated\b/i
3166
+ ];
3167
+ if (isFromVite && ignoreVitePatterns.some((re) => re.test(lowerMessage))) {
3168
+ return;
3169
+ }
3170
+ const hasErrorKeywords = /\b(error|failed|overlay|compile|exception)\b/.test(lowerMessage);
3171
+ const isViteHMRNonError = isFromVite && !hasErrorKeywords;
3182
3172
  if (method === "error") {
3183
3173
  const globalError = {
3184
3174
  id: `console-error-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
@@ -3195,9 +3185,11 @@ var ErrorTracking = class {
3195
3185
  pagePath: window.location.pathname + window.location.search + window.location.hash,
3196
3186
  interactionTrail: [...window.__AUTO_ENGINEER_INTERACTION_TRAIL__ || []]
3197
3187
  };
3198
- window.__AUTO_ENGINEER_ERRORS__ = window.__AUTO_ENGINEER_ERRORS__ || [];
3199
- window.__AUTO_ENGINEER_ERRORS__.push(globalError);
3200
- this.manageArrayLength(window.__AUTO_ENGINEER_ERRORS__, ERROR_CONFIG.MAX_ERRORS);
3188
+ if (!isViteHMRNonError) {
3189
+ window.__AUTO_ENGINEER_ERRORS__ = window.__AUTO_ENGINEER_ERRORS__ || [];
3190
+ window.__AUTO_ENGINEER_ERRORS__.push(globalError);
3191
+ this.manageArrayLength(window.__AUTO_ENGINEER_ERRORS__, ERROR_CONFIG.MAX_ERRORS);
3192
+ }
3201
3193
  }
3202
3194
  const consoleLevelMap = {
3203
3195
  log: "info",
@@ -3209,7 +3201,7 @@ var ErrorTracking = class {
3209
3201
  this.sendMessage({
3210
3202
  type: "CONSOLE_EVENT",
3211
3203
  payload: {
3212
- type: consoleLevelMap[method] === "info" ? "info" : consoleLevelMap[method] === "warning" ? "warning" : "error",
3204
+ type: consoleLevelMap[method] === "info" ? "info" : consoleLevelMap[method] === "warning" ? "warning" : consoleLevelMap[method] === "debug" ? "debug" : "error",
3213
3205
  message,
3214
3206
  logged_at: (/* @__PURE__ */ new Date()).toISOString(),
3215
3207
  filename: fileInfo.filename,
@@ -3230,19 +3222,47 @@ var ErrorTracking = class {
3230
3222
  * 设置网络监控
3231
3223
  */
3232
3224
  setupNetworkMonitoring() {
3225
+ const self = this;
3233
3226
  const originalFetch = window.fetch;
3234
3227
  window.fetch = async (...args) => {
3235
3228
  const startTime = Date.now();
3236
3229
  try {
3237
3230
  const response = await originalFetch(...args);
3238
- this.logNetworkRequest(args, response, Date.now() - startTime);
3231
+ self.logNetworkRequest(args, response, Date.now() - startTime);
3239
3232
  return response;
3240
3233
  } catch (error) {
3241
- this.logNetworkError(args, error, Date.now() - startTime);
3234
+ const duration = Date.now() - startTime;
3235
+ const message = error && (error.message || String(error));
3236
+ const match = typeof message === "string" ? message.match(/^HTTP\s+(\d+):\s*(.*)$/i) : null;
3237
+ if (match) {
3238
+ const status = Number(match[1]);
3239
+ const statusText = match[2] || "";
3240
+ const stack = new Error().stack;
3241
+ const fileInfo = self.extractFileInfoFromStack(stack);
3242
+ self.sendMessage({
3243
+ type: "NETWORK_EVENT",
3244
+ payload: {
3245
+ type: "request_error",
3246
+ url: args[0],
3247
+ method: args[1]?.method || "GET",
3248
+ status,
3249
+ statusText,
3250
+ filename: fileInfo.filename,
3251
+ lineno: fileInfo.lineno,
3252
+ colno: fileInfo.colno,
3253
+ duration,
3254
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
3255
+ pageUrl: window.location.href,
3256
+ interactionTrail: self.getRecentInteractions()
3257
+ },
3258
+ timestamp: Date.now()
3259
+ });
3260
+ } else {
3261
+ self.logNetworkError(args, error, duration);
3262
+ }
3242
3263
  throw error;
3243
3264
  }
3244
3265
  };
3245
- this.internalLog("log", "[ErrorTracking] \u7F51\u7EDC\u76D1\u63A7\u5DF2\u8BBE\u7F6E");
3246
3266
  }
3247
3267
  /**
3248
3268
  * 记录网络请求
@@ -3534,14 +3554,12 @@ var ErrorTracking = class {
3534
3554
  */
3535
3555
  enableConsoleInterception() {
3536
3556
  this.fullyInitialized = true;
3537
- this.internalLog("log", "[ErrorTracking] \u624B\u52A8\u542F\u7528\u63A7\u5236\u53F0\u62E6\u622A");
3538
3557
  }
3539
3558
  /**
3540
3559
  * 手动禁用控制台拦截
3541
3560
  */
3542
3561
  disableConsoleInterception() {
3543
3562
  this.fullyInitialized = false;
3544
- this.internalLog("log", "[ErrorTracking] \u624B\u52A8\u7981\u7528\u63A7\u5236\u53F0\u62E6\u622A");
3545
3563
  }
3546
3564
  /**
3547
3565
  * 销毁错误追踪
@@ -3553,10 +3571,32 @@ var ErrorTracking = class {
3553
3571
  }
3554
3572
  });
3555
3573
  this.initialized = false;
3556
- this.internalLog("log", "[ErrorTracking] \u9519\u8BEF\u8FFD\u8E2A\u6A21\u5757\u5DF2\u9500\u6BC1");
3557
3574
  }
3558
3575
  };
3559
3576
 
3577
+ // src/utils/unified-error-handler/utils/SelectorUtils.ts
3578
+ function getElementClasses(element) {
3579
+ const classAttr = element.getAttribute("class");
3580
+ if (classAttr && classAttr.trim().length > 0) {
3581
+ return dedupeAndClean(classAttr.split(/\s+/));
3582
+ }
3583
+ const anyEl = element;
3584
+ if (typeof anyEl.className === "string") {
3585
+ return dedupeAndClean(anyEl.className.split(/\s+/));
3586
+ }
3587
+ if (anyEl.className && typeof anyEl.className.baseVal === "string") {
3588
+ return dedupeAndClean(anyEl.className.baseVal.split(/\s+/));
3589
+ }
3590
+ if (anyEl.classList && anyEl.classList.length > 0) {
3591
+ return dedupeAndClean(Array.from(anyEl.classList));
3592
+ }
3593
+ return [];
3594
+ }
3595
+ function dedupeAndClean(arr) {
3596
+ const cleaned = arr.map((s) => s.trim()).filter(Boolean);
3597
+ return Array.from(new Set(cleaned));
3598
+ }
3599
+
3560
3600
  // src/utils/unified-error-handler/features/InteractionTracking.ts
3561
3601
  var InteractionTracking = class {
3562
3602
  constructor(sendMessage) {
@@ -3580,7 +3620,6 @@ var InteractionTracking = class {
3580
3620
  this.debounceTimers = /* @__PURE__ */ new Map();
3581
3621
  this.eventListeners = [];
3582
3622
  this.sendMessage = sendMessage;
3583
- console.log("[InteractionTracking] \u4EA4\u4E92\u8FFD\u8E2A\u6A21\u5757\u521D\u59CB\u5316\u5B8C\u6210");
3584
3623
  }
3585
3624
  /** ----------------- 主要控制方法 ----------------- */
3586
3625
  /**
@@ -3596,7 +3635,6 @@ var InteractionTracking = class {
3596
3635
  title: document.title,
3597
3636
  timestamp: Date.now()
3598
3637
  });
3599
- console.log("[InteractionTracking] \u4EA4\u4E92\u8FFD\u8E2A\u5DF2\u5F00\u59CB");
3600
3638
  }
3601
3639
  /**
3602
3640
  * 停止追踪
@@ -3605,7 +3643,6 @@ var InteractionTracking = class {
3605
3643
  if (!this.isTracking) return;
3606
3644
  this.removeEventListeners();
3607
3645
  this.isTracking = false;
3608
- console.log("[InteractionTracking] \u4EA4\u4E92\u8FFD\u8E2A\u5DF2\u505C\u6B62");
3609
3646
  }
3610
3647
  /** ----------------- 事件监听器设置 ----------------- */
3611
3648
  /**
@@ -3918,11 +3955,9 @@ var InteractionTracking = class {
3918
3955
  */
3919
3956
  getElementSelector(element) {
3920
3957
  if (element.id) return `#${element.id}`;
3921
- if (element.className) {
3922
- const classes = element.className.split(" ").filter((c) => c.trim());
3923
- if (classes.length > 0) {
3924
- return `.${classes[0]}`;
3925
- }
3958
+ const classes = getElementClasses(element);
3959
+ if (classes.length > 0) {
3960
+ return `.${classes[0]}`;
3926
3961
  }
3927
3962
  const dataTestId = element.getAttribute("data-testid");
3928
3963
  if (dataTestId) return `[data-testid="${dataTestId}"]`;
@@ -4035,1244 +4070,240 @@ var InteractionTracking = class {
4035
4070
  destroy() {
4036
4071
  this.stopTracking();
4037
4072
  this.interactions = [];
4038
- console.log("[InteractionTracking] \u4EA4\u4E92\u8FFD\u8E2A\u6A21\u5757\u5DF2\u9500\u6BC1");
4039
4073
  }
4040
4074
  };
4041
4075
 
4042
- // src/utils/unified-error-handler/features/ElementSelector.ts
4043
- var ElementSelector2 = class {
4076
+ // src/utils/unified-error-handler/features/MessageBridge.ts
4077
+ var getOriginalConsole2 = () => window.__originalConsole || {
4078
+ log: console.log.bind(console),
4079
+ warn: console.warn.bind(console),
4080
+ error: console.error.bind(console),
4081
+ info: console.info.bind(console),
4082
+ debug: console.debug.bind(console)
4083
+ };
4084
+ var MessageBridge = class {
4044
4085
  constructor(sendMessage) {
4045
- this.config = { ...DEFAULT_SELECTOR_CONFIG };
4046
- this.isActive = false;
4047
- this.highlightedElement = null;
4048
- this.selectedElements = [];
4049
- this.rootElement = null;
4050
- this.tooltip = null;
4051
- this.styleElement = null;
4052
- this.eventListeners = [];
4053
- this.lastClickTimestamp = 0;
4054
- this.lastClickTarget = null;
4055
- this.mousePosition = { x: 0, y: 0 };
4056
- this.sendMessage = sendMessage;
4057
- this.initializeSelector();
4086
+ this.componentTreeGenerator = null;
4087
+ this.messageSender = createDefaultMessageSender({
4088
+ addTimestamp: true,
4089
+ enableDebugLog: false
4090
+ });
4091
+ this.sendMessage = sendMessage || this.messageSender.createSendFunction();
4092
+ this.setupMessageListener();
4058
4093
  }
4059
- /** ----------------- 初始化方法 ----------------- */
4094
+ /** ----------------- 依赖注入方法 ----------------- */
4060
4095
  /**
4061
- * 初始化选择器
4096
+ * 设置组件树生成器
4062
4097
  */
4063
- initializeSelector() {
4064
- this.waitForRootElement();
4065
- this.createTooltip();
4066
- this.createStyles();
4067
- console.log("[ElementSelector] \u5143\u7D20\u9009\u62E9\u5668\u521D\u59CB\u5316\u5B8C\u6210");
4098
+ setComponentTreeGenerator(componentTreeGenerator) {
4099
+ this.componentTreeGenerator = componentTreeGenerator;
4068
4100
  }
4101
+ /** ----------------- 消息监听设置 ----------------- */
4069
4102
  /**
4070
- * 等待根元素加载
4103
+ * 设置消息监听器
4071
4104
  */
4072
- async waitForRootElement() {
4073
- const maxAttempts = 50;
4074
- let attempts = 0;
4075
- while (attempts < maxAttempts) {
4076
- this.rootElement = document.querySelector("#root") || document.body;
4077
- if (this.rootElement) {
4078
- break;
4105
+ setupMessageListener() {
4106
+ this.messageListener = (event) => {
4107
+ if (!this.isOriginAllowed(event.origin)) {
4108
+ return;
4079
4109
  }
4080
- await new Promise((resolve) => setTimeout(resolve, 100));
4081
- attempts++;
4082
- }
4083
- if (!this.rootElement) {
4084
- this.rootElement = document.body;
4085
- }
4086
- }
4087
- /**
4088
- * 创建工具提示
4089
- */
4090
- createTooltip() {
4091
- this.tooltip = document.createElement("div");
4092
- this.tooltip.className = "element-selector-tooltip";
4093
- this.tooltip.setAttribute("role", "tooltip");
4094
- this.tooltip.style.display = "none";
4095
- document.body.appendChild(this.tooltip);
4110
+ if (event.data && typeof event.data === "object" && event.data.type) {
4111
+ this.handleMessage(event.data);
4112
+ }
4113
+ };
4114
+ window.addEventListener("message", this.messageListener);
4096
4115
  }
4097
4116
  /**
4098
- * 创建样式
4117
+ * 检查来源是否被允许
4099
4118
  */
4100
- createStyles() {
4101
- this.styleElement = document.createElement("style");
4102
- this.styleElement.id = "element-selector-styles";
4103
- this.styleElement.textContent = this.generateCSS();
4104
- document.head.appendChild(this.styleElement);
4119
+ isOriginAllowed(origin) {
4120
+ return GLOBAL_CONFIG.ALLOWED_ORIGINS.some(
4121
+ (allowedOrigin) => origin.includes(allowedOrigin.replace("https://", "").replace("http://", ""))
4122
+ );
4105
4123
  }
4124
+ /** ----------------- 主要消息处理方法 ----------------- */
4106
4125
  /**
4107
- * 生成 CSS 样式
4126
+ * 处理消息
4108
4127
  */
4109
- generateCSS() {
4110
- return `
4111
- .element-selector-tooltip {
4112
- position: fixed;
4113
- z-index: ${this.config.TOOLTIP_Z_INDEX};
4114
- pointer-events: none;
4115
- background-color: ${this.config.TOOLTIP_BACKGROUND};
4116
- color: ${this.config.TOOLTIP_COLOR};
4117
- padding: ${this.config.TOOLTIP_PADDING};
4118
- border-radius: ${this.config.TOOLTIP_BORDER_RADIUS};
4119
- font-size: ${this.config.TOOLTIP_FONT_SIZE};
4120
- font-weight: bold;
4121
- line-height: 1;
4122
- white-space: nowrap;
4123
- box-shadow: 0 2px 4px rgba(0,0,0,0.2);
4124
- transition: opacity 0.2s ease-in-out;
4125
- margin: 0;
4126
- }
4127
-
4128
- [data-element-hovered] {
4129
- position: relative;
4130
- outline: ${this.config.HIGHLIGHT_BORDER_WIDTH} ${this.config.HIGHLIGHT_BORDER_STYLE} ${this.config.HIGHLIGHT_COLOR} !important;
4131
- outline-offset: 0 !important;
4132
- background-color: ${this.config.HIGHLIGHT_COLOR}20 !important;
4133
- z-index: 9999;
4134
- }
4135
-
4136
- [data-element-selected] {
4137
- position: relative;
4138
- outline: ${this.config.SELECTED_BORDER_WIDTH} ${this.config.HIGHLIGHT_BORDER_STYLE} ${this.config.SELECTED_COLOR} !important;
4139
- outline-offset: 3px !important;
4140
- background-color: ${this.config.SELECTED_COLOR}15 !important;
4141
- z-index: 9999;
4142
- }
4143
-
4144
- [data-element-selected][contenteditable] {
4145
- outline: none !important;
4146
- }
4147
-
4148
- [data-element-hovered][data-full-width],
4149
- [data-element-selected][data-full-width] {
4150
- outline-offset: -5px !important;
4151
- }
4152
-
4153
- .element-selector-active {
4154
- cursor: ${this.config.cursor} !important;
4155
- }
4156
-
4157
- .element-selector-active * {
4158
- cursor: ${this.config.cursor} !important;
4159
- }
4160
-
4161
- /* \u963B\u6B62\u539F\u751F hover \u6548\u679C\u7684\u5168\u5C40\u6837\u5F0F */
4162
- body.element-selector-active * {
4163
- /* \u963B\u6B62\u539F\u751F CSS hover \u4F2A\u7C7B\u6548\u679C */
4164
- transition: none !important;
4165
- }
4166
-
4167
- /* \u963B\u6B62\u6240\u6709 hover \u76F8\u5173\u7684 CSS \u4F2A\u7C7B\uFF0C\u4F46\u6392\u9664\u6211\u4EEC\u7684\u9009\u62E9\u5668\u5143\u7D20 */
4168
- body.element-selector-active *:hover:not([data-element-selected]):not([data-element-hovered]) {
4169
- background-color: inherit !important;
4170
- color: inherit !important;
4171
- border-color: inherit !important;
4172
- box-shadow: inherit !important;
4173
- transform: inherit !important;
4174
- opacity: inherit !important;
4175
- filter: inherit !important;
4176
- }
4177
-
4178
- /* \u786E\u4FDD\u6211\u4EEC\u7684\u9009\u62E9\u5668\u6837\u5F0F\u4F18\u5148\u7EA7\u6700\u9AD8 */
4179
- body.element-selector-active [data-element-selected] {
4180
- background-color: ${this.config.SELECTED_COLOR}15 !important;
4181
- outline: ${this.config.SELECTED_BORDER_WIDTH} ${this.config.HIGHLIGHT_BORDER_STYLE} ${this.config.SELECTED_COLOR} !important;
4182
- }
4183
-
4184
- body.element-selector-active [data-element-hovered] {
4185
- background-color: ${this.config.HIGHLIGHT_COLOR}20 !important;
4186
- outline: ${this.config.HIGHLIGHT_BORDER_WIDTH} ${this.config.HIGHLIGHT_BORDER_STYLE} ${this.config.HIGHLIGHT_COLOR} !important;
4187
- }
4188
-
4189
- /* \u786E\u4FDD\u5DE5\u5177\u63D0\u793A\u4E0D\u53D7\u5F71\u54CD */
4190
- body.element-selector-active .element-selector-tooltip {
4191
- pointer-events: none !important;
4128
+ handleMessage(message) {
4129
+ try {
4130
+ const { type, payload } = message;
4131
+ switch (type) {
4132
+ case "SET_ELEMENT_CONTENT":
4133
+ this.handleSetElementContent(payload);
4134
+ break;
4135
+ case "SET_ELEMENT_ATTRS":
4136
+ this.handleSetElementAttrs(payload);
4137
+ break;
4138
+ case "DUPLICATE_ELEMENT_REQUESTED":
4139
+ this.handleDuplicateElementRequested(payload);
4140
+ break;
4141
+ case "EDIT_TEXT_REQUESTED":
4142
+ this.handleEditTextRequested(payload);
4143
+ break;
4144
+ // 组件树相关消息
4145
+ case "REQUEST_COMPONENT_TREE":
4146
+ this.handleRequestComponentTree();
4147
+ break;
4148
+ case "GET_PARENT_ELEMENT":
4149
+ this.handleGetParentElement(payload);
4150
+ break;
4151
+ // 样式相关消息
4152
+ case "SET_STYLESHEET":
4153
+ this.handleSetStylesheet(payload);
4154
+ break;
4155
+ default:
4156
+ break;
4192
4157
  }
4193
- `;
4158
+ } catch (error) {
4159
+ console.error("[MessageBridge] \u5904\u7406\u6D88\u606F\u5931\u8D25:", error);
4160
+ this.sendMessage({
4161
+ type: "ERROR_EVENT",
4162
+ payload: {
4163
+ type: "message_handling",
4164
+ originalMessage: message,
4165
+ error: error instanceof Error ? error.message : String(error)
4166
+ },
4167
+ timestamp: Date.now()
4168
+ });
4169
+ }
4194
4170
  }
4195
- /** ----------------- 选择器状态管理 ----------------- */
4171
+ /** ----------------- 元素操作消息处理 ----------------- */
4196
4172
  /**
4197
- * 启用选择器
4173
+ * 处理设置元素内容
4198
4174
  */
4199
- enableSelector() {
4200
- if (this.isActive) return;
4201
- this.isActive = true;
4202
- document.body.classList.add("element-selector-active");
4203
- this.setupEventListeners();
4204
- this.manageButtonStates(true);
4205
- console.log("[ElementSelector] \u9009\u62E9\u5668\u5DF2\u542F\u7528");
4175
+ handleSetElementContent(payload) {
4176
+ if (!payload?.selector || !payload?.content) return;
4177
+ const elements = document.querySelectorAll(payload.selector);
4178
+ elements.forEach((element) => {
4179
+ if (element instanceof HTMLElement) {
4180
+ element.innerHTML = payload.content;
4181
+ }
4182
+ });
4206
4183
  this.sendMessage({
4207
- type: "SELECTOR_ENABLED",
4208
- payload: { isActive: true }
4184
+ type: "ELEMENT_EVENT",
4185
+ payload: {
4186
+ type: "content_updated",
4187
+ selector: payload.selector,
4188
+ content: payload.content,
4189
+ elementsUpdated: elements.length
4190
+ },
4191
+ timestamp: Date.now()
4209
4192
  });
4210
4193
  }
4211
4194
  /**
4212
- * 禁用选择器
4195
+ * 处理设置元素属性
4213
4196
  */
4214
- disableSelector() {
4215
- if (!this.isActive) return;
4216
- this.isActive = false;
4217
- document.body.classList.remove("element-selector-active");
4218
- this.removeEventListeners();
4219
- this.clearHighlight();
4220
- this.clearSelection();
4221
- this.manageButtonStates(false);
4222
- this.hideTooltip();
4223
- console.log("[ElementSelector] \u9009\u62E9\u5668\u5DF2\u7981\u7528");
4197
+ handleSetElementAttrs(payload) {
4198
+ if (!payload?.selector || !payload?.attrs) return;
4199
+ const elements = document.querySelectorAll(payload.selector);
4200
+ elements.forEach((element) => {
4201
+ Object.entries(payload.attrs).forEach(([key, value]) => {
4202
+ element.setAttribute(key, String(value));
4203
+ });
4204
+ });
4224
4205
  this.sendMessage({
4225
- type: "SELECTOR_DISABLED",
4226
- payload: { isActive: false }
4206
+ type: "ELEMENT_EVENT",
4207
+ payload: {
4208
+ type: "attrs_updated",
4209
+ selector: payload.selector,
4210
+ attrs: payload.attrs,
4211
+ elementsUpdated: elements.length
4212
+ },
4213
+ timestamp: Date.now()
4227
4214
  });
4228
4215
  }
4229
4216
  /**
4230
- * 切换选择器状态
4217
+ * 处理复制元素请求
4231
4218
  */
4232
- toggleSelector() {
4233
- if (this.isActive) {
4234
- this.disableSelector();
4235
- } else {
4236
- this.enableSelector();
4219
+ handleDuplicateElementRequested(payload) {
4220
+ if (!payload?.selector) return;
4221
+ const element = document.querySelector(payload.selector);
4222
+ if (element && element.parentElement) {
4223
+ const clone = element.cloneNode(true);
4224
+ clone.setAttribute("data-duplicated", "true");
4225
+ element.parentElement.appendChild(clone);
4226
+ this.sendMessage({
4227
+ type: "ELEMENT_EVENT",
4228
+ payload: {
4229
+ type: "duplicated",
4230
+ originalSelector: payload.selector,
4231
+ duplicatedElement: this.getElementInfo(clone)
4232
+ },
4233
+ timestamp: Date.now()
4234
+ });
4237
4235
  }
4238
4236
  }
4239
4237
  /**
4240
- * 获取选择器状态
4241
- */
4242
- getSelectorState() {
4243
- return {
4244
- isActive: this.isActive,
4245
- highlightedElement: this.highlightedElement ? this.getElementInfo(this.highlightedElement) : null,
4246
- selectedElements: this.selectedElements.map((el) => this.getElementInfo(el)),
4247
- config: { ...this.config }
4248
- };
4249
- }
4250
- /** ----------------- 事件监听器管理 ----------------- */
4251
- /**
4252
- * 设置事件监听器
4238
+ * 处理编辑文本请求
4253
4239
  */
4254
- setupEventListeners() {
4255
- this.addEventListenerWithCleanup(document, "mouseover", this.handleMouseOver.bind(this), { passive: true });
4256
- this.addEventListenerWithCleanup(document, "mouseout", this.handleMouseOut.bind(this), { passive: true });
4257
- this.addEventListenerWithCleanup(document, "mousemove", this.trackMousePosition.bind(this), { passive: true });
4258
- this.addEventListenerWithCleanup(document, "click", this.handleClick.bind(this), { capture: true });
4259
- this.addEventListenerWithCleanup(document, "dblclick", this.handleDoubleClick.bind(this), { capture: true });
4260
- this.addEventListenerWithCleanup(window, "scroll", this.handleScroll.bind(this), { passive: true });
4261
- this.addEventListenerWithCleanup(document, "keydown", this.handleKeyDown.bind(this));
4262
- this.addEventListenerWithCleanup(document, "mousedown", this.preventFormInteraction.bind(this), { capture: true });
4263
- this.addEventListenerWithCleanup(document, "submit", this.preventAllInteraction.bind(this), { capture: true });
4264
- this.addEventListenerWithCleanup(document, "touchstart", this.preventAllInteraction.bind(this), { capture: true });
4265
- this.addEventListenerWithCleanup(document, "touchend", this.preventAllInteraction.bind(this), { capture: true });
4240
+ handleEditTextRequested(payload) {
4241
+ if (!payload?.selector) return;
4242
+ const element = document.querySelector(payload.selector);
4243
+ if (element instanceof HTMLElement) {
4244
+ element.setAttribute("contenteditable", "true");
4245
+ element.focus();
4246
+ const handleInput = () => {
4247
+ this.sendMessage({
4248
+ type: "ELEMENT_EVENT",
4249
+ payload: {
4250
+ type: "text_updated",
4251
+ selector: payload.selector,
4252
+ content: element.innerText
4253
+ },
4254
+ timestamp: Date.now()
4255
+ });
4256
+ };
4257
+ const handleBlur = () => {
4258
+ element.removeAttribute("contenteditable");
4259
+ element.removeEventListener("input", handleInput);
4260
+ element.removeEventListener("blur", handleBlur);
4261
+ this.sendMessage({
4262
+ type: "ELEMENT_EVENT",
4263
+ payload: {
4264
+ type: "edit_completed",
4265
+ selector: payload.selector,
4266
+ finalContent: element.innerText
4267
+ },
4268
+ timestamp: Date.now()
4269
+ });
4270
+ };
4271
+ element.addEventListener("input", handleInput);
4272
+ element.addEventListener("blur", handleBlur);
4273
+ }
4266
4274
  }
4275
+ /** ----------------- 组件树相关消息处理 ----------------- */
4267
4276
  /**
4268
- * 添加事件监听器并记录以便清理
4277
+ * 处理请求组件树
4269
4278
  */
4270
- addEventListenerWithCleanup(element, event, handler, options) {
4271
- element.addEventListener(event, handler, options);
4272
- this.eventListeners.push({ element, event, handler, options });
4279
+ handleRequestComponentTree() {
4280
+ if (!this.componentTreeGenerator) return;
4281
+ try {
4282
+ const rootElement = document.querySelector("#root") || document.body;
4283
+ const componentTree = this.componentTreeGenerator.generateComponentTree(rootElement);
4284
+ this.sendMessage({
4285
+ type: "COMPONENT_EVENT",
4286
+ payload: {
4287
+ type: "tree_response",
4288
+ ...componentTree
4289
+ },
4290
+ timestamp: Date.now()
4291
+ });
4292
+ } catch (error) {
4293
+ const originalConsole = getOriginalConsole2();
4294
+ originalConsole.error("[MessageBridge] \u751F\u6210\u7EC4\u4EF6\u6811\u5931\u8D25:", error);
4295
+ this.sendMessage({
4296
+ type: "COMPONENT_EVENT",
4297
+ payload: {
4298
+ type: "tree_error",
4299
+ error: error instanceof Error ? error.message : String(error)
4300
+ },
4301
+ timestamp: Date.now()
4302
+ });
4303
+ }
4273
4304
  }
4274
4305
  /**
4275
- * 移除所有事件监听器
4276
- */
4277
- removeEventListeners() {
4278
- this.eventListeners.forEach(({ element, event, handler }) => {
4279
- element.removeEventListener(event, handler);
4280
- });
4281
- this.eventListeners = [];
4282
- }
4283
- /** ----------------- 事件处理方法 ----------------- */
4284
- /**
4285
- * 跟踪鼠标位置
4286
- */
4287
- trackMousePosition(event) {
4288
- this.mousePosition = { x: event.clientX, y: event.clientY };
4289
- }
4290
- /**
4291
- * 处理鼠标悬停
4292
- */
4293
- handleMouseOver(event) {
4294
- if (!this.isActive) return;
4295
- const target = event.target;
4296
- if (!this.isSelectableElement(target)) return;
4297
- this.highlightElement(target);
4298
- this.updateTooltip(target);
4299
- }
4300
- /**
4301
- * 处理鼠标离开
4302
- */
4303
- handleMouseOut(event) {
4304
- if (!this.isActive) return;
4305
- this.clearHighlight();
4306
- this.hideTooltip();
4307
- }
4308
- /**
4309
- * 处理点击
4310
- */
4311
- handleClick(event) {
4312
- if (!this.isActive) return;
4313
- const currentTimestamp = Date.now();
4314
- const target = event.target;
4315
- if (this.lastClickTarget === target && currentTimestamp - this.lastClickTimestamp < 100) {
4316
- event.preventDefault();
4317
- event.stopPropagation();
4318
- return;
4319
- }
4320
- this.lastClickTimestamp = currentTimestamp;
4321
- this.lastClickTarget = target;
4322
- event.preventDefault();
4323
- event.stopPropagation();
4324
- if (!this.isSelectableElement(target)) return;
4325
- if (event.metaKey || event.ctrlKey) {
4326
- this.toggleElementSelection(target);
4327
- } else {
4328
- this.selectElement(target);
4329
- }
4330
- this.sendMessage({
4331
- type: "ELEMENT_CLICKED",
4332
- payload: {
4333
- element: this.getElementInfo(target),
4334
- isMultiSelect: event.metaKey || event.ctrlKey
4335
- }
4336
- });
4337
- }
4338
- /**
4339
- * 处理双击
4340
- */
4341
- handleDoubleClick(event) {
4342
- if (!this.isActive) return;
4343
- event.preventDefault();
4344
- event.stopPropagation();
4345
- const target = event.target;
4346
- if (!this.isSelectableElement(target)) return;
4347
- this.sendMessage({
4348
- type: "ELEMENT_DOUBLE_CLICKED",
4349
- payload: {
4350
- element: this.getElementInfo(target)
4351
- }
4352
- });
4353
- }
4354
- /**
4355
- * 处理滚动
4356
- */
4357
- handleScroll() {
4358
- if (!this.isActive) return;
4359
- this.hideTooltip();
4360
- }
4361
- /**
4362
- * 处理键盘事件
4363
- */
4364
- handleKeyDown(event) {
4365
- if (!this.isActive) return;
4366
- const keyboardEvent = event;
4367
- if (keyboardEvent.key === "Escape") {
4368
- event.preventDefault();
4369
- event.stopPropagation();
4370
- this.disableSelector();
4371
- }
4372
- }
4373
- /**
4374
- * 阻止表单交互
4375
- */
4376
- preventFormInteraction(event) {
4377
- if (!this.isActive) return;
4378
- const target = event.target;
4379
- if (["input", "textarea", "select"].includes(target.tagName.toLowerCase())) {
4380
- event.preventDefault();
4381
- }
4382
- }
4383
- /**
4384
- * 阻止所有交互
4385
- */
4386
- preventAllInteraction(event) {
4387
- if (this.isActive) {
4388
- event.preventDefault();
4389
- event.stopPropagation();
4390
- return false;
4391
- }
4392
- }
4393
- /** ----------------- 元素操作方法 ----------------- */
4394
- /**
4395
- * 高亮元素
4396
- */
4397
- highlightElement(element) {
4398
- this.clearHighlight();
4399
- this.highlightedElement = element;
4400
- element.setAttribute("data-element-hovered", "true");
4401
- if (this.isFullWidthElement(element)) {
4402
- element.setAttribute("data-full-width", "true");
4403
- }
4404
- }
4405
- /**
4406
- * 清除高亮
4407
- */
4408
- clearHighlight() {
4409
- if (this.highlightedElement) {
4410
- this.highlightedElement.removeAttribute("data-element-hovered");
4411
- this.highlightedElement.removeAttribute("data-full-width");
4412
- this.highlightedElement = null;
4413
- }
4414
- }
4415
- /**
4416
- * 选择元素
4417
- */
4418
- selectElement(element) {
4419
- this.clearSelection();
4420
- this.selectedElements = [element];
4421
- element.setAttribute("data-element-selected", "true");
4422
- if (this.isFullWidthElement(element)) {
4423
- element.setAttribute("data-full-width", "true");
4424
- }
4425
- }
4426
- /**
4427
- * 切换元素选择状态
4428
- */
4429
- toggleElementSelection(element) {
4430
- const index = this.selectedElements.indexOf(element);
4431
- if (index > -1) {
4432
- this.selectedElements.splice(index, 1);
4433
- element.removeAttribute("data-element-selected");
4434
- element.removeAttribute("data-full-width");
4435
- } else {
4436
- this.selectedElements.push(element);
4437
- element.setAttribute("data-element-selected", "true");
4438
- if (this.isFullWidthElement(element)) {
4439
- element.setAttribute("data-full-width", "true");
4440
- }
4441
- }
4442
- }
4443
- /**
4444
- * 清除选择
4445
- */
4446
- clearSelection() {
4447
- this.selectedElements.forEach((element) => {
4448
- element.removeAttribute("data-element-selected");
4449
- element.removeAttribute("data-full-width");
4450
- });
4451
- this.selectedElements = [];
4452
- }
4453
- /** ----------------- 工具提示管理 ----------------- */
4454
- /**
4455
- * 更新工具提示
4456
- */
4457
- updateTooltip(element) {
4458
- if (!this.tooltip) return;
4459
- const rect = element.getBoundingClientRect();
4460
- const tagName = element.tagName.toLowerCase();
4461
- this.tooltip.textContent = tagName;
4462
- this.tooltip.style.display = "block";
4463
- const isFullWidth = this.isFullWidthElement(element);
4464
- if (isFullWidth) {
4465
- this.tooltip.style.left = this.config.FULL_WIDTH_TOOLTIP_OFFSET + "px";
4466
- this.tooltip.style.top = this.config.FULL_WIDTH_TOOLTIP_OFFSET + "px";
4467
- } else {
4468
- const top = Math.max(0, rect.top - 30);
4469
- this.tooltip.style.left = `${Math.max(0, rect.left)}px`;
4470
- this.tooltip.style.top = `${top}px`;
4471
- }
4472
- }
4473
- /**
4474
- * 隐藏工具提示
4475
- */
4476
- hideTooltip() {
4477
- if (this.tooltip) {
4478
- this.tooltip.style.display = "none";
4479
- }
4480
- }
4481
- /** ----------------- 按钮状态管理 ----------------- */
4482
- /**
4483
- * 管理按钮状态
4484
- */
4485
- manageButtonStates(enable) {
4486
- if (!this.rootElement) return;
4487
- const buttons = this.rootElement.querySelectorAll('button, input[type="button"], input[type="submit"]');
4488
- if (enable) {
4489
- buttons.forEach((button) => {
4490
- const btn = button;
4491
- if (!btn.disabled) {
4492
- btn.disabled = true;
4493
- btn.setAttribute("data-selector-disabled", "true");
4494
- }
4495
- });
4496
- } else {
4497
- buttons.forEach((button) => {
4498
- const btn = button;
4499
- if (btn.hasAttribute("data-selector-disabled")) {
4500
- btn.disabled = false;
4501
- btn.removeAttribute("data-selector-disabled");
4502
- }
4503
- });
4504
- }
4505
- }
4506
- /** ----------------- 新增的精确代码位置定位方法 ----------------- */
4507
- /**
4508
- * 检查元素是否有 howone ID
4509
- */
4510
- hasHowoneId(element) {
4511
- return element.hasAttribute("data-howone-id");
4512
- }
4513
- /**
4514
- * 解析 howone ID
4515
- */
4516
- parseHowoneId(element) {
4517
- const howoneId = element.getAttribute("data-howone-id");
4518
- if (!howoneId) return null;
4519
- try {
4520
- if (howoneId.includes(":")) {
4521
- const parts = howoneId.split(":");
4522
- if (parts.length >= 2) {
4523
- return {
4524
- filePath: parts[0],
4525
- lineNumber: parseInt(parts[1], 10),
4526
- col: parts[2] ? parseInt(parts[2], 10) : 0
4527
- };
4528
- }
4529
- } else {
4530
- const parsed = JSON.parse(howoneId);
4531
- if (parsed.filePath && parsed.lineNumber) {
4532
- return {
4533
- filePath: parsed.filePath,
4534
- lineNumber: parsed.lineNumber,
4535
- col: parsed.col || 0
4536
- };
4537
- }
4538
- }
4539
- } catch (error) {
4540
- console.warn("[ElementSelector] \u89E3\u6790 data-howone-id \u5931\u8D25:", error);
4541
- }
4542
- return null;
4543
- }
4544
- /**
4545
- * 获取元素的代码位置
4546
- */
4547
- getElementLocation(element) {
4548
- return this.parseHowoneId(element);
4549
- }
4550
- /**
4551
- * 提取元素数据(包含位置信息)
4552
- */
4553
- extractElementData(element) {
4554
- const location = this.getElementLocation(element);
4555
- return {
4556
- id: element.id || void 0,
4557
- className: element.className || void 0,
4558
- textContent: element.textContent?.trim().substring(0, 100) || void 0,
4559
- filePath: location?.filePath,
4560
- lineNumber: location?.lineNumber,
4561
- col: location?.col,
4562
- elementType: element.tagName.toLowerCase(),
4563
- attrs: this.getElementAttributes(element)
4564
- };
4565
- }
4566
- /**
4567
- * 根据代码位置查找元素
4568
- */
4569
- findElementsByLocation(filePath, lineNumber) {
4570
- const elements = [];
4571
- const elementsWithHowoneId = this.rootElement?.querySelectorAll("[data-howone-id]") || [];
4572
- elementsWithHowoneId.forEach((element) => {
4573
- const location = this.getElementLocation(element);
4574
- if (location && location.filePath === filePath && location.lineNumber === lineNumber) {
4575
- elements.push(element);
4576
- }
4577
- });
4578
- return elements;
4579
- }
4580
- /**
4581
- * 获取指定坐标位置的元素
4582
- */
4583
- getElementAtPoint(x, y) {
4584
- const originalDisplay = this.tooltip?.style.display;
4585
- if (this.tooltip) {
4586
- this.tooltip.style.display = "none";
4587
- }
4588
- const element = document.elementFromPoint(x, y);
4589
- if (this.tooltip && originalDisplay) {
4590
- this.tooltip.style.display = originalDisplay;
4591
- }
4592
- return element;
4593
- }
4594
- /** ----------------- 元素编辑功能 ----------------- */
4595
- /**
4596
- * 设置元素内容
4597
- */
4598
- setElementContent(selector, content) {
4599
- try {
4600
- const element = document.querySelector(selector);
4601
- if (!element) return false;
4602
- if (element.tagName.toLowerCase() === "input" || element.tagName.toLowerCase() === "textarea") {
4603
- element.value = content;
4604
- } else {
4605
- element.textContent = content;
4606
- }
4607
- this.sendMessage({
4608
- type: "ELEMENT_CONTENT_UPDATED",
4609
- payload: {
4610
- selector,
4611
- content,
4612
- element: this.getElementInfo(element)
4613
- }
4614
- });
4615
- return true;
4616
- } catch (error) {
4617
- console.error("[ElementSelector] \u8BBE\u7F6E\u5143\u7D20\u5185\u5BB9\u5931\u8D25:", error);
4618
- return false;
4619
- }
4620
- }
4621
- /**
4622
- * 设置元素属性
4623
- */
4624
- setElementAttributes(selector, attributes) {
4625
- try {
4626
- const element = document.querySelector(selector);
4627
- if (!element) return false;
4628
- Object.entries(attributes).forEach(([key, value]) => {
4629
- if (value === null || value === void 0) {
4630
- element.removeAttribute(key);
4631
- } else {
4632
- element.setAttribute(key, value);
4633
- }
4634
- });
4635
- this.sendMessage({
4636
- type: "ELEMENT_ATTRIBUTES_UPDATED",
4637
- payload: {
4638
- selector,
4639
- attributes,
4640
- element: this.getElementInfo(element)
4641
- }
4642
- });
4643
- return true;
4644
- } catch (error) {
4645
- console.error("[ElementSelector] \u8BBE\u7F6E\u5143\u7D20\u5C5E\u6027\u5931\u8D25:", error);
4646
- return false;
4647
- }
4648
- }
4649
- /**
4650
- * 复制元素
4651
- */
4652
- duplicateElement(selector) {
4653
- try {
4654
- const element = document.querySelector(selector);
4655
- if (!element || !element.parentNode) return false;
4656
- const clonedElement = element.cloneNode(true);
4657
- clonedElement.removeAttribute("data-blnk-id");
4658
- element.parentNode.insertBefore(clonedElement, element.nextSibling);
4659
- this.sendMessage({
4660
- type: "ELEMENT_DUPLICATED",
4661
- payload: {
4662
- originalSelector: selector,
4663
- duplicatedElement: this.getElementInfo(clonedElement)
4664
- }
4665
- });
4666
- return true;
4667
- } catch (error) {
4668
- console.error("[ElementSelector] \u590D\u5236\u5143\u7D20\u5931\u8D25:", error);
4669
- return false;
4670
- }
4671
- }
4672
- /**
4673
- * 启用文本编辑
4674
- */
4675
- enableTextEditing(selector) {
4676
- try {
4677
- const element = document.querySelector(selector);
4678
- if (!element) return false;
4679
- element.setAttribute("contenteditable", "true");
4680
- element.setAttribute("data-editing", "true");
4681
- element.focus();
4682
- const handleEditComplete = () => {
4683
- element.removeAttribute("contenteditable");
4684
- element.removeAttribute("data-editing");
4685
- element.removeEventListener("blur", handleEditComplete);
4686
- element.removeEventListener("keydown", handleKeyDown);
4687
- this.sendMessage({
4688
- type: "ELEMENT_TEXT_UPDATED",
4689
- payload: {
4690
- selector,
4691
- content: element.textContent || "",
4692
- element: this.getElementInfo(element)
4693
- }
4694
- });
4695
- };
4696
- const handleKeyDown = (event) => {
4697
- const keyboardEvent = event;
4698
- if (keyboardEvent.key === "Enter" && !keyboardEvent.shiftKey) {
4699
- event.preventDefault();
4700
- handleEditComplete();
4701
- } else if (keyboardEvent.key === "Escape") {
4702
- event.preventDefault();
4703
- handleEditComplete();
4704
- }
4705
- };
4706
- element.addEventListener("blur", handleEditComplete);
4707
- element.addEventListener("keydown", handleKeyDown);
4708
- return true;
4709
- } catch (error) {
4710
- console.error("[ElementSelector] \u542F\u7528\u6587\u672C\u7F16\u8F91\u5931\u8D25:", error);
4711
- return false;
4712
- }
4713
- }
4714
- /** ----------------- 高级交互功能 ----------------- */
4715
- /**
4716
- * 获取父元素
4717
- */
4718
- getParentElement(selector) {
4719
- try {
4720
- const element = document.querySelector(selector);
4721
- return element?.parentElement || null;
4722
- } catch (error) {
4723
- console.error("[ElementSelector] \u83B7\u53D6\u7236\u5143\u7D20\u5931\u8D25:", error);
4724
- return null;
4725
- }
4726
- }
4727
- /**
4728
- * 外部悬停控制 - 通过选择器悬停元素
4729
- */
4730
- hoverElementBySelector(selector) {
4731
- try {
4732
- const element = document.querySelector(selector);
4733
- if (!element) return false;
4734
- this.highlightElement(element);
4735
- this.updateTooltip(element);
4736
- return true;
4737
- } catch (error) {
4738
- console.error("[ElementSelector] \u5916\u90E8\u60AC\u505C\u63A7\u5236\u5931\u8D25:", error);
4739
- return false;
4740
- }
4741
- }
4742
- /**
4743
- * 外部悬停控制 - 取消悬停
4744
- */
4745
- unhoverElement() {
4746
- this.clearHighlight();
4747
- this.hideTooltip();
4748
- }
4749
- /** ----------------- 辅助方法 ----------------- */
4750
- /**
4751
- * 检查元素是否为全宽元素
4752
- */
4753
- isFullWidthElement(element) {
4754
- try {
4755
- const rect = element.getBoundingClientRect();
4756
- return Math.abs(rect.width - window.innerWidth) < 5;
4757
- } catch (error) {
4758
- console.warn("[ElementSelector] \u68C0\u67E5\u5168\u5BBD\u5143\u7D20\u5931\u8D25:", error);
4759
- return false;
4760
- }
4761
- }
4762
- /**
4763
- * 检查元素是否可选择
4764
- */
4765
- isSelectableElement(element) {
4766
- if (!element || element === document.body || element === document.documentElement) {
4767
- return false;
4768
- }
4769
- if (this.hasHowoneId(element)) {
4770
- return true;
4771
- }
4772
- if (element.id === "howone-element-tooltip" || element.classList.contains("howone-tooltip")) {
4773
- return false;
4774
- }
4775
- const tagName = element.tagName.toLowerCase();
4776
- if (["script", "style", "meta", "link", "title"].includes(tagName)) {
4777
- return false;
4778
- }
4779
- return true;
4780
- }
4781
- /**
4782
- * 获取元素信息
4783
- */
4784
- getElementInfo(element) {
4785
- const location = this.getElementLocation(element);
4786
- return {
4787
- tagName: element.tagName.toLowerCase(),
4788
- id: element.id || void 0,
4789
- className: element.className || void 0,
4790
- textContent: element.textContent?.trim().substring(0, 100) || void 0,
4791
- attributes: this.getElementAttributes(element),
4792
- selector: this.getElementSelector(element),
4793
- boundingRect: element.getBoundingClientRect(),
4794
- location: location || void 0
4795
- };
4796
- }
4797
- /**
4798
- * 获取元素属性
4799
- */
4800
- getElementAttributes(element) {
4801
- const attrs = {};
4802
- const importantAttrs = ["id", "class", "data-testid", "data-howone-id", "data-component-path", "data-blnk-id", "href", "src", "type", "name"];
4803
- importantAttrs.forEach((attr) => {
4804
- const value = element.getAttribute(attr);
4805
- if (value) {
4806
- attrs[attr] = value;
4807
- }
4808
- });
4809
- return attrs;
4810
- }
4811
- /**
4812
- * 获取元素选择器
4813
- */
4814
- getElementSelector(element) {
4815
- const howoneId = element.getAttribute("data-howone-id");
4816
- if (howoneId) {
4817
- return `[data-howone-id="${howoneId}"]`;
4818
- }
4819
- if (element.id) {
4820
- return `#${element.id}`;
4821
- }
4822
- const dataTestId = element.getAttribute("data-testid");
4823
- if (dataTestId) {
4824
- return `[data-testid="${dataTestId}"]`;
4825
- }
4826
- if (element.className) {
4827
- const classes = element.className.split(" ").filter((c) => c.trim());
4828
- if (classes.length > 0) {
4829
- return `.${classes[0]}`;
4830
- }
4831
- }
4832
- return element.tagName.toLowerCase();
4833
- }
4834
- /** ----------------- 公共接口方法 ----------------- */
4835
- /**
4836
- * 通过选择器高亮元素
4837
- */
4838
- highlightElementBySelector(selector) {
4839
- const element = document.querySelector(selector);
4840
- if (element) {
4841
- this.highlightElement(element);
4842
- }
4843
- }
4844
- /**
4845
- * 通过选择器取消高亮元素
4846
- */
4847
- unhighlightElementBySelector(selector) {
4848
- const element = document.querySelector(selector);
4849
- if (element && element === this.highlightedElement) {
4850
- this.clearHighlight();
4851
- }
4852
- }
4853
- /**
4854
- * 更新选中的元素
4855
- */
4856
- updateSelectedElements(elements) {
4857
- this.clearSelection();
4858
- elements.forEach((elementData) => {
4859
- const element = this.findElementByData(elementData);
4860
- if (element) {
4861
- this.selectedElements.push(element);
4862
- element.setAttribute("data-element-selected", "true");
4863
- if (this.isFullWidthElement(element)) {
4864
- element.setAttribute("data-full-width", "true");
4865
- }
4866
- }
4867
- });
4868
- }
4869
- /**
4870
- * 根据数据查找元素
4871
- */
4872
- findElementByData(elementData) {
4873
- if (elementData.blinkId) {
4874
- return document.querySelector(`[data-blnk-id="${elementData.blinkId}"]`);
4875
- }
4876
- if (elementData.id) {
4877
- return document.getElementById(elementData.id);
4878
- }
4879
- if (elementData.selector) {
4880
- return document.querySelector(elementData.selector);
4881
- }
4882
- return null;
4883
- }
4884
- /**
4885
- * 销毁选择器
4886
- */
4887
- destroy() {
4888
- this.disableSelector();
4889
- if (this.tooltip) {
4890
- this.tooltip.remove();
4891
- this.tooltip = null;
4892
- }
4893
- if (this.styleElement) {
4894
- this.styleElement.remove();
4895
- this.styleElement = null;
4896
- }
4897
- console.log("[ElementSelector] \u5143\u7D20\u9009\u62E9\u5668\u5DF2\u9500\u6BC1");
4898
- }
4899
- };
4900
-
4901
- // src/utils/unified-error-handler/features/MessageBridge.ts
4902
- var getOriginalConsole2 = () => window.__originalConsole || {
4903
- log: console.log.bind(console),
4904
- warn: console.warn.bind(console),
4905
- error: console.error.bind(console),
4906
- info: console.info.bind(console),
4907
- debug: console.debug.bind(console)
4908
- };
4909
- var MessageBridge = class {
4910
- constructor(sendMessage) {
4911
- this.elementSelector = null;
4912
- this.componentTreeGenerator = null;
4913
- this.messageSender = createDefaultMessageSender({
4914
- addTimestamp: true,
4915
- enableDebugLog: false
4916
- });
4917
- this.sendMessage = sendMessage || this.messageSender.createSendFunction();
4918
- this.setupMessageListener();
4919
- console.log("[MessageBridge] \u6D88\u606F\u6865\u63A5\u5668\u521D\u59CB\u5316\u5B8C\u6210");
4920
- }
4921
- /** ----------------- 依赖注入方法 ----------------- */
4922
- /**
4923
- * 设置元素选择器
4924
- */
4925
- setElementSelector(elementSelector2) {
4926
- this.elementSelector = elementSelector2;
4927
- }
4928
- /**
4929
- * 设置组件树生成器
4930
- */
4931
- setComponentTreeGenerator(componentTreeGenerator) {
4932
- this.componentTreeGenerator = componentTreeGenerator;
4933
- }
4934
- /** ----------------- 消息监听设置 ----------------- */
4935
- /**
4936
- * 设置消息监听器
4937
- */
4938
- setupMessageListener() {
4939
- this.messageListener = (event) => {
4940
- if (!this.isOriginAllowed(event.origin)) {
4941
- return;
4942
- }
4943
- if (event.data && typeof event.data === "object" && event.data.type) {
4944
- this.handleMessage(event.data);
4945
- }
4946
- };
4947
- window.addEventListener("message", this.messageListener);
4948
- }
4949
- /**
4950
- * 检查来源是否被允许
4951
- */
4952
- isOriginAllowed(origin) {
4953
- return GLOBAL_CONFIG.ALLOWED_ORIGINS.some(
4954
- (allowedOrigin) => origin.includes(allowedOrigin.replace("https://", "").replace("http://", ""))
4955
- );
4956
- }
4957
- /** ----------------- 主要消息处理方法 ----------------- */
4958
- /**
4959
- * 处理消息
4960
- */
4961
- handleMessage(message) {
4962
- try {
4963
- const { type, payload } = message;
4964
- switch (type) {
4965
- // 选择器相关消息
4966
- case "TOGGLE_SELECTOR":
4967
- this.handleToggleSelector(payload);
4968
- break;
4969
- case "ENABLE_SELECTOR":
4970
- this.handleEnableElementSelector();
4971
- break;
4972
- case "DISABLE_SELECTOR":
4973
- this.handleDisableElementSelector();
4974
- break;
4975
- case "GET_SELECTOR_STATE":
4976
- this.handleGetSelectorState();
4977
- break;
4978
- // 元素操作消息
4979
- case "HOVER_ELEMENT_BY_ID":
4980
- this.handleHoverElementById(payload);
4981
- break;
4982
- case "UNHOVER_ELEMENT_BY_ID":
4983
- this.handleUnhoverElementById(payload);
4984
- break;
4985
- case "HOVER_ELEMENT_REQUESTED":
4986
- this.handleHoverElementRequested(payload);
4987
- break;
4988
- case "UNHOVER_ELEMENT_REQUESTED":
4989
- this.handleUnhoverElementRequested(payload);
4990
- break;
4991
- case "SET_ELEMENT_CONTENT":
4992
- this.handleSetElementContent(payload);
4993
- break;
4994
- case "SET_ELEMENT_ATTRS":
4995
- this.handleSetElementAttrs(payload);
4996
- break;
4997
- case "DUPLICATE_ELEMENT_REQUESTED":
4998
- this.handleDuplicateElementRequested(payload);
4999
- break;
5000
- case "EDIT_TEXT_REQUESTED":
5001
- this.handleEditTextRequested(payload);
5002
- break;
5003
- case "UPDATE_SELECTED_ELEMENTS":
5004
- this.handleUpdateSelectedElements(payload);
5005
- break;
5006
- // 新增的消息类型
5007
- case "GET_ELEMENT_AT_POINT":
5008
- this.handleGetElementAtPoint(payload);
5009
- break;
5010
- case "FIND_ELEMENTS_BY_LOCATION":
5011
- this.handleFindElementsByLocation(payload);
5012
- break;
5013
- case "SET_ELEMENT_ATTRIBUTES":
5014
- this.handleSetElementAttributes(payload);
5015
- break;
5016
- case "ENABLE_TEXT_EDITING":
5017
- this.handleEnableTextEditing(payload);
5018
- break;
5019
- case "HOVER_ELEMENT_BY_SELECTOR":
5020
- this.handleHoverElementBySelector(payload);
5021
- break;
5022
- case "UNHOVER_ELEMENT":
5023
- this.handleUnhoverElement();
5024
- break;
5025
- // 组件树相关消息
5026
- case "REQUEST_COMPONENT_TREE":
5027
- this.handleRequestComponentTree();
5028
- break;
5029
- case "GET_PARENT_ELEMENT":
5030
- this.handleGetParentElement(payload);
5031
- break;
5032
- // 样式相关消息
5033
- case "SET_STYLESHEET":
5034
- this.handleSetStylesheet(payload);
5035
- break;
5036
- default:
5037
- break;
5038
- }
5039
- } catch (error) {
5040
- console.error("[MessageBridge] \u5904\u7406\u6D88\u606F\u5931\u8D25:", error);
5041
- this.sendMessage({
5042
- type: "ERROR_EVENT",
5043
- payload: {
5044
- type: "message_handling",
5045
- originalMessage: message,
5046
- error: error instanceof Error ? error.message : String(error)
5047
- },
5048
- timestamp: Date.now()
5049
- });
5050
- }
5051
- }
5052
- /** ----------------- 选择器相关消息处理 ----------------- */
5053
- /**
5054
- * 处理切换选择器
5055
- */
5056
- handleToggleSelector(payload) {
5057
- if (!this.elementSelector) return;
5058
- const shouldActivate = !!payload;
5059
- if (shouldActivate) {
5060
- this.elementSelector.enableSelector();
5061
- } else {
5062
- this.elementSelector.disableSelector();
5063
- }
5064
- }
5065
- /**
5066
- * 处理获取选择器状态
5067
- */
5068
- handleGetSelectorState() {
5069
- if (!this.elementSelector) return;
5070
- const state = this.elementSelector.getSelectorState();
5071
- this.sendMessage({
5072
- type: "SELECTOR_EVENT",
5073
- payload: {
5074
- type: "state_response",
5075
- ...state
5076
- },
5077
- timestamp: Date.now()
5078
- });
5079
- }
5080
- /**
5081
- * 处理启用元素选择器
5082
- */
5083
- handleEnableElementSelector() {
5084
- if (!this.elementSelector) return;
5085
- this.elementSelector.enableSelector();
5086
- }
5087
- /**
5088
- * 处理禁用元素选择器
5089
- */
5090
- handleDisableElementSelector() {
5091
- if (!this.elementSelector) return;
5092
- this.elementSelector.disableSelector();
5093
- }
5094
- /** ----------------- 元素操作消息处理 ----------------- */
5095
- /**
5096
- * 处理通过 ID 高亮元素
5097
- */
5098
- handleHoverElementById(payload) {
5099
- if (!this.elementSelector || !payload?.id) return;
5100
- const selector = `#${payload.id}`;
5101
- this.elementSelector.highlightElementBySelector(selector);
5102
- }
5103
- /**
5104
- * 处理通过 ID 取消高亮元素
5105
- */
5106
- handleUnhoverElementById(payload) {
5107
- if (!this.elementSelector || !payload?.id) return;
5108
- const selector = `#${payload.id}`;
5109
- this.elementSelector.unhighlightElementBySelector(selector);
5110
- }
5111
- /**
5112
- * 处理高亮元素请求
5113
- */
5114
- handleHoverElementRequested(payload) {
5115
- if (!this.elementSelector || !payload?.selector) return;
5116
- this.elementSelector.highlightElementBySelector(payload.selector);
5117
- }
5118
- /**
5119
- * 处理取消高亮元素请求
5120
- */
5121
- handleUnhoverElementRequested(payload) {
5122
- if (!this.elementSelector || !payload?.selector) return;
5123
- this.elementSelector.unhighlightElementBySelector(payload.selector);
5124
- }
5125
- /**
5126
- * 处理设置元素内容
5127
- */
5128
- handleSetElementContent(payload) {
5129
- if (!payload?.selector || !payload?.content) return;
5130
- const elements = document.querySelectorAll(payload.selector);
5131
- elements.forEach((element) => {
5132
- if (element instanceof HTMLElement) {
5133
- element.innerHTML = payload.content;
5134
- }
5135
- });
5136
- this.sendMessage({
5137
- type: "ELEMENT_EVENT",
5138
- payload: {
5139
- type: "content_updated",
5140
- selector: payload.selector,
5141
- content: payload.content,
5142
- elementsUpdated: elements.length
5143
- },
5144
- timestamp: Date.now()
5145
- });
5146
- }
5147
- /**
5148
- * 处理设置元素属性
5149
- */
5150
- handleSetElementAttrs(payload) {
5151
- if (!payload?.selector || !payload?.attrs) return;
5152
- const elements = document.querySelectorAll(payload.selector);
5153
- elements.forEach((element) => {
5154
- Object.entries(payload.attrs).forEach(([key, value]) => {
5155
- element.setAttribute(key, String(value));
5156
- });
5157
- });
5158
- this.sendMessage({
5159
- type: "ELEMENT_EVENT",
5160
- payload: {
5161
- type: "attrs_updated",
5162
- selector: payload.selector,
5163
- attrs: payload.attrs,
5164
- elementsUpdated: elements.length
5165
- },
5166
- timestamp: Date.now()
5167
- });
5168
- }
5169
- /**
5170
- * 处理复制元素请求
5171
- */
5172
- handleDuplicateElementRequested(payload) {
5173
- if (!payload?.selector) return;
5174
- const element = document.querySelector(payload.selector);
5175
- if (element && element.parentElement) {
5176
- const clone = element.cloneNode(true);
5177
- clone.setAttribute("data-duplicated", "true");
5178
- element.parentElement.appendChild(clone);
5179
- this.sendMessage({
5180
- type: "ELEMENT_EVENT",
5181
- payload: {
5182
- type: "duplicated",
5183
- originalSelector: payload.selector,
5184
- duplicatedElement: this.getElementInfo(clone)
5185
- },
5186
- timestamp: Date.now()
5187
- });
5188
- }
5189
- }
5190
- /**
5191
- * 处理编辑文本请求
5192
- */
5193
- handleEditTextRequested(payload) {
5194
- if (!payload?.selector) return;
5195
- const element = document.querySelector(payload.selector);
5196
- if (element instanceof HTMLElement) {
5197
- element.setAttribute("contenteditable", "true");
5198
- element.focus();
5199
- const handleInput = () => {
5200
- this.sendMessage({
5201
- type: "ELEMENT_EVENT",
5202
- payload: {
5203
- type: "text_updated",
5204
- selector: payload.selector,
5205
- content: element.innerText
5206
- },
5207
- timestamp: Date.now()
5208
- });
5209
- };
5210
- const handleBlur = () => {
5211
- element.removeAttribute("contenteditable");
5212
- element.removeEventListener("input", handleInput);
5213
- element.removeEventListener("blur", handleBlur);
5214
- this.sendMessage({
5215
- type: "ELEMENT_EVENT",
5216
- payload: {
5217
- type: "edit_completed",
5218
- selector: payload.selector,
5219
- finalContent: element.innerText
5220
- },
5221
- timestamp: Date.now()
5222
- });
5223
- };
5224
- element.addEventListener("input", handleInput);
5225
- element.addEventListener("blur", handleBlur);
5226
- }
5227
- }
5228
- /**
5229
- * 处理更新选中元素
5230
- */
5231
- handleUpdateSelectedElements(payload) {
5232
- if (!this.elementSelector || !Array.isArray(payload)) return;
5233
- this.elementSelector.updateSelectedElements(payload);
5234
- this.sendMessage({
5235
- type: "ELEMENT_EVENT",
5236
- payload: {
5237
- type: "selected_elements_updated",
5238
- selectedElements: payload,
5239
- count: payload.length
5240
- },
5241
- timestamp: Date.now()
5242
- });
5243
- }
5244
- /** ----------------- 组件树相关消息处理 ----------------- */
5245
- /**
5246
- * 处理请求组件树
5247
- */
5248
- handleRequestComponentTree() {
5249
- if (!this.componentTreeGenerator) return;
5250
- try {
5251
- const rootElement = document.querySelector("#root") || document.body;
5252
- const componentTree = this.componentTreeGenerator.generateComponentTree(rootElement);
5253
- this.sendMessage({
5254
- type: "COMPONENT_EVENT",
5255
- payload: {
5256
- type: "tree_response",
5257
- ...componentTree
5258
- },
5259
- timestamp: Date.now()
5260
- });
5261
- } catch (error) {
5262
- const originalConsole = getOriginalConsole2();
5263
- originalConsole.error("[MessageBridge] \u751F\u6210\u7EC4\u4EF6\u6811\u5931\u8D25:", error);
5264
- this.sendMessage({
5265
- type: "COMPONENT_EVENT",
5266
- payload: {
5267
- type: "tree_error",
5268
- error: error instanceof Error ? error.message : String(error)
5269
- },
5270
- timestamp: Date.now()
5271
- });
5272
- }
5273
- }
5274
- /**
5275
- * 处理获取父元素
4306
+ * 处理获取父元素
5276
4307
  */
5277
4308
  handleGetParentElement(payload) {
5278
4309
  if (!payload?.selector) return;
@@ -5364,11 +4395,9 @@ var MessageBridge = class {
5364
4395
  if (dataTestId) return `[data-testid="${dataTestId}"]`;
5365
4396
  const dataHowoneId = element.getAttribute("data-howone-id");
5366
4397
  if (dataHowoneId) return `[data-howone-id="${dataHowoneId}"]`;
5367
- if (element.className) {
5368
- const classes = element.className.split(" ").filter((c) => c.trim());
5369
- if (classes.length > 0) {
5370
- return `.${classes[0]}`;
5371
- }
4398
+ const classes = getElementClasses(element);
4399
+ if (classes.length > 0) {
4400
+ return `.${classes[0]}`;
5372
4401
  }
5373
4402
  return element.tagName.toLowerCase();
5374
4403
  }
@@ -5396,106 +4425,6 @@ var MessageBridge = class {
5396
4425
  timestamp: Date.now()
5397
4426
  });
5398
4427
  }
5399
- /** ----------------- 新增的消息处理方法 ----------------- */
5400
- /**
5401
- * 处理获取鼠标位置的元素
5402
- */
5403
- handleGetElementAtPoint(payload) {
5404
- if (!this.elementSelector) return;
5405
- const element = this.elementSelector.getElementAtPoint(payload?.x, payload?.y);
5406
- this.sendMessage({
5407
- type: "ELEMENT_EVENT",
5408
- payload: {
5409
- type: "at_point_response",
5410
- element: element ? this.getElementInfo(element) : null,
5411
- coordinates: { x: payload?.x, y: payload?.y }
5412
- },
5413
- timestamp: Date.now()
5414
- });
5415
- }
5416
- /**
5417
- * 处理根据位置查找元素
5418
- */
5419
- handleFindElementsByLocation(payload) {
5420
- if (!this.elementSelector || !payload?.filePath || !payload?.lineNumber) return;
5421
- const elements = this.elementSelector.findElementsByLocation(payload.filePath, payload.lineNumber);
5422
- this.sendMessage({
5423
- type: "ELEMENT_EVENT",
5424
- payload: {
5425
- type: "elements_by_location_response",
5426
- elements: elements.map((el) => this.getElementInfo(el)),
5427
- location: {
5428
- filePath: payload.filePath,
5429
- lineNumber: payload.lineNumber
5430
- }
5431
- },
5432
- timestamp: Date.now()
5433
- });
5434
- }
5435
- /**
5436
- * 处理设置元素属性(新版本)
5437
- */
5438
- handleSetElementAttributes(payload) {
5439
- if (!this.elementSelector || !payload?.selector || !payload?.attributes) return;
5440
- const success = this.elementSelector.setElementAttributes(payload.selector, payload.attributes);
5441
- this.sendMessage({
5442
- type: "ELEMENT_EVENT",
5443
- payload: {
5444
- type: "attributes_set_response",
5445
- success,
5446
- selector: payload.selector,
5447
- attributes: payload.attributes
5448
- },
5449
- timestamp: Date.now()
5450
- });
5451
- }
5452
- /**
5453
- * 处理启用文本编辑
5454
- */
5455
- handleEnableTextEditing(payload) {
5456
- if (!this.elementSelector || !payload?.selector) return;
5457
- const success = this.elementSelector.enableTextEditing(payload.selector);
5458
- this.sendMessage({
5459
- type: "ELEMENT_EVENT",
5460
- payload: {
5461
- type: "text_editing_enabled_response",
5462
- success,
5463
- selector: payload.selector
5464
- },
5465
- timestamp: Date.now()
5466
- });
5467
- }
5468
- /**
5469
- * 处理通过选择器悬停元素
5470
- */
5471
- handleHoverElementBySelector(payload) {
5472
- if (!this.elementSelector || !payload?.selector) return;
5473
- const success = this.elementSelector.hoverElementBySelector(payload.selector);
5474
- this.sendMessage({
5475
- type: "ELEMENT_EVENT",
5476
- payload: {
5477
- type: "hovered_by_selector_response",
5478
- success,
5479
- selector: payload.selector
5480
- },
5481
- timestamp: Date.now()
5482
- });
5483
- }
5484
- /**
5485
- * 处理取消悬停元素
5486
- */
5487
- handleUnhoverElement() {
5488
- if (!this.elementSelector) return;
5489
- this.elementSelector.unhoverElement();
5490
- this.sendMessage({
5491
- type: "ELEMENT_EVENT",
5492
- payload: {
5493
- type: "unhovered_response",
5494
- success: true
5495
- },
5496
- timestamp: Date.now()
5497
- });
5498
- }
5499
4428
  /** ----------------- 统一消息发送管理方法 ----------------- */
5500
4429
  /**
5501
4430
  * 获取统一的消息发送器实例
@@ -5529,7 +4458,6 @@ var MessageBridge = class {
5529
4458
  window.removeEventListener("message", this.messageListener);
5530
4459
  this.messageListener = void 0;
5531
4460
  }
5532
- console.log("[MessageBridge] \u6D88\u606F\u6865\u63A5\u5668\u5DF2\u9500\u6BC1");
5533
4461
  }
5534
4462
  };
5535
4463
 
@@ -5557,7 +4485,6 @@ var ErrorHandler = class {
5557
4485
  enableInteractionTracking: true
5558
4486
  };
5559
4487
  this.config = { ...this.config, ...options };
5560
- console.log("[ErrorHandler] \u5F00\u59CB\u521D\u59CB\u5316\u7EDF\u4E00\u9519\u8BEF\u5904\u7406\u5668...");
5561
4488
  this.messageSender = createDefaultMessageSender({
5562
4489
  addTimestamp: true,
5563
4490
  enableDebugLog: false
@@ -5565,16 +4492,13 @@ var ErrorHandler = class {
5565
4492
  const sendMessage = this.messageSender.createSendFunction();
5566
4493
  this.errorTracking = new ErrorTracking(sendMessage);
5567
4494
  this.interactionTracking = new InteractionTracking(sendMessage);
5568
- this.elementSelector = new ElementSelector2(sendMessage);
5569
4495
  this.messageBridge = new MessageBridge();
5570
4496
  this.viewDetector = new ViewDetector();
5571
4497
  this.hardRefreshManager = new HardRefreshManager(GLOBAL_CONFIG.ALLOWED_ORIGINS);
5572
4498
  this.componentTreeGenerator = new ComponentTreeGenerator();
5573
4499
  if (this.config.enableViteHMR && ViteHMRDetector.isViteEnvironment()) {
5574
4500
  this.viteHMRDetector = new ViteHMRDetector(sendMessage);
5575
- console.log("[ErrorHandler] Vite HMR \u68C0\u6D4B\u5668\u5DF2\u521D\u59CB\u5316");
5576
4501
  }
5577
- console.log("[ErrorHandler] \u6A21\u5757\u521D\u59CB\u5316\u5B8C\u6210");
5578
4502
  }
5579
4503
  /** ----------------- 主要初始化方法 ----------------- */
5580
4504
  /**
@@ -5586,12 +4510,10 @@ var ErrorHandler = class {
5586
4510
  return;
5587
4511
  }
5588
4512
  try {
5589
- console.log("[ErrorHandler] \u5F00\u59CB\u521D\u59CB\u5316\u5404\u4E2A\u6A21\u5757...");
5590
4513
  this.initializeCore();
5591
4514
  this.setupModuleIntegration();
5592
4515
  this.enableFeatures();
5593
4516
  this.initialized = true;
5594
- console.log("[ErrorHandler] \u521D\u59CB\u5316\u5B8C\u6210");
5595
4517
  } catch (error) {
5596
4518
  console.error("[ErrorHandler] \u521D\u59CB\u5316\u5931\u8D25:", error);
5597
4519
  throw error;
@@ -5604,7 +4526,6 @@ var ErrorHandler = class {
5604
4526
  this.initializeGlobalState();
5605
4527
  this.setupDebugEndpoint();
5606
4528
  this.errorTracking.initialize();
5607
- console.log("[ErrorHandler] \u6838\u5FC3\u529F\u80FD\u521D\u59CB\u5316\u5B8C\u6210");
5608
4529
  }
5609
4530
  /**
5610
4531
  * 初始化全局状态
@@ -5616,7 +4537,6 @@ var ErrorHandler = class {
5616
4537
  if (!window.__AUTO_ENGINEER_INTERACTION_TRAIL__) {
5617
4538
  window.__AUTO_ENGINEER_INTERACTION_TRAIL__ = [];
5618
4539
  }
5619
- console.log("[ErrorHandler] \u5168\u5C40\u72B6\u6001\u521D\u59CB\u5316\u5B8C\u6210");
5620
4540
  }
5621
4541
  /**
5622
4542
  * 设置调试端点
@@ -5636,28 +4556,22 @@ var ErrorHandler = class {
5636
4556
  * 设置模块间的协作
5637
4557
  */
5638
4558
  setupModuleIntegration() {
5639
- this.messageBridge.setElementSelector(this.elementSelector);
5640
4559
  this.messageBridge.setComponentTreeGenerator(this.componentTreeGenerator);
5641
4560
  this.errorTracking.setViewDetector(this.viewDetector);
5642
4561
  this.errorTracking.setInteractionTracking(this.interactionTracking);
5643
- console.log("[ErrorHandler] \u6A21\u5757\u96C6\u6210\u8BBE\u7F6E\u5B8C\u6210");
5644
4562
  }
5645
4563
  /**
5646
4564
  * 启用功能模块
5647
4565
  */
5648
4566
  enableFeatures() {
5649
- console.log("[ErrorHandler] \u542F\u7528\u529F\u80FD\u6A21\u5757...");
5650
4567
  if (this.config.enableInteractionTracking) {
5651
4568
  this.interactionTracking.startTracking();
5652
- console.log("[ErrorHandler] \u4EA4\u4E92\u8FFD\u8E2A\u5DF2\u542F\u7528");
5653
4569
  }
5654
4570
  if (this.viteHMRDetector) {
5655
4571
  this.viteHMRDetector.initialize();
5656
- console.log("[ErrorHandler] Vite HMR \u68C0\u6D4B\u5668\u5DF2\u542F\u7528");
5657
4572
  }
5658
4573
  this.handleHardRefreshLogic();
5659
4574
  this.setupViewDetection();
5660
- console.log("[ErrorHandler] \u529F\u80FD\u6A21\u5757\u542F\u7528\u5B8C\u6210");
5661
4575
  }
5662
4576
  /**
5663
4577
  * 处理硬刷新逻辑
@@ -5666,7 +4580,6 @@ var ErrorHandler = class {
5666
4580
  HardRefreshManager.cleanupRefreshParams();
5667
4581
  const refreshStats = HardRefreshManager.getRefreshStats();
5668
4582
  if (refreshStats.isHardRefresh) {
5669
- console.log("[ErrorHandler] \u68C0\u6D4B\u5230\u786C\u5237\u65B0:", refreshStats);
5670
4583
  this.messageSender.send({
5671
4584
  type: "SYSTEM_EVENT",
5672
4585
  payload: {
@@ -5687,7 +4600,6 @@ var ErrorHandler = class {
5687
4600
  const currentView = this.viewDetector.getCurrentViewInfo();
5688
4601
  if (currentView.title !== lastViewTitle) {
5689
4602
  lastViewTitle = currentView.title;
5690
- console.log("[ErrorHandler] \u89C6\u56FE\u53D8\u5316:", currentView);
5691
4603
  }
5692
4604
  };
5693
4605
  setInterval(checkViewChange, 1e3);
@@ -5720,12 +4632,6 @@ var ErrorHandler = class {
5720
4632
  getErrorStats() {
5721
4633
  return this.errorTracking.getErrorStats();
5722
4634
  }
5723
- /**
5724
- * 获取选择器状态
5725
- */
5726
- getSelectorState() {
5727
- return this.elementSelector.getSelectorState();
5728
- }
5729
4635
  /**
5730
4636
  * 获取交互历史
5731
4637
  */
@@ -5759,30 +4665,11 @@ var ErrorHandler = class {
5759
4665
  isViteEnvironment() {
5760
4666
  return ViteHMRDetector.isViteEnvironment();
5761
4667
  }
5762
- /**
5763
- * 启用元素选择器
5764
- */
5765
- enableElementSelector() {
5766
- this.elementSelector.enableSelector();
5767
- }
5768
- /**
5769
- * 禁用元素选择器
5770
- */
5771
- disableElementSelector() {
5772
- this.elementSelector.disableSelector();
5773
- }
5774
- /**
5775
- * 切换元素选择器状态
5776
- */
5777
- toggleElementSelector() {
5778
- this.elementSelector.toggleSelector();
5779
- }
5780
4668
  /**
5781
4669
  * 更新配置
5782
4670
  */
5783
4671
  updateConfig(newConfig) {
5784
4672
  this.config = { ...this.config, ...newConfig };
5785
- console.log("[ErrorHandler] \u914D\u7F6E\u5DF2\u66F4\u65B0:", this.config);
5786
4673
  }
5787
4674
  /**
5788
4675
  * 销毁错误处理器
@@ -5791,7 +4678,6 @@ var ErrorHandler = class {
5791
4678
  try {
5792
4679
  this.errorTracking.destroy();
5793
4680
  this.interactionTracking.destroy();
5794
- this.elementSelector.destroy();
5795
4681
  this.messageBridge.destroy();
5796
4682
  if (this.viteHMRDetector) {
5797
4683
  this.viteHMRDetector.destroy();
@@ -5801,7 +4687,6 @@ var ErrorHandler = class {
5801
4687
  this.viewDetector.clearCache();
5802
4688
  }
5803
4689
  this.initialized = false;
5804
- console.log("[ErrorHandler] \u5DF2\u9500\u6BC1");
5805
4690
  } catch (error) {
5806
4691
  const originalConsole = getOriginalConsole3();
5807
4692
  originalConsole.error("[ErrorHandler] \u9500\u6BC1\u65F6\u53D1\u751F\u9519\u8BEF:", error);
@@ -5823,7 +4708,6 @@ var ErrorHandler = class {
5823
4708
  errorStats: this.getErrorStats(),
5824
4709
  currentView: this.getCurrentView(),
5825
4710
  interactionHistory: this.getInteractionHistory(),
5826
- selectorState: this.getSelectorState(),
5827
4711
  isViteEnvironment: this.isViteEnvironment(),
5828
4712
  timestamp: Date.now()
5829
4713
  };
@@ -5847,7 +4731,6 @@ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
5847
4731
  var globalErrorHandler = null;
5848
4732
  var initializeErrorHandler = () => {
5849
4733
  if (!globalErrorHandler) {
5850
- console.log("[HowOneProvider] \u5728\u6A21\u5757\u9876\u5C42\u521D\u59CB\u5316\u9519\u8BEF\u5904\u7406\u5668...");
5851
4734
  globalErrorHandler = new ErrorHandler({
5852
4735
  enableViteHMR: true,
5853
4736
  enableElementSelector: true,
@@ -5855,7 +4738,6 @@ var initializeErrorHandler = () => {
5855
4738
  });
5856
4739
  globalErrorHandler.init();
5857
4740
  window.__ERROR_HANDLER__ = globalErrorHandler;
5858
- console.log("[HowOneProvider] \u9519\u8BEF\u5904\u7406\u5668\u5DF2\u5728\u6A21\u5757\u9876\u5C42\u521D\u59CB\u5316\u5B8C\u6210");
5859
4741
  }
5860
4742
  return globalErrorHandler;
5861
4743
  };
@@ -5883,7 +4765,6 @@ var HowOneProvider = ({
5883
4765
  urlToken = hashParams.get("access_token") || hashParams.get("token");
5884
4766
  }
5885
4767
  if (urlToken) {
5886
- console.log("[HowOneProvider] Token captured from URL, storing to localStorage...");
5887
4768
  setToken(urlToken);
5888
4769
  setTokenState(urlToken);
5889
4770
  setUser(parseUserFromToken(urlToken));
@@ -5893,7 +4774,6 @@ var HowOneProvider = ({
5893
4774
  const newSearch = params.toString();
5894
4775
  const newUrl = window.location.pathname + (newSearch ? "?" + newSearch : "");
5895
4776
  window.history.replaceState({}, "", newUrl);
5896
- console.log("[HowOneProvider] Token stored successfully, URL cleaned");
5897
4777
  }
5898
4778
  } catch (e) {
5899
4779
  console.error("[HowOneProvider] Failed to capture token from URL:", e);
@@ -5908,7 +4788,6 @@ var HowOneProvider = ({
5908
4788
  if (redirectOnUnauthenticated && !token && !user) {
5909
4789
  const currentUrl = new URL(window.location.href);
5910
4790
  if (!currentUrl.pathname.includes("/auth")) {
5911
- console.log("[HowOneProvider] No token found, redirecting to auth page...");
5912
4791
  try {
5913
4792
  const authUrlObj = new URL(authUrl);
5914
4793
  const redirectUri = window.location.href;
@@ -5916,7 +4795,6 @@ var HowOneProvider = ({
5916
4795
  if (projectId) {
5917
4796
  authUrlObj.searchParams.set("project_id", projectId);
5918
4797
  }
5919
- console.log("[HowOneProvider] Redirecting to:", authUrlObj.toString());
5920
4798
  window.location.href = authUrlObj.toString();
5921
4799
  } catch (error) {
5922
4800
  console.error("[HowOneProvider] Failed to build auth URL:", error);
@@ -7196,7 +6074,6 @@ var SimpleErrorHandler = class {
7196
6074
  this.setupErrorListeners();
7197
6075
  this.setupCompatibility();
7198
6076
  this.initialized = true;
7199
- console.log("[\u7B80\u5316\u9519\u8BEF\u5904\u7406] \u521D\u59CB\u5316\u5B8C\u6210");
7200
6077
  }
7201
6078
  /**
7202
6079
  * 设置错误监听器