@qontinui/ui-bridge 0.1.1 → 0.2.0
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/ai/index.d.mts +893 -0
- package/dist/ai/index.d.ts +893 -0
- package/dist/ai/index.js +3897 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/index.mjs +3839 -0
- package/dist/ai/index.mjs.map +1 -0
- package/dist/control/index.d.mts +5 -4
- package/dist/control/index.d.ts +5 -4
- package/dist/core/index.d.mts +6 -4
- package/dist/core/index.d.ts +6 -4
- package/dist/core/index.js +581 -4
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +581 -4
- package/dist/core/index.mjs.map +1 -1
- package/dist/debug/index.d.mts +3 -3
- package/dist/debug/index.d.ts +3 -3
- package/dist/index.d.mts +7 -5
- package/dist/index.d.ts +7 -5
- package/dist/index.js +4112 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4056 -13
- package/dist/index.mjs.map +1 -1
- package/dist/{metrics-QCnK0EFw.d.ts → metrics-C9XRi_mL.d.ts} +2 -2
- package/dist/{metrics-BCG7z7Aq.d.mts → metrics-NC3csD0R.d.mts} +2 -2
- package/dist/react/index.d.mts +6 -5
- package/dist/react/index.d.ts +6 -5
- package/dist/react/index.js +587 -10
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +587 -10
- package/dist/react/index.mjs.map +1 -1
- package/dist/{registry-CT6BVVKr.d.mts → registry-CIEDjbQ9.d.ts} +22 -1
- package/dist/{registry-D4mQ01B3.d.ts → registry-SsSDq46X.d.mts} +22 -1
- package/dist/render-log/index.d.mts +1 -1
- package/dist/render-log/index.d.ts +1 -1
- package/dist/types-BvCfFuEV.d.ts +534 -0
- package/dist/types-CFT3Dnx4.d.mts +534 -0
- package/dist/{types-BpvpStn3.d.mts → types-CPMbN_Iw.d.mts} +8 -0
- package/dist/{types-BpvpStn3.d.ts → types-CPMbN_Iw.d.ts} +8 -0
- package/dist/{types-DdJD9yw5.d.mts → types-Dr6tH-bm.d.mts} +1 -1
- package/dist/{types-BDkXy5si.d.ts → types-oCTrRxSw.d.ts} +1 -1
- package/dist/{websocket-client-DupH0X7B.d.ts → websocket-client-CX4QJesI.d.ts} +1 -1
- package/dist/{websocket-client-B2LC9CYc.d.mts → websocket-client-C_Na0OSp.d.mts} +1 -1
- package/package.json +6 -1
package/dist/control/index.d.mts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { A as ActionExecutor, b as ControlActionRequest, c as ControlActionResponse, C as ComponentActionRequest, a as ComponentActionResponse, W as WaitResult, F as FindRequest, g as FindResponse, d as ControlSnapshot, i as WorkflowEngine, j as WorkflowRunRequest, k as WorkflowRunResponse } from '../types-
|
|
2
|
-
export { D as DiscoveredElement, e as DiscoveryRequest, f as DiscoveryResponse, K as KeyboardAction, M as MouseAction, S as ScrollAction, h as SelectAction, T as TypeAction, l as WorkflowRunStatus, m as WorkflowStepResult } from '../types-
|
|
3
|
-
import { U as UIBridgeRegistry } from '../registry-
|
|
4
|
-
import { a0 as WaitOptions } from '../types-
|
|
1
|
+
import { A as ActionExecutor, b as ControlActionRequest, c as ControlActionResponse, C as ComponentActionRequest, a as ComponentActionResponse, W as WaitResult, F as FindRequest, g as FindResponse, d as ControlSnapshot, i as WorkflowEngine, j as WorkflowRunRequest, k as WorkflowRunResponse } from '../types-Dr6tH-bm.mjs';
|
|
2
|
+
export { D as DiscoveredElement, e as DiscoveryRequest, f as DiscoveryResponse, K as KeyboardAction, M as MouseAction, S as ScrollAction, h as SelectAction, T as TypeAction, l as WorkflowRunStatus, m as WorkflowStepResult } from '../types-Dr6tH-bm.mjs';
|
|
3
|
+
import { U as UIBridgeRegistry } from '../registry-SsSDq46X.mjs';
|
|
4
|
+
import { a0 as WaitOptions } from '../types-CPMbN_Iw.mjs';
|
|
5
|
+
import '../types-CFT3Dnx4.mjs';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Action Executor
|
package/dist/control/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { A as ActionExecutor, b as ControlActionRequest, c as ControlActionResponse, C as ComponentActionRequest, a as ComponentActionResponse, W as WaitResult, F as FindRequest, g as FindResponse, d as ControlSnapshot, i as WorkflowEngine, j as WorkflowRunRequest, k as WorkflowRunResponse } from '../types-
|
|
2
|
-
export { D as DiscoveredElement, e as DiscoveryRequest, f as DiscoveryResponse, K as KeyboardAction, M as MouseAction, S as ScrollAction, h as SelectAction, T as TypeAction, l as WorkflowRunStatus, m as WorkflowStepResult } from '../types-
|
|
3
|
-
import { U as UIBridgeRegistry } from '../registry-
|
|
4
|
-
import { a0 as WaitOptions } from '../types-
|
|
1
|
+
import { A as ActionExecutor, b as ControlActionRequest, c as ControlActionResponse, C as ComponentActionRequest, a as ComponentActionResponse, W as WaitResult, F as FindRequest, g as FindResponse, d as ControlSnapshot, i as WorkflowEngine, j as WorkflowRunRequest, k as WorkflowRunResponse } from '../types-oCTrRxSw.js';
|
|
2
|
+
export { D as DiscoveredElement, e as DiscoveryRequest, f as DiscoveryResponse, K as KeyboardAction, M as MouseAction, S as ScrollAction, h as SelectAction, T as TypeAction, l as WorkflowRunStatus, m as WorkflowStepResult } from '../types-oCTrRxSw.js';
|
|
3
|
+
import { U as UIBridgeRegistry } from '../registry-CIEDjbQ9.js';
|
|
4
|
+
import { a0 as WaitOptions } from '../types-CPMbN_Iw.js';
|
|
5
|
+
import '../types-BvCfFuEV.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Action Executor
|
package/dist/core/index.d.mts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { E as ElementIdentifier } from '../types-
|
|
2
|
-
export { A as ActionHandler, a as ActionRequest, b as ActionResponse, B as BranchCondition, c as BridgeEvent, d as BridgeEventListener, e as BridgeEventType, f as BridgeSnapshot, C as ComponentAction, g as CustomAction, h as ElementState, i as ElementType, j as ExtractConfig, L as LogConfig, k as LoopConfig, N as NavigationResult, P as PathResult, R as RegisteredComponent, l as RegisteredElement, S as StandardAction, m as StateSnapshot, T as TransitionResult, U as UIBridgeConfig, n as UIBridgeFeatures, o as UIState, p as UIStateGroup, q as UITransition, W as WSClientConfig, r as WSClientMessage, s as WSClientMessageType, t as WSConnectionState, u as WSDiscoverMessage, v as WSErrorMessage, w as WSEventMessage, x as WSExecuteActionMessage, y as WSExecuteComponentActionMessage, z as WSExecuteWorkflowMessage, D as WSFindMessage, F as WSGetElementMessage, G as WSGetSnapshotMessage, H as WSMessageBase, I as WSPingMessage, J as WSPongMessage, K as WSResponseMessage, M as WSServerMessage, O as WSServerMessageType, Q as WSSubscribeMessage, V as WSSubscribedMessage, X as WSSubscriptionOptions, Y as WSUnsubscribeMessage, Z as WSUnsubscribedMessage, _ as WSWelcomeMessage, $ as WSWorkflowProgressMessage, a0 as WaitOptions, a1 as Workflow, a2 as WorkflowStep, a3 as WorkflowStepType } from '../types-
|
|
3
|
-
export { R as RegistryOptions, U as UIBridgeRegistry, g as getGlobalRegistry, r as resetGlobalRegistry, s as setGlobalRegistry } from '../registry-
|
|
4
|
-
export { U as UIBridgeWSClient, c as createWSClient } from '../websocket-client-
|
|
1
|
+
import { E as ElementIdentifier } from '../types-CPMbN_Iw.mjs';
|
|
2
|
+
export { A as ActionHandler, a as ActionRequest, b as ActionResponse, B as BranchCondition, c as BridgeEvent, d as BridgeEventListener, e as BridgeEventType, f as BridgeSnapshot, C as ComponentAction, g as CustomAction, h as ElementState, i as ElementType, j as ExtractConfig, L as LogConfig, k as LoopConfig, N as NavigationResult, P as PathResult, R as RegisteredComponent, l as RegisteredElement, S as StandardAction, m as StateSnapshot, T as TransitionResult, U as UIBridgeConfig, n as UIBridgeFeatures, o as UIState, p as UIStateGroup, q as UITransition, W as WSClientConfig, r as WSClientMessage, s as WSClientMessageType, t as WSConnectionState, u as WSDiscoverMessage, v as WSErrorMessage, w as WSEventMessage, x as WSExecuteActionMessage, y as WSExecuteComponentActionMessage, z as WSExecuteWorkflowMessage, D as WSFindMessage, F as WSGetElementMessage, G as WSGetSnapshotMessage, H as WSMessageBase, I as WSPingMessage, J as WSPongMessage, K as WSResponseMessage, M as WSServerMessage, O as WSServerMessageType, Q as WSSubscribeMessage, V as WSSubscribedMessage, X as WSSubscriptionOptions, Y as WSUnsubscribeMessage, Z as WSUnsubscribedMessage, _ as WSWelcomeMessage, $ as WSWorkflowProgressMessage, a0 as WaitOptions, a1 as Workflow, a2 as WorkflowStep, a3 as WorkflowStepType } from '../types-CPMbN_Iw.mjs';
|
|
3
|
+
export { R as RegistryOptions, U as UIBridgeRegistry, g as getGlobalRegistry, r as resetGlobalRegistry, s as setGlobalRegistry } from '../registry-SsSDq46X.mjs';
|
|
4
|
+
export { U as UIBridgeWSClient, c as createWSClient } from '../websocket-client-C_Na0OSp.mjs';
|
|
5
|
+
import '../types-CFT3Dnx4.mjs';
|
|
6
|
+
import '../types-Dr6tH-bm.mjs';
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Element Identification Module
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { E as ElementIdentifier } from '../types-
|
|
2
|
-
export { A as ActionHandler, a as ActionRequest, b as ActionResponse, B as BranchCondition, c as BridgeEvent, d as BridgeEventListener, e as BridgeEventType, f as BridgeSnapshot, C as ComponentAction, g as CustomAction, h as ElementState, i as ElementType, j as ExtractConfig, L as LogConfig, k as LoopConfig, N as NavigationResult, P as PathResult, R as RegisteredComponent, l as RegisteredElement, S as StandardAction, m as StateSnapshot, T as TransitionResult, U as UIBridgeConfig, n as UIBridgeFeatures, o as UIState, p as UIStateGroup, q as UITransition, W as WSClientConfig, r as WSClientMessage, s as WSClientMessageType, t as WSConnectionState, u as WSDiscoverMessage, v as WSErrorMessage, w as WSEventMessage, x as WSExecuteActionMessage, y as WSExecuteComponentActionMessage, z as WSExecuteWorkflowMessage, D as WSFindMessage, F as WSGetElementMessage, G as WSGetSnapshotMessage, H as WSMessageBase, I as WSPingMessage, J as WSPongMessage, K as WSResponseMessage, M as WSServerMessage, O as WSServerMessageType, Q as WSSubscribeMessage, V as WSSubscribedMessage, X as WSSubscriptionOptions, Y as WSUnsubscribeMessage, Z as WSUnsubscribedMessage, _ as WSWelcomeMessage, $ as WSWorkflowProgressMessage, a0 as WaitOptions, a1 as Workflow, a2 as WorkflowStep, a3 as WorkflowStepType } from '../types-
|
|
3
|
-
export { R as RegistryOptions, U as UIBridgeRegistry, g as getGlobalRegistry, r as resetGlobalRegistry, s as setGlobalRegistry } from '../registry-
|
|
4
|
-
export { U as UIBridgeWSClient, c as createWSClient } from '../websocket-client-
|
|
1
|
+
import { E as ElementIdentifier } from '../types-CPMbN_Iw.js';
|
|
2
|
+
export { A as ActionHandler, a as ActionRequest, b as ActionResponse, B as BranchCondition, c as BridgeEvent, d as BridgeEventListener, e as BridgeEventType, f as BridgeSnapshot, C as ComponentAction, g as CustomAction, h as ElementState, i as ElementType, j as ExtractConfig, L as LogConfig, k as LoopConfig, N as NavigationResult, P as PathResult, R as RegisteredComponent, l as RegisteredElement, S as StandardAction, m as StateSnapshot, T as TransitionResult, U as UIBridgeConfig, n as UIBridgeFeatures, o as UIState, p as UIStateGroup, q as UITransition, W as WSClientConfig, r as WSClientMessage, s as WSClientMessageType, t as WSConnectionState, u as WSDiscoverMessage, v as WSErrorMessage, w as WSEventMessage, x as WSExecuteActionMessage, y as WSExecuteComponentActionMessage, z as WSExecuteWorkflowMessage, D as WSFindMessage, F as WSGetElementMessage, G as WSGetSnapshotMessage, H as WSMessageBase, I as WSPingMessage, J as WSPongMessage, K as WSResponseMessage, M as WSServerMessage, O as WSServerMessageType, Q as WSSubscribeMessage, V as WSSubscribedMessage, X as WSSubscriptionOptions, Y as WSUnsubscribeMessage, Z as WSUnsubscribedMessage, _ as WSWelcomeMessage, $ as WSWorkflowProgressMessage, a0 as WaitOptions, a1 as Workflow, a2 as WorkflowStep, a3 as WorkflowStepType } from '../types-CPMbN_Iw.js';
|
|
3
|
+
export { R as RegistryOptions, U as UIBridgeRegistry, g as getGlobalRegistry, r as resetGlobalRegistry, s as setGlobalRegistry } from '../registry-CIEDjbQ9.js';
|
|
4
|
+
export { U as UIBridgeWSClient, c as createWSClient } from '../websocket-client-CX4QJesI.js';
|
|
5
|
+
import '../types-BvCfFuEV.js';
|
|
6
|
+
import '../types-oCTrRxSw.js';
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Element Identification Module
|
package/dist/core/index.js
CHANGED
|
@@ -219,6 +219,376 @@ function elementMatchesIdentifier(element, identifier) {
|
|
|
219
219
|
return identifier.uiId && element.getAttribute("data-ui-id") === identifier.uiId || identifier.testId && element.getAttribute("data-testid") === identifier.testId || identifier.awasId && element.getAttribute("data-awas-element") === identifier.awasId || identifier.htmlId && element.id === identifier.htmlId || false;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
// src/ai/fuzzy-matcher.ts
|
|
223
|
+
var DEFAULT_FUZZY_CONFIG = {
|
|
224
|
+
threshold: 0.7,
|
|
225
|
+
levenshteinWeight: 0.3,
|
|
226
|
+
jaroWinklerWeight: 0.4,
|
|
227
|
+
ngramWeight: 0.3,
|
|
228
|
+
ngramSize: 2,
|
|
229
|
+
caseSensitive: false,
|
|
230
|
+
ignoreWhitespace: true
|
|
231
|
+
};
|
|
232
|
+
function levenshteinDistance(s1, s2) {
|
|
233
|
+
const len1 = s1.length;
|
|
234
|
+
const len2 = s2.length;
|
|
235
|
+
const matrix = Array(len1 + 1).fill(null).map(() => Array(len2 + 1).fill(0));
|
|
236
|
+
for (let i = 0; i <= len1; i++) matrix[i][0] = i;
|
|
237
|
+
for (let j = 0; j <= len2; j++) matrix[0][j] = j;
|
|
238
|
+
for (let i = 1; i <= len1; i++) {
|
|
239
|
+
for (let j = 1; j <= len2; j++) {
|
|
240
|
+
const cost = s1[i - 1] === s2[j - 1] ? 0 : 1;
|
|
241
|
+
matrix[i][j] = Math.min(
|
|
242
|
+
matrix[i - 1][j] + 1,
|
|
243
|
+
// deletion
|
|
244
|
+
matrix[i][j - 1] + 1,
|
|
245
|
+
// insertion
|
|
246
|
+
matrix[i - 1][j - 1] + cost
|
|
247
|
+
// substitution
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return matrix[len1][len2];
|
|
252
|
+
}
|
|
253
|
+
function levenshteinSimilarity(s1, s2) {
|
|
254
|
+
if (s1.length === 0 && s2.length === 0) return 1;
|
|
255
|
+
if (s1.length === 0 || s2.length === 0) return 0;
|
|
256
|
+
const distance = levenshteinDistance(s1, s2);
|
|
257
|
+
const maxLength = Math.max(s1.length, s2.length);
|
|
258
|
+
return 1 - distance / maxLength;
|
|
259
|
+
}
|
|
260
|
+
function jaroSimilarity(s1, s2) {
|
|
261
|
+
if (s1.length === 0 && s2.length === 0) return 1;
|
|
262
|
+
if (s1.length === 0 || s2.length === 0) return 0;
|
|
263
|
+
const matchDistance = Math.floor(Math.max(s1.length, s2.length) / 2) - 1;
|
|
264
|
+
const s1Matches = new Array(s1.length).fill(false);
|
|
265
|
+
const s2Matches = new Array(s2.length).fill(false);
|
|
266
|
+
let matches = 0;
|
|
267
|
+
let transpositions = 0;
|
|
268
|
+
for (let i = 0; i < s1.length; i++) {
|
|
269
|
+
const start = Math.max(0, i - matchDistance);
|
|
270
|
+
const end = Math.min(i + matchDistance + 1, s2.length);
|
|
271
|
+
for (let j = start; j < end; j++) {
|
|
272
|
+
if (s2Matches[j] || s1[i] !== s2[j]) continue;
|
|
273
|
+
s1Matches[i] = true;
|
|
274
|
+
s2Matches[j] = true;
|
|
275
|
+
matches++;
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (matches === 0) return 0;
|
|
280
|
+
let k = 0;
|
|
281
|
+
for (let i = 0; i < s1.length; i++) {
|
|
282
|
+
if (!s1Matches[i]) continue;
|
|
283
|
+
while (!s2Matches[k]) k++;
|
|
284
|
+
if (s1[i] !== s2[k]) transpositions++;
|
|
285
|
+
k++;
|
|
286
|
+
}
|
|
287
|
+
return (matches / s1.length + matches / s2.length + (matches - transpositions / 2) / matches) / 3;
|
|
288
|
+
}
|
|
289
|
+
function jaroWinklerSimilarity(s1, s2, prefixScale = 0.1) {
|
|
290
|
+
const jaroSim = jaroSimilarity(s1, s2);
|
|
291
|
+
let prefixLength = 0;
|
|
292
|
+
const maxPrefix = Math.min(4, Math.min(s1.length, s2.length));
|
|
293
|
+
for (let i = 0; i < maxPrefix; i++) {
|
|
294
|
+
if (s1[i] === s2[i]) {
|
|
295
|
+
prefixLength++;
|
|
296
|
+
} else {
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return jaroSim + prefixLength * prefixScale * (1 - jaroSim);
|
|
301
|
+
}
|
|
302
|
+
function generateNgrams(s, n) {
|
|
303
|
+
const ngrams = /* @__PURE__ */ new Set();
|
|
304
|
+
if (s.length < n) {
|
|
305
|
+
ngrams.add(s);
|
|
306
|
+
return ngrams;
|
|
307
|
+
}
|
|
308
|
+
for (let i = 0; i <= s.length - n; i++) {
|
|
309
|
+
ngrams.add(s.substring(i, i + n));
|
|
310
|
+
}
|
|
311
|
+
return ngrams;
|
|
312
|
+
}
|
|
313
|
+
function ngramSimilarity(s1, s2, n = 2) {
|
|
314
|
+
if (s1.length === 0 && s2.length === 0) return 1;
|
|
315
|
+
if (s1.length === 0 || s2.length === 0) return 0;
|
|
316
|
+
const ngrams1 = generateNgrams(s1, n);
|
|
317
|
+
const ngrams2 = generateNgrams(s2, n);
|
|
318
|
+
let intersection = 0;
|
|
319
|
+
for (const ngram of ngrams1) {
|
|
320
|
+
if (ngrams2.has(ngram)) {
|
|
321
|
+
intersection++;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
const union = ngrams1.size + ngrams2.size - intersection;
|
|
325
|
+
return union === 0 ? 0 : intersection / union;
|
|
326
|
+
}
|
|
327
|
+
function normalizeString(s, config = {}) {
|
|
328
|
+
let normalized = s;
|
|
329
|
+
if (!config.caseSensitive) {
|
|
330
|
+
normalized = normalized.toLowerCase();
|
|
331
|
+
}
|
|
332
|
+
if (config.ignoreWhitespace !== false) {
|
|
333
|
+
normalized = normalized.replace(/\s+/g, " ").trim();
|
|
334
|
+
}
|
|
335
|
+
return normalized;
|
|
336
|
+
}
|
|
337
|
+
function fuzzyMatch(source, target, config = {}) {
|
|
338
|
+
const finalConfig = { ...DEFAULT_FUZZY_CONFIG, ...config };
|
|
339
|
+
const normalizedSource = normalizeString(source, finalConfig);
|
|
340
|
+
const normalizedTarget = normalizeString(target, finalConfig);
|
|
341
|
+
const levenshteinScore = levenshteinSimilarity(normalizedSource, normalizedTarget);
|
|
342
|
+
const jaroWinklerScore = jaroWinklerSimilarity(normalizedSource, normalizedTarget);
|
|
343
|
+
const ngramScore = ngramSimilarity(normalizedSource, normalizedTarget, finalConfig.ngramSize);
|
|
344
|
+
const similarity = levenshteinScore * finalConfig.levenshteinWeight + jaroWinklerScore * finalConfig.jaroWinklerWeight + ngramScore * finalConfig.ngramWeight;
|
|
345
|
+
return {
|
|
346
|
+
similarity,
|
|
347
|
+
isMatch: similarity >= finalConfig.threshold,
|
|
348
|
+
scores: {
|
|
349
|
+
levenshtein: levenshteinScore,
|
|
350
|
+
jaroWinkler: jaroWinklerScore,
|
|
351
|
+
ngram: ngramScore
|
|
352
|
+
},
|
|
353
|
+
normalizedSource,
|
|
354
|
+
normalizedTarget
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
function tokenize(s) {
|
|
358
|
+
return s.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\s+/g, " ").trim().toLowerCase().split(" ").filter((token) => token.length > 0);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// src/ai/alias-generator.ts
|
|
362
|
+
var DEFAULT_ALIAS_CONFIG = {
|
|
363
|
+
includeText: true,
|
|
364
|
+
includeAriaLabel: true,
|
|
365
|
+
includePlaceholder: true,
|
|
366
|
+
includeTitle: true,
|
|
367
|
+
includeSynonyms: true,
|
|
368
|
+
maxAliases: 20,
|
|
369
|
+
minLength: 2,
|
|
370
|
+
maxLength: 50
|
|
371
|
+
};
|
|
372
|
+
var SYNONYMS = {
|
|
373
|
+
// Submit-related
|
|
374
|
+
submit: ["send", "go", "confirm", "ok", "apply", "save", "done", "finish"],
|
|
375
|
+
send: ["submit", "deliver", "post"],
|
|
376
|
+
save: ["submit", "store", "keep", "apply"],
|
|
377
|
+
cancel: ["close", "dismiss", "abort", "back", "exit", "quit", "nevermind"],
|
|
378
|
+
close: ["cancel", "dismiss", "exit", "x"],
|
|
379
|
+
delete: ["remove", "trash", "erase", "clear", "destroy"],
|
|
380
|
+
remove: ["delete", "clear", "discard"],
|
|
381
|
+
edit: ["modify", "change", "update", "alter"],
|
|
382
|
+
update: ["edit", "modify", "save", "refresh"],
|
|
383
|
+
add: ["create", "new", "plus", "insert"],
|
|
384
|
+
create: ["add", "new", "make"],
|
|
385
|
+
search: ["find", "lookup", "query", "filter"],
|
|
386
|
+
find: ["search", "locate", "lookup"],
|
|
387
|
+
login: ["signin", "sign in", "log in", "authenticate", "enter"],
|
|
388
|
+
logout: ["signout", "sign out", "log out", "exit"],
|
|
389
|
+
register: ["signup", "sign up", "join", "create account"],
|
|
390
|
+
next: ["continue", "forward", "proceed", "advance"],
|
|
391
|
+
previous: ["back", "backward", "return", "prior"],
|
|
392
|
+
back: ["previous", "return", "backward"],
|
|
393
|
+
start: ["begin", "launch", "initiate", "run", "execute"],
|
|
394
|
+
stop: ["end", "halt", "pause", "terminate"],
|
|
395
|
+
enable: ["activate", "turn on", "switch on"],
|
|
396
|
+
disable: ["deactivate", "turn off", "switch off"],
|
|
397
|
+
show: ["display", "reveal", "view", "open"],
|
|
398
|
+
hide: ["conceal", "collapse", "close"],
|
|
399
|
+
expand: ["open", "show", "unfold", "reveal"],
|
|
400
|
+
collapse: ["close", "hide", "fold", "minimize"],
|
|
401
|
+
yes: ["ok", "confirm", "agree", "accept"],
|
|
402
|
+
no: ["cancel", "decline", "reject", "deny"],
|
|
403
|
+
help: ["support", "assistance", "info", "information", "faq"],
|
|
404
|
+
settings: ["preferences", "options", "config", "configuration"],
|
|
405
|
+
profile: ["account", "user", "me"],
|
|
406
|
+
download: ["export", "save", "get"],
|
|
407
|
+
upload: ["import", "load", "attach"],
|
|
408
|
+
refresh: ["reload", "update", "sync"],
|
|
409
|
+
copy: ["duplicate", "clone"],
|
|
410
|
+
paste: ["insert"],
|
|
411
|
+
select: ["choose", "pick"],
|
|
412
|
+
toggle: ["switch", "flip"],
|
|
413
|
+
// Form fields
|
|
414
|
+
email: ["e-mail", "mail"],
|
|
415
|
+
password: ["pass", "pwd", "secret"],
|
|
416
|
+
username: ["user", "login", "account", "name"],
|
|
417
|
+
firstname: ["first name", "given name", "forename"],
|
|
418
|
+
lastname: ["last name", "surname", "family name"],
|
|
419
|
+
fullname: ["full name", "name", "complete name"],
|
|
420
|
+
phone: ["telephone", "tel", "mobile", "cell"],
|
|
421
|
+
address: ["location", "street"],
|
|
422
|
+
city: ["town"],
|
|
423
|
+
country: ["nation"],
|
|
424
|
+
zip: ["zipcode", "postal", "postal code", "postcode"],
|
|
425
|
+
// Navigation
|
|
426
|
+
home: ["main", "start", "dashboard"],
|
|
427
|
+
menu: ["navigation", "nav"],
|
|
428
|
+
sidebar: ["side bar", "side panel", "side menu"]
|
|
429
|
+
};
|
|
430
|
+
var ELEMENT_ACTION_WORDS = {
|
|
431
|
+
button: ["button", "btn", "click"],
|
|
432
|
+
input: ["input", "field", "textbox", "box"],
|
|
433
|
+
textarea: ["textarea", "text area", "text field", "multiline"],
|
|
434
|
+
select: ["select", "dropdown", "combo", "picker", "chooser"],
|
|
435
|
+
checkbox: ["checkbox", "check", "tick"],
|
|
436
|
+
radio: ["radio", "option", "choice"],
|
|
437
|
+
link: ["link", "anchor", "href"],
|
|
438
|
+
form: ["form"],
|
|
439
|
+
menu: ["menu"],
|
|
440
|
+
menuitem: ["menu item", "option"],
|
|
441
|
+
tab: ["tab"],
|
|
442
|
+
dialog: ["dialog", "modal", "popup"],
|
|
443
|
+
switch: ["switch", "toggle"],
|
|
444
|
+
slider: ["slider", "range"]
|
|
445
|
+
};
|
|
446
|
+
function normalizeAlias(text) {
|
|
447
|
+
return text.toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
448
|
+
}
|
|
449
|
+
function extractWords(text) {
|
|
450
|
+
const tokens = tokenize(text);
|
|
451
|
+
return tokens.filter((t) => t.length >= 2);
|
|
452
|
+
}
|
|
453
|
+
function generateTextAliases(text, config) {
|
|
454
|
+
if (!text || !config.includeText) return [];
|
|
455
|
+
const aliases = [];
|
|
456
|
+
const normalized = normalizeAlias(text);
|
|
457
|
+
if (normalized.length >= config.minLength && normalized.length <= config.maxLength) {
|
|
458
|
+
aliases.push(normalized);
|
|
459
|
+
}
|
|
460
|
+
const words = extractWords(text);
|
|
461
|
+
for (const word of words) {
|
|
462
|
+
if (word.length >= config.minLength) {
|
|
463
|
+
aliases.push(word);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (words.length >= 2 && words.length <= 4) {
|
|
467
|
+
const twoWords = words.slice(0, 2).join(" ");
|
|
468
|
+
if (twoWords.length <= config.maxLength) {
|
|
469
|
+
aliases.push(twoWords);
|
|
470
|
+
}
|
|
471
|
+
if (words.length > 2) {
|
|
472
|
+
const lastTwo = words.slice(-2).join(" ");
|
|
473
|
+
if (lastTwo.length <= config.maxLength) {
|
|
474
|
+
aliases.push(lastTwo);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return aliases;
|
|
479
|
+
}
|
|
480
|
+
function generateSynonyms(aliases, config) {
|
|
481
|
+
if (!config.includeSynonyms) return [];
|
|
482
|
+
const synonyms = [];
|
|
483
|
+
for (const alias of aliases) {
|
|
484
|
+
const words = alias.toLowerCase().split(/\s+/);
|
|
485
|
+
for (const word of words) {
|
|
486
|
+
if (SYNONYMS[word]) {
|
|
487
|
+
for (const synonym of SYNONYMS[word]) {
|
|
488
|
+
const newAlias = alias.toLowerCase().replace(word, synonym);
|
|
489
|
+
if (newAlias !== alias.toLowerCase()) {
|
|
490
|
+
synonyms.push(newAlias);
|
|
491
|
+
}
|
|
492
|
+
if (synonym.length >= config.minLength) {
|
|
493
|
+
synonyms.push(synonym);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return synonyms;
|
|
500
|
+
}
|
|
501
|
+
function generateTypeAliases(elementType) {
|
|
502
|
+
const type = elementType.toLowerCase();
|
|
503
|
+
return ELEMENT_ACTION_WORDS[type] || [type];
|
|
504
|
+
}
|
|
505
|
+
function generateAliases(input, config = {}) {
|
|
506
|
+
const finalConfig = { ...DEFAULT_ALIAS_CONFIG, ...config };
|
|
507
|
+
const aliasSet = /* @__PURE__ */ new Set();
|
|
508
|
+
const addAlias = (alias) => {
|
|
509
|
+
const normalized = normalizeAlias(alias);
|
|
510
|
+
if (normalized.length >= finalConfig.minLength && normalized.length <= finalConfig.maxLength) {
|
|
511
|
+
aliasSet.add(normalized);
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
const addAliases = (aliases2) => {
|
|
515
|
+
for (const alias of aliases2) {
|
|
516
|
+
addAlias(alias);
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
if (finalConfig.includeText && input.textContent) {
|
|
520
|
+
addAliases(generateTextAliases(input.textContent, finalConfig));
|
|
521
|
+
}
|
|
522
|
+
if (finalConfig.includeAriaLabel && input.ariaLabel) {
|
|
523
|
+
addAliases(generateTextAliases(input.ariaLabel, finalConfig));
|
|
524
|
+
}
|
|
525
|
+
if (finalConfig.includeAriaLabel && input.ariaLabelledBy) {
|
|
526
|
+
addAliases(generateTextAliases(input.ariaLabelledBy, finalConfig));
|
|
527
|
+
}
|
|
528
|
+
if (finalConfig.includePlaceholder && input.placeholder) {
|
|
529
|
+
addAliases(generateTextAliases(input.placeholder, finalConfig));
|
|
530
|
+
}
|
|
531
|
+
if (finalConfig.includeTitle && input.title) {
|
|
532
|
+
addAliases(generateTextAliases(input.title, finalConfig));
|
|
533
|
+
}
|
|
534
|
+
if (input.labelText) {
|
|
535
|
+
addAliases(generateTextAliases(input.labelText, finalConfig));
|
|
536
|
+
}
|
|
537
|
+
if (input.id) {
|
|
538
|
+
addAliases(extractWords(input.id));
|
|
539
|
+
}
|
|
540
|
+
if (input.name) {
|
|
541
|
+
addAliases(extractWords(input.name));
|
|
542
|
+
}
|
|
543
|
+
if (input.value && (input.elementType === "button" || input.inputType === "submit" || input.inputType === "button")) {
|
|
544
|
+
addAliases(generateTextAliases(input.value, finalConfig));
|
|
545
|
+
}
|
|
546
|
+
if (input.elementType) {
|
|
547
|
+
addAliases(generateTypeAliases(input.elementType));
|
|
548
|
+
}
|
|
549
|
+
if (input.inputType) {
|
|
550
|
+
addAlias(input.inputType);
|
|
551
|
+
if (input.inputType === "email") {
|
|
552
|
+
addAliases(["email", "e-mail", "email address"]);
|
|
553
|
+
} else if (input.inputType === "password") {
|
|
554
|
+
addAliases(["password", "pass", "pwd"]);
|
|
555
|
+
} else if (input.inputType === "tel") {
|
|
556
|
+
addAliases(["phone", "telephone", "mobile"]);
|
|
557
|
+
} else if (input.inputType === "url") {
|
|
558
|
+
addAliases(["url", "website", "link", "address"]);
|
|
559
|
+
} else if (input.inputType === "search") {
|
|
560
|
+
addAliases(["search", "find", "query"]);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
if (finalConfig.includeSynonyms) {
|
|
564
|
+
const currentAliases = Array.from(aliasSet);
|
|
565
|
+
addAliases(generateSynonyms(currentAliases, finalConfig));
|
|
566
|
+
}
|
|
567
|
+
let aliases = Array.from(aliasSet);
|
|
568
|
+
aliases.sort((a, b) => a.length - b.length);
|
|
569
|
+
if (aliases.length > finalConfig.maxAliases) {
|
|
570
|
+
aliases = aliases.slice(0, finalConfig.maxAliases);
|
|
571
|
+
}
|
|
572
|
+
return aliases;
|
|
573
|
+
}
|
|
574
|
+
function generateDescription(input) {
|
|
575
|
+
const parts = [];
|
|
576
|
+
let name = input.ariaLabel || input.labelText || input.textContent || input.placeholder || input.title || input.id || input.name;
|
|
577
|
+
if (name) {
|
|
578
|
+
name = name.trim();
|
|
579
|
+
if (name.length > 30) {
|
|
580
|
+
name = name.substring(0, 27) + "...";
|
|
581
|
+
}
|
|
582
|
+
parts.push(`"${name}"`);
|
|
583
|
+
}
|
|
584
|
+
const typeWords = ELEMENT_ACTION_WORDS[input.elementType || ""] || [input.elementType || "element"];
|
|
585
|
+
parts.push(typeWords[0]);
|
|
586
|
+
if (input.inputType && input.inputType !== "text") {
|
|
587
|
+
parts.push(`(${input.inputType})`);
|
|
588
|
+
}
|
|
589
|
+
return parts.join(" ");
|
|
590
|
+
}
|
|
591
|
+
|
|
222
592
|
// src/core/registry.ts
|
|
223
593
|
function getElementState(element) {
|
|
224
594
|
const rect = element.getBoundingClientRect();
|
|
@@ -417,9 +787,13 @@ var UIBridgeRegistry = class {
|
|
|
417
787
|
registerElement(id, element, options = {}) {
|
|
418
788
|
const type = options.type ?? inferElementType(element);
|
|
419
789
|
const actions = options.actions ?? inferActions(type);
|
|
420
|
-
element.
|
|
790
|
+
const existingUiId = element.getAttribute("data-ui-id");
|
|
791
|
+
const actualId = existingUiId || id;
|
|
792
|
+
if (!existingUiId) {
|
|
793
|
+
element.setAttribute("data-ui-id", actualId);
|
|
794
|
+
}
|
|
421
795
|
const registered = {
|
|
422
|
-
id,
|
|
796
|
+
id: actualId,
|
|
423
797
|
element,
|
|
424
798
|
type,
|
|
425
799
|
label: options.label,
|
|
@@ -430,8 +804,8 @@ var UIBridgeRegistry = class {
|
|
|
430
804
|
registeredAt: Date.now(),
|
|
431
805
|
mounted: true
|
|
432
806
|
};
|
|
433
|
-
this.elements.set(
|
|
434
|
-
this.emit("element:registered", { id, type, label: options.label });
|
|
807
|
+
this.elements.set(actualId, registered);
|
|
808
|
+
this.emit("element:registered", { id: actualId, type, label: options.label });
|
|
435
809
|
return registered;
|
|
436
810
|
}
|
|
437
811
|
/**
|
|
@@ -471,6 +845,209 @@ var UIBridgeRegistry = class {
|
|
|
471
845
|
}
|
|
472
846
|
return void 0;
|
|
473
847
|
}
|
|
848
|
+
/**
|
|
849
|
+
* Search for elements using AI search criteria
|
|
850
|
+
*/
|
|
851
|
+
searchElements(criteria) {
|
|
852
|
+
const results = [];
|
|
853
|
+
const threshold = criteria.fuzzyThreshold ?? 0.7;
|
|
854
|
+
for (const element of this.elements.values()) {
|
|
855
|
+
if (!element.mounted) continue;
|
|
856
|
+
const state = element.getState();
|
|
857
|
+
if (!criteria.fuzzy && !state.visible) continue;
|
|
858
|
+
const aliases = element.aliases ?? this.generateElementAliases(element);
|
|
859
|
+
const textContent = state.textContent?.trim() || "";
|
|
860
|
+
const label = element.label || "";
|
|
861
|
+
let maxScore = 0;
|
|
862
|
+
const matchReasons = [];
|
|
863
|
+
const scores = {};
|
|
864
|
+
if (criteria.text) {
|
|
865
|
+
if (textContent.toLowerCase() === criteria.text.toLowerCase() || label.toLowerCase() === criteria.text.toLowerCase()) {
|
|
866
|
+
maxScore = 1;
|
|
867
|
+
matchReasons.push("exact text match");
|
|
868
|
+
scores.text = 1;
|
|
869
|
+
} else if (criteria.fuzzy !== false) {
|
|
870
|
+
const textResult = fuzzyMatch(criteria.text, textContent, { threshold });
|
|
871
|
+
const labelResult = fuzzyMatch(criteria.text, label, { threshold });
|
|
872
|
+
const bestResult = textResult.similarity > labelResult.similarity ? textResult : labelResult;
|
|
873
|
+
if (bestResult.isMatch) {
|
|
874
|
+
scores.text = bestResult.similarity;
|
|
875
|
+
if (bestResult.similarity > maxScore) {
|
|
876
|
+
maxScore = bestResult.similarity;
|
|
877
|
+
matchReasons.push(`text similarity: ${(bestResult.similarity * 100).toFixed(0)}%`);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
if (criteria.textContains) {
|
|
883
|
+
if (textContent.toLowerCase().includes(criteria.textContains.toLowerCase()) || label.toLowerCase().includes(criteria.textContains.toLowerCase())) {
|
|
884
|
+
const containsScore = 0.85;
|
|
885
|
+
scores.text = Math.max(scores.text ?? 0, containsScore);
|
|
886
|
+
if (containsScore > maxScore) {
|
|
887
|
+
maxScore = containsScore;
|
|
888
|
+
matchReasons.push("text contains");
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
if (criteria.accessibleName) {
|
|
893
|
+
const ariaLabel = element.element.getAttribute("aria-label") || "";
|
|
894
|
+
const accessibleName = ariaLabel || label || textContent;
|
|
895
|
+
if (accessibleName.toLowerCase() === criteria.accessibleName.toLowerCase()) {
|
|
896
|
+
scores.accessibility = 1;
|
|
897
|
+
if (1 > maxScore) {
|
|
898
|
+
maxScore = 1;
|
|
899
|
+
matchReasons.push("accessible name match");
|
|
900
|
+
}
|
|
901
|
+
} else if (criteria.fuzzy !== false) {
|
|
902
|
+
const result = fuzzyMatch(criteria.accessibleName, accessibleName, { threshold });
|
|
903
|
+
if (result.isMatch) {
|
|
904
|
+
scores.accessibility = result.similarity;
|
|
905
|
+
if (result.similarity > maxScore) {
|
|
906
|
+
maxScore = result.similarity;
|
|
907
|
+
matchReasons.push(`accessible name similarity: ${(result.similarity * 100).toFixed(0)}%`);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
if (criteria.role) {
|
|
913
|
+
const role = element.element.getAttribute("role") || this.inferRole(element.type);
|
|
914
|
+
if (role?.toLowerCase() === criteria.role.toLowerCase()) {
|
|
915
|
+
scores.role = 1;
|
|
916
|
+
if (1 > maxScore) {
|
|
917
|
+
maxScore = 1;
|
|
918
|
+
matchReasons.push(`role: ${criteria.role}`);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
if (criteria.type) {
|
|
923
|
+
if (element.type === criteria.type) {
|
|
924
|
+
const typeScore = 0.9;
|
|
925
|
+
scores.role = Math.max(scores.role ?? 0, typeScore);
|
|
926
|
+
if (typeScore > maxScore) {
|
|
927
|
+
maxScore = typeScore;
|
|
928
|
+
matchReasons.push(`type: ${criteria.type}`);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
for (const alias of aliases) {
|
|
933
|
+
const searchText = criteria.text || criteria.textContains || criteria.accessibleName;
|
|
934
|
+
if (searchText) {
|
|
935
|
+
if (alias.toLowerCase() === searchText.toLowerCase()) {
|
|
936
|
+
scores.fuzzy = 1;
|
|
937
|
+
if (1 > maxScore) {
|
|
938
|
+
maxScore = 1;
|
|
939
|
+
matchReasons.push(`alias: "${alias}"`);
|
|
940
|
+
}
|
|
941
|
+
} else if (criteria.fuzzy !== false) {
|
|
942
|
+
const result = fuzzyMatch(searchText, alias, { threshold });
|
|
943
|
+
if (result.isMatch && result.similarity > (scores.fuzzy ?? 0)) {
|
|
944
|
+
scores.fuzzy = result.similarity;
|
|
945
|
+
if (result.similarity > maxScore) {
|
|
946
|
+
maxScore = result.similarity;
|
|
947
|
+
matchReasons.push(`fuzzy alias: "${alias}"`);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
if (maxScore >= threshold) {
|
|
954
|
+
const aiElement = {
|
|
955
|
+
id: element.id,
|
|
956
|
+
type: element.type,
|
|
957
|
+
label: element.label,
|
|
958
|
+
tagName: element.element.tagName.toLowerCase(),
|
|
959
|
+
role: element.element.getAttribute("role") || void 0,
|
|
960
|
+
accessibleName: element.element.getAttribute("aria-label") || element.label,
|
|
961
|
+
actions: element.actions,
|
|
962
|
+
state,
|
|
963
|
+
registered: true,
|
|
964
|
+
description: element.description || generateDescription({
|
|
965
|
+
textContent,
|
|
966
|
+
ariaLabel: element.element.getAttribute("aria-label"),
|
|
967
|
+
elementType: element.type,
|
|
968
|
+
id: element.id,
|
|
969
|
+
labelText: element.label
|
|
970
|
+
}),
|
|
971
|
+
aliases,
|
|
972
|
+
purpose: element.purpose,
|
|
973
|
+
suggestedActions: [],
|
|
974
|
+
semanticType: element.semanticType
|
|
975
|
+
};
|
|
976
|
+
results.push({
|
|
977
|
+
element: aiElement,
|
|
978
|
+
confidence: maxScore,
|
|
979
|
+
matchReasons,
|
|
980
|
+
scores
|
|
981
|
+
});
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
results.sort((a, b) => b.confidence - a.confidence);
|
|
985
|
+
return results;
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* Find element by visible text
|
|
989
|
+
*/
|
|
990
|
+
findByText(text, fuzzy = true) {
|
|
991
|
+
const results = this.searchElements({ text, fuzzy, fuzzyThreshold: fuzzy ? 0.7 : 1 });
|
|
992
|
+
if (results.length > 0) {
|
|
993
|
+
return this.elements.get(results[0].element.id);
|
|
994
|
+
}
|
|
995
|
+
return void 0;
|
|
996
|
+
}
|
|
997
|
+
/**
|
|
998
|
+
* Find element by accessible name
|
|
999
|
+
*/
|
|
1000
|
+
findByAccessibleName(name) {
|
|
1001
|
+
const results = this.searchElements({ accessibleName: name, fuzzy: true });
|
|
1002
|
+
if (results.length > 0) {
|
|
1003
|
+
return this.elements.get(results[0].element.id);
|
|
1004
|
+
}
|
|
1005
|
+
return void 0;
|
|
1006
|
+
}
|
|
1007
|
+
/**
|
|
1008
|
+
* Generate aliases for an element
|
|
1009
|
+
*/
|
|
1010
|
+
generateElementAliases(element) {
|
|
1011
|
+
const state = element.getState();
|
|
1012
|
+
return generateAliases({
|
|
1013
|
+
textContent: state.textContent,
|
|
1014
|
+
ariaLabel: element.element.getAttribute("aria-label"),
|
|
1015
|
+
placeholder: element.element.getAttribute("placeholder"),
|
|
1016
|
+
title: element.element.getAttribute("title"),
|
|
1017
|
+
elementType: element.type,
|
|
1018
|
+
tagName: element.element.tagName.toLowerCase(),
|
|
1019
|
+
id: element.id,
|
|
1020
|
+
labelText: element.label
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Infer ARIA role from element type
|
|
1025
|
+
*/
|
|
1026
|
+
inferRole(type) {
|
|
1027
|
+
const roleMap = {
|
|
1028
|
+
button: "button",
|
|
1029
|
+
input: "textbox",
|
|
1030
|
+
select: "combobox",
|
|
1031
|
+
checkbox: "checkbox",
|
|
1032
|
+
radio: "radio",
|
|
1033
|
+
link: "link",
|
|
1034
|
+
form: void 0,
|
|
1035
|
+
textarea: "textbox",
|
|
1036
|
+
menu: "menu",
|
|
1037
|
+
menuitem: "menuitem",
|
|
1038
|
+
tab: "tab",
|
|
1039
|
+
dialog: "dialog",
|
|
1040
|
+
custom: void 0,
|
|
1041
|
+
switch: "switch",
|
|
1042
|
+
slider: "slider",
|
|
1043
|
+
combobox: "combobox",
|
|
1044
|
+
listbox: "listbox",
|
|
1045
|
+
option: "option",
|
|
1046
|
+
textbox: "textbox",
|
|
1047
|
+
generic: void 0
|
|
1048
|
+
};
|
|
1049
|
+
return roleMap[type];
|
|
1050
|
+
}
|
|
474
1051
|
/**
|
|
475
1052
|
* Register a component
|
|
476
1053
|
*/
|