@jsenv/dom 0.6.1 → 0.7.1
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 +339 -327
- 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 -1470
- package/src/utils.js +0 -69
- package/src/value_effect.js +0 -35
package/src/size/resize.js
DELETED
|
@@ -1,695 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Resize.js - Element Resize Manager
|
|
3
|
-
*
|
|
4
|
-
* This module provides a comprehensive solution for making HTML elements resizable
|
|
5
|
-
* with intelligent space distribution among siblings. It handles both horizontal and
|
|
6
|
-
* vertical resizing while maintaining layout integrity.
|
|
7
|
-
*
|
|
8
|
-
* Key features:
|
|
9
|
-
* - Makes elements resizable via data-resize="horizontal|vertical|both" attribute
|
|
10
|
-
* - Intelligently distributes space among sibling elements during resize
|
|
11
|
-
* - Respects min-width/min-height constraints of all affected elements
|
|
12
|
-
* - Dispatches custom events (resizestart, resize, resizeend) with position info
|
|
13
|
-
* - Preserves layout integrity by ensuring all available space is properly allocated
|
|
14
|
-
* - Supports flex layouts by temporarily adjusting flex behavior during resize
|
|
15
|
-
* - Provides percentage-based sizing for responsive layouts (without data-resize-absolute)
|
|
16
|
-
* - Absolute pixel sizing when data-resize-absolute is specified
|
|
17
|
-
* - Handles both grow and shrink operations with space redistribution
|
|
18
|
-
*
|
|
19
|
-
* Usage:
|
|
20
|
-
* 1. Add data-resize="horizontal" (or "vertical"/"both") to elements you want resizable
|
|
21
|
-
* 2. Add a resize handle with data-resize-handle attribute
|
|
22
|
-
* 3. Optionally add data-resize-absolute to maintain pixel-based sizing
|
|
23
|
-
*
|
|
24
|
-
* Example:
|
|
25
|
-
* <div style="display: flex">
|
|
26
|
-
* <div data-resize="horizontal" style="width: 200px">
|
|
27
|
-
* Resizable content
|
|
28
|
-
* <div data-resize-handle></div>
|
|
29
|
-
* </div>
|
|
30
|
-
* <div>Adjacent content that adapts automatically</div>
|
|
31
|
-
* </div>
|
|
32
|
-
*
|
|
33
|
-
* Advanced usage:
|
|
34
|
-
* - Target specific elements with data-resize-handle="elementId"
|
|
35
|
-
* - Listen for resize events: element.addEventListener("resize", (e) => {...})
|
|
36
|
-
* - Access resize information from event.detail (xMove, yMove, etc.)
|
|
37
|
-
*/
|
|
38
|
-
|
|
39
|
-
import { addAttributeEffect } from "../attr/add_attribute_effect.js";
|
|
40
|
-
import { canTakeSize } from "./can_take_size.js";
|
|
41
|
-
import { getAvailableHeight } from "./get_available_height.js";
|
|
42
|
-
import { getAvailableWidth } from "./get_available_width.js";
|
|
43
|
-
import { getHeight } from "./get_height.js";
|
|
44
|
-
import { getMinHeight } from "./get_min_height.js";
|
|
45
|
-
import { getMinWidth } from "./get_min_width.js";
|
|
46
|
-
import { getWidth } from "./get_width.js";
|
|
47
|
-
|
|
48
|
-
const style = /*css*/ `
|
|
49
|
-
*[data-resize] {
|
|
50
|
-
flex-shrink: 1 !important; /* flex-shrink === 0 would prevent element to shrink as much as it could */
|
|
51
|
-
flex-grow: 0 !important; /* flex-grow === 1 (or more) would prevent element to shrink as much as it could */
|
|
52
|
-
flex-basis: auto !important; /* flex-basis !== auto would prevent element to grow as much as it could */
|
|
53
|
-
}`;
|
|
54
|
-
document.head.appendChild(document.createElement("style")).textContent = style;
|
|
55
|
-
|
|
56
|
-
const start = (event) => {
|
|
57
|
-
if (event.button !== 0) {
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
const target = event.target;
|
|
61
|
-
if (!target.closest) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const elementWithDataResizeHandle = target.closest("[data-resize-handle]");
|
|
65
|
-
if (!elementWithDataResizeHandle) {
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
let elementToResize;
|
|
69
|
-
const dataResizeHandle =
|
|
70
|
-
elementWithDataResizeHandle.getAttribute("data-resize-handle");
|
|
71
|
-
if (!dataResizeHandle || dataResizeHandle === "true") {
|
|
72
|
-
elementToResize = elementWithDataResizeHandle.closest("[data-resize]");
|
|
73
|
-
} else {
|
|
74
|
-
elementToResize = document.querySelector(`#${dataResizeHandle}`);
|
|
75
|
-
}
|
|
76
|
-
if (!elementToResize) {
|
|
77
|
-
console.warn("No element to resize found");
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
// inspired by https://developer.mozilla.org/en-US/docs/Web/CSS/resize
|
|
81
|
-
// "horizontal", "vertical", "both"
|
|
82
|
-
const resizeDirection = getResizeDirection(elementToResize);
|
|
83
|
-
if (!resizeDirection.x && !resizeDirection.y) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
event.preventDefault();
|
|
87
|
-
|
|
88
|
-
const endCallbackSet = new Set();
|
|
89
|
-
const parentElement = elementToResize.parentElement;
|
|
90
|
-
const availableWidth = getAvailableWidth(elementToResize);
|
|
91
|
-
const availableHeight = getAvailableHeight(elementToResize);
|
|
92
|
-
const xAtStart = event.clientX;
|
|
93
|
-
const yAtStart = event.clientY;
|
|
94
|
-
const resizeInfo = {
|
|
95
|
-
xAtStart,
|
|
96
|
-
yAtStart,
|
|
97
|
-
x: xAtStart,
|
|
98
|
-
y: yAtStart,
|
|
99
|
-
xMove: 0,
|
|
100
|
-
yMove: 0,
|
|
101
|
-
|
|
102
|
-
availableWidth,
|
|
103
|
-
availableHeight,
|
|
104
|
-
widthAtStart: undefined,
|
|
105
|
-
heightAtStart: undefined,
|
|
106
|
-
width: undefined,
|
|
107
|
-
height: undefined,
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const horizontalPreviousSiblingSet = new Set();
|
|
111
|
-
const horizontalNextSiblingSet = new Set();
|
|
112
|
-
const minWidthMap = new Map();
|
|
113
|
-
const widthMap = new Map();
|
|
114
|
-
const currentWidthMap = new Map();
|
|
115
|
-
const setWidth = (element, width) => {
|
|
116
|
-
if (currentWidthMap.get(element) === width) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
element.style.width = `${width}px`;
|
|
120
|
-
currentWidthMap.set(element, width);
|
|
121
|
-
if (element === elementToResize) {
|
|
122
|
-
resizeInfo.width = width;
|
|
123
|
-
}
|
|
124
|
-
dispatchResizeEvent(element);
|
|
125
|
-
};
|
|
126
|
-
const saveWidth = (element) => {
|
|
127
|
-
const width = getWidth(element);
|
|
128
|
-
widthMap.set(element, width);
|
|
129
|
-
currentWidthMap.set(element, width);
|
|
130
|
-
return width;
|
|
131
|
-
};
|
|
132
|
-
const setWidthAsPercentage = (element, width) => {
|
|
133
|
-
currentWidthMap.set(element, width);
|
|
134
|
-
const ratio = width / availableWidth;
|
|
135
|
-
// const roundedRatio = Math.round(ratio * 10000) / 10000;
|
|
136
|
-
const percentage = ratio * 100;
|
|
137
|
-
element.style.width = `${percentage}%`;
|
|
138
|
-
if (element === elementToResize) {
|
|
139
|
-
resizeInfo.width = width;
|
|
140
|
-
}
|
|
141
|
-
dispatchResizeEvent(element);
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
const verticalPreviousSiblingSet = new Set();
|
|
145
|
-
const verticalNextSiblingSet = new Set();
|
|
146
|
-
const minHeightMap = new Map();
|
|
147
|
-
const heightMap = new Map();
|
|
148
|
-
const currentHeightMap = new Map();
|
|
149
|
-
const setHeight = (element, height) => {
|
|
150
|
-
if (currentHeightMap.get(element) === height) {
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
element.style.height = `${height}px`;
|
|
154
|
-
currentHeightMap.set(element, height);
|
|
155
|
-
if (element === elementToResize) {
|
|
156
|
-
resizeInfo.height = height;
|
|
157
|
-
}
|
|
158
|
-
dispatchResizeEvent(element);
|
|
159
|
-
};
|
|
160
|
-
const saveHeight = (element) => {
|
|
161
|
-
const height = getHeight(element);
|
|
162
|
-
heightMap.set(element, height);
|
|
163
|
-
currentHeightMap.set(element, height);
|
|
164
|
-
return height;
|
|
165
|
-
};
|
|
166
|
-
const setHeightAsPercentage = (element, height) => {
|
|
167
|
-
currentHeightMap.set(element, height);
|
|
168
|
-
const ratio = height / availableHeight;
|
|
169
|
-
// const roundedRatio = Math.round(ratio * 10000) / 10000;
|
|
170
|
-
const percentage = ratio * 100;
|
|
171
|
-
element.style.height = `${percentage}%`;
|
|
172
|
-
if (element === elementToResize) {
|
|
173
|
-
resizeInfo.height = height;
|
|
174
|
-
}
|
|
175
|
-
dispatchResizeEvent(element);
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
size_and_min_size: {
|
|
179
|
-
if (resizeDirection.x) {
|
|
180
|
-
const width = saveWidth(elementToResize);
|
|
181
|
-
resizeInfo.widthAtStart = width;
|
|
182
|
-
resizeInfo.width = width;
|
|
183
|
-
const minWidth = getMinWidth(elementToResize, availableWidth);
|
|
184
|
-
minWidthMap.set(elementToResize, minWidth);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if (resizeDirection.y) {
|
|
188
|
-
const height = saveHeight(elementToResize);
|
|
189
|
-
resizeInfo.heightAtStart = height;
|
|
190
|
-
resizeInfo.height = height;
|
|
191
|
-
const minHeight = getMinHeight(elementToResize, availableHeight);
|
|
192
|
-
minHeightMap.set(elementToResize, minHeight);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const horizontallyResizableElementSet = new Set();
|
|
197
|
-
const verticallyResizableElementSet = new Set();
|
|
198
|
-
const detectResizableDirections = (element) => {
|
|
199
|
-
const elementResizeDirection = getResizeDirection(element);
|
|
200
|
-
if (elementResizeDirection.x) {
|
|
201
|
-
horizontallyResizableElementSet.add(element);
|
|
202
|
-
}
|
|
203
|
-
if (elementResizeDirection.y) {
|
|
204
|
-
verticallyResizableElementSet.add(element);
|
|
205
|
-
}
|
|
206
|
-
return elementResizeDirection.x || elementResizeDirection.y;
|
|
207
|
-
};
|
|
208
|
-
const detectResizableSibling = (sibling, resizableElementSet) => {
|
|
209
|
-
if (detectResizableDirections(sibling)) {
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
const computedStyle = window.getComputedStyle(sibling);
|
|
213
|
-
if (computedStyle.flexGrow === "1") {
|
|
214
|
-
resizableElementSet.add(sibling);
|
|
215
|
-
}
|
|
216
|
-
};
|
|
217
|
-
detectResizableDirections(elementToResize);
|
|
218
|
-
|
|
219
|
-
siblings: {
|
|
220
|
-
const parentElementComputedStyle = window.getComputedStyle(parentElement);
|
|
221
|
-
if (resizeDirection.x) {
|
|
222
|
-
horizontallyResizableElementSet.add(elementToResize);
|
|
223
|
-
if (
|
|
224
|
-
parentElementComputedStyle.display === "flex" &&
|
|
225
|
-
parentElementComputedStyle.flexDirection === "row"
|
|
226
|
-
) {
|
|
227
|
-
prev_siblings: {
|
|
228
|
-
let previousSibling = elementToResize.previousElementSibling;
|
|
229
|
-
while (previousSibling) {
|
|
230
|
-
if (canTakeSize(previousSibling)) {
|
|
231
|
-
minWidthMap.set(
|
|
232
|
-
previousSibling,
|
|
233
|
-
getMinWidth(previousSibling, availableWidth),
|
|
234
|
-
);
|
|
235
|
-
saveWidth(previousSibling);
|
|
236
|
-
horizontalPreviousSiblingSet.add(previousSibling);
|
|
237
|
-
}
|
|
238
|
-
detectResizableSibling(
|
|
239
|
-
previousSibling,
|
|
240
|
-
horizontallyResizableElementSet,
|
|
241
|
-
);
|
|
242
|
-
previousSibling = previousSibling.previousElementSibling;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
next_siblings: {
|
|
246
|
-
let nextSibling = elementToResize.nextElementSibling;
|
|
247
|
-
while (nextSibling) {
|
|
248
|
-
if (canTakeSize(nextSibling)) {
|
|
249
|
-
minWidthMap.set(
|
|
250
|
-
nextSibling,
|
|
251
|
-
getMinWidth(nextSibling, availableWidth),
|
|
252
|
-
);
|
|
253
|
-
saveWidth(nextSibling);
|
|
254
|
-
horizontalNextSiblingSet.add(nextSibling);
|
|
255
|
-
}
|
|
256
|
-
detectResizableSibling(
|
|
257
|
-
nextSibling,
|
|
258
|
-
horizontallyResizableElementSet,
|
|
259
|
-
);
|
|
260
|
-
nextSibling = nextSibling.nextElementSibling;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (resizeDirection.y) {
|
|
267
|
-
verticallyResizableElementSet.add(elementToResize);
|
|
268
|
-
if (
|
|
269
|
-
parentElementComputedStyle.display === "flex" &&
|
|
270
|
-
parentElementComputedStyle.flexDirection === "column"
|
|
271
|
-
) {
|
|
272
|
-
prev_siblings: {
|
|
273
|
-
let previousSibling = elementToResize.previousElementSibling;
|
|
274
|
-
while (previousSibling) {
|
|
275
|
-
if (canTakeSize(previousSibling)) {
|
|
276
|
-
minHeightMap.set(
|
|
277
|
-
previousSibling,
|
|
278
|
-
getMinHeight(previousSibling, availableHeight),
|
|
279
|
-
);
|
|
280
|
-
saveHeight(previousSibling);
|
|
281
|
-
verticalPreviousSiblingSet.add(previousSibling);
|
|
282
|
-
}
|
|
283
|
-
detectResizableSibling(
|
|
284
|
-
previousSibling,
|
|
285
|
-
verticallyResizableElementSet,
|
|
286
|
-
);
|
|
287
|
-
previousSibling = previousSibling.previousElementSibling;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
next_siblings: {
|
|
291
|
-
let nextSibling = elementToResize.nextElementSibling;
|
|
292
|
-
while (nextSibling) {
|
|
293
|
-
if (canTakeSize(nextSibling)) {
|
|
294
|
-
minHeightMap.set(
|
|
295
|
-
nextSibling,
|
|
296
|
-
getMinHeight(nextSibling, availableHeight),
|
|
297
|
-
);
|
|
298
|
-
saveHeight(nextSibling);
|
|
299
|
-
verticalNextSiblingSet.add(nextSibling);
|
|
300
|
-
}
|
|
301
|
-
detectResizableSibling(nextSibling, verticallyResizableElementSet);
|
|
302
|
-
nextSibling = nextSibling.nextElementSibling;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
const dispatchResizeStartEvent = (element) => {
|
|
310
|
-
const resizeStartEventDetail = {
|
|
311
|
-
availableWidth,
|
|
312
|
-
availableHeight,
|
|
313
|
-
widthAtStart: widthMap.get(element),
|
|
314
|
-
heightAtStart: heightMap.get(element),
|
|
315
|
-
width: currentWidthMap.get(element),
|
|
316
|
-
height: currentHeightMap.get(element),
|
|
317
|
-
};
|
|
318
|
-
|
|
319
|
-
const resizeStartEvent = new CustomEvent("resizestart", {
|
|
320
|
-
detail: resizeStartEventDetail,
|
|
321
|
-
});
|
|
322
|
-
element.dispatchEvent(resizeStartEvent);
|
|
323
|
-
};
|
|
324
|
-
const dispatchResizeEvent = (element) => {
|
|
325
|
-
const resizeEventDetail = {
|
|
326
|
-
availableWidth,
|
|
327
|
-
availableHeight,
|
|
328
|
-
widthAtStart: widthMap.get(element),
|
|
329
|
-
heightAtStart: heightMap.get(element),
|
|
330
|
-
width: currentWidthMap.get(element),
|
|
331
|
-
height: currentHeightMap.get(element),
|
|
332
|
-
};
|
|
333
|
-
|
|
334
|
-
const resizeEvent = new CustomEvent("resize", {
|
|
335
|
-
detail: resizeEventDetail,
|
|
336
|
-
});
|
|
337
|
-
element.dispatchEvent(resizeEvent);
|
|
338
|
-
};
|
|
339
|
-
const dispatchResizeEndEvent = (element) => {
|
|
340
|
-
const resizeEndEventDetail = {
|
|
341
|
-
availableWidth,
|
|
342
|
-
availableHeight,
|
|
343
|
-
widthAtStart: widthMap.get(element),
|
|
344
|
-
heightAtStart: heightMap.get(element),
|
|
345
|
-
width: currentWidthMap.get(element),
|
|
346
|
-
height: currentHeightMap.get(element),
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
const resizeEndEvent = new CustomEvent("resizeend", {
|
|
350
|
-
detail: resizeEndEventDetail,
|
|
351
|
-
});
|
|
352
|
-
element.dispatchEvent(resizeEndEvent);
|
|
353
|
-
};
|
|
354
|
-
|
|
355
|
-
const computeSizeTransformMap = ({
|
|
356
|
-
positionDelta,
|
|
357
|
-
resizableElementSet,
|
|
358
|
-
previousSiblingSet,
|
|
359
|
-
nextSiblingSet,
|
|
360
|
-
sizeMap,
|
|
361
|
-
minSizeMap,
|
|
362
|
-
}) => {
|
|
363
|
-
if (positionDelta === 0) {
|
|
364
|
-
return null;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
let spaceRemaining = 0;
|
|
368
|
-
const sizeTransformMap = new Map();
|
|
369
|
-
const requestShrink = (element, shrinkRequested) => {
|
|
370
|
-
if (!resizableElementSet.has(element)) {
|
|
371
|
-
return 0;
|
|
372
|
-
}
|
|
373
|
-
const minSize = minSizeMap.get(element);
|
|
374
|
-
const size = sizeMap.get(element);
|
|
375
|
-
const sizeAfterShrink = size - shrinkRequested;
|
|
376
|
-
|
|
377
|
-
if (sizeAfterShrink <= minSize) {
|
|
378
|
-
const actualShrink = size - minSize;
|
|
379
|
-
sizeTransformMap.set(element, -actualShrink);
|
|
380
|
-
spaceRemaining += actualShrink;
|
|
381
|
-
return actualShrink;
|
|
382
|
-
}
|
|
383
|
-
sizeTransformMap.set(element, -shrinkRequested);
|
|
384
|
-
spaceRemaining += shrinkRequested;
|
|
385
|
-
return shrinkRequested;
|
|
386
|
-
};
|
|
387
|
-
const requestGrow = (element, growRequested) => {
|
|
388
|
-
if (!resizableElementSet.has(element)) {
|
|
389
|
-
return 0;
|
|
390
|
-
}
|
|
391
|
-
if (spaceRemaining === 0) {
|
|
392
|
-
return 0;
|
|
393
|
-
}
|
|
394
|
-
if (growRequested > spaceRemaining) {
|
|
395
|
-
const actualGrow = spaceRemaining;
|
|
396
|
-
sizeTransformMap.set(element, spaceRemaining);
|
|
397
|
-
spaceRemaining = 0;
|
|
398
|
-
return actualGrow;
|
|
399
|
-
}
|
|
400
|
-
sizeTransformMap.set(element, growRequested);
|
|
401
|
-
spaceRemaining -= growRequested;
|
|
402
|
-
return growRequested;
|
|
403
|
-
};
|
|
404
|
-
const stealSpaceFromSiblings = (siblingSet, spaceToSteal) => {
|
|
405
|
-
let spaceStolen = 0;
|
|
406
|
-
let remainingSpaceToSteal = spaceToSteal;
|
|
407
|
-
for (const sibling of siblingSet) {
|
|
408
|
-
const shrink = requestShrink(sibling, remainingSpaceToSteal);
|
|
409
|
-
if (!shrink) {
|
|
410
|
-
continue;
|
|
411
|
-
}
|
|
412
|
-
spaceStolen += shrink;
|
|
413
|
-
remainingSpaceToSteal -= shrink;
|
|
414
|
-
if (remainingSpaceToSteal <= 0) {
|
|
415
|
-
break;
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
return spaceStolen;
|
|
419
|
-
};
|
|
420
|
-
const giveSpaceToSiblings = (siblingSet, spaceToGive) => {
|
|
421
|
-
let spaceGiven = 0;
|
|
422
|
-
let remainingSpaceToGive = spaceToGive;
|
|
423
|
-
for (const sibling of siblingSet) {
|
|
424
|
-
const grow = requestGrow(sibling, remainingSpaceToGive);
|
|
425
|
-
if (!grow) {
|
|
426
|
-
continue;
|
|
427
|
-
}
|
|
428
|
-
spaceGiven += grow;
|
|
429
|
-
remainingSpaceToGive -= grow;
|
|
430
|
-
if (remainingSpaceToGive <= 0) {
|
|
431
|
-
break;
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
return spaceGiven;
|
|
435
|
-
};
|
|
436
|
-
|
|
437
|
-
if (positionDelta > 0) {
|
|
438
|
-
let remainingMoveToApply = positionDelta;
|
|
439
|
-
if (nextSiblingSet.size === 0) {
|
|
440
|
-
if (previousSiblingSet.size === 0) {
|
|
441
|
-
spaceRemaining = availableHeight;
|
|
442
|
-
requestGrow(elementToResize, remainingMoveToApply);
|
|
443
|
-
return sizeTransformMap;
|
|
444
|
-
}
|
|
445
|
-
const shrink = requestShrink(elementToResize, remainingMoveToApply);
|
|
446
|
-
if (shrink) {
|
|
447
|
-
giveSpaceToSiblings(previousSiblingSet, shrink);
|
|
448
|
-
}
|
|
449
|
-
return sizeTransformMap;
|
|
450
|
-
}
|
|
451
|
-
const spaceStolenNext = stealSpaceFromSiblings(
|
|
452
|
-
nextSiblingSet,
|
|
453
|
-
remainingMoveToApply,
|
|
454
|
-
);
|
|
455
|
-
if (spaceStolenNext) {
|
|
456
|
-
sizeTransformMap.set(elementToResize, spaceStolenNext);
|
|
457
|
-
return sizeTransformMap;
|
|
458
|
-
}
|
|
459
|
-
const shrink = requestShrink(elementToResize, remainingMoveToApply);
|
|
460
|
-
if (shrink) {
|
|
461
|
-
giveSpaceToSiblings(previousSiblingSet, shrink);
|
|
462
|
-
}
|
|
463
|
-
return sizeTransformMap;
|
|
464
|
-
}
|
|
465
|
-
let remainingMoveToApply = -positionDelta;
|
|
466
|
-
if (previousSiblingSet.size === 0) {
|
|
467
|
-
const shrink = requestShrink(elementToResize, remainingMoveToApply);
|
|
468
|
-
if (shrink) {
|
|
469
|
-
giveSpaceToSiblings(nextSiblingSet, shrink);
|
|
470
|
-
}
|
|
471
|
-
return sizeTransformMap;
|
|
472
|
-
}
|
|
473
|
-
const spaceStolenPrev = stealSpaceFromSiblings(
|
|
474
|
-
previousSiblingSet,
|
|
475
|
-
remainingMoveToApply,
|
|
476
|
-
);
|
|
477
|
-
if (spaceStolenPrev) {
|
|
478
|
-
sizeTransformMap.set(elementToResize, spaceStolenPrev);
|
|
479
|
-
return sizeTransformMap;
|
|
480
|
-
}
|
|
481
|
-
const shrink = requestShrink(elementToResize, remainingMoveToApply);
|
|
482
|
-
if (shrink) {
|
|
483
|
-
giveSpaceToSiblings(nextSiblingSet, shrink);
|
|
484
|
-
}
|
|
485
|
-
return sizeTransformMap;
|
|
486
|
-
};
|
|
487
|
-
const syncSizesWithPositionDelta = ({
|
|
488
|
-
positionDelta,
|
|
489
|
-
resizableElementSet,
|
|
490
|
-
previousSiblingSet,
|
|
491
|
-
nextSiblingSet,
|
|
492
|
-
minSizeMap,
|
|
493
|
-
sizeMap,
|
|
494
|
-
setSizeAsPercentage,
|
|
495
|
-
setSize,
|
|
496
|
-
isEnd,
|
|
497
|
-
} = {}) => {
|
|
498
|
-
const sizeTransformMap = computeSizeTransformMap({
|
|
499
|
-
positionDelta,
|
|
500
|
-
resizableElementSet,
|
|
501
|
-
previousSiblingSet,
|
|
502
|
-
nextSiblingSet,
|
|
503
|
-
minSizeMap,
|
|
504
|
-
sizeMap,
|
|
505
|
-
});
|
|
506
|
-
if (!sizeTransformMap) {
|
|
507
|
-
return null;
|
|
508
|
-
}
|
|
509
|
-
for (const element of [
|
|
510
|
-
...previousSiblingSet,
|
|
511
|
-
elementToResize,
|
|
512
|
-
...nextSiblingSet,
|
|
513
|
-
]) {
|
|
514
|
-
if (!resizableElementSet.has(element)) {
|
|
515
|
-
continue;
|
|
516
|
-
}
|
|
517
|
-
const size = sizeMap.get(element);
|
|
518
|
-
const delta = sizeTransformMap.get(element);
|
|
519
|
-
const newSize = delta ? size + delta : size;
|
|
520
|
-
if (isEnd && !elementToResize.hasAttribute("data-resize-absolute")) {
|
|
521
|
-
setSizeAsPercentage(element, newSize);
|
|
522
|
-
} else {
|
|
523
|
-
setSize(element, newSize);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
return sizeTransformMap;
|
|
527
|
-
};
|
|
528
|
-
const syncHorizontalSizesWithPositionDelta = (
|
|
529
|
-
positionDelta,
|
|
530
|
-
{ isEnd } = {},
|
|
531
|
-
) =>
|
|
532
|
-
syncSizesWithPositionDelta({
|
|
533
|
-
positionDelta,
|
|
534
|
-
resizableElementSet: horizontallyResizableElementSet,
|
|
535
|
-
previousSiblingSet: horizontalPreviousSiblingSet,
|
|
536
|
-
nextSiblingSet: horizontalNextSiblingSet,
|
|
537
|
-
minSizeMap: minWidthMap,
|
|
538
|
-
sizeMap: widthMap,
|
|
539
|
-
setSizeAsPercentage: setWidthAsPercentage,
|
|
540
|
-
setSize: setWidth,
|
|
541
|
-
isEnd,
|
|
542
|
-
});
|
|
543
|
-
const syncVerticalSizesWithPositionDelta = (positionDelta, { isEnd } = {}) =>
|
|
544
|
-
syncSizesWithPositionDelta({
|
|
545
|
-
positionDelta,
|
|
546
|
-
resizableElementSet: verticallyResizableElementSet,
|
|
547
|
-
previousSiblingSet: verticalPreviousSiblingSet,
|
|
548
|
-
nextSiblingSet: verticalNextSiblingSet,
|
|
549
|
-
minSizeMap: minHeightMap,
|
|
550
|
-
sizeMap: heightMap,
|
|
551
|
-
setSizeAsPercentage: setHeightAsPercentage,
|
|
552
|
-
setSize: setHeight,
|
|
553
|
-
isEnd,
|
|
554
|
-
});
|
|
555
|
-
|
|
556
|
-
const handleMouseMove = (e) => {
|
|
557
|
-
if (resizeDirection.x) {
|
|
558
|
-
resizeInfo.x = e.clientX;
|
|
559
|
-
resizeInfo.xMove = resizeInfo.x - xAtStart;
|
|
560
|
-
syncHorizontalSizesWithPositionDelta(resizeInfo.xMove);
|
|
561
|
-
}
|
|
562
|
-
if (resizeDirection.y) {
|
|
563
|
-
resizeInfo.y = e.clientY;
|
|
564
|
-
resizeInfo.yMove = resizeInfo.y - yAtStart;
|
|
565
|
-
syncVerticalSizesWithPositionDelta(resizeInfo.yMove);
|
|
566
|
-
}
|
|
567
|
-
};
|
|
568
|
-
const handleMouseUp = (e) => {
|
|
569
|
-
e.preventDefault();
|
|
570
|
-
if (resizeDirection.x) {
|
|
571
|
-
resizeInfo.x = e.clientX;
|
|
572
|
-
resizeInfo.xMove = resizeInfo.x - xAtStart;
|
|
573
|
-
syncHorizontalSizesWithPositionDelta(resizeInfo.xMove, { isEnd: true });
|
|
574
|
-
}
|
|
575
|
-
if (resizeDirection.y) {
|
|
576
|
-
resizeInfo.y = e.clientY;
|
|
577
|
-
resizeInfo.yMove = resizeInfo.y - yAtStart;
|
|
578
|
-
syncVerticalSizesWithPositionDelta(resizeInfo.yMove, { isEnd: true });
|
|
579
|
-
}
|
|
580
|
-
for (const endCallback of endCallbackSet) {
|
|
581
|
-
endCallback();
|
|
582
|
-
}
|
|
583
|
-
dispatchResizeEndEvent(elementToResize);
|
|
584
|
-
};
|
|
585
|
-
|
|
586
|
-
const backdrop = document.createElement("div");
|
|
587
|
-
backdrop.style.position = "fixed";
|
|
588
|
-
backdrop.style.inset = "0";
|
|
589
|
-
backdrop.style.cursor =
|
|
590
|
-
resizeDirection.x && resizeDirection.y
|
|
591
|
-
? "nwse-resize"
|
|
592
|
-
: resizeDirection.x
|
|
593
|
-
? "ew-resize"
|
|
594
|
-
: "ns-resize";
|
|
595
|
-
backdrop.style.userSelect = "none";
|
|
596
|
-
document.body.appendChild(backdrop);
|
|
597
|
-
document.addEventListener("mousemove", handleMouseMove);
|
|
598
|
-
document.addEventListener("mouseup", handleMouseUp);
|
|
599
|
-
elementToResize.setAttribute("data-resizing", "");
|
|
600
|
-
endCallbackSet.add(() => {
|
|
601
|
-
document.removeEventListener("mousemove", handleMouseMove);
|
|
602
|
-
document.removeEventListener("mouseup", handleMouseUp);
|
|
603
|
-
document.body.removeChild(backdrop);
|
|
604
|
-
elementToResize.removeAttribute("data-resizing");
|
|
605
|
-
});
|
|
606
|
-
dispatchResizeStartEvent(elementToResize);
|
|
607
|
-
};
|
|
608
|
-
|
|
609
|
-
const getResizeDirection = (element) => {
|
|
610
|
-
const direction = element.getAttribute("data-resize");
|
|
611
|
-
const x = direction === "horizontal" || direction === "both";
|
|
612
|
-
const y = direction === "vertical" || direction === "both";
|
|
613
|
-
return { x, y };
|
|
614
|
-
};
|
|
615
|
-
|
|
616
|
-
document.addEventListener(
|
|
617
|
-
"mousedown",
|
|
618
|
-
(e) => {
|
|
619
|
-
start(e);
|
|
620
|
-
},
|
|
621
|
-
{ capture: true },
|
|
622
|
-
);
|
|
623
|
-
|
|
624
|
-
addAttributeEffect("data-resize", (element) => {
|
|
625
|
-
const direction = element.getAttribute("data-resize");
|
|
626
|
-
const horizontalResizeEnabled =
|
|
627
|
-
direction === "horizontal" || direction === "both";
|
|
628
|
-
const verticalResizeEnabled =
|
|
629
|
-
direction === "vertical" || direction === "both";
|
|
630
|
-
if (!horizontalResizeEnabled && !verticalResizeEnabled) {
|
|
631
|
-
return null;
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
const cleanupCallbackSet = new Set();
|
|
635
|
-
|
|
636
|
-
// disable flex stuff to ensure element can be resized
|
|
637
|
-
force_resizable: {
|
|
638
|
-
const distributeSpace = (
|
|
639
|
-
element,
|
|
640
|
-
{ getAvailableSpace, getSize, setSize },
|
|
641
|
-
) => {
|
|
642
|
-
const availableSpace = getAvailableSpace(element);
|
|
643
|
-
const childMap = new Map();
|
|
644
|
-
|
|
645
|
-
let totalSpace = 0;
|
|
646
|
-
const childTakingFreeSpaceSet = new Set();
|
|
647
|
-
for (const child of element.parentElement.children) {
|
|
648
|
-
if (child.hasAttribute("data-resize")) {
|
|
649
|
-
childTakingFreeSpaceSet.add(child);
|
|
650
|
-
}
|
|
651
|
-
if (canTakeSize(child)) {
|
|
652
|
-
const size = getSize(child);
|
|
653
|
-
childMap.set(child, size);
|
|
654
|
-
totalSpace += size;
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
const remainingSpace = availableSpace - totalSpace;
|
|
658
|
-
if (remainingSpace > 0) {
|
|
659
|
-
for (const child of childTakingFreeSpaceSet) {
|
|
660
|
-
const size = childMap.get(child);
|
|
661
|
-
const ratio = size / totalSpace;
|
|
662
|
-
const additionalSpace = remainingSpace * ratio;
|
|
663
|
-
const newSize = size + additionalSpace;
|
|
664
|
-
setSize(child, newSize);
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
};
|
|
668
|
-
|
|
669
|
-
if (horizontalResizeEnabled) {
|
|
670
|
-
distributeSpace(element, {
|
|
671
|
-
getAvailableSpace: getAvailableWidth,
|
|
672
|
-
getSize: getWidth,
|
|
673
|
-
setSize: (element, width) => {
|
|
674
|
-
element.style.width = `${width}px`;
|
|
675
|
-
},
|
|
676
|
-
});
|
|
677
|
-
}
|
|
678
|
-
if (verticalResizeEnabled) {
|
|
679
|
-
distributeSpace(element, {
|
|
680
|
-
getAvailableSpace: getAvailableHeight,
|
|
681
|
-
getSize: getHeight,
|
|
682
|
-
setSize: (element, height) => {
|
|
683
|
-
element.style.height = `${height}px`;
|
|
684
|
-
},
|
|
685
|
-
});
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
return () => {
|
|
690
|
-
for (const cleanupCallback of cleanupCallbackSet) {
|
|
691
|
-
cleanupCallback();
|
|
692
|
-
}
|
|
693
|
-
cleanupCallbackSet.clear();
|
|
694
|
-
};
|
|
695
|
-
});
|