@rpascene/shared 0.30.8

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 (177) hide show
  1. package/README.md +9 -0
  2. package/dist/es/baseDB.mjs +109 -0
  3. package/dist/es/build/copy-static.mjs +29 -0
  4. package/dist/es/common.mjs +37 -0
  5. package/dist/es/constants/example-code.mjs +202 -0
  6. package/dist/es/constants/index.mjs +74 -0
  7. package/dist/es/env/basic.mjs +6 -0
  8. package/dist/es/env/constants.mjs +97 -0
  9. package/dist/es/env/decide-model-config.mjs +172 -0
  10. package/dist/es/env/global-config-manager.mjs +82 -0
  11. package/dist/es/env/helper.mjs +45 -0
  12. package/dist/es/env/index.mjs +5 -0
  13. package/dist/es/env/init-debug.mjs +18 -0
  14. package/dist/es/env/model-config-manager.mjs +99 -0
  15. package/dist/es/env/parse.mjs +69 -0
  16. package/dist/es/env/types.mjs +265 -0
  17. package/dist/es/env/utils.mjs +18 -0
  18. package/dist/es/extractor/constants.mjs +2 -0
  19. package/dist/es/extractor/cs_postmessage.mjs +61 -0
  20. package/dist/es/extractor/customLocator.mjs +646 -0
  21. package/dist/es/extractor/debug.mjs +6 -0
  22. package/dist/es/extractor/dom-util.mjs +92 -0
  23. package/dist/es/extractor/index.mjs +7 -0
  24. package/dist/es/extractor/locator.mjs +95 -0
  25. package/dist/es/extractor/tree.mjs +81 -0
  26. package/dist/es/extractor/util.mjs +244 -0
  27. package/dist/es/extractor/web-extractor.mjs +361 -0
  28. package/dist/es/img/box-select.mjs +184 -0
  29. package/dist/es/img/draw-box.mjs +42 -0
  30. package/dist/es/img/get-jimp.mjs +10 -0
  31. package/dist/es/img/get-photon.mjs +19 -0
  32. package/dist/es/img/get-sharp.mjs +11 -0
  33. package/dist/es/img/index.mjs +5 -0
  34. package/dist/es/img/info.mjs +32 -0
  35. package/dist/es/img/transform.mjs +192 -0
  36. package/dist/es/index.mjs +3 -0
  37. package/dist/es/logger.mjs +61 -0
  38. package/dist/es/node/fs.mjs +44 -0
  39. package/dist/es/node/index.mjs +1 -0
  40. package/dist/es/polyfills/async-hooks.mjs +2 -0
  41. package/dist/es/polyfills/index.mjs +1 -0
  42. package/dist/es/types/index.mjs +3 -0
  43. package/dist/es/us-keyboard-layout.mjs +1414 -0
  44. package/dist/es/us-keyboard-layout.mjs.LICENSE.txt +5 -0
  45. package/dist/es/utils.mjs +66 -0
  46. package/dist/lib/baseDB.js +149 -0
  47. package/dist/lib/build/copy-static.js +77 -0
  48. package/dist/lib/common.js +93 -0
  49. package/dist/lib/constants/example-code.js +239 -0
  50. package/dist/lib/constants/index.js +153 -0
  51. package/dist/lib/env/basic.js +40 -0
  52. package/dist/lib/env/constants.js +143 -0
  53. package/dist/lib/env/decide-model-config.js +212 -0
  54. package/dist/lib/env/global-config-manager.js +116 -0
  55. package/dist/lib/env/helper.js +85 -0
  56. package/dist/lib/env/index.js +94 -0
  57. package/dist/lib/env/init-debug.js +52 -0
  58. package/dist/lib/env/model-config-manager.js +133 -0
  59. package/dist/lib/env/parse.js +106 -0
  60. package/dist/lib/env/types.js +650 -0
  61. package/dist/lib/env/utils.js +61 -0
  62. package/dist/lib/extractor/constants.js +42 -0
  63. package/dist/lib/extractor/cs_postmessage.js +98 -0
  64. package/dist/lib/extractor/customLocator.js +698 -0
  65. package/dist/lib/extractor/debug.js +12 -0
  66. package/dist/lib/extractor/dom-util.js +150 -0
  67. package/dist/lib/extractor/index.js +153 -0
  68. package/dist/lib/extractor/locator.js +141 -0
  69. package/dist/lib/extractor/tree.js +127 -0
  70. package/dist/lib/extractor/util.js +335 -0
  71. package/dist/lib/extractor/web-extractor.js +407 -0
  72. package/dist/lib/img/box-select.js +232 -0
  73. package/dist/lib/img/draw-box.js +89 -0
  74. package/dist/lib/img/get-jimp.js +72 -0
  75. package/dist/lib/img/get-photon.js +76 -0
  76. package/dist/lib/img/get-sharp.js +63 -0
  77. package/dist/lib/img/index.js +102 -0
  78. package/dist/lib/img/info.js +86 -0
  79. package/dist/lib/img/transform.js +279 -0
  80. package/dist/lib/index.js +43 -0
  81. package/dist/lib/logger.js +114 -0
  82. package/dist/lib/node/fs.js +97 -0
  83. package/dist/lib/node/index.js +60 -0
  84. package/dist/lib/polyfills/async-hooks.js +36 -0
  85. package/dist/lib/polyfills/index.js +60 -0
  86. package/dist/lib/types/index.js +37 -0
  87. package/dist/lib/us-keyboard-layout.js +1457 -0
  88. package/dist/lib/us-keyboard-layout.js.LICENSE.txt +5 -0
  89. package/dist/lib/utils.js +136 -0
  90. package/dist/types/baseDB.d.ts +25 -0
  91. package/dist/types/build/copy-static.d.ts +31 -0
  92. package/dist/types/common.d.ts +12 -0
  93. package/dist/types/constants/example-code.d.ts +2 -0
  94. package/dist/types/constants/index.d.ts +23 -0
  95. package/dist/types/env/basic.d.ts +6 -0
  96. package/dist/types/env/constants.d.ts +40 -0
  97. package/dist/types/env/decide-model-config.d.ts +14 -0
  98. package/dist/types/env/global-config-manager.d.ts +32 -0
  99. package/dist/types/env/helper.d.ts +6 -0
  100. package/dist/types/env/index.d.ts +4 -0
  101. package/dist/types/env/init-debug.d.ts +1 -0
  102. package/dist/types/env/model-config-manager.d.ts +24 -0
  103. package/dist/types/env/parse.d.ts +12 -0
  104. package/dist/types/env/types.d.ts +295 -0
  105. package/dist/types/env/utils.d.ts +7 -0
  106. package/dist/types/extractor/constants.d.ts +1 -0
  107. package/dist/types/extractor/cs_postmessage.d.ts +2 -0
  108. package/dist/types/extractor/customLocator.d.ts +69 -0
  109. package/dist/types/extractor/debug.d.ts +1 -0
  110. package/dist/types/extractor/dom-util.d.ts +26 -0
  111. package/dist/types/extractor/index.d.ts +36 -0
  112. package/dist/types/extractor/locator.d.ts +7 -0
  113. package/dist/types/extractor/tree.d.ts +9 -0
  114. package/dist/types/extractor/util.d.ts +43 -0
  115. package/dist/types/extractor/web-extractor.d.ts +19 -0
  116. package/dist/types/img/box-select.d.ts +25 -0
  117. package/dist/types/img/draw-box.d.ts +15 -0
  118. package/dist/types/img/get-jimp.d.ts +2 -0
  119. package/dist/types/img/get-photon.d.ts +8 -0
  120. package/dist/types/img/get-sharp.d.ts +3 -0
  121. package/dist/types/img/index.d.ts +4 -0
  122. package/dist/types/img/info.d.ts +29 -0
  123. package/dist/types/img/transform.d.ts +88 -0
  124. package/dist/types/index.d.ts +3 -0
  125. package/dist/types/logger.d.ts +4 -0
  126. package/dist/types/node/fs.d.ts +15 -0
  127. package/dist/types/node/index.d.ts +1 -0
  128. package/dist/types/polyfills/async-hooks.d.ts +6 -0
  129. package/dist/types/polyfills/index.d.ts +4 -0
  130. package/dist/types/types/index.d.ts +37 -0
  131. package/dist/types/us-keyboard-layout.d.ts +32 -0
  132. package/dist/types/utils.d.ts +22 -0
  133. package/package.json +102 -0
  134. package/src/baseDB.ts +158 -0
  135. package/src/build/copy-static.ts +62 -0
  136. package/src/common.ts +67 -0
  137. package/src/constants/example-code.ts +202 -0
  138. package/src/constants/index.ts +81 -0
  139. package/src/env/basic.ts +12 -0
  140. package/src/env/constants.ts +291 -0
  141. package/src/env/decide-model-config.ts +319 -0
  142. package/src/env/global-config-manager.ts +174 -0
  143. package/src/env/helper.ts +80 -0
  144. package/src/env/index.ts +4 -0
  145. package/src/env/init-debug.ts +29 -0
  146. package/src/env/model-config-manager.ts +145 -0
  147. package/src/env/parse.ts +131 -0
  148. package/src/env/types.ts +573 -0
  149. package/src/env/utils.ts +39 -0
  150. package/src/extractor/constants.ts +5 -0
  151. package/src/extractor/cs_postmessage.ts +101 -0
  152. package/src/extractor/customLocator.ts +1138 -0
  153. package/src/extractor/debug.ts +10 -0
  154. package/src/extractor/dom-util.ts +141 -0
  155. package/src/extractor/index.ts +54 -0
  156. package/src/extractor/locator.ts +179 -0
  157. package/src/extractor/tree.ts +179 -0
  158. package/src/extractor/util.ts +468 -0
  159. package/src/extractor/web-extractor.ts +559 -0
  160. package/src/img/box-select.ts +346 -0
  161. package/src/img/draw-box.ts +60 -0
  162. package/src/img/get-jimp.ts +12 -0
  163. package/src/img/get-photon.ts +48 -0
  164. package/src/img/get-sharp.ts +18 -0
  165. package/src/img/index.ts +24 -0
  166. package/src/img/info.ts +79 -0
  167. package/src/img/jimp.d.ts +4 -0
  168. package/src/img/transform.ts +396 -0
  169. package/src/index.ts +6 -0
  170. package/src/logger.ts +93 -0
  171. package/src/node/fs.ts +84 -0
  172. package/src/node/index.ts +1 -0
  173. package/src/polyfills/async-hooks.ts +6 -0
  174. package/src/polyfills/index.ts +4 -0
  175. package/src/types/index.ts +53 -0
  176. package/src/us-keyboard-layout.ts +723 -0
  177. package/src/utils.ts +127 -0
