sidakram-bippy 0.2.24
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +7 -0
- package/README.md +617 -0
- package/dist/chunk-347RWTP3.js +736 -0
- package/dist/chunk-475IQUDX.cjs +878 -0
- package/dist/chunk-7ROEST76.js +807 -0
- package/dist/chunk-GVWERSAB.cjs +803 -0
- package/dist/chunk-HQYIPSLJ.cjs +20 -0
- package/dist/chunk-JOS5RHYU.cjs +20 -0
- package/dist/chunk-N23WFCSF.js +18 -0
- package/dist/chunk-XX7FLNAQ.js +18 -0
- package/dist/core.cjs +270 -0
- package/dist/core.d.cts +275 -0
- package/dist/core.d.ts +275 -0
- package/dist/core.js +1 -0
- package/dist/experiments/inspect.cjs +1732 -0
- package/dist/experiments/inspect.d.cts +11 -0
- package/dist/experiments/inspect.d.ts +11 -0
- package/dist/experiments/inspect.js +1721 -0
- package/dist/experiments/shrinkwrap.cjs +374 -0
- package/dist/experiments/shrinkwrap.d.cts +10 -0
- package/dist/experiments/shrinkwrap.d.ts +10 -0
- package/dist/experiments/shrinkwrap.js +369 -0
- package/dist/index.cjs +271 -0
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.global.js +9 -0
- package/dist/index.js +2 -0
- package/dist/shrinkwrap.global.js +9 -0
- package/package.json +124 -0
@@ -0,0 +1,374 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
require('../chunk-JOS5RHYU.cjs');
|
4
|
+
var chunk475IQUDX_cjs = require('../chunk-475IQUDX.cjs');
|
5
|
+
|
6
|
+
/**
|
7
|
+
* @license bippy
|
8
|
+
*
|
9
|
+
* Copyright (c) Aiden Bai, Million Software, Inc.
|
10
|
+
*
|
11
|
+
* This source code is licensed under the MIT license found in the
|
12
|
+
* LICENSE file in the root directory of this source tree.
|
13
|
+
*/
|
14
|
+
|
15
|
+
// src/experiments/shrinkwrap.ts
|
16
|
+
var getDpr = () => {
|
17
|
+
return Math.min(window.devicePixelRatio || 1, 2);
|
18
|
+
};
|
19
|
+
var CANVAS_HTML_STR = `<canvas style="position:fixed;top:0;left:0;pointer-events:none;z-index:2147483646" aria-hidden="true"></canvas>`;
|
20
|
+
var COLORS = [
|
21
|
+
[255, 0, 0],
|
22
|
+
[0, 255, 0],
|
23
|
+
[0, 0, 255],
|
24
|
+
[255, 165, 0],
|
25
|
+
[128, 0, 128],
|
26
|
+
[0, 128, 128],
|
27
|
+
[255, 105, 180],
|
28
|
+
[75, 0, 130],
|
29
|
+
[255, 69, 0],
|
30
|
+
[46, 139, 87],
|
31
|
+
[220, 20, 60],
|
32
|
+
[70, 130, 180]
|
33
|
+
];
|
34
|
+
var interactiveElements = [
|
35
|
+
"a",
|
36
|
+
"button",
|
37
|
+
"details",
|
38
|
+
"embed",
|
39
|
+
"input",
|
40
|
+
"label",
|
41
|
+
"menu",
|
42
|
+
"menuitem",
|
43
|
+
"object",
|
44
|
+
"select",
|
45
|
+
"textarea",
|
46
|
+
"summary"
|
47
|
+
];
|
48
|
+
var interactiveRoles = [
|
49
|
+
"button",
|
50
|
+
"menu",
|
51
|
+
"menuitem",
|
52
|
+
"link",
|
53
|
+
"checkbox",
|
54
|
+
"radio",
|
55
|
+
"slider",
|
56
|
+
"tab",
|
57
|
+
"tabpanel",
|
58
|
+
"textbox",
|
59
|
+
"combobox",
|
60
|
+
"grid",
|
61
|
+
"listbox",
|
62
|
+
"option",
|
63
|
+
"progressbar",
|
64
|
+
"scrollbar",
|
65
|
+
"searchbox",
|
66
|
+
"switch",
|
67
|
+
"tree",
|
68
|
+
"treeitem",
|
69
|
+
"spinbutton",
|
70
|
+
"tooltip",
|
71
|
+
"a-button-inner",
|
72
|
+
"a-dropdown-button",
|
73
|
+
"click",
|
74
|
+
"menuitemcheckbox",
|
75
|
+
"menuitemradio",
|
76
|
+
"a-button-text",
|
77
|
+
"button-text",
|
78
|
+
"button-icon",
|
79
|
+
"button-icon-only",
|
80
|
+
"button-text-icon-only",
|
81
|
+
"dropdown",
|
82
|
+
"combobox"
|
83
|
+
];
|
84
|
+
var interactiveEvents = [
|
85
|
+
"click",
|
86
|
+
"mousedown",
|
87
|
+
"mouseup",
|
88
|
+
"touchstart",
|
89
|
+
"touchend",
|
90
|
+
"keydown",
|
91
|
+
"keyup",
|
92
|
+
"focus",
|
93
|
+
"blur"
|
94
|
+
];
|
95
|
+
var isScrollable = (element) => {
|
96
|
+
const isScrollable2 = element.hasAttribute("aria-scrollable") || element.hasAttribute("scrollable") || "style" in element && (element.style.overflow === "auto" || element.style.overflow === "scroll" || element.style.overflowY === "auto" || element.style.overflowY === "scroll" || element.style.overflowX === "auto" || element.style.overflowX === "scroll");
|
97
|
+
return isScrollable2;
|
98
|
+
};
|
99
|
+
var isInteractive = (element) => {
|
100
|
+
const fiber = chunk475IQUDX_cjs.getFiberFromHostInstance(element);
|
101
|
+
if ((fiber == null ? void 0 : fiber.stateNode) instanceof Element) {
|
102
|
+
for (const propName of Object.keys(fiber.memoizedProps || {})) {
|
103
|
+
if (!propName.startsWith("on")) continue;
|
104
|
+
const event = propName.slice(2).toLowerCase().replace(/capture$/, "");
|
105
|
+
if (!interactiveEvents.includes(event)) continue;
|
106
|
+
if (fiber.memoizedProps[propName]) {
|
107
|
+
return true;
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
for (const event of interactiveEvents) {
|
112
|
+
const dotOnHandler = element[`on${event}`];
|
113
|
+
const explicitOnHandler = element.hasAttribute(`on${event}`);
|
114
|
+
const ngClick = element.hasAttribute(`ng-${event}`);
|
115
|
+
const atClick = element.hasAttribute(`@${event}`);
|
116
|
+
const vOnClick = element.hasAttribute(`v-on:${event}`);
|
117
|
+
if (dotOnHandler || explicitOnHandler || ngClick || atClick || vOnClick) {
|
118
|
+
return true;
|
119
|
+
}
|
120
|
+
}
|
121
|
+
const tagName = element.tagName.toLowerCase();
|
122
|
+
const role = element.getAttribute("role");
|
123
|
+
const ariaRole = element.getAttribute("aria-role");
|
124
|
+
const tabIndex = element.getAttribute("tabindex");
|
125
|
+
const hasInteractiveRole = interactiveElements.includes(tagName) || role && interactiveRoles.includes(role) || ariaRole && interactiveRoles.includes(ariaRole) || tabIndex !== null && tabIndex !== "-1";
|
126
|
+
const hasAriaProps = element.hasAttribute("aria-expanded") || element.hasAttribute("aria-pressed") || element.hasAttribute("aria-selected") || element.hasAttribute("aria-checked");
|
127
|
+
const isFormRelated = "form" in element && element.form !== void 0 || element.hasAttribute("contenteditable");
|
128
|
+
const isDraggable = "draggable" in element && element.draggable || element.getAttribute("draggable") === "true";
|
129
|
+
return hasInteractiveRole || isFormRelated || isDraggable || hasAriaProps;
|
130
|
+
};
|
131
|
+
var isElementVisible = (element) => {
|
132
|
+
const style = window.getComputedStyle(element);
|
133
|
+
return element.offsetWidth > 0 && element.offsetHeight > 0 && style.visibility !== "hidden" && style.display !== "none";
|
134
|
+
};
|
135
|
+
var isTopElement = (element) => {
|
136
|
+
const doc = element.ownerDocument;
|
137
|
+
if (doc !== window.document) {
|
138
|
+
return true;
|
139
|
+
}
|
140
|
+
const shadowRoot = element.getRootNode();
|
141
|
+
if (shadowRoot instanceof ShadowRoot) {
|
142
|
+
const rect2 = element.getBoundingClientRect();
|
143
|
+
const point = {
|
144
|
+
x: rect2.left + rect2.width / 2,
|
145
|
+
y: rect2.top + rect2.height / 2
|
146
|
+
};
|
147
|
+
try {
|
148
|
+
const topEl = shadowRoot.elementFromPoint(point.x, point.y);
|
149
|
+
if (!topEl) return false;
|
150
|
+
let current = topEl;
|
151
|
+
while (current && current !== shadowRoot) {
|
152
|
+
if (current === element) return true;
|
153
|
+
current = current.parentElement;
|
154
|
+
}
|
155
|
+
return false;
|
156
|
+
} catch (e) {
|
157
|
+
return true;
|
158
|
+
}
|
159
|
+
}
|
160
|
+
const rect = element.getBoundingClientRect();
|
161
|
+
const scrollX = window.scrollX;
|
162
|
+
const scrollY = window.scrollY;
|
163
|
+
const viewportTop = scrollY;
|
164
|
+
const viewportLeft = scrollX;
|
165
|
+
const viewportBottom = window.innerHeight + scrollY;
|
166
|
+
const viewportRight = window.innerWidth + scrollX;
|
167
|
+
const absTop = rect.top + scrollY;
|
168
|
+
const absLeft = rect.left + scrollX;
|
169
|
+
const absBottom = rect.bottom + scrollY;
|
170
|
+
const absRight = rect.right + scrollX;
|
171
|
+
if (absBottom < viewportTop || absTop > viewportBottom || absRight < viewportLeft || absLeft > viewportRight) {
|
172
|
+
return false;
|
173
|
+
}
|
174
|
+
try {
|
175
|
+
const centerX = rect.left + rect.width / 2;
|
176
|
+
const centerY = rect.top + rect.height / 2;
|
177
|
+
const point = {
|
178
|
+
x: centerX,
|
179
|
+
y: centerY
|
180
|
+
};
|
181
|
+
if (point.x < 0 || point.x >= window.innerWidth || point.y < 0 || point.y >= window.innerHeight) {
|
182
|
+
return true;
|
183
|
+
}
|
184
|
+
const topEl = document.elementFromPoint(point.x, point.y);
|
185
|
+
if (!topEl) return false;
|
186
|
+
let current = topEl;
|
187
|
+
while (current && current !== document.documentElement) {
|
188
|
+
if (current === element) return true;
|
189
|
+
current = current.parentElement;
|
190
|
+
}
|
191
|
+
return false;
|
192
|
+
} catch (e) {
|
193
|
+
return true;
|
194
|
+
}
|
195
|
+
};
|
196
|
+
var createShrinkwrap = () => {
|
197
|
+
const draw = (elements) => chunk475IQUDX_cjs.__async(void 0, null, function* () {
|
198
|
+
if (!ctx) return;
|
199
|
+
const rectMap = yield getRectMap(elements);
|
200
|
+
clear();
|
201
|
+
const drawnLabelBounds = [];
|
202
|
+
let visibleCount = 0;
|
203
|
+
const visibleIndices = /* @__PURE__ */ new Map();
|
204
|
+
const viewportWidth = window.innerWidth;
|
205
|
+
const viewportHeight = window.innerHeight;
|
206
|
+
const COVERAGE_THRESHOLD = 0.97;
|
207
|
+
for (let i = 0, len = elements.length; i < len; i++) {
|
208
|
+
const element = elements[i];
|
209
|
+
const rect = rectMap.get(element);
|
210
|
+
if (!rect) continue;
|
211
|
+
const { width: width2, height: height2 } = rect;
|
212
|
+
const x = rect.x;
|
213
|
+
const y = rect.y;
|
214
|
+
if (width2 / viewportWidth > COVERAGE_THRESHOLD && height2 / viewportHeight > COVERAGE_THRESHOLD)
|
215
|
+
continue;
|
216
|
+
const text = `${visibleCount + 1}`;
|
217
|
+
const textSize = 16;
|
218
|
+
ctx.textRendering = "optimizeSpeed";
|
219
|
+
ctx.font = `${textSize}px monospace`;
|
220
|
+
const { width: textWidth } = ctx.measureText(text);
|
221
|
+
let labelY = y - textSize - 4;
|
222
|
+
if (labelY < 0) {
|
223
|
+
labelY = 0;
|
224
|
+
}
|
225
|
+
const labelBounds = {
|
226
|
+
x,
|
227
|
+
y: labelY,
|
228
|
+
width: textWidth + 4,
|
229
|
+
height: textSize + 4
|
230
|
+
};
|
231
|
+
const hasCollision = drawnLabelBounds.some(
|
232
|
+
(bound) => labelBounds.x < bound.x + bound.width && labelBounds.x + labelBounds.width > bound.x && labelBounds.y < bound.y + bound.height && labelBounds.y + labelBounds.height > bound.y
|
233
|
+
);
|
234
|
+
if (!hasCollision) {
|
235
|
+
drawnLabelBounds.push(labelBounds);
|
236
|
+
visibleCount++;
|
237
|
+
visibleIndices.set(element, visibleCount);
|
238
|
+
ctx.beginPath();
|
239
|
+
ctx.rect(x, y, width2, height2);
|
240
|
+
const color = COLORS[i % COLORS.length].join(",");
|
241
|
+
ctx.fillStyle = `rgba(${color},0.1)`;
|
242
|
+
ctx.strokeStyle = `rgba(${color})`;
|
243
|
+
ctx.fill();
|
244
|
+
ctx.stroke();
|
245
|
+
ctx.fillStyle = `rgba(${color})`;
|
246
|
+
ctx.fillRect(x, labelY, textWidth + 4, textSize + 4);
|
247
|
+
ctx.fillStyle = "rgba(255,255,255)";
|
248
|
+
ctx.fillText(text, x + 2, labelY + textSize);
|
249
|
+
}
|
250
|
+
}
|
251
|
+
return visibleIndices;
|
252
|
+
});
|
253
|
+
const clear = () => {
|
254
|
+
if (!ctx) return;
|
255
|
+
ctx.clearRect(0, 0, canvas.width / dpr, canvas.height / dpr);
|
256
|
+
};
|
257
|
+
const host = document.createElement("div");
|
258
|
+
host.setAttribute("data-react-scan", "true");
|
259
|
+
const root = host.attachShadow({ mode: "open" });
|
260
|
+
root.innerHTML = CANVAS_HTML_STR;
|
261
|
+
const canvas = root.firstChild;
|
262
|
+
let dpr = Math.min(window.devicePixelRatio || 1, 2);
|
263
|
+
const { innerWidth, innerHeight } = window;
|
264
|
+
canvas.style.width = `${innerWidth}px`;
|
265
|
+
canvas.style.height = `${innerHeight}px`;
|
266
|
+
const width = innerWidth * dpr;
|
267
|
+
const height = innerHeight * dpr;
|
268
|
+
canvas.width = width;
|
269
|
+
canvas.height = height;
|
270
|
+
const ctx = canvas.getContext("2d", { alpha: true });
|
271
|
+
if (ctx) {
|
272
|
+
ctx.scale(dpr, dpr);
|
273
|
+
}
|
274
|
+
root.appendChild(canvas);
|
275
|
+
document.documentElement.appendChild(host);
|
276
|
+
let isResizeScheduled = false;
|
277
|
+
const resizeHandler = () => {
|
278
|
+
if (!isResizeScheduled) {
|
279
|
+
isResizeScheduled = true;
|
280
|
+
setTimeout(() => {
|
281
|
+
const width2 = window.innerWidth;
|
282
|
+
const height2 = window.innerHeight;
|
283
|
+
dpr = getDpr();
|
284
|
+
canvas.style.width = `${width2}px`;
|
285
|
+
canvas.style.height = `${height2}px`;
|
286
|
+
canvas.width = width2 * dpr;
|
287
|
+
canvas.height = height2 * dpr;
|
288
|
+
if (ctx) {
|
289
|
+
ctx.resetTransform();
|
290
|
+
ctx.scale(dpr, dpr);
|
291
|
+
}
|
292
|
+
shrinkwrap.trackInteractive();
|
293
|
+
isResizeScheduled = false;
|
294
|
+
});
|
295
|
+
}
|
296
|
+
};
|
297
|
+
let isScrollScheduled = false;
|
298
|
+
const scrollHandler = () => {
|
299
|
+
if (isScrollScheduled) return;
|
300
|
+
isScrollScheduled = true;
|
301
|
+
setTimeout(() => {
|
302
|
+
requestAnimationFrame(() => {
|
303
|
+
shrinkwrap.trackInteractive();
|
304
|
+
});
|
305
|
+
isScrollScheduled = false;
|
306
|
+
}, 8);
|
307
|
+
};
|
308
|
+
const fiberRoots = /* @__PURE__ */ new Set();
|
309
|
+
const shrinkwrap = {
|
310
|
+
draw(elements) {
|
311
|
+
draw(elements).then((visibleIndices) => {
|
312
|
+
if (!visibleIndices) return;
|
313
|
+
const elementMap = {};
|
314
|
+
visibleIndices.forEach((index, element) => {
|
315
|
+
elementMap[index] = element;
|
316
|
+
});
|
317
|
+
window.shrinkwrap = {
|
318
|
+
elementMap
|
319
|
+
};
|
320
|
+
});
|
321
|
+
},
|
322
|
+
trackInteractive() {
|
323
|
+
chunk475IQUDX_cjs.instrument({
|
324
|
+
onCommitFiberRoot(_, root2) {
|
325
|
+
fiberRoots.add(root2);
|
326
|
+
const elements = [];
|
327
|
+
for (const fiberRoot of fiberRoots) {
|
328
|
+
chunk475IQUDX_cjs.traverseFiber(fiberRoot.current, (fiber) => {
|
329
|
+
if (chunk475IQUDX_cjs.isHostFiber(fiber) && isInteractive(fiber.stateNode) && isElementVisible(fiber.stateNode) && isTopElement(fiber.stateNode)) {
|
330
|
+
elements.push(fiber.stateNode);
|
331
|
+
}
|
332
|
+
});
|
333
|
+
}
|
334
|
+
shrinkwrap.draw(elements);
|
335
|
+
}
|
336
|
+
});
|
337
|
+
},
|
338
|
+
cleanup() {
|
339
|
+
fiberRoots.clear();
|
340
|
+
window.removeEventListener("scroll", scrollHandler);
|
341
|
+
window.removeEventListener("resize", resizeHandler);
|
342
|
+
document.documentElement.removeChild(host);
|
343
|
+
}
|
344
|
+
};
|
345
|
+
window.addEventListener("scroll", scrollHandler);
|
346
|
+
window.addEventListener("resize", resizeHandler);
|
347
|
+
return shrinkwrap;
|
348
|
+
};
|
349
|
+
var getRectMap = (elements) => {
|
350
|
+
return new Promise((resolve) => {
|
351
|
+
const rects = /* @__PURE__ */ new Map();
|
352
|
+
const observer = new IntersectionObserver((entries) => {
|
353
|
+
for (let i = 0, len = entries.length; i < len; i++) {
|
354
|
+
const entry = entries[i];
|
355
|
+
const element = entry.target;
|
356
|
+
const rect = entry.boundingClientRect;
|
357
|
+
if (entry.isIntersecting && rect.width && rect.height) {
|
358
|
+
rects.set(element, rect);
|
359
|
+
}
|
360
|
+
}
|
361
|
+
observer.disconnect();
|
362
|
+
resolve(rects);
|
363
|
+
});
|
364
|
+
for (let i = 0, len = elements.length; i < len; i++) {
|
365
|
+
const element = elements[i];
|
366
|
+
observer.observe(element);
|
367
|
+
}
|
368
|
+
});
|
369
|
+
};
|
370
|
+
|
371
|
+
exports.createShrinkwrap = createShrinkwrap;
|
372
|
+
exports.getRectMap = getRectMap;
|
373
|
+
exports.isInteractive = isInteractive;
|
374
|
+
exports.isScrollable = isScrollable;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
declare const isScrollable: (element: Element) => boolean;
|
2
|
+
declare const isInteractive: (element: Element) => {};
|
3
|
+
declare const createShrinkwrap: () => {
|
4
|
+
draw(elements: Element[]): void;
|
5
|
+
trackInteractive(): void;
|
6
|
+
cleanup(): void;
|
7
|
+
};
|
8
|
+
declare const getRectMap: (elements: Element[]) => Promise<Map<Element, DOMRect>>;
|
9
|
+
|
10
|
+
export { createShrinkwrap, getRectMap, isInteractive, isScrollable };
|
@@ -0,0 +1,10 @@
|
|
1
|
+
declare const isScrollable: (element: Element) => boolean;
|
2
|
+
declare const isInteractive: (element: Element) => {};
|
3
|
+
declare const createShrinkwrap: () => {
|
4
|
+
draw(elements: Element[]): void;
|
5
|
+
trackInteractive(): void;
|
6
|
+
cleanup(): void;
|
7
|
+
};
|
8
|
+
declare const getRectMap: (elements: Element[]) => Promise<Map<Element, DOMRect>>;
|
9
|
+
|
10
|
+
export { createShrinkwrap, getRectMap, isInteractive, isScrollable };
|