sidakram-bippy 0.2.24

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 };