@jsenv/dom 0.1.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.
Files changed (101) hide show
  1. package/dist/jsenv_dom.js +9653 -0
  2. package/index.js +101 -0
  3. package/package.json +47 -0
  4. package/src/attr/add_attribute_effect.js +93 -0
  5. package/src/attr/attributes.js +32 -0
  6. package/src/demos/3_columns_resize_demo.html +84 -0
  7. package/src/demos/3_rows_resize_demo.html +89 -0
  8. package/src/demos/aside_and_main_demo.html +93 -0
  9. package/src/demos/coordinates_demo.html +450 -0
  10. package/src/demos/document_autoscroll_demo.html +517 -0
  11. package/src/demos/drag_gesture_constraints_demo.html +701 -0
  12. package/src/demos/drag_gesture_demo.html +1047 -0
  13. package/src/demos/drag_gesture_element_to_impact_demo.html +445 -0
  14. package/src/demos/drag_reference_element_demo.html +480 -0
  15. package/src/demos/flex_details_set_demo.html +302 -0
  16. package/src/demos/flex_details_set_demo_2.html +315 -0
  17. package/src/demos/visible_rect_demo.html +525 -0
  18. package/src/interaction/drag/constraint_feedback_line.js +92 -0
  19. package/src/interaction/drag/drag_constraint.js +659 -0
  20. package/src/interaction/drag/drag_debug_markers.js +635 -0
  21. package/src/interaction/drag/drag_element_positioner.js +382 -0
  22. package/src/interaction/drag/drag_gesture.js +566 -0
  23. package/src/interaction/drag/drag_resize_demo.html +571 -0
  24. package/src/interaction/drag/drag_to_move.js +301 -0
  25. package/src/interaction/drag/drag_to_resize_gesture.js +68 -0
  26. package/src/interaction/drag/drop_target_detection.js +148 -0
  27. package/src/interaction/drag/sticky_frontiers.js +160 -0
  28. package/src/interaction/element_log.js +8 -0
  29. package/src/interaction/event_marker.js +14 -0
  30. package/src/interaction/focus/active_element.js +33 -0
  31. package/src/interaction/focus/arrow_navigation.js +599 -0
  32. package/src/interaction/focus/element_is_focusable.js +57 -0
  33. package/src/interaction/focus/element_is_visible.js +36 -0
  34. package/src/interaction/focus/find_focusable.js +21 -0
  35. package/src/interaction/focus/focus_group.js +91 -0
  36. package/src/interaction/focus/focus_group_registry.js +12 -0
  37. package/src/interaction/focus/focus_nav.js +12 -0
  38. package/src/interaction/focus/focus_nav_event_marker.js +14 -0
  39. package/src/interaction/focus/focus_trap.js +105 -0
  40. package/src/interaction/focus/tab_navigation.js +128 -0
  41. package/src/interaction/focus/tests/focus_group_skip_tab_test.html +206 -0
  42. package/src/interaction/focus/tests/tree_focus_test.html +304 -0
  43. package/src/interaction/focus/tests/tree_focus_test.jsx +261 -0
  44. package/src/interaction/focus/tests/tree_focus_test_preact.html +13 -0
  45. package/src/interaction/isolate_interactions.js +161 -0
  46. package/src/interaction/keyboard.js +26 -0
  47. package/src/interaction/scroll/capture_scroll.js +47 -0
  48. package/src/interaction/scroll/is_scrollable.js +159 -0
  49. package/src/interaction/scroll/scroll_container.js +110 -0
  50. package/src/interaction/scroll/scroll_trap.js +44 -0
  51. package/src/interaction/scroll/scrollbar_size.js +20 -0
  52. package/src/interaction/scroll/wheel_through.js +138 -0
  53. package/src/iterable_weak_set.js +66 -0
  54. package/src/position/dom_coords.js +340 -0
  55. package/src/position/offset_parent.js +15 -0
  56. package/src/position/position_fixed.js +15 -0
  57. package/src/position/position_sticky.js +213 -0
  58. package/src/position/sticky_rect.js +79 -0
  59. package/src/position/visible_rect.js +482 -0
  60. package/src/pub_sub.js +28 -0
  61. package/src/size/can_take_size.js +11 -0
  62. package/src/size/details_content_full_height.js +63 -0
  63. package/src/size/flex_details_set.js +974 -0
  64. package/src/size/get_available_height.js +22 -0
  65. package/src/size/get_available_width.js +22 -0
  66. package/src/size/get_border_sizes.js +14 -0
  67. package/src/size/get_height.js +4 -0
  68. package/src/size/get_inner_height.js +15 -0
  69. package/src/size/get_inner_width.js +15 -0
  70. package/src/size/get_margin_sizes.js +10 -0
  71. package/src/size/get_max_height.js +57 -0
  72. package/src/size/get_max_width.js +47 -0
  73. package/src/size/get_min_height.js +14 -0
  74. package/src/size/get_min_width.js +14 -0
  75. package/src/size/get_padding_sizes.js +10 -0
  76. package/src/size/get_width.js +4 -0
  77. package/src/size/hooks/use_available_height.js +27 -0
  78. package/src/size/hooks/use_available_width.js +27 -0
  79. package/src/size/hooks/use_max_height.js +10 -0
  80. package/src/size/hooks/use_max_width.js +10 -0
  81. package/src/size/hooks/use_resize_status.js +62 -0
  82. package/src/size/resize.js +695 -0
  83. package/src/size/resolve_css_size.js +32 -0
  84. package/src/style/dom_styles.js +97 -0
  85. package/src/style/style_composition.js +78 -0
  86. package/src/style/style_controller.js +345 -0
  87. package/src/style/style_parsing.js +317 -0
  88. package/src/transition/demos/animation_resumption_test.xhtml +500 -0
  89. package/src/transition/demos/height_toggle_test.xhtml +515 -0
  90. package/src/transition/dom_transition.js +254 -0
  91. package/src/transition/easing.js +48 -0
  92. package/src/transition/group_transition.js +261 -0
  93. package/src/transition/transform_style_parser.js +32 -0
  94. package/src/transition/transition_playback.js +366 -0
  95. package/src/transition/transition_timeline.js +79 -0
  96. package/src/traversal.js +247 -0
  97. package/src/ui_transition/demos/content_states_transition_demo.html +628 -0
  98. package/src/ui_transition/demos/smooth_height_transition_demo.html +149 -0
  99. package/src/ui_transition/demos/transition_testing.html +354 -0
  100. package/src/ui_transition/ui_transition.js +1492 -0
  101. package/src/utils.js +69 -0
