@schukai/monster 4.141.3 → 4.142.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/package.json +1 -1
- package/source/components/datatable/pagination.mjs +9 -3
- package/source/components/form/control-bar.mjs +55 -35
- package/source/components/form/select.mjs +190 -38
- package/source/components/form/style/control-bar.pcss +13 -0
- package/source/components/form/style/select.pcss +6 -0
- package/source/components/form/stylesheet/control-bar.mjs +1 -1
- package/source/components/form/stylesheet/select.mjs +1 -1
- package/source/components/form/util/floating-layout-queue.mjs +228 -0
- package/source/components/form/util/floating-ui.mjs +47 -8
- package/source/components/layout/panel.mjs +65 -12
- package/source/components/layout/split-panel.mjs +62 -47
- package/test/cases/components/form/button-bar.mjs +114 -2
- package/test/cases/components/form/select.mjs +488 -1
- package/test/cases/components/layout/panel.mjs +87 -73
- package/test/cases/components/layout/slit-panel.mjs +121 -73
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © Volker Schukai and all contributing authors, {{copyRightYear}}. All rights reserved.
|
|
3
|
+
* Node module: @schukai/monster
|
|
4
|
+
*
|
|
5
|
+
* SPDX-License-Identifier: AGPL-3.0
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { getGlobal } from "../../../types/global.mjs";
|
|
9
|
+
|
|
10
|
+
export {
|
|
11
|
+
FLOATING_LAYOUT_REASON,
|
|
12
|
+
cancelFloatingLayout,
|
|
13
|
+
enqueueFloatingLayout,
|
|
14
|
+
flushFloatingLayoutQueueForTests,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const FLOATING_LAYOUT_REASON = Object.freeze({
|
|
18
|
+
OPEN: 1 << 0,
|
|
19
|
+
RESIZE: 1 << 1,
|
|
20
|
+
CONTENT: 1 << 2,
|
|
21
|
+
POSITION: 1 << 3,
|
|
22
|
+
VIEWPORT: 1 << 4,
|
|
23
|
+
SETTLE: 1 << 5,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const jobs = new Map();
|
|
27
|
+
let queueFrame = null;
|
|
28
|
+
let queueTimeout = null;
|
|
29
|
+
let flushing = false;
|
|
30
|
+
|
|
31
|
+
function enqueueFloatingLayout({
|
|
32
|
+
popperElement,
|
|
33
|
+
owner = null,
|
|
34
|
+
reason = FLOATING_LAYOUT_REASON.POSITION,
|
|
35
|
+
measure = undefined,
|
|
36
|
+
mutate = undefined,
|
|
37
|
+
position = undefined,
|
|
38
|
+
isActive = undefined,
|
|
39
|
+
onError = undefined,
|
|
40
|
+
} = {}) {
|
|
41
|
+
if (!(popperElement instanceof HTMLElement)) {
|
|
42
|
+
return Promise.resolve();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let job = jobs.get(popperElement);
|
|
46
|
+
if (!job) {
|
|
47
|
+
job = createJob(popperElement);
|
|
48
|
+
jobs.set(popperElement, job);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
job.owner = owner || job.owner;
|
|
52
|
+
job.reasons |= reason;
|
|
53
|
+
if (measure instanceof Function) {
|
|
54
|
+
job.measure = measure;
|
|
55
|
+
}
|
|
56
|
+
if (mutate instanceof Function) {
|
|
57
|
+
job.mutate = mutate;
|
|
58
|
+
}
|
|
59
|
+
if (position instanceof Function) {
|
|
60
|
+
job.position = position;
|
|
61
|
+
}
|
|
62
|
+
job.isActive = isActive instanceof Function ? isActive : job.isActive;
|
|
63
|
+
job.onError = onError instanceof Function ? onError : job.onError;
|
|
64
|
+
|
|
65
|
+
if (job.running) {
|
|
66
|
+
job.pending = true;
|
|
67
|
+
return Promise.resolve();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
scheduleQueueFlush();
|
|
71
|
+
return job.promise;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function cancelFloatingLayout(popperElement) {
|
|
75
|
+
const job = jobs.get(popperElement);
|
|
76
|
+
if (!job) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
job.cancelled = true;
|
|
81
|
+
job.resolve();
|
|
82
|
+
jobs.delete(popperElement);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function flushFloatingLayoutQueueForTests() {
|
|
86
|
+
cancelQueueFrame();
|
|
87
|
+
return flushQueue();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function createJob(popperElement) {
|
|
91
|
+
let resolve;
|
|
92
|
+
const promise = new Promise((res) => {
|
|
93
|
+
resolve = res;
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
popperElement,
|
|
98
|
+
owner: null,
|
|
99
|
+
reasons: 0,
|
|
100
|
+
measure: null,
|
|
101
|
+
mutate: null,
|
|
102
|
+
position: null,
|
|
103
|
+
isActive: null,
|
|
104
|
+
onError: null,
|
|
105
|
+
running: false,
|
|
106
|
+
pending: false,
|
|
107
|
+
cancelled: false,
|
|
108
|
+
promise,
|
|
109
|
+
resolve,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function scheduleQueueFlush() {
|
|
114
|
+
if (queueFrame !== null) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const globalObject = getGlobal();
|
|
119
|
+
const schedule =
|
|
120
|
+
globalObject?.requestAnimationFrame instanceof Function
|
|
121
|
+
? globalObject.requestAnimationFrame.bind(globalObject)
|
|
122
|
+
: (callback) => globalObject.setTimeout(callback, 16);
|
|
123
|
+
|
|
124
|
+
const runScheduledFlush = () => {
|
|
125
|
+
if (queueFrame === null && queueTimeout === null) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
queueFrame = null;
|
|
129
|
+
if (queueTimeout !== null) {
|
|
130
|
+
globalObject.clearTimeout(queueTimeout);
|
|
131
|
+
queueTimeout = null;
|
|
132
|
+
}
|
|
133
|
+
flushQueue().catch((error) => {
|
|
134
|
+
setTimeout(() => {
|
|
135
|
+
throw error;
|
|
136
|
+
}, 0);
|
|
137
|
+
});
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
queueFrame = schedule(runScheduledFlush);
|
|
141
|
+
queueTimeout = globalObject.setTimeout(runScheduledFlush, 32);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function cancelQueueFrame() {
|
|
145
|
+
if (queueFrame === null && queueTimeout === null) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const globalObject = getGlobal();
|
|
150
|
+
if (
|
|
151
|
+
queueFrame !== null &&
|
|
152
|
+
globalObject?.cancelAnimationFrame instanceof Function
|
|
153
|
+
) {
|
|
154
|
+
globalObject.cancelAnimationFrame(queueFrame);
|
|
155
|
+
} else if (queueFrame !== null) {
|
|
156
|
+
globalObject.clearTimeout(queueFrame);
|
|
157
|
+
}
|
|
158
|
+
queueFrame = null;
|
|
159
|
+
if (queueTimeout !== null) {
|
|
160
|
+
globalObject.clearTimeout(queueTimeout);
|
|
161
|
+
queueTimeout = null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async function flushQueue() {
|
|
166
|
+
if (flushing) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
flushing = true;
|
|
171
|
+
const currentJobs = Array.from(jobs.values());
|
|
172
|
+
|
|
173
|
+
for (const job of currentJobs) {
|
|
174
|
+
await flushJob(job);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
flushing = false;
|
|
178
|
+
|
|
179
|
+
if (Array.from(jobs.values()).some((job) => job.pending && !job.cancelled)) {
|
|
180
|
+
for (const job of jobs.values()) {
|
|
181
|
+
if (job.pending) {
|
|
182
|
+
job.pending = false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
scheduleQueueFlush();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async function flushJob(job) {
|
|
190
|
+
if (job.cancelled || !jobs.has(job.popperElement)) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const isActive =
|
|
195
|
+
job.isActive instanceof Function ? job.isActive(job.popperElement) : true;
|
|
196
|
+
if (!isActive) {
|
|
197
|
+
job.resolve();
|
|
198
|
+
jobs.delete(job.popperElement);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const reasons = job.reasons;
|
|
203
|
+
job.reasons = 0;
|
|
204
|
+
job.running = true;
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
const measurement =
|
|
208
|
+
job.measure instanceof Function ? job.measure(reasons) : undefined;
|
|
209
|
+
if (job.mutate instanceof Function) {
|
|
210
|
+
job.mutate(measurement, reasons);
|
|
211
|
+
}
|
|
212
|
+
if (job.position instanceof Function) {
|
|
213
|
+
await job.position(measurement, reasons);
|
|
214
|
+
}
|
|
215
|
+
} catch (error) {
|
|
216
|
+
if (job.onError instanceof Function) {
|
|
217
|
+
job.onError(error);
|
|
218
|
+
} else {
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
221
|
+
} finally {
|
|
222
|
+
job.running = false;
|
|
223
|
+
if (!job.pending && job.reasons === 0) {
|
|
224
|
+
job.resolve();
|
|
225
|
+
jobs.delete(job.popperElement);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
@@ -25,6 +25,11 @@ import {
|
|
|
25
25
|
} from "@floating-ui/dom";
|
|
26
26
|
import { isArray, isFunction, isObject, isString } from "../../../types/is.mjs";
|
|
27
27
|
import { Processing } from "../../../util/processing.mjs";
|
|
28
|
+
import {
|
|
29
|
+
FLOATING_LAYOUT_REASON,
|
|
30
|
+
cancelFloatingLayout,
|
|
31
|
+
enqueueFloatingLayout,
|
|
32
|
+
} from "./floating-layout-queue.mjs";
|
|
28
33
|
|
|
29
34
|
export {
|
|
30
35
|
applyAdaptiveFloatingElementSize,
|
|
@@ -55,7 +60,14 @@ function positionPopper(controlElement, popperElement, options) {
|
|
|
55
60
|
const config = normalizePopperConfig(options, controlElement, popperElement);
|
|
56
61
|
|
|
57
62
|
return new Processing(() => {
|
|
58
|
-
|
|
63
|
+
return enqueueFloatingLayout({
|
|
64
|
+
popperElement,
|
|
65
|
+
reason: FLOATING_LAYOUT_REASON.POSITION,
|
|
66
|
+
isActive: () => isPositionedPopperOpen(popperElement),
|
|
67
|
+
position: () => {
|
|
68
|
+
enableFloatingPositioning(controlElement, popperElement, config);
|
|
69
|
+
},
|
|
70
|
+
});
|
|
59
71
|
}).run();
|
|
60
72
|
}
|
|
61
73
|
|
|
@@ -87,8 +99,16 @@ function enableFloatingPositioning(controlElement, popperElement, config) {
|
|
|
87
99
|
return;
|
|
88
100
|
}
|
|
89
101
|
|
|
90
|
-
|
|
91
|
-
|
|
102
|
+
enqueueFloatingLayout({
|
|
103
|
+
popperElement,
|
|
104
|
+
reason:
|
|
105
|
+
FLOATING_LAYOUT_REASON.POSITION | FLOATING_LAYOUT_REASON.RESIZE,
|
|
106
|
+
isActive: () => isPositionedPopperOpen(popperElement),
|
|
107
|
+
position: () => {
|
|
108
|
+
runFloatingUpdateHook(popperElement);
|
|
109
|
+
syncFloatingPopover(controlElement, popperElement, config);
|
|
110
|
+
},
|
|
111
|
+
});
|
|
92
112
|
});
|
|
93
113
|
runFloatingUpdateHook(popperElement);
|
|
94
114
|
syncFloatingPopover(controlElement, popperElement, config);
|
|
@@ -165,6 +185,7 @@ function syncFloatingPopover(
|
|
|
165
185
|
}
|
|
166
186
|
|
|
167
187
|
function closePositionedPopper(popperElement) {
|
|
188
|
+
cancelFloatingLayout(popperElement);
|
|
168
189
|
stopAutoUpdate(popperElement);
|
|
169
190
|
cancelFloatingAppearanceFrame(popperElement);
|
|
170
191
|
delete popperElement.dataset.monsterAppearance;
|
|
@@ -189,7 +210,10 @@ function normalizePopperConfig(options, controlElement, popperElement) {
|
|
|
189
210
|
options,
|
|
190
211
|
);
|
|
191
212
|
|
|
192
|
-
if (
|
|
213
|
+
if (
|
|
214
|
+
config.boundaryElement !== null &&
|
|
215
|
+
!(config.boundaryElement instanceof HTMLElement)
|
|
216
|
+
) {
|
|
193
217
|
config.boundaryElement = resolveClippingBoundaryElement(
|
|
194
218
|
controlElement,
|
|
195
219
|
popperElement,
|
|
@@ -981,7 +1005,7 @@ function startAutoUpdate(controlElement, popperElement, callback) {
|
|
|
981
1005
|
autoUpdateCleanupMap.set(
|
|
982
1006
|
popperElement,
|
|
983
1007
|
autoUpdate(controlElement, popperElement, callback, {
|
|
984
|
-
elementResize:
|
|
1008
|
+
elementResize: false,
|
|
985
1009
|
layoutShift: false,
|
|
986
1010
|
}),
|
|
987
1011
|
);
|
|
@@ -1009,7 +1033,15 @@ function startFloatingResizeObserver(controlElement, popperElement, config) {
|
|
|
1009
1033
|
return;
|
|
1010
1034
|
}
|
|
1011
1035
|
|
|
1012
|
-
|
|
1036
|
+
enqueueFloatingLayout({
|
|
1037
|
+
popperElement,
|
|
1038
|
+
reason: FLOATING_LAYOUT_REASON.SETTLE,
|
|
1039
|
+
isActive: () => isPositionedPopperOpen(popperElement),
|
|
1040
|
+
position: () => {
|
|
1041
|
+
runFloatingUpdateHook(popperElement);
|
|
1042
|
+
syncFloatingPopover(controlElement, popperElement, config, false);
|
|
1043
|
+
},
|
|
1044
|
+
});
|
|
1013
1045
|
});
|
|
1014
1046
|
|
|
1015
1047
|
observer.observe(popperElement);
|
|
@@ -1038,8 +1070,15 @@ function scheduleSettlingPass(controlElement, popperElement, config) {
|
|
|
1038
1070
|
return;
|
|
1039
1071
|
}
|
|
1040
1072
|
|
|
1041
|
-
|
|
1042
|
-
|
|
1073
|
+
enqueueFloatingLayout({
|
|
1074
|
+
popperElement,
|
|
1075
|
+
reason: FLOATING_LAYOUT_REASON.SETTLE,
|
|
1076
|
+
isActive: () => isPositionedPopperOpen(popperElement),
|
|
1077
|
+
position: () => {
|
|
1078
|
+
runFloatingUpdateHook(popperElement);
|
|
1079
|
+
syncFloatingPopover(controlElement, popperElement, config, false);
|
|
1080
|
+
},
|
|
1081
|
+
});
|
|
1043
1082
|
});
|
|
1044
1083
|
|
|
1045
1084
|
settlingFrameMap.set(popperElement, frameId);
|
|
@@ -99,6 +99,25 @@ class Panel extends CustomElement {
|
|
|
99
99
|
calcHeight.call(this);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Get the height that fits this panel into the currently available viewport.
|
|
104
|
+
*
|
|
105
|
+
* @return {number}
|
|
106
|
+
*/
|
|
107
|
+
getMaximumHeight() {
|
|
108
|
+
return getMaximumPanelHeight.call(this);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Recalculate and apply the current maximum panel height.
|
|
113
|
+
*
|
|
114
|
+
* @return {Panel}
|
|
115
|
+
*/
|
|
116
|
+
recalculateHeight() {
|
|
117
|
+
calcHeight.call(this);
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
|
|
102
121
|
/**
|
|
103
122
|
* This method is called by the dom and should not be called directly.
|
|
104
123
|
*
|
|
@@ -145,11 +164,24 @@ class Panel extends CustomElement {
|
|
|
145
164
|
function calcHeight() {
|
|
146
165
|
this.style.boxSizing = "border-box";
|
|
147
166
|
|
|
148
|
-
|
|
149
|
-
if (height < 0) {
|
|
167
|
+
const height = getMaximumPanelHeight.call(this);
|
|
168
|
+
if (height < 0 || Number.isNaN(height)) {
|
|
150
169
|
return;
|
|
151
170
|
}
|
|
152
171
|
|
|
172
|
+
this.style.height = `${height}px`;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* @private
|
|
177
|
+
* @return {number}
|
|
178
|
+
*/
|
|
179
|
+
function getMaximumPanelHeight() {
|
|
180
|
+
let height = calculateMaximumHeight.call(this, this);
|
|
181
|
+
if (height < 0 || Number.isNaN(height)) {
|
|
182
|
+
return -1;
|
|
183
|
+
}
|
|
184
|
+
|
|
153
185
|
const parent =
|
|
154
186
|
this.parentNode instanceof HTMLElement ? this.parentNode : null;
|
|
155
187
|
const parentHeight = parent?.clientHeight || 0;
|
|
@@ -157,7 +189,7 @@ function calcHeight() {
|
|
|
157
189
|
height = Math.min(height, parentHeight);
|
|
158
190
|
}
|
|
159
191
|
|
|
160
|
-
|
|
192
|
+
return height;
|
|
161
193
|
}
|
|
162
194
|
|
|
163
195
|
/**
|
|
@@ -202,12 +234,18 @@ function calculateMaximumHeight(element) {
|
|
|
202
234
|
const boxShadowVertical = parseFloat(style.boxShadow.split(" ")[3] || 0);
|
|
203
235
|
|
|
204
236
|
// Accumulate values
|
|
205
|
-
totalBottomBorder += isNaN(borderBottomWidth)
|
|
237
|
+
totalBottomBorder += Number.isNaN(borderBottomWidth)
|
|
238
|
+
? 0
|
|
239
|
+
: borderBottomWidth;
|
|
206
240
|
totalBottomPadding +=
|
|
207
|
-
isNaN(paddingBottom) || boxSizing === "border-box"
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
241
|
+
Number.isNaN(paddingBottom) || boxSizing === "border-box"
|
|
242
|
+
? 0
|
|
243
|
+
: paddingBottom;
|
|
244
|
+
totalBottomMargin += Number.isNaN(marginBottom) ? 0 : marginBottom;
|
|
245
|
+
totalOutlineHeight += Number.isNaN(outlineHeight) ? 0 : outlineHeight;
|
|
246
|
+
totalBoxShadowHeight += Number.isNaN(boxShadowVertical)
|
|
247
|
+
? 0
|
|
248
|
+
: boxShadowVertical;
|
|
211
249
|
|
|
212
250
|
currentElement = currentElement.parentNode || currentElement.host;
|
|
213
251
|
}
|
|
@@ -221,7 +259,7 @@ function calculateMaximumHeight(element) {
|
|
|
221
259
|
totalBottomMargin -
|
|
222
260
|
totalOutlineHeight -
|
|
223
261
|
totalBoxShadowHeight;
|
|
224
|
-
return maximumHeight +
|
|
262
|
+
return maximumHeight + getNumericOption.call(this, "heightAdjustment");
|
|
225
263
|
}
|
|
226
264
|
|
|
227
265
|
/**
|
|
@@ -234,7 +272,7 @@ function attachResizeObserver() {
|
|
|
234
272
|
try {
|
|
235
273
|
this[timerCallbackSymbol].touch();
|
|
236
274
|
return;
|
|
237
|
-
} catch
|
|
275
|
+
} catch {
|
|
238
276
|
delete this[timerCallbackSymbol];
|
|
239
277
|
}
|
|
240
278
|
}
|
|
@@ -244,8 +282,13 @@ function attachResizeObserver() {
|
|
|
244
282
|
});
|
|
245
283
|
});
|
|
246
284
|
|
|
247
|
-
|
|
248
|
-
|
|
285
|
+
if (this.ownerDocument.body instanceof Element) {
|
|
286
|
+
this[resizeObserverSymbol].observe(this.ownerDocument.body);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (this.ownerDocument.scrollingElement instanceof Element) {
|
|
290
|
+
this[resizeObserverSymbol].observe(this.ownerDocument.scrollingElement);
|
|
291
|
+
}
|
|
249
292
|
}
|
|
250
293
|
|
|
251
294
|
function disconnectResizeObserver() {
|
|
@@ -254,6 +297,16 @@ function disconnectResizeObserver() {
|
|
|
254
297
|
}
|
|
255
298
|
}
|
|
256
299
|
|
|
300
|
+
/**
|
|
301
|
+
* @private
|
|
302
|
+
* @param {string} name
|
|
303
|
+
* @return {number}
|
|
304
|
+
*/
|
|
305
|
+
function getNumericOption(name) {
|
|
306
|
+
const value = Number.parseFloat(this.getOption(name));
|
|
307
|
+
return Number.isNaN(value) ? 0 : value;
|
|
308
|
+
}
|
|
309
|
+
|
|
257
310
|
/**
|
|
258
311
|
* @private
|
|
259
312
|
* @return {Panel}
|
|
@@ -175,9 +175,9 @@ class SplitPanel extends CustomElement {
|
|
|
175
175
|
setDimension(dimension) {
|
|
176
176
|
// check if percent and greater than100
|
|
177
177
|
if (dimension.includes("%")) {
|
|
178
|
-
if (
|
|
178
|
+
if (parseFloat(dimension) > 100) {
|
|
179
179
|
throw new Error("dimension must be less than 100%");
|
|
180
|
-
} else if (
|
|
180
|
+
} else if (parseFloat(dimension) < 0) {
|
|
181
181
|
throw new Error("dimension must be greater than 0%");
|
|
182
182
|
}
|
|
183
183
|
}
|
|
@@ -217,17 +217,19 @@ class SplitPanel extends CustomElement {
|
|
|
217
217
|
function applyPanelDimensions() {
|
|
218
218
|
const splitType = this.getOption("splitType");
|
|
219
219
|
const dimension = this[internalSymbol].getSubject().currentDimension;
|
|
220
|
+
const draggerSize = getDraggerSize.call(this);
|
|
220
221
|
|
|
221
222
|
if (splitType === TYPE_VERTICAL) {
|
|
222
223
|
this[startPanelElementSymbol].style.width = dimension;
|
|
223
|
-
this[endPanelElementSymbol].style.width =
|
|
224
|
+
this[endPanelElementSymbol].style.width =
|
|
225
|
+
`calc(100% - ${dimension} - ${draggerSize})`;
|
|
224
226
|
this[draggerElementSymbol].style.cursor = "ew-resize";
|
|
225
227
|
this[splitScreenElementSymbol].classList.add("vertical");
|
|
226
228
|
this[splitScreenElementSymbol].classList.remove("horizontal");
|
|
227
229
|
} else {
|
|
228
230
|
this[startPanelElementSymbol].style.height = dimension;
|
|
229
231
|
this[endPanelElementSymbol].style.height =
|
|
230
|
-
`calc(100% - ${dimension} -
|
|
232
|
+
`calc(100% - ${dimension} - ${draggerSize})`;
|
|
231
233
|
this[draggerElementSymbol].style.cursor = "ns-resize";
|
|
232
234
|
this[splitScreenElementSymbol].classList.add("horizontal");
|
|
233
235
|
this[splitScreenElementSymbol].classList.remove("vertical");
|
|
@@ -267,6 +269,29 @@ function initControlReferences() {
|
|
|
267
269
|
);
|
|
268
270
|
}
|
|
269
271
|
|
|
272
|
+
/**
|
|
273
|
+
* @private
|
|
274
|
+
* @return {string}
|
|
275
|
+
*/
|
|
276
|
+
function getDraggerSize() {
|
|
277
|
+
if (!(this[draggerElementSymbol] instanceof Element)) {
|
|
278
|
+
return "0px";
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const inlineProperty =
|
|
282
|
+
this[draggerElementSymbol] instanceof HTMLElement
|
|
283
|
+
? this[draggerElementSymbol].style
|
|
284
|
+
.getPropertyValue("--monster-dragger-width")
|
|
285
|
+
.trim()
|
|
286
|
+
: "";
|
|
287
|
+
const computedProperty = window
|
|
288
|
+
.getComputedStyle(this[draggerElementSymbol])
|
|
289
|
+
.getPropertyValue("--monster-dragger-width")
|
|
290
|
+
.trim();
|
|
291
|
+
|
|
292
|
+
return inlineProperty || computedProperty || "0px";
|
|
293
|
+
}
|
|
294
|
+
|
|
270
295
|
/**
|
|
271
296
|
* @private
|
|
272
297
|
*/
|
|
@@ -316,43 +341,42 @@ function initEventHandler() {
|
|
|
316
341
|
if (!touch) return;
|
|
317
342
|
|
|
318
343
|
// identical logic as in mousemove - but with touch.clientX/clientY
|
|
319
|
-
|
|
320
|
-
getComputedStyle(self[draggerElementSymbol]).getPropertyValue(
|
|
321
|
-
"--monster-dragger-width",
|
|
322
|
-
) || "0";
|
|
344
|
+
const draggerWidth = getDraggerSize.call(self);
|
|
323
345
|
|
|
324
346
|
if (self.getOption("splitType") === TYPE_HORIZONTAL) {
|
|
325
|
-
const
|
|
326
|
-
|
|
347
|
+
const containerRect =
|
|
348
|
+
self[splitScreenElementSymbol].getBoundingClientRect();
|
|
349
|
+
let newTopHeight = touch.clientY - containerRect.top;
|
|
327
350
|
|
|
328
351
|
const min = this.getOption("dimension").min;
|
|
329
352
|
const max = this.getOption("dimension").max;
|
|
330
353
|
const topAsPercent =
|
|
331
354
|
(newTopHeight / this[splitScreenElementSymbol].offsetHeight) * 100;
|
|
332
355
|
|
|
333
|
-
if (
|
|
334
|
-
else if (
|
|
335
|
-
else newTopHeight = topAsPercent
|
|
356
|
+
if (parseFloat(min) > topAsPercent) newTopHeight = min;
|
|
357
|
+
else if (parseFloat(max) < topAsPercent) newTopHeight = max;
|
|
358
|
+
else newTopHeight = `${topAsPercent}%`;
|
|
336
359
|
|
|
337
360
|
const newTopHeightPx =
|
|
338
|
-
(
|
|
361
|
+
(parseFloat(newTopHeight) / 100) *
|
|
339
362
|
this[splitScreenElementSymbol].offsetHeight;
|
|
340
363
|
|
|
341
364
|
self[startPanelElementSymbol].style.height = `${newTopHeightPx}px`;
|
|
342
365
|
self[endPanelElementSymbol].style.height =
|
|
343
366
|
`calc(100% - ${newTopHeightPx}px - ${draggerWidth})`;
|
|
344
367
|
} else {
|
|
345
|
-
const
|
|
346
|
-
|
|
368
|
+
const containerRect =
|
|
369
|
+
self[splitScreenElementSymbol].getBoundingClientRect();
|
|
370
|
+
let newLeftWidth = touch.clientX - containerRect.left;
|
|
347
371
|
|
|
348
372
|
const min = this.getOption("dimension").min;
|
|
349
373
|
const max = this.getOption("dimension").max;
|
|
350
374
|
const leftAsPercent =
|
|
351
375
|
(newLeftWidth / this[splitScreenElementSymbol].offsetWidth) * 100;
|
|
352
376
|
|
|
353
|
-
if (
|
|
354
|
-
else if (
|
|
355
|
-
else newLeftWidth = leftAsPercent
|
|
377
|
+
if (parseFloat(min) > leftAsPercent) newLeftWidth = min;
|
|
378
|
+
else if (parseFloat(max) < leftAsPercent) newLeftWidth = max;
|
|
379
|
+
else newLeftWidth = `${leftAsPercent}%`;
|
|
356
380
|
|
|
357
381
|
self[startPanelElementSymbol].style.width = `${newLeftWidth}`;
|
|
358
382
|
self[endPanelElementSymbol].style.width =
|
|
@@ -370,7 +394,7 @@ function initEventHandler() {
|
|
|
370
394
|
document.addEventListener("touchend", dragTouchEnd);
|
|
371
395
|
});
|
|
372
396
|
|
|
373
|
-
|
|
397
|
+
const userSelectDefault = getDocument().body.style.userSelect;
|
|
374
398
|
|
|
375
399
|
this[draggerElementSymbol].addEventListener("mousedown", () => {
|
|
376
400
|
self[internalSymbol].getSubject().isDragging = true;
|
|
@@ -378,18 +402,7 @@ function initEventHandler() {
|
|
|
378
402
|
const eventListener = (e) => {
|
|
379
403
|
e.preventDefault();
|
|
380
404
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
let draggerWidth = getComputedStyle(
|
|
384
|
-
self[draggerElementSymbol],
|
|
385
|
-
).getPropertyValue("--monster-dragger-width");
|
|
386
|
-
if (
|
|
387
|
-
draggerWidth === "" ||
|
|
388
|
-
draggerWidth === undefined ||
|
|
389
|
-
draggerWidth === null
|
|
390
|
-
) {
|
|
391
|
-
draggerWidth = "0";
|
|
392
|
-
}
|
|
405
|
+
const draggerWidth = getDraggerSize.call(self);
|
|
393
406
|
|
|
394
407
|
if (!self[internalSymbol].getSubject().isDragging) {
|
|
395
408
|
return;
|
|
@@ -398,36 +411,38 @@ function initEventHandler() {
|
|
|
398
411
|
getDocument().body.style.userSelect = "none";
|
|
399
412
|
|
|
400
413
|
if (self.getOption("splitType") === TYPE_HORIZONTAL) {
|
|
401
|
-
const
|
|
414
|
+
const containerRect =
|
|
415
|
+
self[splitScreenElementSymbol].getBoundingClientRect();
|
|
402
416
|
const topPanel = self[startPanelElementSymbol];
|
|
403
417
|
const bottomPanel = self[endPanelElementSymbol];
|
|
404
|
-
let newTopHeight = e.clientY -
|
|
418
|
+
let newTopHeight = e.clientY - containerRect.top;
|
|
405
419
|
|
|
406
420
|
const min = this.getOption("dimension").min;
|
|
407
421
|
const max = this.getOption("dimension").max;
|
|
408
422
|
|
|
409
423
|
const topAsPercent =
|
|
410
424
|
(newTopHeight / this[splitScreenElementSymbol].offsetHeight) * 100;
|
|
411
|
-
if (
|
|
425
|
+
if (parseFloat(min) > topAsPercent) {
|
|
412
426
|
newTopHeight = min;
|
|
413
|
-
} else if (
|
|
427
|
+
} else if (parseFloat(max) < topAsPercent) {
|
|
414
428
|
newTopHeight = max;
|
|
415
429
|
} else {
|
|
416
|
-
newTopHeight = topAsPercent
|
|
430
|
+
newTopHeight = `${topAsPercent}%`;
|
|
417
431
|
}
|
|
418
432
|
|
|
419
433
|
// calc new top height to pixel
|
|
420
434
|
const newTopHeightPx =
|
|
421
|
-
(
|
|
435
|
+
(parseFloat(newTopHeight) / 100) *
|
|
422
436
|
this[splitScreenElementSymbol].offsetHeight;
|
|
423
437
|
|
|
424
438
|
topPanel.style.height = `${newTopHeightPx}px`;
|
|
425
|
-
bottomPanel.style.height = `calc(100% - ${newTopHeightPx}px - ${draggerWidth})`;
|
|
439
|
+
bottomPanel.style.height = `calc(100% - ${newTopHeightPx}px - ${draggerWidth})`;
|
|
426
440
|
} else {
|
|
427
|
-
const
|
|
441
|
+
const containerRect =
|
|
442
|
+
self[splitScreenElementSymbol].getBoundingClientRect();
|
|
428
443
|
const leftPanel = self[startPanelElementSymbol];
|
|
429
444
|
const rightPanel = self[endPanelElementSymbol];
|
|
430
|
-
let newLeftWidth = e.clientX -
|
|
445
|
+
let newLeftWidth = e.clientX - containerRect.left;
|
|
431
446
|
|
|
432
447
|
const min = this.getOption("dimension").min;
|
|
433
448
|
const max = this.getOption("dimension").max;
|
|
@@ -435,26 +450,26 @@ function initEventHandler() {
|
|
|
435
450
|
const leftAsPercent =
|
|
436
451
|
(newLeftWidth / this[splitScreenElementSymbol].offsetWidth) * 100;
|
|
437
452
|
|
|
438
|
-
if (
|
|
453
|
+
if (parseFloat(min) > leftAsPercent) {
|
|
439
454
|
newLeftWidth = min;
|
|
440
|
-
} else if (
|
|
455
|
+
} else if (parseFloat(max) < leftAsPercent) {
|
|
441
456
|
newLeftWidth = max;
|
|
442
457
|
} else {
|
|
443
|
-
newLeftWidth = leftAsPercent
|
|
458
|
+
newLeftWidth = `${leftAsPercent}%`;
|
|
444
459
|
}
|
|
445
460
|
|
|
446
461
|
leftPanel.style.width = `${newLeftWidth}`;
|
|
447
|
-
rightPanel.style.width = `calc(100% - ${newLeftWidth} - ${draggerWidth})`;
|
|
462
|
+
rightPanel.style.width = `calc(100% - ${newLeftWidth} - ${draggerWidth})`;
|
|
448
463
|
}
|
|
449
464
|
};
|
|
450
465
|
|
|
451
|
-
const dragEventHandler = (
|
|
466
|
+
const dragEventHandler = () => {
|
|
452
467
|
self[internalSymbol].getSubject().isDragging = false;
|
|
453
468
|
|
|
454
469
|
document.body.style.userSelect = userSelectDefault;
|
|
455
470
|
|
|
456
471
|
document.removeEventListener("mousemove", eventListener);
|
|
457
|
-
document.removeEventListener("mouseup",
|
|
472
|
+
document.removeEventListener("mouseup", dragEventHandler);
|
|
458
473
|
};
|
|
459
474
|
|
|
460
475
|
document.addEventListener("mousemove", eventListener);
|