scordi-extension 1.14.3 → 1.14.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/sdk/index.d.ts +1 -0
  2. package/dist/sdk/index.d.ts.map +1 -1
  3. package/dist/sdk/index.js +605 -587
  4. package/package.json +13 -4
  5. package/dist/.vite/manifest.json +0 -67
  6. package/dist/assets/DataExtractBlock-B7AuVonx.js +0 -6
  7. package/dist/assets/index-B9PKMhAi.js +0 -6
  8. package/dist/assets/index-CMlx_xZE.css +0 -1
  9. package/dist/assets/index-CZjAbH8z.js +0 -1
  10. package/dist/assets/index-DkFIvNAm.css +0 -1
  11. package/dist/assets/index-r5QRyJ4m.js +0 -1
  12. package/dist/assets/index.html-BIbPySIb.js +0 -74
  13. package/dist/assets/index.html-cr-_Qdxq.js +0 -49
  14. package/dist/assets/index.ts-BqxJYCmp.js +0 -160
  15. package/dist/assets/internal-messages-Drf0Gb9U.js +0 -1
  16. package/dist/assets/loading-page-1924caaa.js +0 -51
  17. package/dist/assets/main.tsx-BEyI95mZ.js +0 -2
  18. package/dist/assets/main.tsx-BKzdlur-.js +0 -2
  19. package/dist/assets/main.tsx-loader-BYP9L25W.js +0 -13
  20. package/dist/assets/main.tsx-loader-FYb0LhDu.js +0 -13
  21. package/dist/assets/schemas-C8r0jYHO.js +0 -21
  22. package/dist/logo.png +0 -0
  23. package/dist/manifest.json +0 -55
  24. package/dist/public/logo.png +0 -0
  25. package/dist/service-worker-loader.js +0 -3
  26. package/dist/src/blocks/AiParseDataBlock.ts.js +0 -101
  27. package/dist/src/blocks/ClearValueFormBlock.ts.js +0 -55
  28. package/dist/src/blocks/DataExtractBlock.ts.js +0 -28
  29. package/dist/src/blocks/ElementExistsBlock.ts.js +0 -26
  30. package/dist/src/blocks/EventClickBlock.ts.js +0 -143
  31. package/dist/src/blocks/FetchApiBlock.ts.js +0 -50
  32. package/dist/src/blocks/GetAttributeValueBlock.ts.js +0 -33
  33. package/dist/src/blocks/GetElementDataBlock.ts.js +0 -114
  34. package/dist/src/blocks/GetTextBlock.ts.js +0 -152
  35. package/dist/src/blocks/GetValueFormBlock.ts.js +0 -52
  36. package/dist/src/blocks/KeypressBlock.ts.js +0 -89
  37. package/dist/src/blocks/SaveAssetsBlock.ts.js +0 -35
  38. package/dist/src/blocks/ScrollBlock.ts.js +0 -111
  39. package/dist/src/blocks/SetValueFormBlock.ts.js +0 -56
  40. package/dist/src/blocks/WaitBlock.ts.js +0 -24
  41. package/dist/src/blocks/index.ts.js +0 -163
  42. package/dist/src/blocks/types.ts.js +0 -11
  43. package/dist/src/content/elements/finders/CssSelector.ts.js +0 -51
  44. package/dist/src/content/elements/finders/ElementSelector.ts.js +0 -20
  45. package/dist/src/content/elements/finders/IframeSelector.ts.js +0 -32
  46. package/dist/src/content/elements/finders/ShadowDOMSelector.ts.js +0 -38
  47. package/dist/src/content/elements/finders/XPathFinder.ts.js +0 -32
  48. package/dist/src/content/elements/index.ts.js +0 -26
  49. package/dist/src/content/elements/utils/CSSSelectorGenerator.ts.js +0 -72
  50. package/dist/src/content/elements/utils/XPathGenerator.ts.js +0 -62
  51. package/dist/src/content/handler/ExternalMessageHandler.ts.js +0 -78
  52. package/dist/src/content/handler/InternalMessageHandler.ts.js +0 -18
  53. package/dist/src/content/kernel/MessageKernel.ts.js +0 -83
  54. package/dist/src/content/main.tsx-loader.js +0 -22
  55. package/dist/src/content/main.tsx.js +0 -13
  56. package/dist/src/content/utils/index.ts.js +0 -1
  57. package/dist/src/content/utils/synchronizedLock.ts.js +0 -35
  58. package/dist/src/popup/index.html +0 -12
  59. package/dist/src/types/internal-messages.ts.js +0 -15
  60. package/dist/vendor/.vite-deps-chunk-PR4QN5HX.js__v--57e88532.js +0 -42
  61. package/dist/vendor/.vite-deps-chunk-PR4QN5HX.js__v--ba9031c0.js +0 -42
  62. package/dist/vendor/.vite-deps-chunk-VBBIEGWT.js__v--57e88532.js +0 -4156
  63. package/dist/vendor/.vite-deps-jsonata.js__v--5da6ca24.js +0 -5761
  64. package/dist/vendor/.vite-deps-jsonata.js__v--ba9031c0.js +0 -5761
  65. package/dist/vendor/.vite-deps-zod.js__v--13965f26.js +0 -219
  66. package/dist/vendor/.vite-deps-zod.js__v--ba9031c0.js +0 -12651
  67. package/dist/vendor/crx-client-port.js +0 -66
  68. package/dist/vendor/crx-client-preamble.js +0 -4
  69. package/dist/vendor/react-refresh.js +0 -670
  70. package/dist/vendor/vite-client.js +0 -1098
  71. package/dist/vendor/vite-dist-client-env.mjs.js +0 -19
  72. package/dist/vendor/webcomponents-custom-elements.js +0 -47
