@whenessel/seql-js 1.4.0 → 1.5.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/README.md CHANGED
@@ -146,6 +146,30 @@ Manage the LRU cache to improve performance for frequent generations/resolutions
146
146
  - `src/resolver/`: Logic for resolving EID JSON back to DOM elements.
147
147
  - `src/types/`: Core type definitions for EIDs, Semantics, and Constraints.
148
148
  - `src/utils/`: Shared utilities, constants, and scoring algorithms.
149
+ - `extensions/chrome/`: Chrome DevTools extension for visual SEQL inspection.
150
+
151
+ ## Developer Tools
152
+
153
+ ### Chrome DevTools Extension
154
+
155
+ The SEQL Inspector extension provides visual tooling for working with SEQL selectors directly in Chrome DevTools.
156
+
157
+ **Features:**
158
+
159
+ - Generate SEQL selectors for all elements or pick individual elements
160
+ - Full iframe support with automatic detection and context switching
161
+ - Live search and resolution testing
162
+ - Interactive element highlighting and inspection
163
+ - Tree view with grouping and filtering
164
+
165
+ **Installation:**
166
+
167
+ ```bash
168
+ yarn extension:prepare
169
+ # Then load extensions/chrome/ as unpacked extension in Chrome
170
+ ```
171
+
172
+ See [Chrome Extension README](extensions/chrome/README.md) for detailed documentation.
149
173
 
150
174
  ## Scripts
151
175
 
@@ -154,6 +178,7 @@ Manage the LRU cache to improve performance for frequent generations/resolutions
154
178
  - `yarn test:watch`: Run tests in watch mode.
155
179
  - `yarn test:coverage`: Run tests with coverage report.
156
180
  - `yarn types:check`: Run TypeScript type checking.
181
+ - `yarn extension:prepare`: Build library and prepare Chrome extension.
157
182
  - `npx vitest <path>`: Run a specific test file.
158
183
 
159
184
  ## Documentation
package/dist/seql-js.d.ts CHANGED
@@ -452,12 +452,12 @@ export declare class CssGenerator {
452
452
  * div with utility classes) can still be identified using positional information
453
453
  * (nthChild).
454
454
  */
455
- export declare const DEFAULT_GENERATOR_OPTIONS: Omit<Required<GeneratorOptions>, 'cache'> & Pick<GeneratorOptions, 'cache'>;
455
+ export declare const DEFAULT_GENERATOR_OPTIONS: Omit<Required<GeneratorOptions>, 'cache' | 'root'> & Pick<GeneratorOptions, 'cache' | 'root'>;
456
456
 
457
457
  /**
458
458
  * Default resolver options
459
459
  */
460
- export declare const DEFAULT_RESOLVER_OPTIONS: Required<ResolverOptions>;
460
+ export declare const DEFAULT_RESOLVER_OPTIONS: Omit<Required<ResolverOptions>, 'root'> & Pick<ResolverOptions, 'root'>;
461
461
 
462
462
  /**
463
463
  * EID specification version
@@ -744,6 +744,21 @@ export declare interface GeneratorOptions {
744
744
  source?: string;
745
745
  /** Optional cache instance for performance optimization */
746
746
  cache?: EIDCache;
747
+ /**
748
+ * Root element or document for validation (optional).
749
+ *
750
+ * ⚠️ IMPORTANT: When working with iframes, pass iframe.contentDocument
751
+ * to ensure cross-document validation works correctly.
752
+ *
753
+ * @example
754
+ * // Main document
755
+ * generateEID(element, { root: document });
756
+ *
757
+ * // Iframe content
758
+ * const iframe = document.querySelector('iframe');
759
+ * generateEID(iframeElement, { root: iframe.contentDocument });
760
+ */
761
+ root?: Document | Element;
747
762
  }
748
763
 
749
764
  /**
@@ -948,7 +963,7 @@ export declare interface ResolveResult {
948
963
  /** Metadata about resolution */
949
964
  meta: {
950
965
  degraded: boolean;
951
- degradationReason?: string;
966
+ degradationReason?: 'not-found' | 'strict-not-found' | 'ambiguous' | 'anchor-fallback' | 'anchor-not-found' | 'first-of-multiple' | 'best-of-multiple' | 'multiple-matches' | 'over-constrained' | 'relaxed-text-matching' | 'invalid-context' | 'invalid-selector' | 'invalid-anchor-selector';
952
967
  };
953
968
  }
954
969
 
@@ -963,6 +978,21 @@ export declare interface ResolverOptions {
963
978
  enableFallback?: boolean;
964
979
  /** Maximum candidates to consider (default: 20) */
965
980
  maxCandidates?: number;
981
+ /**
982
+ * Root element or document for CSS queries.
983
+ *
984
+ * ⚠️ IMPORTANT: When working with iframes, you MUST pass iframe.contentDocument
985
+ * as the root parameter. Otherwise, resolution will fail or return incorrect elements.
986
+ *
987
+ * @example
988
+ * // Main document
989
+ * resolve(eid, document, { root: document });
990
+ *
991
+ * // Iframe content
992
+ * const iframe = document.querySelector('iframe');
993
+ * resolve(eid, iframe.contentDocument, { root: iframe.contentDocument });
994
+ */
995
+ root?: Document | Element;
966
996
  }
967
997
 
968
998
  /**
@@ -985,6 +1015,21 @@ export declare interface ResolverOptions {
985
1015
  * highlightElement(elements[0]);
986
1016
  * }
987
1017
  * ```
1018
+ *
1019
+ * @example
1020
+ * ```typescript
1021
+ * // Working with iframes - pass iframe.contentDocument as both root and in options
1022
+ * const iframe = document.querySelector('iframe');
1023
+ * const iframeDoc = iframe.contentDocument;
1024
+ * const selector = "v1: form#payment :: input[name=cardnumber]";
1025
+ *
1026
+ * // IMPORTANT: Pass contentDocument as root in options for correct resolution
1027
+ * const elements = resolveSEQL(selector, iframeDoc, { root: iframeDoc });
1028
+ *
1029
+ * if (elements.length > 0) {
1030
+ * console.log('Found payment input in iframe:', elements[0]);
1031
+ * }
1032
+ * ```
988
1033
  */
989
1034
  export declare function resolveSEQL(selector: string, root: Document | Element, options?: ResolverOptions): Element[];
990
1035
 
@@ -1095,6 +1140,19 @@ export declare class SemanticsMatcher {
1095
1140
  * Prioritizes direct text nodes, but falls back to full textContent if no direct text
1096
1141
  */
1097
1142
  matchText(element: Element, text: TextContent): boolean;
1143
+ /**
1144
+ * Lenient text matching - uses partial matching instead of exact
1145
+ * Used as fallback when exact matching fails
1146
+ */
1147
+ private matchTextLenient;
1148
+ /**
1149
+ * Checks if a single element matches the semantics with lenient text matching
1150
+ */
1151
+ private matchElementLenient;
1152
+ /**
1153
+ * Filters elements with lenient matching (exported for use in resolver)
1154
+ */
1155
+ matchLenient(elements: Element[], semantics: ElementSemantics): Element[];
1098
1156
  /**
1099
1157
  * Matches attributes
1100
1158
  */