@@ -0,0 +1,468 @@
1
+ import type { Rect } from '../types';
2
+ import { generateHashId } from '../utils';
3
+ import { extractTextWithPosition } from './web-extractor';
4
+
5
+ const MAX_VALUE_LENGTH = 300;
6
+ let debugMode = false;
7
+
8
+ export function setDebugMode(mode: boolean) {
9
+ debugMode = mode;
10
+ }
11
+
12
+ export function getDebugMode(): boolean {
13
+ return debugMode;
14
+ }
15
+
16
+ export function logger(..._msg: any[]): void {
17
+ if (!debugMode) {
18
+ return;
19
+ }
20
+ console.log(..._msg);
21
+ }
22
+
23
+ export function isElementPartiallyInViewport(
24
+ rect: ReturnType<typeof getRect>,
25
+ currentWindow: typeof window,
26
+ currentDocument: typeof document,
27
+ visibleAreaRatio: number = 2 / 3,
28
+ ) {
29
+ const elementHeight = rect.height;
30
+ const elementWidth = rect.width;
31
+
32
+ const viewportRect = {
33
+ left: 0,
34
+ top: 0,
35
+ width:
36
+ currentWindow.innerWidth || currentDocument.documentElement.clientWidth,
37
+ height:
38
+ currentWindow.innerHeight || currentDocument.documentElement.clientHeight,
39
+ right:
40
+ currentWindow.innerWidth || currentDocument.documentElement.clientWidth,
41
+ bottom:
42
+ currentWindow.innerHeight || currentDocument.documentElement.clientHeight,
43
+ x: 0,
44
+ y: 0,
45
+ zoom: 1,
46
+ };
47
+
48
+ const overlapRect = overlappedRect(rect, viewportRect);
49
+ if (!overlapRect) {
50
+ return false;
51
+ }
52
+
53
+ const visibleArea = overlapRect.width * overlapRect.height;
54
+ const totalArea = elementHeight * elementWidth;
55
+ // return visibleArea > 30 * 30 || visibleArea / totalArea >= 2 / 3;
56
+ return visibleArea / totalArea >= visibleAreaRatio;
57
+ }
58
+
59
+ export function getPseudoElementContent(
60
+ element: globalThis.Node,
61
+ currentWindow: typeof globalThis.window,
62
+ ): {
63
+ before: string;
64
+ after: string;
65
+ } {
66
+ if (!(element instanceof currentWindow.HTMLElement)) {
67
+ return { before: '', after: '' };
68
+ }
69
+ const beforeContent = currentWindow
70
+ .getComputedStyle(element, '::before')
71
+ .getPropertyValue('content');
72
+ const afterContent = currentWindow
73
+ .getComputedStyle(element, '::after')
74
+ .getPropertyValue('content');
75
+ return {
76
+ before: beforeContent === 'none' ? '' : beforeContent.replace(/"/g, ''),
77
+ after: afterContent === 'none' ? '' : afterContent.replace(/"/g, ''),
78
+ };
79
+ }
80
+
81
+ export function hasOverflowY(
82
+ element: globalThis.HTMLElement,
83
+ currentWindow: typeof globalThis.window,
84
+ ): boolean {
85
+ const style = currentWindow.getComputedStyle(element);
86
+ return (
87
+ style.overflowY === 'scroll' ||
88
+ style.overflowY === 'auto' ||
89
+ style.overflowY === 'hidden'
90
+ );
91
+ }
92
+
93
+ export interface ExtractedRect {
94
+ width: number;
95
+ height: number;
96
+ left: number;
97
+ top: number;
98
+ right: number;
99
+ bottom: number;
100
+ x: number;
101
+ y: number;
102
+ zoom: number;
103
+ }
104
+
105
+ // tell if two rects are overlapped, return the overlapped rect. If not, return null
106
+ export function overlappedRect(
107
+ rect1: ExtractedRect,
108
+ rect2: ExtractedRect,
109
+ ): ExtractedRect | null {
110
+ const left = Math.max(rect1.left, rect2.left);
111
+ const top = Math.max(rect1.top, rect2.top);
112
+ const right = Math.min(rect1.right, rect2.right);
113
+ const bottom = Math.min(rect1.bottom, rect2.bottom);
114
+ if (left < right && top < bottom) {
115
+ return {
116
+ left,
117
+ top,
118
+ right,
119
+ bottom,
120
+ width: right - left,
121
+ height: bottom - top,
122
+ x: left,
123
+ y: top,
124
+ zoom: 1,
125
+ };
126
+ }
127
+ return null;
128
+ }
129
+
130
+ export function getRect(
131
+ el: globalThis.HTMLElement | globalThis.Node,
132
+ baseZoom: number, // base zoom
133
+ currentWindow: typeof globalThis.window,
134
+ ): ExtractedRect {
135
+ let originalRect: DOMRect;
136
+ let newZoom = 1;
137
+ if (!(el instanceof currentWindow.HTMLElement)) {
138
+ const range = currentWindow.document.createRange();
139
+ range.selectNodeContents(el);
140
+ originalRect = range.getBoundingClientRect();
141
+ } else {
142
+ originalRect = el.getBoundingClientRect();
143
+ // from Chrome v128, the API would return differently https://docs.google.com/document/d/1AcnDShjT-kEuRaMchZPm5uaIgNZ4OiYtM4JI9qiV8Po/edit
144
+ if (!('currentCSSZoom' in el)) {
145
+ newZoom =
146
+ Number.parseFloat((currentWindow.getComputedStyle(el) as any).zoom) ||
147
+ 1;
148
+ }
149
+ }
150
+
151
+ const zoom = newZoom * baseZoom;
152
+
153
+ return {
154
+ width: originalRect.width * zoom,
155
+ height: originalRect.height * zoom,
156
+ left: originalRect.left * zoom,
157
+ top: originalRect.top * zoom,
158
+ right: originalRect.right * zoom,
159
+ bottom: originalRect.bottom * zoom,
160
+ x: originalRect.x * zoom,
161
+ y: originalRect.y * zoom,
162
+ zoom,
163
+ };
164
+ }
165
+
166
+ const isElementCovered = (
167
+ el: globalThis.HTMLElement | globalThis.Node,
168
+ rect: ExtractedRect,
169
+ currentWindow: typeof globalThis.window,
170
+ ) => {
171
+ // Gets the center coordinates of the element
172
+ const x = rect.left + rect.width / 2;
173
+ const y = rect.top + rect.height / 2;
174
+
175
+ // Gets the element above that point
176
+ const topElement = currentWindow.document.elementFromPoint(x, y);
177
+ if (!topElement) {
178
+ return false; // usually because it's outside the screen
179
+ }
180
+
181
+ if (topElement === el) {
182
+ return false;
183
+ }
184
+ if (el?.contains(topElement)) {
185
+ return false;
186
+ }
187
+
188
+ if ((topElement as HTMLElement)?.contains(el)) {
189
+ return false;
190
+ }
191
+
192
+ const rectOfTopElement = getRect(topElement as HTMLElement, 1, currentWindow);
193
+
194
+ // get the remaining area of the base element
195
+ const overlapRect = overlappedRect(rect, rectOfTopElement);
196
+ if (!overlapRect) {
197
+ return false;
198
+ }
199
+
200
+ // Todo: we should modify the 'box-select' as well to make the indicator more accurate
201
+ // const remainingArea =
202
+ // rect.width * rect.height - overlapRect.width * overlapRect.height;
203
+
204
+ // if (remainingArea > 100) {
205
+ // return false;
206
+ // }
207
+
208
+ logger(el, 'Element is covered by another element', {
209
+ topElement,
210
+ el,
211
+ rect,
212
+ x,
213
+ y,
214
+ });
215
+ return true;
216
+ // Determines if the returned element is the target element itself
217
+ // return el.contains(topElement) || (topElement as HTMLElement).contains(el);
218
+ // return topElement !== el && !el.contains(topElement);
219
+ };
220
+
221
+ export function elementRect(
222
+ el: globalThis.HTMLElement | globalThis.Node | null,
223
+ currentWindow: typeof globalThis.window,
224
+ currentDocument: typeof globalThis.document,
225
+ baseZoom = 1,
226
+ ):
227
+ | {
228
+ left: number;
229
+ top: number;
230
+ width: number;
231
+ height: number;
232
+ zoom: number;
233
+ isVisible: boolean;
234
+ }
235
+ | false {
236
+ if (!el) {
237
+ logger(el, 'Element is not in the DOM hierarchy');
238
+ return false;
239
+ }
240
+
241
+ if (
242
+ !(el instanceof currentWindow.HTMLElement) &&
243
+ el.nodeType !== Node.TEXT_NODE &&
244
+ el.nodeName.toLowerCase() !== 'svg'
245
+ ) {
246
+ logger(el, 'Element is not in the DOM hierarchy');
247
+ return false;
248
+ }
249
+
250
+ if (el instanceof currentWindow.HTMLElement) {
251
+ const style = currentWindow.getComputedStyle(el);
252
+ if (
253
+ style.display === 'none' ||
254
+ style.visibility === 'hidden' ||
255
+ (style.opacity === '0' && el.tagName !== 'INPUT')
256
+ ) {
257
+ logger(el, 'Element is hidden');
258
+ return false;
259
+ }
260
+ }
261
+
262
+ const rect = getRect(el, baseZoom, currentWindow);
263
+
264
+ if (rect.width === 0 && rect.height === 0) {
265
+ logger(el, 'Element has no size');
266
+ return false;
267
+ }
268
+
269
+ // check if the element is covered by another element
270
+ // if the element is zoomed, the coverage check should be done with the original zoom
271
+ if (baseZoom === 1 && isElementCovered(el, rect, currentWindow)) {
272
+ return false;
273
+ }
274
+
275
+ const isVisible = isElementPartiallyInViewport(
276
+ rect,
277
+ currentWindow,
278
+ currentDocument,
279
+ );
280
+
281
+ // check if the element is hidden by an ancestor
282
+ let parent: HTMLElement | Node | null = el;
283
+ const parentUntilNonStatic = (currentNode: HTMLElement | Node | null) => {
284
+ // find a parent element that is not static
285
+ let parent = currentNode?.parentElement;
286
+ while (parent) {
287
+ const style = currentWindow.getComputedStyle(parent);
288
+ if (style.position !== 'static') {
289
+ return parent;
290
+ }
291
+ parent = parent.parentElement;
292
+ }
293
+ return null;
294
+ };
295
+
296
+ while (parent && parent !== currentDocument.body) {
297
+ if (!(parent instanceof currentWindow.HTMLElement)) {
298
+ parent = parent.parentElement;
299
+ continue;
300
+ }
301
+ const parentStyle = currentWindow.getComputedStyle(parent);
302
+ if (parentStyle.overflow === 'hidden') {
303
+ const parentRect = getRect(parent, 1, currentWindow);
304
+ const tolerance = 10;
305
+
306
+ if (
307
+ rect.right < parentRect.left - tolerance ||
308
+ rect.left > parentRect.right + tolerance ||
309
+ rect.bottom < parentRect.top - tolerance ||
310
+ rect.top > parentRect.bottom + tolerance
311
+ ) {
312
+ logger(el, 'element is partially or totally hidden by an ancestor', {
313
+ rect,
314
+ parentRect,
315
+ });
316
+ return false;
317
+ }
318
+ }
319
+ // if the parent is a fixed element, stop the search
320
+ if (parentStyle.position === 'fixed' || parentStyle.position === 'sticky') {
321
+ break;
322
+ }
323
+
324
+ if (parentStyle.position === 'absolute') {
325
+ parent = parentUntilNonStatic(parent);
326
+ } else {
327
+ parent = parent.parentElement;
328
+ }
329
+ }
330
+
331
+ return {
332
+ left: Math.round(rect.left),
333
+ top: Math.round(rect.top),
334
+ width: Math.round(rect.width),
335
+ height: Math.round(rect.height),
336
+ zoom: rect.zoom,
337
+ isVisible,
338
+ };
339
+ }
340
+
341
+ export function validTextNodeContent(node: globalThis.Node): string | false {
342
+ if (!node) {
343
+ return false;
344
+ }
345
+ if (
346
+ node.nodeType !== Node.ELEMENT_NODE &&
347
+ node.nodeType !== Node.TEXT_NODE &&
348
+ (node as any).nodeName !== '#text'
349
+ ) {
350
+ return false;
351
+ }
352
+
353
+ const content = node.textContent || (node as HTMLElement).innerText;
354
+ if (content && !/^\s*$/.test(content)) {
355
+ return content.trim();
356
+ }
357
+
358
+ return false;
359
+ }
360
+
361
+ export function getNodeAttributes(
362
+ node: globalThis.HTMLElement | globalThis.Node,
363
+ currentWindow: typeof globalThis.window,
364
+ ): Record<string, string> {
365
+ if (
366
+ !node ||
367
+ !(node instanceof currentWindow.HTMLElement) ||
368
+ !node.attributes
369
+ ) {
370
+ return {};
371
+ }
372
+
373
+ const attributesList = Array.from(node.attributes).map((attr) => {
374
+ if (attr.name === 'class') {
375
+ return [attr.name, `.${attr.value.split(' ').join('.')}`];
376
+ }
377
+ if (!attr.value) {
378
+ return [];
379
+ }
380
+
381
+ let value = attr.value;
382
+ if (value.startsWith('data:image')) {
383
+ value = 'image';
384
+ }
385
+
386
+ if (value.length > MAX_VALUE_LENGTH) {
387
+ value = `${value.slice(0, MAX_VALUE_LENGTH)}...`;
388
+ }
389
+ return [attr.name, value];
390
+ });
391
+
392
+ return Object.fromEntries(attributesList);
393
+ }
394
+
395
+ export function rpasceneGenerateHash(
396
+ node: globalThis.Node | null,
397
+ content: string,
398
+ rect: Rect,
399
+ ): string {
400
+ const slicedHash = generateHashId(rect, content);
401
+
402
+ if (node) {
403
+ if (!(window as any).rpasceneNodeHashCacheList) {
404
+ setNodeHashCacheListOnWindow();
405
+ }
406
+
407
+ setNodeToCacheList(node, slicedHash);
408
+ }
409
+
410
+ // Returns the first 10 characters as a short hash
411
+ return slicedHash;
412
+ }
413
+
414
+ export function setNodeHashCacheListOnWindow() {
415
+ if (typeof window !== 'undefined') {
416
+ (window as any).rpasceneNodeHashCacheList = [];
417
+ }
418
+ }
419
+
420
+ export function setNodeToCacheList(node: globalThis.Node, id: string) {
421
+ if (typeof window !== 'undefined') {
422
+ if (getNodeFromCacheList(id)) {
423
+ return;
424
+ }
425
+ (window as any).rpasceneNodeHashCacheList?.push({ node, id });
426
+ }
427
+ }
428
+
429
+ export function getNodeFromCacheList(id: string) {
430
+ if (typeof window !== 'undefined') {
431
+ return (window as any).rpasceneNodeHashCacheList?.find(
432
+ (item: { node: Node; id: string }) => item.id === id,
433
+ )?.node;
434
+ }
435
+ return null;
436
+ }
437
+
438
+ export function generateId(numberId: number) {
439
+ // const letters = 'ABCDEFGHIJKLMNPRSTUVXYZ';
440
+ // const numbers = '0123456789';
441
+ // const randomLetter = letters.charAt(Math.floor(Math.random() * letters.length)).toUpperCase();
442
+ // const randomNumber = numbers.charAt(Math.floor(Math.random() * numbers.length));
443
+ // return randomLetter + numberId;
444
+ return `${numberId}`;
445
+ }
446
+
447
+ export function setGenerateHashOnWindow() {
448
+ if (typeof window !== 'undefined') {
449
+ (window as any).rpasceneGenerateHash = rpasceneGenerateHash;
450
+ }
451
+ }
452
+
453
+ export function setRpasceneVisibleRectOnWindow() {
454
+ if (typeof window !== 'undefined') {
455
+ (window as any).rpasceneVisibleRect = elementRect;
456
+ }
457
+ }
458
+
459
+ export function setExtractTextWithPositionOnWindow() {
460
+ if (typeof window !== 'undefined') {
461
+ (window as any).extractTextWithPosition = extractTextWithPosition;
462
+ }
463
+ }
464
+
465
+ export function getTopDocument(): globalThis.HTMLElement {
466
+ const container: globalThis.HTMLElement = document.body || document;
467
+ return container;
468
+ }