@@ -1,111 +0,0 @@
1
- import z from "/vendor/.vite-deps-zod.js__v--13965f26.js";
2
- import { BaseBlockSchema } from "/src/blocks/types.ts.js";
3
- import { findElement } from "/src/content/elements/index.ts.js";
4
- export const ScrollBlockSchema = BaseBlockSchema.extend({
5
- name: z.literal("scroll"),
6
- scrollType: z.enum(["toElement", "toBottom", "byDistance", "untilLoaded"]).optional(),
7
- distance: z.number().optional(),
8
- behavior: z.enum(["auto", "smooth"]).optional(),
9
- maxScrolls: z.number().optional(),
10
- waitAfterScroll: z.number().optional()
11
- });
12
- export function validateScrollBlock(data) {
13
- return ScrollBlockSchema.parse(data);
14
- }
15
- export async function handlerScroll(data) {
16
- try {
17
- const {
18
- selector = "",
19
- scrollType = "toBottom",
20
- distance = 500,
21
- behavior = "smooth",
22
- maxScrolls = 50,
23
- waitAfterScroll = 300,
24
- findBy = "cssSelector",
25
- option
26
- } = data;
27
- switch (scrollType) {
28
- case "toElement":
29
- if (!selector) {
30
- throw new Error("Selector is required for toElement scroll type");
31
- }
32
- return await scrollToElement(selector, findBy, option, behavior);
33
- case "toBottom":
34
- return await scrollToBottom(behavior, waitAfterScroll);
35
- case "byDistance":
36
- return await scrollByDistance(distance, behavior);
37
- case "untilLoaded":
38
- return await scrollUntilLoaded(maxScrolls, distance, behavior, waitAfterScroll);
39
- default:
40
- throw new Error(`Unknown scroll type: ${scrollType}`);
41
- }
42
- } catch (error) {
43
- return {
44
- hasError: true,
45
- message: error instanceof Error ? error.message : "Unknown error in scroll handler",
46
- data: false
47
- };
48
- }
49
- }
50
- async function scrollToElement(selector, findBy, option, behavior) {
51
- const element = await findElement({ selector, findBy, option });
52
- if (!element) {
53
- return {
54
- hasError: true,
55
- message: "Element not found for scrolling",
56
- data: false
57
- };
58
- }
59
- const targetElement = Array.isArray(element) ? element[0] : element;
60
- targetElement.scrollIntoView({ behavior, block: "center" });
61
- return { data: true };
62
- }
63
- async function scrollToBottom(behavior, waitAfterScroll) {
64
- let lastHeight = document.body.scrollHeight;
65
- let attempts = 0;
66
- const maxAttempts = 50;
67
- while (attempts < maxAttempts) {
68
- window.scrollTo({
69
- top: document.body.scrollHeight,
70
- behavior
71
- });
72
- await new Promise((resolve) => setTimeout(resolve, waitAfterScroll));
73
- const newHeight = document.body.scrollHeight;
74
- if (newHeight === lastHeight) {
75
- break;
76
- }
77
- lastHeight = newHeight;
78
- attempts++;
79
- }
80
- return { data: true };
81
- }
82
- async function scrollByDistance(distance, behavior) {
83
- window.scrollBy({
84
- top: distance,
85
- behavior
86
- });
87
- return { data: true };
88
- }
89
- async function scrollUntilLoaded(maxScrolls, distance, behavior, waitAfterScroll) {
90
- let scrollCount = 0;
91
- let lastHeight = document.body.scrollHeight;
92
- while (scrollCount < maxScrolls) {
93
- window.scrollBy({
94
- top: distance,
95
- behavior
96
- // Use provided behavior
97
- });
98
- await new Promise((resolve) => setTimeout(resolve, waitAfterScroll));
99
- const newHeight = document.body.scrollHeight;
100
- const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
101
- const windowHeight = window.innerHeight;
102
- if (scrollTop + windowHeight >= newHeight - 10) {
103
- if (newHeight === lastHeight) {
104
- break;
105
- }
106
- }
107
- lastHeight = newHeight;
108
- scrollCount++;
109
- }
110
- return { data: true };
111
- }
@@ -1,56 +0,0 @@
1
- import { findElement } from "/src/content/elements/index.ts.js";
2
- import { BaseBlockSchema } from "/src/blocks/types.ts.js";
3
- import z from "/vendor/.vite-deps-zod.js__v--13965f26.js";
4
- export const SetValueFormsBlockSchema = BaseBlockSchema.extend({
5
- name: z.literal("set-value-form"),
6
- setValue: z.string(),
7
- type: z.enum(["text-field", "select", "checkbox"]).optional()
8
- });
9
- export function validateSetValueFormsBlock(data) {
10
- return SetValueFormsBlockSchema.parse(data);
11
- }
12
- export async function handlerSetValueForm(data) {
13
- try {
14
- const { selector = "", setValue, type = "text-field", findBy = "cssSelector" } = data;
15
- if (!selector) {
16
- throw new Error("Selector is required for set-value-form block");
17
- }
18
- const element = await findElement({ selector, findBy, option: data.option });
19
- if (!element) {
20
- throw new Error("Form element not found");
21
- }
22
- setFormValue(element, setValue, type);
23
- return { data: "Form element updated successfully" };
24
- } catch (error) {
25
- return {
26
- hasError: true,
27
- message: error instanceof Error ? error.message : "Unknown error in set-value-form handler",
28
- data: null
29
- };
30
- }
31
- }
32
- function setFormValue(element, value, type) {
33
- switch (type) {
34
- case "text-field":
35
- if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
36
- element.value = value;
37
- element.dispatchEvent(new Event("input", { bubbles: true }));
38
- element.dispatchEvent(new Event("change", { bubbles: true }));
39
- }
40
- break;
41
- case "select":
42
- if (element instanceof HTMLSelectElement) {
43
- element.value = value;
44
- element.dispatchEvent(new Event("change", { bubbles: true }));
45
- }
46
- break;
47
- case "checkbox":
48
- if (element instanceof HTMLInputElement && element.type === "checkbox") {
49
- element.checked = value === "true" || value === "checked";
50
- element.dispatchEvent(new Event("change", { bubbles: true }));
51
- }
52
- break;
53
- default:
54
- throw new Error(`Unsupported form element type: ${type}`);
55
- }
56
- }
@@ -1,24 +0,0 @@
1
- import z from "/vendor/.vite-deps-zod.js__v--13965f26.js";
2
- export const WaitBlockSchema = z.object({
3
- name: z.literal("wait"),
4
- duration: z.number().min(0)
5
- });
6
- export function validateWaitBlock(data) {
7
- return WaitBlockSchema.parse(data);
8
- }
9
- export async function handlerWait(data) {
10
- try {
11
- const { duration } = data;
12
- console.log(`[Wait] Waiting for ${duration}ms...`);
13
- await new Promise((resolve) => setTimeout(resolve, duration));
14
- console.log(`[Wait] Wait completed after ${duration}ms`);
15
- return { data: true };
16
- } catch (error) {
17
- console.log(error);
18
- return {
19
- hasError: true,
20
- message: error instanceof Error ? error.message : "Unknown error in wait handler",
21
- data: false
22
- };
23
- }
24
- }
@@ -1,163 +0,0 @@
1
- export { BaseBlockSchema } from "/src/blocks/types.ts.js";
2
- export { createSchema, createArraySchema, Schema } from "/src/blocks/AiParseDataBlock.ts.js";
3
- export { GetTextBlockSchema } from "/src/blocks/GetTextBlock.ts.js";
4
- export { GetAttributeValueBlockSchema } from "/src/blocks/GetAttributeValueBlock.ts.js";
5
- export { GetValueFormsBlockSchema } from "/src/blocks/GetValueFormBlock.ts.js";
6
- export { SetValueFormsBlockSchema } from "/src/blocks/SetValueFormBlock.ts.js";
7
- export { ClearValueFormsBlockSchema } from "/src/blocks/ClearValueFormBlock.ts.js";
8
- export { ElementExistsBlockSchema } from "/src/blocks/ElementExistsBlock.ts.js";
9
- export { EventClickBlockSchema } from "/src/blocks/EventClickBlock.ts.js";
10
- export { KeypressBlockSchema } from "/src/blocks/KeypressBlock.ts.js";
11
- export { WaitBlockSchema } from "/src/blocks/WaitBlock.ts.js";
12
- export { SaveAssetsBlockSchema } from "/src/blocks/SaveAssetsBlock.ts.js";
13
- export { GetElementDataBlockSchema } from "/src/blocks/GetElementDataBlock.ts.js";
14
- export { ScrollBlockSchema } from "/src/blocks/ScrollBlock.ts.js";
15
- export { AiParseDataBlockSchema } from "/src/blocks/AiParseDataBlock.ts.js";
16
- export { FetchApiBlockSchema } from "/src/blocks/FetchApiBlock.ts.js";
17
- export { DataExtractBlockSchema } from "/src/blocks/DataExtractBlock.ts.js";
18
- import { handlerGetText, validateGetTextBlock } from "/src/blocks/GetTextBlock.ts.js";
19
- import {
20
- handlerGetAttributeValue,
21
- validateGetAttributeValueBlock
22
- } from "/src/blocks/GetAttributeValueBlock.ts.js";
23
- import {
24
- handlerGetValueForm,
25
- validateGetValueFormsBlock
26
- } from "/src/blocks/GetValueFormBlock.ts.js";
27
- import {
28
- handlerSetValueForm,
29
- validateSetValueFormsBlock
30
- } from "/src/blocks/SetValueFormBlock.ts.js";
31
- import {
32
- handlerClearValueForm,
33
- validateClearValueFormsBlock
34
- } from "/src/blocks/ClearValueFormBlock.ts.js";
35
- import {
36
- handlerElementExists,
37
- validateElementExistsBlock
38
- } from "/src/blocks/ElementExistsBlock.ts.js";
39
- import { handlerEventClick, validateEventClickBlock } from "/src/blocks/EventClickBlock.ts.js";
40
- import { handlerKeypress, validateKeypressBlock } from "/src/blocks/KeypressBlock.ts.js";
41
- import { handlerWait, validateWaitBlock } from "/src/blocks/WaitBlock.ts.js";
42
- import { handlerSaveAssets, validateSaveAssetsBlock } from "/src/blocks/SaveAssetsBlock.ts.js";
43
- import {
44
- handlerGetElementData,
45
- validateGetElementDataBlock
46
- } from "/src/blocks/GetElementDataBlock.ts.js";
47
- import { handlerScroll, validateScrollBlock } from "/src/blocks/ScrollBlock.ts.js";
48
- import { handlerAiParseData, validateAiParseDataBlock } from "/src/blocks/AiParseDataBlock.ts.js";
49
- import { handlerFetchApi, validateFetchApiBlock } from "/src/blocks/FetchApiBlock.ts.js";
50
- import { handlerDataExtract, validateDataExtractBlock } from "/src/blocks/DataExtractBlock.ts.js";
51
- import { GetTextBlockSchema as GetTextBlockSchema2 } from "/src/blocks/GetTextBlock.ts.js";
52
- import { GetAttributeValueBlockSchema as GetAttributeValueBlockSchema2 } from "/src/blocks/GetAttributeValueBlock.ts.js";
53
- import { GetValueFormsBlockSchema as GetValueFormsBlockSchema2 } from "/src/blocks/GetValueFormBlock.ts.js";
54
- import { SetValueFormsBlockSchema as SetValueFormsBlockSchema2 } from "/src/blocks/SetValueFormBlock.ts.js";
55
- import { ClearValueFormsBlockSchema as ClearValueFormsBlockSchema2 } from "/src/blocks/ClearValueFormBlock.ts.js";
56
- import { ElementExistsBlockSchema as ElementExistsBlockSchema2 } from "/src/blocks/ElementExistsBlock.ts.js";
57
- import { EventClickBlockSchema as EventClickBlockSchema2 } from "/src/blocks/EventClickBlock.ts.js";
58
- import { KeypressBlockSchema as KeypressBlockSchema2 } from "/src/blocks/KeypressBlock.ts.js";
59
- import { WaitBlockSchema as WaitBlockSchema2 } from "/src/blocks/WaitBlock.ts.js";
60
- import { SaveAssetsBlockSchema as SaveAssetsBlockSchema2 } from "/src/blocks/SaveAssetsBlock.ts.js";
61
- import { GetElementDataBlockSchema as GetElementDataBlockSchema2 } from "/src/blocks/GetElementDataBlock.ts.js";
62
- import { ScrollBlockSchema as ScrollBlockSchema2 } from "/src/blocks/ScrollBlock.ts.js";
63
- import { AiParseDataBlockSchema as AiParseDataBlockSchema2 } from "/src/blocks/AiParseDataBlock.ts.js";
64
- import { FetchApiBlockSchema as FetchApiBlockSchema2 } from "/src/blocks/FetchApiBlock.ts.js";
65
- import { DataExtractBlockSchema as DataExtractBlockSchema2 } from "/src/blocks/DataExtractBlock.ts.js";
66
- export const AllBlockSchemas = {
67
- "get-text": GetTextBlockSchema2,
68
- "attribute-value": GetAttributeValueBlockSchema2,
69
- "get-value-form": GetValueFormsBlockSchema2,
70
- "set-value-form": SetValueFormsBlockSchema2,
71
- "clear-value-form": ClearValueFormsBlockSchema2,
72
- "element-exists": ElementExistsBlockSchema2,
73
- "event-click": EventClickBlockSchema2,
74
- "keypress": KeypressBlockSchema2,
75
- "wait": WaitBlockSchema2,
76
- "save-assets": SaveAssetsBlockSchema2,
77
- "get-element-data": GetElementDataBlockSchema2,
78
- "scroll": ScrollBlockSchema2,
79
- "ai-parse-data": AiParseDataBlockSchema2,
80
- "fetch-api": FetchApiBlockSchema2,
81
- "data-extract": DataExtractBlockSchema2
82
- };
83
- export class BlockHandler {
84
- // Implementation
85
- static async executeBlock(block) {
86
- try {
87
- switch (block.name) {
88
- case "get-text": {
89
- const validatedBlock = validateGetTextBlock(block);
90
- return await handlerGetText(validatedBlock);
91
- }
92
- case "attribute-value": {
93
- const validatedBlock = validateGetAttributeValueBlock(block);
94
- return await handlerGetAttributeValue(validatedBlock);
95
- }
96
- case "get-value-form": {
97
- const validatedBlock = validateGetValueFormsBlock(block);
98
- return await handlerGetValueForm(validatedBlock);
99
- }
100
- case "set-value-form": {
101
- const validatedBlock = validateSetValueFormsBlock(block);
102
- return await handlerSetValueForm(validatedBlock);
103
- }
104
- case "clear-value-form": {
105
- const validatedBlock = validateClearValueFormsBlock(block);
106
- return await handlerClearValueForm(validatedBlock);
107
- }
108
- case "element-exists": {
109
- const validatedBlock = validateElementExistsBlock(block);
110
- return await handlerElementExists(validatedBlock);
111
- }
112
- case "event-click": {
113
- const validatedBlock = validateEventClickBlock(block);
114
- return await handlerEventClick(validatedBlock);
115
- }
116
- case "keypress": {
117
- const validatedBlock = validateKeypressBlock(block);
118
- return await handlerKeypress(validatedBlock);
119
- }
120
- case "wait": {
121
- const validatedBlock = validateWaitBlock(block);
122
- return await handlerWait(validatedBlock);
123
- }
124
- case "save-assets": {
125
- const validatedBlock = validateSaveAssetsBlock(block);
126
- return await handlerSaveAssets(validatedBlock);
127
- }
128
- case "get-element-data": {
129
- const validatedBlock = validateGetElementDataBlock(block);
130
- return await handlerGetElementData(validatedBlock);
131
- }
132
- case "scroll": {
133
- const validatedBlock = validateScrollBlock(block);
134
- return await handlerScroll(validatedBlock);
135
- }
136
- case "ai-parse-data": {
137
- const validatedBlock = validateAiParseDataBlock(block);
138
- return await handlerAiParseData(validatedBlock);
139
- }
140
- case "fetch-api": {
141
- const validatedBlock = validateFetchApiBlock(block);
142
- return await handlerFetchApi(validatedBlock);
143
- }
144
- case "data-extract": {
145
- const validatedBlock = validateDataExtractBlock(block);
146
- return await handlerDataExtract(validatedBlock);
147
- }
148
- default:
149
- return {
150
- hasError: true,
151
- message: `Unknown block type: ${block.name}`,
152
- data: null
153
- };
154
- }
155
- } catch (error) {
156
- return {
157
- hasError: true,
158
- message: error instanceof Error ? error.message : "Unknown error in block execution",
159
- data: null
160
- };
161
- }
162
- }
163
- }
@@ -1,11 +0,0 @@
1
- import { z } from "/vendor/.vite-deps-zod.js__v--13965f26.js";
2
- export const BaseBlockSchema = z.object({
3
- name: z.string(),
4
- selector: z.string(),
5
- findBy: z.enum(["cssSelector", "xpath"]),
6
- option: z.object({
7
- waitForSelector: z.boolean().optional(),
8
- waitSelectorTimeout: z.number().optional(),
9
- multiple: z.boolean().optional()
10
- })
11
- });
@@ -1,51 +0,0 @@
1
- import { ElementSelector } from "/src/content/elements/finders/ElementSelector.ts.js";
2
- export class CssSelector extends ElementSelector {
3
- async find(data, documentCtx = document) {
4
- const { selector, option } = data;
5
- const { multiple = false } = option || {};
6
- try {
7
- const processedSelector = this.processCustomPseudoSelectors(selector, documentCtx);
8
- if (multiple) {
9
- return Array.from(documentCtx.querySelectorAll(processedSelector));
10
- } else {
11
- return documentCtx.querySelector(processedSelector);
12
- }
13
- } catch (error) {
14
- console.error("CSS Selector error:", error);
15
- return null;
16
- }
17
- }
18
- processCustomPseudoSelectors(selector, documentCtx) {
19
- const containsRegex = /:contains\(['"]([^'"]*)['"]\)/g;
20
- if (containsRegex.test(selector)) {
21
- this.markElementsWithText(documentCtx);
22
- return selector.replace(
23
- /:contains\(['"]([^'"]*)['"]\)/g,
24
- (_match, text) => `[data-contains="${text}"]`
25
- );
26
- }
27
- const equalRegex = /:equal\(['"]([^'"]*)['"]\)/g;
28
- if (equalRegex.test(selector)) {
29
- this.markElementsWithText(documentCtx);
30
- return selector.replace(
31
- /:equal\(['"]([^'"]*)['"]\)/g,
32
- (_match, text) => `[data-equal="${text}"]`
33
- );
34
- }
35
- return selector;
36
- }
37
- markElementsWithText(documentCtx) {
38
- const allElements = documentCtx.querySelectorAll("*");
39
- allElements.forEach((element) => {
40
- const text = element.textContent?.trim() || "";
41
- if (text) {
42
- element.setAttribute("data-contains", text);
43
- const childNodes = Array.from(element.childNodes);
44
- const directText = childNodes.filter((node) => node.nodeType === Node.TEXT_NODE).map((node) => node.textContent?.trim() || "").join(" ").trim();
45
- if (directText && directText === text || element.children.length === 0 && text) {
46
- element.setAttribute("data-equal", text);
47
- }
48
- }
49
- });
50
- }
51
- }
@@ -1,20 +0,0 @@
1
- export class ElementSelector {
2
- async waitForElement(data, documentCtx, timeout) {
3
- return new Promise((resolve) => {
4
- const startTime = Date.now();
5
- const checkElement = async () => {
6
- const element = await this.find(data, documentCtx);
7
- if (element && (Array.isArray(element) ? element.length > 0 : true)) {
8
- resolve(element);
9
- return;
10
- }
11
- if (Date.now() - startTime >= timeout) {
12
- resolve(null);
13
- return;
14
- }
15
- setTimeout(checkElement, 100);
16
- };
17
- checkElement();
18
- });
19
- }
20
- }
@@ -1,32 +0,0 @@
1
- import { ElementSelector } from "/src/content/elements/finders/ElementSelector.ts.js";
2
- export class IframSelector extends ElementSelector {
3
- async find(data, documentCtx = document) {
4
- const { selector, option } = data;
5
- const { multiple = false } = option || {};
6
- if (!selector || selector.trim() === "") {
7
- return null;
8
- }
9
- const parts = selector.split("|>").map((part) => part.trim());
10
- if (parts.length !== 2) {
11
- return null;
12
- }
13
- const iframeSelector = parts[0];
14
- const targetSelector = parts[1];
15
- if (!iframeSelector || !targetSelector) {
16
- return null;
17
- }
18
- try {
19
- const iframe = documentCtx.querySelector(iframeSelector);
20
- if (!iframe || !iframe.contentDocument) return null;
21
- const iframeDoc = iframe.contentDocument;
22
- if (multiple) {
23
- return Array.from(iframeDoc.querySelectorAll(targetSelector));
24
- } else {
25
- return iframeDoc.querySelector(targetSelector);
26
- }
27
- } catch (error) {
28
- console.error("Iframe Selector error:", error);
29
- return null;
30
- }
31
- }
32
- }
@@ -1,38 +0,0 @@
1
- import { ElementSelector } from "/src/content/elements/finders/ElementSelector.ts.js";
2
- export class ShadowDOMSelector extends ElementSelector {
3
- async find(data, documentCtx = document) {
4
- const { selector, option } = data;
5
- const { multiple = false } = option || {};
6
- if (!selector || selector.trim() === "") {
7
- return null;
8
- }
9
- const parts = selector.split(">>").map((part) => part.trim());
10
- let currentContext = documentCtx;
11
- try {
12
- for (let i = 0; i < parts.length; i++) {
13
- const part = parts[i];
14
- const isLast = i === parts.length - 1;
15
- if (!part) {
16
- return null;
17
- }
18
- if (isLast && multiple) {
19
- return Array.from(currentContext.querySelectorAll(part));
20
- }
21
- const element = currentContext.querySelector(part);
22
- if (!element) return null;
23
- if (isLast) {
24
- return element;
25
- }
26
- if (element.shadowRoot) {
27
- currentContext = element.shadowRoot;
28
- } else {
29
- return null;
30
- }
31
- }
32
- } catch (error) {
33
- console.error("Shadow DOM Selector error:", error);
34
- return null;
35
- }
36
- return null;
37
- }
38
- }
@@ -1,32 +0,0 @@
1
- import { ElementSelector } from "/src/content/elements/finders/ElementSelector.ts.js";
2
- export class XPathSelector extends ElementSelector {
3
- async find(data, documentCtx = document) {
4
- const { selector, option } = data;
5
- const { multiple = false } = option || {};
6
- try {
7
- const result = documentCtx.evaluate(
8
- selector,
9
- documentCtx,
10
- null,
11
- multiple ? XPathResult.ORDERED_NODE_SNAPSHOT_TYPE : XPathResult.FIRST_ORDERED_NODE_TYPE,
12
- null
13
- );
14
- if (multiple) {
15
- const nodes = [];
16
- for (let i = 0; i < result.snapshotLength; i++) {
17
- const node = result.snapshotItem(i);
18
- if (node && node.nodeType === Node.ELEMENT_NODE) {
19
- nodes.push(node);
20
- }
21
- }
22
- return Promise.resolve(nodes.length > 0 ? nodes : null);
23
- } else {
24
- const node = result.singleNodeValue;
25
- return node && node.nodeType === Node.ELEMENT_NODE ? node : null;
26
- }
27
- } catch (error) {
28
- console.error("XPath error:", error);
29
- return null;
30
- }
31
- }
32
- }
@@ -1,26 +0,0 @@
1
- import { CssSelector } from "/src/content/elements/finders/CssSelector.ts.js";
2
- import { IframSelector } from "/src/content/elements/finders/IframeSelector.ts.js";
3
- import { ShadowDOMSelector } from "/src/content/elements/finders/ShadowDOMSelector.ts.js";
4
- import { XPathSelector } from "/src/content/elements/finders/XPathFinder.ts.js";
5
- export async function findElement(data, documentCtx = document) {
6
- const { selector, findBy = "cssSelector", option } = data;
7
- const { waitForSelector = false, waitSelectorTimeout = 5e3 } = option || {};
8
- const selectorInstance = buildSelector(selector, findBy);
9
- if (waitForSelector) {
10
- return selectorInstance.waitForElement(data, documentCtx, waitSelectorTimeout);
11
- }
12
- return selectorInstance.find(data, documentCtx);
13
- }
14
- function buildSelector(selector, findBy) {
15
- if (findBy === "xpath") {
16
- return new XPathSelector();
17
- }
18
- if (selector.includes(">>")) {
19
- return new ShadowDOMSelector();
20
- }
21
- if (selector.includes("|>")) {
22
- return new IframSelector();
23
- }
24
- return new CssSelector();
25
- }
26
- export { CSSSelectorGenerator } from "/src/content/elements/utils/CSSSelectorGenerator.ts.js";
@@ -1,72 +0,0 @@
1
- export class CSSSelectorGenerator {
2
- /**
3
- * 요소의 안정적인 CSS 셀렉터 생성
4
- * @param element 대상 요소
5
- * @returns 생성된 CSS 셀렉터
6
- */
7
- static generate(element) {
8
- const staticAttributes = ["data-testid", "aria-label", "title", "alt", "role"];
9
- for (const attr of staticAttributes) {
10
- const value = element.getAttribute(attr);
11
- if (value && !this.isDynamicValue(value)) {
12
- return `[${attr}="${CSS.escape(value)}"]`;
13
- }
14
- }
15
- const tagName = element.tagName.toLowerCase();
16
- const parent = element.parentElement;
17
- if (parent) {
18
- const siblings = Array.from(parent.children);
19
- const index = siblings.indexOf(element) + 1;
20
- if (siblings.length > 1) {
21
- return `${tagName}:nth-child(${index})`;
22
- }
23
- }
24
- if (parent) {
25
- const parentSelector = this.generateParentSelector(parent);
26
- if (parentSelector) {
27
- return `${parentSelector} > ${tagName}:nth-child(${Array.from(parent.children).indexOf(element) + 1})`;
28
- }
29
- }
30
- return tagName;
31
- }
32
- /**
33
- * 부모 요소의 셀렉터 생성
34
- */
35
- static generateParentSelector(parent) {
36
- const tagName = parent.tagName.toLowerCase();
37
- const staticAttributes = ["data-testid", "aria-label", "title", "alt", "role"];
38
- for (const attr of staticAttributes) {
39
- const value = parent.getAttribute(attr);
40
- if (value && !this.isDynamicValue(value)) {
41
- return `[${attr}="${CSS.escape(value)}"]`;
42
- }
43
- }
44
- const grandParent = parent.parentElement;
45
- if (grandParent) {
46
- const siblings = Array.from(grandParent.children);
47
- const index = siblings.indexOf(parent) + 1;
48
- if (siblings.length > 1) {
49
- return `${tagName}:nth-child(${index})`;
50
- }
51
- }
52
- return tagName;
53
- }
54
- /**
55
- * 동적 값 패턴 감지
56
- * @param value 확인할 값
57
- * @returns 동적 값 여부
58
- */
59
- static isDynamicValue(value) {
60
- const dynamicPatterns = [
61
- /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
62
- // UUID
63
- /^\d{13}$/,
64
- // timestamp
65
- /^[a-zA-Z0-9]{16,}$/,
66
- // long random string
67
- /^[a-zA-Z0-9]+-\d+$/
68
- // name-123 pattern
69
- ];
70
- return dynamicPatterns.some((pattern) => pattern.test(value));
71
- }
72
- }