sidakram-bippy 0.2.24

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.
@@ -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 };