@jsenv/dom 0.6.0 → 0.7.0
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/dist/jsenv_dom.js +262 -330
- package/package.json +2 -4
- package/index.js +0 -124
- package/src/attr/add_attribute_effect.js +0 -93
- package/src/attr/attributes.js +0 -32
- package/src/color/color_constrast.js +0 -69
- package/src/color/color_parsing.js +0 -319
- package/src/color/color_scheme.js +0 -28
- package/src/color/pick_light_or_dark.js +0 -34
- package/src/color/resolve_css_color.js +0 -60
- package/src/demos/3_columns_resize_demo.html +0 -84
- package/src/demos/3_rows_resize_demo.html +0 -89
- package/src/demos/aside_and_main_demo.html +0 -93
- package/src/demos/coordinates_demo.html +0 -450
- package/src/demos/document_autoscroll_demo.html +0 -517
- package/src/demos/drag_gesture_constraints_demo.html +0 -701
- package/src/demos/drag_gesture_demo.html +0 -1047
- package/src/demos/drag_gesture_element_to_impact_demo.html +0 -445
- package/src/demos/drag_reference_element_demo.html +0 -480
- package/src/demos/flex_details_set_demo.html +0 -302
- package/src/demos/flex_details_set_demo_2.html +0 -315
- package/src/demos/visible_rect_demo.html +0 -525
- package/src/element_signature.js +0 -100
- package/src/interaction/drag/constraint_feedback_line.js +0 -92
- package/src/interaction/drag/drag_constraint.js +0 -659
- package/src/interaction/drag/drag_debug_markers.js +0 -635
- package/src/interaction/drag/drag_element_positioner.js +0 -382
- package/src/interaction/drag/drag_gesture.js +0 -566
- package/src/interaction/drag/drag_resize_demo.html +0 -571
- package/src/interaction/drag/drag_to_move.js +0 -301
- package/src/interaction/drag/drag_to_resize_gesture.js +0 -68
- package/src/interaction/drag/drop_target_detection.js +0 -148
- package/src/interaction/drag/sticky_frontiers.js +0 -160
- package/src/interaction/event_marker.js +0 -14
- package/src/interaction/focus/active_element.js +0 -33
- package/src/interaction/focus/arrow_navigation.js +0 -599
- package/src/interaction/focus/element_is_focusable.js +0 -57
- package/src/interaction/focus/element_visibility.js +0 -111
- package/src/interaction/focus/find_focusable.js +0 -21
- package/src/interaction/focus/focus_group.js +0 -91
- package/src/interaction/focus/focus_group_registry.js +0 -12
- package/src/interaction/focus/focus_nav.js +0 -12
- package/src/interaction/focus/focus_nav_event_marker.js +0 -14
- package/src/interaction/focus/focus_trap.js +0 -105
- package/src/interaction/focus/tab_navigation.js +0 -128
- package/src/interaction/focus/tests/focus_group_skip_tab_test.html +0 -206
- package/src/interaction/focus/tests/tree_focus_test.html +0 -304
- package/src/interaction/focus/tests/tree_focus_test.jsx +0 -261
- package/src/interaction/focus/tests/tree_focus_test_preact.html +0 -13
- package/src/interaction/isolate_interactions.js +0 -161
- package/src/interaction/keyboard.js +0 -26
- package/src/interaction/scroll/capture_scroll.js +0 -47
- package/src/interaction/scroll/is_scrollable.js +0 -159
- package/src/interaction/scroll/scroll_container.js +0 -110
- package/src/interaction/scroll/scroll_trap.js +0 -44
- package/src/interaction/scroll/scrollbar_size.js +0 -20
- package/src/interaction/scroll/wheel_through.js +0 -138
- package/src/iterable_weak_set.js +0 -66
- package/src/position/dom_coords.js +0 -340
- package/src/position/offset_parent.js +0 -15
- package/src/position/position_fixed.js +0 -15
- package/src/position/position_sticky.js +0 -213
- package/src/position/sticky_rect.js +0 -79
- package/src/position/visible_rect.js +0 -486
- package/src/pub_sub.js +0 -31
- package/src/size/can_take_size.js +0 -11
- package/src/size/details_content_full_height.js +0 -63
- package/src/size/flex_details_set.js +0 -974
- package/src/size/get_available_height.js +0 -22
- package/src/size/get_available_width.js +0 -22
- package/src/size/get_border_sizes.js +0 -14
- package/src/size/get_height.js +0 -4
- package/src/size/get_inner_height.js +0 -15
- package/src/size/get_inner_width.js +0 -15
- package/src/size/get_margin_sizes.js +0 -10
- package/src/size/get_max_height.js +0 -57
- package/src/size/get_max_width.js +0 -47
- package/src/size/get_min_height.js +0 -14
- package/src/size/get_min_width.js +0 -14
- package/src/size/get_padding_sizes.js +0 -10
- package/src/size/get_width.js +0 -4
- package/src/size/hooks/use_available_height.js +0 -27
- package/src/size/hooks/use_available_width.js +0 -27
- package/src/size/hooks/use_max_height.js +0 -10
- package/src/size/hooks/use_max_width.js +0 -10
- package/src/size/hooks/use_resize_status.js +0 -62
- package/src/size/resize.js +0 -695
- package/src/size/resolve_css_size.js +0 -32
- package/src/style/dom_styles.js +0 -97
- package/src/style/style_composition.js +0 -121
- package/src/style/style_controller.js +0 -345
- package/src/style/style_default.js +0 -153
- package/src/style/style_default_demo.html +0 -128
- package/src/style/style_parsing.js +0 -375
- package/src/transition/demos/animation_resumption_test.xhtml +0 -500
- package/src/transition/demos/height_toggle_test.xhtml +0 -515
- package/src/transition/dom_transition.js +0 -254
- package/src/transition/easing.js +0 -48
- package/src/transition/group_transition.js +0 -261
- package/src/transition/transform_style_parser.js +0 -32
- package/src/transition/transition_playback.js +0 -366
- package/src/transition/transition_timeline.js +0 -79
- package/src/traversal.js +0 -247
- package/src/ui_transition/demos/content_states_transition_demo.html +0 -628
- package/src/ui_transition/demos/smooth_height_transition_demo.html +0 -149
- package/src/ui_transition/demos/transition_testing.html +0 -354
- package/src/ui_transition/ui_transition.js +0 -1491
- package/src/utils.js +0 -69
- package/src/value_effect.js +0 -35
|
@@ -1,525 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Visible Rect Demo</title>
|
|
7
|
-
<style>
|
|
8
|
-
body {
|
|
9
|
-
margin: 0;
|
|
10
|
-
padding: 20px;
|
|
11
|
-
font-family: Arial, sans-serif;
|
|
12
|
-
background: #f5f5f5;
|
|
13
|
-
min-height: 300vh; /* Make page tall enough to scroll */
|
|
14
|
-
min-width: 1200px; /* Force horizontal scrolling */
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.demo-header {
|
|
18
|
-
background: white;
|
|
19
|
-
padding: 20px;
|
|
20
|
-
border-radius: 8px;
|
|
21
|
-
margin-bottom: 20px;
|
|
22
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.demo-title {
|
|
26
|
-
margin: 0 0 10px 0;
|
|
27
|
-
font-size: 24px;
|
|
28
|
-
color: #333;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.demo-description {
|
|
32
|
-
margin: 0;
|
|
33
|
-
color: #666;
|
|
34
|
-
line-height: 1.5;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.scrollable-container {
|
|
38
|
-
padding: 20px;
|
|
39
|
-
/* width/height will be set dynamically when overflow: auto */
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
.scrollable-container.custom-mode {
|
|
43
|
-
max-width: 600px;
|
|
44
|
-
max-height: 400px;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.scrollable-content {
|
|
48
|
-
position: relative;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.target-row {
|
|
52
|
-
display: flex;
|
|
53
|
-
gap: 20px;
|
|
54
|
-
align-items: flex-start;
|
|
55
|
-
margin: 50px 0;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.side-content {
|
|
59
|
-
flex: 0 0 200px;
|
|
60
|
-
padding: 20px;
|
|
61
|
-
background: rgba(0, 0, 0, 0.05);
|
|
62
|
-
border-radius: 8px;
|
|
63
|
-
min-height: 150px;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.side-content h4 {
|
|
67
|
-
margin: 0 0 10px 0;
|
|
68
|
-
font-size: 14px;
|
|
69
|
-
color: #333;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.side-content p {
|
|
73
|
-
margin: 0;
|
|
74
|
-
font-size: 13px;
|
|
75
|
-
color: #666;
|
|
76
|
-
line-height: 1.4;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
.target-element {
|
|
80
|
-
flex: 1;
|
|
81
|
-
width: 400px;
|
|
82
|
-
min-width: 400px;
|
|
83
|
-
height: 600px;
|
|
84
|
-
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
85
|
-
border: 15px solid #333;
|
|
86
|
-
display: flex;
|
|
87
|
-
align-items: center;
|
|
88
|
-
justify-content: center;
|
|
89
|
-
color: white;
|
|
90
|
-
font-weight: bold;
|
|
91
|
-
font-size: 18px;
|
|
92
|
-
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
|
|
93
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.overlay-ui {
|
|
97
|
-
position: fixed;
|
|
98
|
-
z-index: 1000;
|
|
99
|
-
overflow: hidden;
|
|
100
|
-
inset: 0;
|
|
101
|
-
pointer-events: none;
|
|
102
|
-
background: rgba(
|
|
103
|
-
0,
|
|
104
|
-
0,
|
|
105
|
-
255,
|
|
106
|
-
0.05
|
|
107
|
-
); /* Discrete blue background to make it visible */
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
.overlay-container {
|
|
111
|
-
position: absolute;
|
|
112
|
-
background: rgba(255, 0, 0, 0.5);
|
|
113
|
-
border: 2px dashed white;
|
|
114
|
-
box-sizing: border-box; /* Ensure border is included in size */
|
|
115
|
-
display: flex;
|
|
116
|
-
align-items: center;
|
|
117
|
-
justify-content: center;
|
|
118
|
-
color: white;
|
|
119
|
-
font-weight: bold;
|
|
120
|
-
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.8);
|
|
121
|
-
font-size: 12px;
|
|
122
|
-
/* Only transition visual properties, not positioning */
|
|
123
|
-
transition:
|
|
124
|
-
background-color 0.2s ease,
|
|
125
|
-
border-color 0.2s ease;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/* Dynamic styling based on visibility ratio */
|
|
129
|
-
.overlay-container.high-visibility {
|
|
130
|
-
background: rgba(0, 255, 0, 0.6);
|
|
131
|
-
border-color: #00ff00;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
.overlay-container.medium-visibility {
|
|
135
|
-
background: rgba(255, 165, 0, 0.6);
|
|
136
|
-
border-color: #ffa500;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.overlay-container.low-visibility {
|
|
140
|
-
background: rgba(255, 0, 0, 0.6);
|
|
141
|
-
border-color: #ff0000;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
.debug-info {
|
|
145
|
-
position: fixed;
|
|
146
|
-
top: 100px;
|
|
147
|
-
right: 10px;
|
|
148
|
-
background: rgba(0, 0, 0, 0.9);
|
|
149
|
-
color: white;
|
|
150
|
-
padding: 15px;
|
|
151
|
-
border-radius: 8px;
|
|
152
|
-
font-family: monospace;
|
|
153
|
-
font-size: 11px;
|
|
154
|
-
z-index: 2000;
|
|
155
|
-
max-width: 300px;
|
|
156
|
-
line-height: 1.4;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
.debug-info h4 {
|
|
160
|
-
margin: 0 0 10px 0;
|
|
161
|
-
font-size: 12px;
|
|
162
|
-
color: #4caf50;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
.debug-info .section {
|
|
166
|
-
margin-bottom: 10px;
|
|
167
|
-
padding-bottom: 8px;
|
|
168
|
-
border-bottom: 1px solid #333;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
.debug-info .section:last-child {
|
|
172
|
-
border-bottom: none;
|
|
173
|
-
margin-bottom: 0;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
.content-section {
|
|
177
|
-
background: white;
|
|
178
|
-
margin: 40px 0;
|
|
179
|
-
padding: 40px;
|
|
180
|
-
border-radius: 8px;
|
|
181
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
182
|
-
text-align: center;
|
|
183
|
-
min-width: 1000px; /* Force horizontal scrolling */
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
.content-section:nth-child(even) {
|
|
187
|
-
background: linear-gradient(135deg, #e3f2fd, #bbdefb);
|
|
188
|
-
color: #1976d2;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
.content-section:nth-child(odd) {
|
|
192
|
-
background: linear-gradient(135deg, #f3e5f5, #ce93d8);
|
|
193
|
-
color: #7b1fa2;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
.scroll-indicator {
|
|
197
|
-
position: fixed;
|
|
198
|
-
top: 10px;
|
|
199
|
-
right: 10px;
|
|
200
|
-
background: rgba(0, 0, 0, 0.8);
|
|
201
|
-
color: white;
|
|
202
|
-
padding: 10px;
|
|
203
|
-
border-radius: 4px;
|
|
204
|
-
font-family: monospace;
|
|
205
|
-
font-size: 12px;
|
|
206
|
-
z-index: 2000;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
.controls {
|
|
210
|
-
background: white;
|
|
211
|
-
padding: 15px;
|
|
212
|
-
border-radius: 8px;
|
|
213
|
-
margin-bottom: 20px;
|
|
214
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
215
|
-
max-width: 400px;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
.controls h3 {
|
|
219
|
-
margin: 0 0 15px 0;
|
|
220
|
-
font-size: 16px;
|
|
221
|
-
color: #333;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
.controls button {
|
|
225
|
-
padding: 10px 15px;
|
|
226
|
-
background: #4caf50;
|
|
227
|
-
color: white;
|
|
228
|
-
border: none;
|
|
229
|
-
border-radius: 4px;
|
|
230
|
-
cursor: pointer;
|
|
231
|
-
font-size: 14px;
|
|
232
|
-
font-weight: bold;
|
|
233
|
-
margin-right: 10px;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
.controls button:hover {
|
|
237
|
-
background: #45a049;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
.controls button.active {
|
|
241
|
-
background: #2196f3;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
.mode-status {
|
|
245
|
-
margin-top: 10px;
|
|
246
|
-
padding: 8px 12px;
|
|
247
|
-
background: #f0f0f0;
|
|
248
|
-
border-radius: 4px;
|
|
249
|
-
font-size: 12px;
|
|
250
|
-
color: #666;
|
|
251
|
-
font-style: italic;
|
|
252
|
-
}
|
|
253
|
-
</style>
|
|
254
|
-
</head>
|
|
255
|
-
<body>
|
|
256
|
-
<div class="demo-header">
|
|
257
|
-
<h1 class="demo-title">Visible Rect Demo</h1>
|
|
258
|
-
<p class="demo-description">
|
|
259
|
-
This demo shows how the <code>visibleRectEffect</code> API tracks the
|
|
260
|
-
visible portion of an element with two different visibility ratios:
|
|
261
|
-
<br />• <strong>Document Visibility:</strong> How much of the element is
|
|
262
|
-
visible in the browser viewport <br />•
|
|
263
|
-
<strong>Scroll Container Visibility:</strong> How much of the element is
|
|
264
|
-
visible within its scrollable parent <br /><strong
|
|
265
|
-
>Instructions:</strong
|
|
266
|
-
>
|
|
267
|
-
Scroll the page and watch how both ratios change. In custom container
|
|
268
|
-
mode, notice how scroll container visibility can be 100% while document
|
|
269
|
-
visibility is 0%.
|
|
270
|
-
</p>
|
|
271
|
-
</div>
|
|
272
|
-
|
|
273
|
-
<div class="controls">
|
|
274
|
-
<h3>Scrollable Container</h3>
|
|
275
|
-
<button id="documentBtn" class="active">Document</button>
|
|
276
|
-
<button id="customBtn">Custom Container</button>
|
|
277
|
-
<div class="mode-status" id="modeStatus">Current: Document scrolling</div>
|
|
278
|
-
</div>
|
|
279
|
-
|
|
280
|
-
<div class="scroll-indicator" id="scrollIndicator">Scroll: 0px</div>
|
|
281
|
-
|
|
282
|
-
<!-- Debug info panel -->
|
|
283
|
-
<div class="debug-info" id="debugInfo">
|
|
284
|
-
<h4>Visible Rect API Data</h4>
|
|
285
|
-
<div class="section">
|
|
286
|
-
<strong>Visible Rect:</strong><br />
|
|
287
|
-
<span id="visibleRect">No data</span>
|
|
288
|
-
</div>
|
|
289
|
-
<div class="section">
|
|
290
|
-
<strong>Element Full Size:</strong><br />
|
|
291
|
-
<span id="fullSize">No data</span>
|
|
292
|
-
</div>
|
|
293
|
-
<div class="section">
|
|
294
|
-
<strong>Document Visibility:</strong><br />
|
|
295
|
-
<span id="visibilityRatio">No data</span>
|
|
296
|
-
</div>
|
|
297
|
-
<div class="section">
|
|
298
|
-
<strong>Scroll Container Visibility:</strong><br />
|
|
299
|
-
<span id="scrollVisibilityRatio">No data</span>
|
|
300
|
-
</div>
|
|
301
|
-
<div class="section">
|
|
302
|
-
<strong>Visibility Status:</strong><br />
|
|
303
|
-
<span id="visibility">No data</span>
|
|
304
|
-
</div>
|
|
305
|
-
</div>
|
|
306
|
-
|
|
307
|
-
<!-- Single container that can switch between document and custom scrolling -->
|
|
308
|
-
<div class="scrollable-container" id="scrollableContainer">
|
|
309
|
-
<div class="scrollable-content">
|
|
310
|
-
<h3>Scrollable Content Area</h3>
|
|
311
|
-
<p>Content above the target element</p>
|
|
312
|
-
|
|
313
|
-
<div class="target-row">
|
|
314
|
-
<div class="side-content">
|
|
315
|
-
<h4>Left Content</h4>
|
|
316
|
-
<p>
|
|
317
|
-
This is some content on the left side of the target element. It
|
|
318
|
-
helps demonstrate how the overlay system works when the target is
|
|
319
|
-
part of a more complex layout.
|
|
320
|
-
</p>
|
|
321
|
-
<p>Additional content to make this section taller.</p>
|
|
322
|
-
</div>
|
|
323
|
-
|
|
324
|
-
<div class="target-element" id="targetElement">Target Element</div>
|
|
325
|
-
|
|
326
|
-
<div class="side-content">
|
|
327
|
-
<h4>Right Content</h4>
|
|
328
|
-
<p>
|
|
329
|
-
This is content on the right side of the target element. The
|
|
330
|
-
flexbox layout ensures proper alignment while maintaining the
|
|
331
|
-
overlay functionality.
|
|
332
|
-
</p>
|
|
333
|
-
<p>More content to balance the layout.</p>
|
|
334
|
-
</div>
|
|
335
|
-
</div>
|
|
336
|
-
|
|
337
|
-
<p>Content below target element</p>
|
|
338
|
-
</div>
|
|
339
|
-
</div>
|
|
340
|
-
|
|
341
|
-
<!-- Overlay UI showing the visible rect -->
|
|
342
|
-
<div class="overlay-ui" id="overlayUI" style="display: none">
|
|
343
|
-
<div class="overlay-container" id="overlayContainer">VISIBLE RECT</div>
|
|
344
|
-
</div>
|
|
345
|
-
|
|
346
|
-
<script type="module">
|
|
347
|
-
import { visibleRectEffect } from "../position/visible_rect.js";
|
|
348
|
-
|
|
349
|
-
const targetElement = document.getElementById("targetElement");
|
|
350
|
-
const scrollableContainer = document.getElementById(
|
|
351
|
-
"scrollableContainer",
|
|
352
|
-
);
|
|
353
|
-
const overlayUI = document.getElementById("overlayUI");
|
|
354
|
-
const overlayContainer = document.getElementById("overlayContainer");
|
|
355
|
-
const scrollIndicator = document.getElementById("scrollIndicator");
|
|
356
|
-
const documentBtn = document.getElementById("documentBtn");
|
|
357
|
-
const customBtn = document.getElementById("customBtn");
|
|
358
|
-
const modeStatus = document.getElementById("modeStatus");
|
|
359
|
-
const visibleRectSpan = document.getElementById("visibleRect");
|
|
360
|
-
const fullSizeSpan = document.getElementById("fullSize");
|
|
361
|
-
const visibilityRatioSpan = document.getElementById("visibilityRatio");
|
|
362
|
-
const scrollVisibilityRatioSpan = document.getElementById(
|
|
363
|
-
"scrollVisibilityRatio",
|
|
364
|
-
);
|
|
365
|
-
const visibilitySpan = document.getElementById("visibility");
|
|
366
|
-
|
|
367
|
-
let currentVisibleRectEffect = null;
|
|
368
|
-
const STORAGE_KEY = "overlay-demo-mode";
|
|
369
|
-
|
|
370
|
-
// Load saved mode from localStorage
|
|
371
|
-
const savedMode = localStorage.getItem(STORAGE_KEY) || "document";
|
|
372
|
-
|
|
373
|
-
// Update mode status display
|
|
374
|
-
function updateModeStatus(mode) {
|
|
375
|
-
if (mode === "document") {
|
|
376
|
-
modeStatus.textContent = "Current: Document scrolling";
|
|
377
|
-
} else {
|
|
378
|
-
modeStatus.textContent = "Current: Custom container scrolling";
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
// Update scroll indicator
|
|
383
|
-
const updateScrollIndicator = () => {
|
|
384
|
-
const scrollY = window.scrollY || document.documentElement.scrollTop;
|
|
385
|
-
const scrollX = window.scrollX || document.documentElement.scrollLeft;
|
|
386
|
-
scrollIndicator.textContent = `Scroll: ${Math.round(scrollX)}px, ${Math.round(scrollY)}px`;
|
|
387
|
-
};
|
|
388
|
-
|
|
389
|
-
// Initialize scroll indicator
|
|
390
|
-
updateScrollIndicator();
|
|
391
|
-
window.addEventListener("scroll", updateScrollIndicator);
|
|
392
|
-
|
|
393
|
-
// Initialize overlay
|
|
394
|
-
function initializeOverlay() {
|
|
395
|
-
if (currentVisibleRectEffect) {
|
|
396
|
-
currentVisibleRectEffect.disconnect();
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
overlayUI.style.display = "block";
|
|
400
|
-
|
|
401
|
-
currentVisibleRectEffect = visibleRectEffect(
|
|
402
|
-
targetElement,
|
|
403
|
-
(visibleRect, fullRect) => {
|
|
404
|
-
// Update overlay container position and size
|
|
405
|
-
overlayContainer.style.left = `${visibleRect.left}px`;
|
|
406
|
-
overlayContainer.style.top = `${visibleRect.top}px`;
|
|
407
|
-
overlayContainer.style.width = `${visibleRect.width}px`;
|
|
408
|
-
overlayContainer.style.height = `${visibleRect.height}px`;
|
|
409
|
-
|
|
410
|
-
// Hide overlay if element is not visible
|
|
411
|
-
if (visibleRect.width <= 0 || visibleRect.height <= 0) {
|
|
412
|
-
overlayContainer.style.display = "none";
|
|
413
|
-
} else {
|
|
414
|
-
overlayContainer.style.display = "flex";
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// Update dynamic styling based on visibility ratio
|
|
418
|
-
overlayContainer.classList.remove(
|
|
419
|
-
"high-visibility",
|
|
420
|
-
"medium-visibility",
|
|
421
|
-
"low-visibility",
|
|
422
|
-
);
|
|
423
|
-
let visibilityClass = "low-visibility";
|
|
424
|
-
let overlayText = "VISIBLE RECT";
|
|
425
|
-
|
|
426
|
-
if (visibleRect.visibilityRatio >= 0.8) {
|
|
427
|
-
visibilityClass = "high-visibility";
|
|
428
|
-
overlayText = "FULLY VISIBLE";
|
|
429
|
-
} else if (visibleRect.visibilityRatio >= 0.3) {
|
|
430
|
-
visibilityClass = "medium-visibility";
|
|
431
|
-
overlayText = "PARTIALLY VISIBLE";
|
|
432
|
-
} else if (visibleRect.visibilityRatio > 0) {
|
|
433
|
-
visibilityClass = "low-visibility";
|
|
434
|
-
overlayText = "BARELY VISIBLE";
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
overlayContainer.classList.add(visibilityClass);
|
|
438
|
-
overlayContainer.textContent = overlayText;
|
|
439
|
-
|
|
440
|
-
// Update debug information
|
|
441
|
-
visibleRectSpan.innerHTML = `
|
|
442
|
-
left: ${Math.round(visibleRect.left)}px<br>
|
|
443
|
-
top: ${Math.round(visibleRect.top)}px<br>
|
|
444
|
-
width: ${Math.round(visibleRect.width)}px<br>
|
|
445
|
-
height: ${Math.round(visibleRect.height)}px
|
|
446
|
-
`;
|
|
447
|
-
|
|
448
|
-
fullSizeSpan.innerHTML = `
|
|
449
|
-
width: ${Math.round(fullRect.width)}px<br>
|
|
450
|
-
height: ${Math.round(fullRect.height)}px
|
|
451
|
-
`;
|
|
452
|
-
|
|
453
|
-
// Display the visibility ratios from the API
|
|
454
|
-
visibilityRatioSpan.innerHTML = `
|
|
455
|
-
${(visibleRect.visibilityRatio * 100).toFixed(1)}%<br>
|
|
456
|
-
<small>Document Ratio: ${visibleRect.visibilityRatio.toFixed(3)}</small>
|
|
457
|
-
`;
|
|
458
|
-
|
|
459
|
-
scrollVisibilityRatioSpan.innerHTML = `
|
|
460
|
-
${(visibleRect.scrollVisibilityRatio * 100).toFixed(1)}%<br>
|
|
461
|
-
<small>Scroll Ratio: ${visibleRect.scrollVisibilityRatio.toFixed(3)}</small>
|
|
462
|
-
`;
|
|
463
|
-
|
|
464
|
-
const isVisible = visibleRect.width > 0 && visibleRect.height > 0;
|
|
465
|
-
|
|
466
|
-
visibilitySpan.innerHTML = `
|
|
467
|
-
${isVisible ? "Visible" : "Hidden"}<br>
|
|
468
|
-
<small>${visibilityClass.replace("-", " ").toUpperCase()}</small>
|
|
469
|
-
`;
|
|
470
|
-
|
|
471
|
-
console.log("Visible rect updated:", { visibleRect, fullRect });
|
|
472
|
-
},
|
|
473
|
-
);
|
|
474
|
-
|
|
475
|
-
console.log("Visible rect effect initialized");
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
// Set document scrolling mode
|
|
479
|
-
function setDocumentScrolling() {
|
|
480
|
-
scrollableContainer.style.overflow = "visible";
|
|
481
|
-
scrollableContainer.classList.remove("custom-mode");
|
|
482
|
-
localStorage.setItem(STORAGE_KEY, "document");
|
|
483
|
-
updateModeStatus("document");
|
|
484
|
-
initializeOverlay();
|
|
485
|
-
console.log("Document scrolling mode activated");
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
// Set custom container scrolling mode
|
|
489
|
-
function setCustomContainerScrolling() {
|
|
490
|
-
scrollableContainer.style.overflow = "auto";
|
|
491
|
-
scrollableContainer.classList.add("custom-mode");
|
|
492
|
-
localStorage.setItem(STORAGE_KEY, "custom");
|
|
493
|
-
updateModeStatus("custom");
|
|
494
|
-
initializeOverlay();
|
|
495
|
-
console.log("Custom container scrolling mode activated");
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
// Button handlers
|
|
499
|
-
documentBtn.addEventListener("click", () => {
|
|
500
|
-
documentBtn.classList.add("active");
|
|
501
|
-
customBtn.classList.remove("active");
|
|
502
|
-
setDocumentScrolling();
|
|
503
|
-
});
|
|
504
|
-
|
|
505
|
-
customBtn.addEventListener("click", () => {
|
|
506
|
-
customBtn.classList.add("active");
|
|
507
|
-
documentBtn.classList.remove("active");
|
|
508
|
-
setCustomContainerScrolling();
|
|
509
|
-
});
|
|
510
|
-
|
|
511
|
-
// Initialize with saved mode
|
|
512
|
-
if (savedMode === "custom") {
|
|
513
|
-
customBtn.classList.add("active");
|
|
514
|
-
documentBtn.classList.remove("active");
|
|
515
|
-
setCustomContainerScrolling();
|
|
516
|
-
} else {
|
|
517
|
-
documentBtn.classList.add("active");
|
|
518
|
-
customBtn.classList.remove("active");
|
|
519
|
-
setDocumentScrolling();
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
console.log("Visible rect demo initialized");
|
|
523
|
-
</script>
|
|
524
|
-
</body>
|
|
525
|
-
</html>
|
package/src/element_signature.js
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generates a unique signature for various types of elements that can be used for identification in logs.
|
|
3
|
-
*
|
|
4
|
-
* This function handles different types of elements and returns an appropriate identifier:
|
|
5
|
-
* - For DOM elements: Creates a CSS selector using tag name, data-ui-name, ID, classes, or parent hierarchy
|
|
6
|
-
* - For React/Preact elements (JSX): Returns JSX-like representation with type and props
|
|
7
|
-
* - For functions: Returns function name and optional underlying element reference in brackets
|
|
8
|
-
* - For null/undefined: Returns the string representation
|
|
9
|
-
*
|
|
10
|
-
* The returned signature for DOM elements is a valid CSS selector that can be copy-pasted
|
|
11
|
-
* into browser dev tools to locate the element in the DOM.
|
|
12
|
-
*
|
|
13
|
-
* @param {HTMLElement|Object|Function|null|undefined} element - The element to generate a signature for
|
|
14
|
-
* @returns {string} A unique identifier string in various formats depending on element type
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* // For DOM element with data-ui-name
|
|
18
|
-
* // <div data-ui-name="header">
|
|
19
|
-
* getElementSignature(element) // Returns: `div[data-ui-name="header"]`
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* // For DOM element with ID
|
|
23
|
-
* // <div id="main" class="container active">
|
|
24
|
-
* getElementSignature(element) // Returns: "div#main"
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* // For DOM element with classes only
|
|
28
|
-
* // <button class="btn primary">
|
|
29
|
-
* getElementSignature(element) // Returns: "button.btn.primary"
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* // For DOM element without distinguishing features (uses parent hierarchy)
|
|
33
|
-
* // <p> inside <section id="content">
|
|
34
|
-
* getElementSignature(element) // Returns: "section#content > p"
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* // For React/Preact element with props
|
|
38
|
-
* // <MyComponent id="widget" />
|
|
39
|
-
* getElementSignature(element) // Returns: `<MyComponent id="widget" />`
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* // For named function with underlying element reference
|
|
43
|
-
* const MyComponent = () => {}; MyComponent.underlyingElementId = "div#main";
|
|
44
|
-
* getElementSignature(MyComponent) // Returns: "[function MyComponent for div#main]"
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* // For anonymous function without underlying element
|
|
48
|
-
* const anonymousFunc = () => {};
|
|
49
|
-
* getElementSignature(anonymousFunc) // Returns: "[function]"
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* // For named function without underlying element
|
|
53
|
-
* function namedHandler() {}
|
|
54
|
-
* getElementSignature(namedHandler) // Returns: "[function namedHandler]"
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* // For null/undefined
|
|
58
|
-
* getElementSignature(null) // Returns: "null"
|
|
59
|
-
*/
|
|
60
|
-
export const getElementSignature = (element) => {
|
|
61
|
-
if (!element) {
|
|
62
|
-
return String(element);
|
|
63
|
-
}
|
|
64
|
-
if (typeof element === "function") {
|
|
65
|
-
const functionName = element.name;
|
|
66
|
-
const functionLabel = functionName
|
|
67
|
-
? `function ${functionName}`
|
|
68
|
-
: "function";
|
|
69
|
-
const underlyingElementId = element.underlyingElementId;
|
|
70
|
-
if (underlyingElementId) {
|
|
71
|
-
return `[${functionLabel} for ${underlyingElementId}]`;
|
|
72
|
-
}
|
|
73
|
-
return `[${functionLabel}]`;
|
|
74
|
-
}
|
|
75
|
-
if (element.props) {
|
|
76
|
-
const type = element.type;
|
|
77
|
-
const id = element.props.id;
|
|
78
|
-
if (id) {
|
|
79
|
-
return `<${type} id="${id}" />`;
|
|
80
|
-
}
|
|
81
|
-
return `<${type} />`;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const tagName = element.tagName.toLowerCase();
|
|
85
|
-
const dataUIName = element.getAttribute("data-ui-name");
|
|
86
|
-
if (dataUIName) {
|
|
87
|
-
return `${tagName}[data-ui-name="${dataUIName}"]`;
|
|
88
|
-
}
|
|
89
|
-
const elementId = element.id;
|
|
90
|
-
if (elementId) {
|
|
91
|
-
return `${tagName}#${elementId}`;
|
|
92
|
-
}
|
|
93
|
-
const className = element.className;
|
|
94
|
-
if (className) {
|
|
95
|
-
return `${tagName}.${className.split(" ").join(".")}`;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const parentSignature = getElementSignature(element.parentElement);
|
|
99
|
-
return `${parentSignature} > ${tagName}`;
|
|
100
|
-
};
|