@@ -0,0 +1,450 @@
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>Coordinates Systems Demo</title>
7
+ <style>
8
+ body {
9
+ margin: 0;
10
+ padding: 0;
11
+ font-family: Arial, sans-serif;
12
+ background: linear-gradient(45deg, #f0f0f0, #e0e0e0);
13
+ /* Make document 10,000px wide */
14
+ width: 10000px;
15
+ height: 100vh;
16
+ position: relative;
17
+ }
18
+
19
+ .info-panel {
20
+ position: fixed;
21
+ top: 10px;
22
+ left: 10px;
23
+ background: rgba(255, 255, 255, 0.95);
24
+ padding: 20px;
25
+ border-radius: 8px;
26
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
27
+ font-family: monospace;
28
+ font-size: 12px;
29
+ line-height: 1.4;
30
+ z-index: 1000;
31
+ max-width: 400px;
32
+ border-left: 4px solid #2196f3;
33
+ }
34
+
35
+ .info-section {
36
+ margin-bottom: 15px;
37
+ padding-bottom: 10px;
38
+ border-bottom: 1px solid #eee;
39
+ }
40
+
41
+ .info-section:last-child {
42
+ border-bottom: none;
43
+ margin-bottom: 0;
44
+ }
45
+
46
+ .info-title {
47
+ font-weight: bold;
48
+ color: #333;
49
+ margin-bottom: 5px;
50
+ font-size: 13px;
51
+ }
52
+
53
+ .info-value {
54
+ color: #666;
55
+ margin-left: 10px;
56
+ }
57
+
58
+ .red-square {
59
+ width: 100px;
60
+ height: 100px;
61
+ background: #f44336;
62
+ position: absolute;
63
+ /* Center horizontally in the 10,000px wide document */
64
+ left: calc(5000px - 50px); /* 5000px (middle) - 50px (half width) */
65
+ top: 200px;
66
+ border: 2px solid #d32f2f;
67
+ border-radius: 4px;
68
+ display: flex;
69
+ align-items: center;
70
+ justify-content: center;
71
+ color: white;
72
+ font-weight: bold;
73
+ text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
74
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
75
+ }
76
+
77
+ .scrollable-container {
78
+ width: 200px;
79
+ height: 200px;
80
+ /* Make the scrollable content 4000px wide */
81
+ overflow-x: scroll;
82
+ overflow-y: hidden;
83
+ position: absolute;
84
+ /* Center horizontally in the 10,000px wide document */
85
+ left: calc(5000px - 100px); /* 5000px (middle) - 100px (half width) */
86
+ top: 400px;
87
+ background: white;
88
+ border: 3px solid #333;
89
+ border-radius: 8px;
90
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
91
+ }
92
+
93
+ .scrollable-content {
94
+ width: 1000px;
95
+ height: 100%;
96
+ background: linear-gradient(
97
+ 90deg,
98
+ #e3f2fd,
99
+ #bbdefb,
100
+ #90caf9,
101
+ #64b5f6,
102
+ #42a5f5
103
+ );
104
+ position: relative;
105
+ display: flex;
106
+ align-items: center;
107
+ }
108
+
109
+ .blue-square {
110
+ width: 100px;
111
+ height: 100px;
112
+ background: #2196f3;
113
+ position: absolute;
114
+ /* Center horizontally in the 4000px wide scrollable content */
115
+ left: 550px; /* 2000px (middle) - 50px (half width) */
116
+ border: 2px solid #1976d2;
117
+ border-radius: 4px;
118
+ display: flex;
119
+ align-items: center;
120
+ justify-content: center;
121
+ color: white;
122
+ font-weight: bold;
123
+ text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
124
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
125
+ }
126
+
127
+ .scroll-indicators {
128
+ position: fixed;
129
+ bottom: 10px;
130
+ left: 10px;
131
+ background: rgba(0, 0, 0, 0.8);
132
+ color: white;
133
+ padding: 15px;
134
+ border-radius: 8px;
135
+ font-family: monospace;
136
+ font-size: 11px;
137
+ z-index: 1000;
138
+ line-height: 1.4;
139
+ }
140
+
141
+ .coordinate-info {
142
+ position: fixed;
143
+ top: 10px;
144
+ right: 10px;
145
+ background: rgba(255, 255, 255, 0.95);
146
+ padding: 20px;
147
+ border-radius: 8px;
148
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
149
+ font-family: monospace;
150
+ font-size: 12px;
151
+ line-height: 1.4;
152
+ z-index: 1000;
153
+ max-width: 350px;
154
+ border-left: 4px solid #ff9800;
155
+ }
156
+
157
+ .setup-instructions {
158
+ position: fixed;
159
+ bottom: 10px;
160
+ right: 10px;
161
+ background: rgba(76, 175, 80, 0.9);
162
+ color: white;
163
+ padding: 15px;
164
+ border-radius: 8px;
165
+ font-size: 12px;
166
+ z-index: 1000;
167
+ max-width: 250px;
168
+ text-align: center;
169
+ }
170
+
171
+ .auto-setup-btn {
172
+ background: #fff;
173
+ color: #4caf50;
174
+ border: none;
175
+ padding: 8px 15px;
176
+ border-radius: 4px;
177
+ cursor: pointer;
178
+ font-weight: bold;
179
+ margin-top: 10px;
180
+ font-size: 11px;
181
+ }
182
+
183
+ .auto-setup-btn:hover {
184
+ background: #f0f0f0;
185
+ }
186
+ </style>
187
+ </head>
188
+ <body>
189
+ <div class="info-panel" id="infoPanel">
190
+ <div class="info-section">
191
+ <div class="info-title">🔴 Red Square Coordinates</div>
192
+ <div class="info-value">
193
+ getBoundingClientRect().left: <span id="redLeft">-</span>px
194
+ </div>
195
+ <div class="info-value">
196
+ offsetLeft: <span id="redOffsetLeft">-</span>px
197
+ </div>
198
+ <div class="info-value">
199
+ Absolute position: <span id="redAbsolute">-</span>
200
+ </div>
201
+ </div>
202
+
203
+ <div class="info-section">
204
+ <div class="info-title">🔵 Blue Square Coordinates</div>
205
+ <div class="info-value">
206
+ getBoundingClientRect().left: <span id="blueLeft">-</span>px
207
+ </div>
208
+ <div class="info-value">
209
+ offsetLeft: <span id="blueOffsetLeft">-</span>px
210
+ </div>
211
+ <div class="info-value">
212
+ Relative to container: <span id="blueRelative">-</span>
213
+ </div>
214
+ </div>
215
+
216
+ <div class="info-section">
217
+ <div class="info-title">📦 Scrollable Container</div>
218
+ <div class="info-value">
219
+ getBoundingClientRect().left: <span id="containerLeft">-</span>px
220
+ </div>
221
+ <div class="info-value">
222
+ scrollLeft: <span id="containerScrollLeft">-</span>px
223
+ </div>
224
+ <div class="info-value">
225
+ scrollWidth: <span id="containerScrollWidth">-</span>px
226
+ </div>
227
+ <div class="info-value">
228
+ clientWidth: <span id="containerClientWidth">-</span>px
229
+ </div>
230
+ </div>
231
+ </div>
232
+
233
+ <div class="coordinate-info" id="coordinateInfo">
234
+ <div class="info-section">
235
+ <div class="info-title">🖼️ Viewport Info</div>
236
+ <div class="info-value">
237
+ scrollWidth: <span id="docScrollWidth">-</span>px
238
+ </div>
239
+ <div class="info-value">
240
+ scrollLeft: <span id="docScrollLeft">-</span>px
241
+ </div>
242
+ <div class="info-value">
243
+ Width: <span id="docOffsetWidth">-</span>px
244
+ </div>
245
+ <div class="info-value">
246
+ Available width:
247
+ <span id="docClientWidth">-</span>px
248
+ </div>
249
+ </div>
250
+
251
+ <div class="info-section">
252
+ <div class="info-title">🎯 Mouse Position</div>
253
+ <div class="info-value">
254
+ clientX: <span id="mouseClientX">-</span>px
255
+ </div>
256
+ <div class="info-value">pageX: <span id="mousePageX">-</span>px</div>
257
+ <div class="info-value">
258
+ screenX: <span id="mouseScreenX">-</span>px
259
+ </div>
260
+ </div>
261
+ </div>
262
+
263
+ <div class="scroll-indicators" id="scrollIndicators" style="opacity: 0">
264
+ <div><strong>Scroll Status:</strong></div>
265
+ <div>Document: <span id="docScrollStatus">Not centered</span></div>
266
+ <div>Container: <span id="containerScrollStatus">Not centered</span></div>
267
+ <div><strong>Target Positions:</strong></div>
268
+ <div>
269
+ Doc center: 5000px - 50vw = <span id="docTargetScroll">-</span>px
270
+ </div>
271
+ <div>
272
+ Container center: 2000px - 100px =
273
+ <span id="containerTargetScroll">1900</span>px
274
+ </div>
275
+ </div>
276
+
277
+ <div class="setup-instructions">
278
+ <div><strong>Setup Instructions:</strong></div>
279
+ <div>1. Scroll document to middle</div>
280
+ <div>2. Scroll blue container to middle</div>
281
+ <div>3. Observe coordinate changes</div>
282
+ <button class="auto-setup-btn" onclick="autoSetup()">Auto Setup</button>
283
+ </div>
284
+
285
+ <div class="red-square" id="redSquare">RED</div>
286
+
287
+ <div class="scrollable-container" id="scrollableContainer">
288
+ <div class="scrollable-content">
289
+ <div class="blue-square" id="blueSquare">BLUE</div>
290
+ </div>
291
+ </div>
292
+
293
+ <script>
294
+ const elements = {
295
+ redSquare: document.getElementById("redSquare"),
296
+ blueSquare: document.getElementById("blueSquare"),
297
+ scrollableContainer: document.getElementById("scrollableContainer"),
298
+
299
+ // Red square info
300
+ redLeft: document.getElementById("redLeft"),
301
+ redOffsetLeft: document.getElementById("redOffsetLeft"),
302
+ redAbsolute: document.getElementById("redAbsolute"),
303
+
304
+ // Blue square info
305
+ blueLeft: document.getElementById("blueLeft"),
306
+ blueOffsetLeft: document.getElementById("blueOffsetLeft"),
307
+ blueRelative: document.getElementById("blueRelative"),
308
+
309
+ // Container info
310
+ containerLeft: document.getElementById("containerLeft"),
311
+ containerScrollLeft: document.getElementById("containerScrollLeft"),
312
+ containerScrollWidth: document.getElementById("containerScrollWidth"),
313
+ containerClientWidth: document.getElementById("containerClientWidth"),
314
+
315
+ // Document info
316
+ docScrollLeft: document.getElementById("docScrollLeft"),
317
+ docScrollWidth: document.getElementById("docScrollWidth"),
318
+ docClientWidth: document.getElementById("docClientWidth"),
319
+ bodyWidth: document.getElementById("bodyWidth"),
320
+
321
+ // Viewport info
322
+ offsetWidth: document.getElementById("docOffsetWidth"),
323
+
324
+ // Mouse info
325
+ mouseClientX: document.getElementById("mouseClientX"),
326
+ mousePageX: document.getElementById("mousePageX"),
327
+ mouseScreenX: document.getElementById("mouseScreenX"),
328
+
329
+ // Status indicators
330
+ docScrollStatus: document.getElementById("docScrollStatus"),
331
+ containerScrollStatus: document.getElementById("containerScrollStatus"),
332
+ docTargetScroll: document.getElementById("docTargetScroll"),
333
+ };
334
+
335
+ function updateCoordinateInfo() {
336
+ // Red square coordinates
337
+ const redRect = elements.redSquare.getBoundingClientRect();
338
+ elements.redLeft.textContent = Math.round(redRect.left);
339
+ elements.redOffsetLeft.textContent = elements.redSquare.offsetLeft;
340
+ elements.redAbsolute.textContent = `left: ${elements.redSquare.style.left}`;
341
+
342
+ // Blue square coordinates
343
+ const blueRect = elements.blueSquare.getBoundingClientRect();
344
+ elements.blueLeft.textContent = Math.round(blueRect.left);
345
+ elements.blueOffsetLeft.textContent = elements.blueSquare.offsetLeft;
346
+ elements.blueRelative.textContent = `left: ${elements.blueSquare.style.left}`;
347
+
348
+ // Container coordinates
349
+ const containerRect =
350
+ elements.scrollableContainer.getBoundingClientRect();
351
+ elements.containerLeft.textContent = Math.round(containerRect.left);
352
+ elements.containerScrollLeft.textContent =
353
+ elements.scrollableContainer.scrollLeft;
354
+ elements.containerScrollWidth.textContent =
355
+ elements.scrollableContainer.scrollWidth;
356
+ elements.containerClientWidth.textContent =
357
+ elements.scrollableContainer.clientWidth;
358
+
359
+ // Document coordinates
360
+ const docScrollLeft = document.documentElement.scrollLeft;
361
+ elements.docScrollLeft.textContent = Math.round(docScrollLeft);
362
+ elements.docScrollWidth.textContent =
363
+ document.documentElement.scrollWidth;
364
+ elements.docClientWidth.textContent =
365
+ document.documentElement.clientWidth;
366
+
367
+ // Viewport info
368
+ elements.offsetWidth.textContent = window.innerWidth;
369
+
370
+ // Calculate target scroll positions
371
+ const docTargetScroll = 5000 - window.innerWidth / 2;
372
+ elements.docTargetScroll.textContent = Math.round(docTargetScroll);
373
+
374
+ // Update scroll status
375
+ const docScrollDiff = Math.abs(docScrollLeft - docTargetScroll);
376
+ elements.docScrollStatus.textContent =
377
+ docScrollDiff < 10
378
+ ? "✅ Centered"
379
+ : `❌ Off by ${Math.round(docScrollDiff)}px`;
380
+
381
+ const containerScrollDiff = Math.abs(
382
+ elements.scrollableContainer.scrollLeft - 1900,
383
+ );
384
+ elements.containerScrollStatus.textContent =
385
+ containerScrollDiff < 10
386
+ ? "✅ Centered"
387
+ : `❌ Off by ${Math.round(containerScrollDiff)}px`;
388
+ }
389
+
390
+ window.autoSetup = function () {
391
+ // Calculate the exact center positions
392
+ const docCenterScroll =
393
+ document.documentElement.scrollWidth / 2 - window.innerWidth / 2;
394
+ const containerCenterScroll =
395
+ elements.scrollableContainer.scrollWidth / 2;
396
+
397
+ // Scroll document to center
398
+ window.scrollTo({
399
+ left: docCenterScroll,
400
+ behavior: "smooth",
401
+ });
402
+
403
+ // Wait a bit for document scroll to start, then scroll container
404
+ setTimeout(() => {
405
+ elements.scrollableContainer.scrollTo({
406
+ left: containerCenterScroll,
407
+ behavior: "smooth",
408
+ });
409
+ }, 100);
410
+ };
411
+
412
+ // Track mouse movement
413
+ document.addEventListener("mousemove", (e) => {
414
+ elements.mouseClientX.textContent = e.clientX;
415
+ elements.mousePageX.textContent = e.pageX;
416
+ elements.mouseScreenX.textContent = e.screenX;
417
+ });
418
+
419
+ // Update info on scroll
420
+ window.addEventListener("scroll", updateCoordinateInfo);
421
+ elements.scrollableContainer.addEventListener(
422
+ "scroll",
423
+ updateCoordinateInfo,
424
+ );
425
+
426
+ // Update info on resize
427
+ window.addEventListener("resize", updateCoordinateInfo);
428
+
429
+ // Initial update
430
+ updateCoordinateInfo();
431
+
432
+ // Auto-update every 100ms to catch any changes
433
+ setInterval(updateCoordinateInfo, 100);
434
+
435
+ // Automatically run the setup after page loads
436
+ setTimeout(() => {
437
+ window.autoSetup();
438
+ }, 500);
439
+
440
+ console.log("Coordinates Demo initialized");
441
+ console.log("Document width:", document.body.offsetWidth, "px");
442
+ console.log("Red square at:", elements.redSquare.style.left);
443
+ console.log(
444
+ "Blue square at:",
445
+ elements.blueSquare.style.left,
446
+ "(relative to scrollable content)",
447
+ );
448
+ </script>
449
+ </body>
450
+ </html>