@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.
- package/README.md +9 -0
- package/dist/es/baseDB.mjs +109 -0
- package/dist/es/build/copy-static.mjs +29 -0
- package/dist/es/common.mjs +37 -0
- package/dist/es/constants/example-code.mjs +202 -0
- package/dist/es/constants/index.mjs +74 -0
- package/dist/es/env/basic.mjs +6 -0
- package/dist/es/env/constants.mjs +97 -0
- package/dist/es/env/decide-model-config.mjs +172 -0
- package/dist/es/env/global-config-manager.mjs +82 -0
- package/dist/es/env/helper.mjs +45 -0
- package/dist/es/env/index.mjs +5 -0
- package/dist/es/env/init-debug.mjs +18 -0
- package/dist/es/env/model-config-manager.mjs +99 -0
- package/dist/es/env/parse.mjs +69 -0
- package/dist/es/env/types.mjs +265 -0
- package/dist/es/env/utils.mjs +18 -0
- package/dist/es/extractor/constants.mjs +2 -0
- package/dist/es/extractor/cs_postmessage.mjs +61 -0
- package/dist/es/extractor/customLocator.mjs +646 -0
- package/dist/es/extractor/debug.mjs +6 -0
- package/dist/es/extractor/dom-util.mjs +92 -0
- package/dist/es/extractor/index.mjs +7 -0
- package/dist/es/extractor/locator.mjs +95 -0
- package/dist/es/extractor/tree.mjs +81 -0
- package/dist/es/extractor/util.mjs +244 -0
- package/dist/es/extractor/web-extractor.mjs +361 -0
- package/dist/es/img/box-select.mjs +184 -0
- package/dist/es/img/draw-box.mjs +42 -0
- package/dist/es/img/get-jimp.mjs +10 -0
- package/dist/es/img/get-photon.mjs +19 -0
- package/dist/es/img/get-sharp.mjs +11 -0
- package/dist/es/img/index.mjs +5 -0
- package/dist/es/img/info.mjs +32 -0
- package/dist/es/img/transform.mjs +192 -0
- package/dist/es/index.mjs +3 -0
- package/dist/es/logger.mjs +61 -0
- package/dist/es/node/fs.mjs +44 -0
- package/dist/es/node/index.mjs +1 -0
- package/dist/es/polyfills/async-hooks.mjs +2 -0
- package/dist/es/polyfills/index.mjs +1 -0
- package/dist/es/types/index.mjs +3 -0
- package/dist/es/us-keyboard-layout.mjs +1414 -0
- package/dist/es/us-keyboard-layout.mjs.LICENSE.txt +5 -0
- package/dist/es/utils.mjs +66 -0
- package/dist/lib/baseDB.js +149 -0
- package/dist/lib/build/copy-static.js +77 -0
- package/dist/lib/common.js +93 -0
- package/dist/lib/constants/example-code.js +239 -0
- package/dist/lib/constants/index.js +153 -0
- package/dist/lib/env/basic.js +40 -0
- package/dist/lib/env/constants.js +143 -0
- package/dist/lib/env/decide-model-config.js +212 -0
- package/dist/lib/env/global-config-manager.js +116 -0
- package/dist/lib/env/helper.js +85 -0
- package/dist/lib/env/index.js +94 -0
- package/dist/lib/env/init-debug.js +52 -0
- package/dist/lib/env/model-config-manager.js +133 -0
- package/dist/lib/env/parse.js +106 -0
- package/dist/lib/env/types.js +650 -0
- package/dist/lib/env/utils.js +61 -0
- package/dist/lib/extractor/constants.js +42 -0
- package/dist/lib/extractor/cs_postmessage.js +98 -0
- package/dist/lib/extractor/customLocator.js +698 -0
- package/dist/lib/extractor/debug.js +12 -0
- package/dist/lib/extractor/dom-util.js +150 -0
- package/dist/lib/extractor/index.js +153 -0
- package/dist/lib/extractor/locator.js +141 -0
- package/dist/lib/extractor/tree.js +127 -0
- package/dist/lib/extractor/util.js +335 -0
- package/dist/lib/extractor/web-extractor.js +407 -0
- package/dist/lib/img/box-select.js +232 -0
- package/dist/lib/img/draw-box.js +89 -0
- package/dist/lib/img/get-jimp.js +72 -0
- package/dist/lib/img/get-photon.js +76 -0
- package/dist/lib/img/get-sharp.js +63 -0
- package/dist/lib/img/index.js +102 -0
- package/dist/lib/img/info.js +86 -0
- package/dist/lib/img/transform.js +279 -0
- package/dist/lib/index.js +43 -0
- package/dist/lib/logger.js +114 -0
- package/dist/lib/node/fs.js +97 -0
- package/dist/lib/node/index.js +60 -0
- package/dist/lib/polyfills/async-hooks.js +36 -0
- package/dist/lib/polyfills/index.js +60 -0
- package/dist/lib/types/index.js +37 -0
- package/dist/lib/us-keyboard-layout.js +1457 -0
- package/dist/lib/us-keyboard-layout.js.LICENSE.txt +5 -0
- package/dist/lib/utils.js +136 -0
- package/dist/types/baseDB.d.ts +25 -0
- package/dist/types/build/copy-static.d.ts +31 -0
- package/dist/types/common.d.ts +12 -0
- package/dist/types/constants/example-code.d.ts +2 -0
- package/dist/types/constants/index.d.ts +23 -0
- package/dist/types/env/basic.d.ts +6 -0
- package/dist/types/env/constants.d.ts +40 -0
- package/dist/types/env/decide-model-config.d.ts +14 -0
- package/dist/types/env/global-config-manager.d.ts +32 -0
- package/dist/types/env/helper.d.ts +6 -0
- package/dist/types/env/index.d.ts +4 -0
- package/dist/types/env/init-debug.d.ts +1 -0
- package/dist/types/env/model-config-manager.d.ts +24 -0
- package/dist/types/env/parse.d.ts +12 -0
- package/dist/types/env/types.d.ts +295 -0
- package/dist/types/env/utils.d.ts +7 -0
- package/dist/types/extractor/constants.d.ts +1 -0
- package/dist/types/extractor/cs_postmessage.d.ts +2 -0
- package/dist/types/extractor/customLocator.d.ts +69 -0
- package/dist/types/extractor/debug.d.ts +1 -0
- package/dist/types/extractor/dom-util.d.ts +26 -0
- package/dist/types/extractor/index.d.ts +36 -0
- package/dist/types/extractor/locator.d.ts +7 -0
- package/dist/types/extractor/tree.d.ts +9 -0
- package/dist/types/extractor/util.d.ts +43 -0
- package/dist/types/extractor/web-extractor.d.ts +19 -0
- package/dist/types/img/box-select.d.ts +25 -0
- package/dist/types/img/draw-box.d.ts +15 -0
- package/dist/types/img/get-jimp.d.ts +2 -0
- package/dist/types/img/get-photon.d.ts +8 -0
- package/dist/types/img/get-sharp.d.ts +3 -0
- package/dist/types/img/index.d.ts +4 -0
- package/dist/types/img/info.d.ts +29 -0
- package/dist/types/img/transform.d.ts +88 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/logger.d.ts +4 -0
- package/dist/types/node/fs.d.ts +15 -0
- package/dist/types/node/index.d.ts +1 -0
- package/dist/types/polyfills/async-hooks.d.ts +6 -0
- package/dist/types/polyfills/index.d.ts +4 -0
- package/dist/types/types/index.d.ts +37 -0
- package/dist/types/us-keyboard-layout.d.ts +32 -0
- package/dist/types/utils.d.ts +22 -0
- package/package.json +102 -0
- package/src/baseDB.ts +158 -0
- package/src/build/copy-static.ts +62 -0
- package/src/common.ts +67 -0
- package/src/constants/example-code.ts +202 -0
- package/src/constants/index.ts +81 -0
- package/src/env/basic.ts +12 -0
- package/src/env/constants.ts +291 -0
- package/src/env/decide-model-config.ts +319 -0
- package/src/env/global-config-manager.ts +174 -0
- package/src/env/helper.ts +80 -0
- package/src/env/index.ts +4 -0
- package/src/env/init-debug.ts +29 -0
- package/src/env/model-config-manager.ts +145 -0
- package/src/env/parse.ts +131 -0
- package/src/env/types.ts +573 -0
- package/src/env/utils.ts +39 -0
- package/src/extractor/constants.ts +5 -0
- package/src/extractor/cs_postmessage.ts +101 -0
- package/src/extractor/customLocator.ts +1138 -0
- package/src/extractor/debug.ts +10 -0
- package/src/extractor/dom-util.ts +141 -0
- package/src/extractor/index.ts +54 -0
- package/src/extractor/locator.ts +179 -0
- package/src/extractor/tree.ts +179 -0
- package/src/extractor/util.ts +468 -0
- package/src/extractor/web-extractor.ts +559 -0
- package/src/img/box-select.ts +346 -0
- package/src/img/draw-box.ts +60 -0
- package/src/img/get-jimp.ts +12 -0
- package/src/img/get-photon.ts +48 -0
- package/src/img/get-sharp.ts +18 -0
- package/src/img/index.ts +24 -0
- package/src/img/info.ts +79 -0
- package/src/img/jimp.d.ts +4 -0
- package/src/img/transform.ts +396 -0
- package/src/index.ts +6 -0
- package/src/logger.ts +93 -0
- package/src/node/fs.ts +84 -0
- package/src/node/index.ts +1 -0
- package/src/polyfills/async-hooks.ts +6 -0
- package/src/polyfills/index.ts +4 -0
- package/src/types/index.ts +53 -0
- package/src/us-keyboard-layout.ts +723 -0
- 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
|
+
}
|