@schukai/monster 4.148.7 → 4.148.9
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/form/control-bar.mjs +212 -177
- package/source/dom/customelement.mjs +105 -40
- package/source/dom/updater.mjs +381 -119
- package/test/cases/components/form/control-bar.mjs +218 -10
- package/test/cases/dom/customelement.mjs +136 -1
- package/test/cases/dom/updater.mjs +174 -0
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.6"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.148.
|
|
1
|
+
{"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.6"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.148.9"}
|
|
@@ -43,7 +43,6 @@ import { positionPopper } from "./util/floating-ui.mjs";
|
|
|
43
43
|
import { convertToPixels } from "../../dom/dimension.mjs";
|
|
44
44
|
import { addErrorAttribute } from "../../dom/error.mjs";
|
|
45
45
|
import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
|
|
46
|
-
import { Processing } from "../../util/processing.mjs";
|
|
47
46
|
export { ControlBar };
|
|
48
47
|
|
|
49
48
|
/**
|
|
@@ -217,7 +216,7 @@ const EVENT_LAYOUT_CHANGED = "monster-control-bar-layout-changed";
|
|
|
217
216
|
* @type {number}
|
|
218
217
|
*/
|
|
219
218
|
const LAYOUT_CHANGED_EVENT_DELAY = 20;
|
|
220
|
-
const
|
|
219
|
+
const LAYOUT_RESIZE_EPSILON = 0.5;
|
|
221
220
|
|
|
222
221
|
/**
|
|
223
222
|
* @private
|
|
@@ -332,6 +331,8 @@ class ControlBar extends CustomElement {
|
|
|
332
331
|
suppressSlotChange: false,
|
|
333
332
|
suppressMutation: false,
|
|
334
333
|
suppressResize: false,
|
|
334
|
+
itemInlineSizes: new WeakMap(),
|
|
335
|
+
joinedInlineOffsets: new WeakMap(),
|
|
335
336
|
};
|
|
336
337
|
|
|
337
338
|
initControlReferences.call(this);
|
|
@@ -643,7 +644,7 @@ function initEventHandler() {
|
|
|
643
644
|
if (self[layoutStateSymbol]?.suppressResize) {
|
|
644
645
|
return;
|
|
645
646
|
}
|
|
646
|
-
if (!
|
|
647
|
+
if (!hasLayoutResizeEntry.call(self, entries)) {
|
|
647
648
|
return;
|
|
648
649
|
}
|
|
649
650
|
scheduleLayout.call(self, { measure: true, layout: true });
|
|
@@ -721,7 +722,8 @@ function runLayout() {
|
|
|
721
722
|
state.needsLayout = false;
|
|
722
723
|
state.running = true;
|
|
723
724
|
|
|
724
|
-
|
|
725
|
+
let popperUpdate;
|
|
726
|
+
try {
|
|
725
727
|
syncEmptyVisibility.call(this);
|
|
726
728
|
|
|
727
729
|
if (needsObserve) {
|
|
@@ -741,7 +743,17 @@ function runLayout() {
|
|
|
741
743
|
|
|
742
744
|
if (needsLayout) {
|
|
743
745
|
try {
|
|
744
|
-
rearrangeItems.call(this);
|
|
746
|
+
let shouldStabilize = rearrangeItems.call(this);
|
|
747
|
+
let stabilizationPass = 0;
|
|
748
|
+
const maximumStabilizationPasses = this.children.length + 1;
|
|
749
|
+
while (
|
|
750
|
+
shouldStabilize &&
|
|
751
|
+
stabilizationPass < maximumStabilizationPasses
|
|
752
|
+
) {
|
|
753
|
+
calculateControlBarDimensions.call(this);
|
|
754
|
+
shouldStabilize = rearrangeItems.call(this);
|
|
755
|
+
stabilizationPass++;
|
|
756
|
+
}
|
|
745
757
|
} catch (error) {
|
|
746
758
|
addErrorAttribute(
|
|
747
759
|
this,
|
|
@@ -750,27 +762,40 @@ function runLayout() {
|
|
|
750
762
|
}
|
|
751
763
|
}
|
|
752
764
|
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
.catch((error) => {
|
|
765
|
+
try {
|
|
766
|
+
popperUpdate = updatePopper.call(this);
|
|
767
|
+
} catch (error) {
|
|
757
768
|
addErrorAttribute(
|
|
758
769
|
this,
|
|
759
|
-
error?.message ||
|
|
760
|
-
|
|
770
|
+
error?.message || "An error occurred while updating the popper",
|
|
771
|
+
);
|
|
772
|
+
}
|
|
773
|
+
} catch (error) {
|
|
774
|
+
addErrorAttribute(
|
|
775
|
+
this,
|
|
776
|
+
error?.message ||
|
|
777
|
+
"An error occurred while running the control bar layout",
|
|
778
|
+
);
|
|
779
|
+
} finally {
|
|
780
|
+
state.running = false;
|
|
781
|
+
if (state.needsObserve || state.needsMeasure || state.needsLayout) {
|
|
782
|
+
scheduleLayoutFrame.call(this);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
if (popperUpdate instanceof Promise) {
|
|
787
|
+
popperUpdate.catch((error) => {
|
|
788
|
+
addErrorAttribute(
|
|
789
|
+
this,
|
|
790
|
+
error?.message || "An error occurred while updating the popper",
|
|
761
791
|
);
|
|
762
|
-
})
|
|
763
|
-
.finally(() => {
|
|
764
|
-
state.running = false;
|
|
765
|
-
if (state.needsObserve || state.needsMeasure || state.needsLayout) {
|
|
766
|
-
scheduleLayoutFrame.call(this);
|
|
767
|
-
}
|
|
768
792
|
});
|
|
793
|
+
}
|
|
769
794
|
}
|
|
770
795
|
|
|
771
796
|
/**
|
|
772
797
|
* @private
|
|
773
|
-
* @return {
|
|
798
|
+
* @return {boolean}
|
|
774
799
|
*/
|
|
775
800
|
function rearrangeItems() {
|
|
776
801
|
let space = 0;
|
|
@@ -825,7 +850,7 @@ function rearrangeItems() {
|
|
|
825
850
|
});
|
|
826
851
|
}
|
|
827
852
|
|
|
828
|
-
const switchWidth = this[dimensionsSymbol].getVia("data.switchWidth") ||
|
|
853
|
+
const switchWidth = this[dimensionsSymbol].getVia("data.switchWidth") || 0;
|
|
829
854
|
|
|
830
855
|
const layoutItems = (availableSpace) => {
|
|
831
856
|
if (availableSpace < 0) {
|
|
@@ -854,67 +879,52 @@ function rearrangeItems() {
|
|
|
854
879
|
return { visibleItemsInMainSlot, itemsToMoveToPopper };
|
|
855
880
|
};
|
|
856
881
|
|
|
857
|
-
const
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
layout = layoutItems(space - switchWidth - LAYOUT_SWITCH_HYSTERESIS);
|
|
863
|
-
if (layout.itemsToMoveToPopper.length === 0) {
|
|
864
|
-
layout = layoutItems(space);
|
|
865
|
-
}
|
|
866
|
-
} else {
|
|
867
|
-
layout = layoutItems(space - LAYOUT_SWITCH_HYSTERESIS);
|
|
868
|
-
if (layout.itemsToMoveToPopper.length > 0) {
|
|
869
|
-
layout = layoutItems(space - switchWidth);
|
|
870
|
-
} else {
|
|
871
|
-
layout = layoutItems(space);
|
|
872
|
-
}
|
|
873
|
-
}
|
|
882
|
+
const totalItemWidth = itemEntries.reduce((sum, entry) => {
|
|
883
|
+
return entry.hidden ? sum : sum + entry.width;
|
|
884
|
+
}, 0);
|
|
885
|
+
const shouldOverflow = totalItemWidth > space;
|
|
886
|
+
let layout = layoutItems(shouldOverflow ? space - switchWidth : space);
|
|
874
887
|
|
|
875
888
|
layout = normalizeSpacerOverflowLayout(
|
|
876
889
|
layout,
|
|
877
890
|
itemEntries.map((entry) => entry.element),
|
|
878
891
|
);
|
|
879
|
-
layout = stabilizeOverflowBoundary.call(
|
|
880
|
-
this,
|
|
881
|
-
layout,
|
|
882
|
-
itemEntries,
|
|
883
|
-
switchCurrentlyVisible,
|
|
884
|
-
);
|
|
885
892
|
|
|
886
893
|
const shouldShowSwitch = layout.itemsToMoveToPopper.length > 0 && hasItems;
|
|
887
|
-
updateLastOverflowBoundary.call(
|
|
888
|
-
this,
|
|
889
|
-
layout,
|
|
890
|
-
itemEntries.map((entry) => entry.element),
|
|
891
|
-
);
|
|
892
894
|
const shouldUseStackedLayout =
|
|
893
895
|
shouldShowSwitch || isStackedBreakpointMatched.call(this);
|
|
896
|
+
let layoutChanged = false;
|
|
894
897
|
|
|
895
|
-
suppressLayoutFeedback.call(this);
|
|
896
898
|
setLayoutStackedState.call(this, shouldUseStackedLayout);
|
|
897
899
|
|
|
898
900
|
for (const item of layout.itemsToMoveToPopper) {
|
|
899
901
|
if (item.getAttribute("slot") !== "popper") {
|
|
900
902
|
item.setAttribute("slot", "popper");
|
|
903
|
+
layoutChanged = true;
|
|
901
904
|
}
|
|
902
905
|
}
|
|
903
906
|
|
|
904
907
|
for (const item of layout.visibleItemsInMainSlot) {
|
|
905
908
|
if (item.hasAttribute("slot")) {
|
|
906
909
|
item.removeAttribute("slot");
|
|
910
|
+
layoutChanged = true;
|
|
907
911
|
}
|
|
908
912
|
}
|
|
909
913
|
|
|
910
914
|
setSwitchVisible.call(this, shouldShowSwitch);
|
|
911
|
-
|
|
912
|
-
|
|
915
|
+
layoutChanged =
|
|
916
|
+
updateControlSizing.call(this, layout, shouldShowSwitch) || layoutChanged;
|
|
917
|
+
layoutChanged =
|
|
918
|
+
updateJoinedBorders.call(this, layout, shouldShowSwitch) || layoutChanged;
|
|
913
919
|
applyLayoutAlignment.call(this);
|
|
914
920
|
if (!shouldShowSwitch) {
|
|
915
921
|
hide.call(this);
|
|
916
922
|
}
|
|
917
923
|
syncEmptyVisibility.call(this);
|
|
924
|
+
if (layoutChanged) {
|
|
925
|
+
suppressLayoutFeedback.call(this);
|
|
926
|
+
}
|
|
927
|
+
return layoutChanged;
|
|
918
928
|
}
|
|
919
929
|
|
|
920
930
|
/**
|
|
@@ -1007,88 +1017,6 @@ function isControlItemVisible(item) {
|
|
|
1007
1017
|
});
|
|
1008
1018
|
}
|
|
1009
1019
|
|
|
1010
|
-
/**
|
|
1011
|
-
* @private
|
|
1012
|
-
* @param {{visibleItemsInMainSlot: HTMLElement[], itemsToMoveToPopper: HTMLElement[]}} layout
|
|
1013
|
-
* @param {{element: HTMLElement, hidden: boolean}[]} itemEntries
|
|
1014
|
-
* @param {boolean} switchCurrentlyVisible
|
|
1015
|
-
* @return {{visibleItemsInMainSlot: HTMLElement[], itemsToMoveToPopper: HTMLElement[]}}
|
|
1016
|
-
*/
|
|
1017
|
-
function stabilizeOverflowBoundary(layout, itemEntries, switchCurrentlyVisible) {
|
|
1018
|
-
const state = this[layoutStateSymbol];
|
|
1019
|
-
if (!switchCurrentlyVisible || !state) {
|
|
1020
|
-
return layout;
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
|
-
const orderedItems = itemEntries.map((entry) => entry.element);
|
|
1024
|
-
const nextBoundary = getFirstOverflowIndex(layout, orderedItems);
|
|
1025
|
-
const previousBoundary = state.lastOverflowStartIndex;
|
|
1026
|
-
if (
|
|
1027
|
-
typeof previousBoundary !== "number" ||
|
|
1028
|
-
typeof nextBoundary !== "number" ||
|
|
1029
|
-
nextBoundary <= previousBoundary ||
|
|
1030
|
-
previousBoundary < 0 ||
|
|
1031
|
-
previousBoundary >= itemEntries.length
|
|
1032
|
-
) {
|
|
1033
|
-
return layout;
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
const popperItems = new Set();
|
|
1037
|
-
const mainItems = new Set();
|
|
1038
|
-
for (let index = 0; index < itemEntries.length; index++) {
|
|
1039
|
-
const entry = itemEntries[index];
|
|
1040
|
-
if (index >= previousBoundary && !entry.hidden) {
|
|
1041
|
-
popperItems.add(entry.element);
|
|
1042
|
-
} else {
|
|
1043
|
-
mainItems.add(entry.element);
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
return normalizeSpacerOverflowLayout(
|
|
1048
|
-
{
|
|
1049
|
-
visibleItemsInMainSlot: orderedItems.filter((item) => mainItems.has(item)),
|
|
1050
|
-
itemsToMoveToPopper: orderedItems.filter((item) => popperItems.has(item)),
|
|
1051
|
-
},
|
|
1052
|
-
orderedItems,
|
|
1053
|
-
);
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
|
-
/**
|
|
1057
|
-
* @private
|
|
1058
|
-
* @param {{itemsToMoveToPopper: HTMLElement[]}} layout
|
|
1059
|
-
* @param {HTMLElement[]} orderedItems
|
|
1060
|
-
* @return {void}
|
|
1061
|
-
*/
|
|
1062
|
-
function updateLastOverflowBoundary(layout, orderedItems) {
|
|
1063
|
-
const state = this[layoutStateSymbol];
|
|
1064
|
-
if (!state) {
|
|
1065
|
-
return;
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
const boundary = getFirstOverflowIndex(layout, orderedItems);
|
|
1069
|
-
if (typeof boundary === "number") {
|
|
1070
|
-
state.lastOverflowStartIndex = boundary;
|
|
1071
|
-
return;
|
|
1072
|
-
}
|
|
1073
|
-
delete state.lastOverflowStartIndex;
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
/**
|
|
1077
|
-
* @private
|
|
1078
|
-
* @param {{itemsToMoveToPopper: HTMLElement[]}} layout
|
|
1079
|
-
* @param {HTMLElement[]} orderedItems
|
|
1080
|
-
* @return {number|undefined}
|
|
1081
|
-
*/
|
|
1082
|
-
function getFirstOverflowIndex(layout, orderedItems) {
|
|
1083
|
-
const popperItems = new Set(layout.itemsToMoveToPopper);
|
|
1084
|
-
for (let index = 0; index < orderedItems.length; index++) {
|
|
1085
|
-
if (popperItems.has(orderedItems[index])) {
|
|
1086
|
-
return index;
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
return undefined;
|
|
1090
|
-
}
|
|
1091
|
-
|
|
1092
1020
|
/**
|
|
1093
1021
|
* @private
|
|
1094
1022
|
* @param {{visibleItemsInMainSlot: HTMLElement[], itemsToMoveToPopper: HTMLElement[]}} layout
|
|
@@ -1160,15 +1088,15 @@ function calcBoxWidth(node) {
|
|
|
1160
1088
|
throw new Error("no computed style");
|
|
1161
1089
|
}
|
|
1162
1090
|
const bounding = node.getBoundingClientRect();
|
|
1091
|
+
this[layoutStateSymbol]?.itemInlineSizes?.set(node, bounding.width);
|
|
1092
|
+
const joinedInlineOffset =
|
|
1093
|
+
this[layoutStateSymbol]?.joinedInlineOffsets?.get(node) || 0;
|
|
1163
1094
|
|
|
1164
1095
|
return (
|
|
1165
|
-
getComputedCssPixels(dim["border-left-width"]) +
|
|
1166
|
-
getComputedCssPixels(dim["padding-left"]) +
|
|
1167
1096
|
getComputedCssPixels(dim["margin-left"]) +
|
|
1168
1097
|
bounding["width"] +
|
|
1169
|
-
getComputedCssPixels(dim["
|
|
1170
|
-
|
|
1171
|
-
getComputedCssPixels(dim["padding-right"])
|
|
1098
|
+
getComputedCssPixels(dim["margin-right"]) -
|
|
1099
|
+
joinedInlineOffset
|
|
1172
1100
|
);
|
|
1173
1101
|
}
|
|
1174
1102
|
|
|
@@ -1197,7 +1125,7 @@ function getComputedCssPixels(value) {
|
|
|
1197
1125
|
* @private
|
|
1198
1126
|
* @param {Object} layout
|
|
1199
1127
|
* @param {boolean} shouldShowSwitch
|
|
1200
|
-
* @return {
|
|
1128
|
+
* @return {boolean}
|
|
1201
1129
|
*/
|
|
1202
1130
|
function updateControlSizing(layout, shouldShowSwitch) {
|
|
1203
1131
|
const mainItems = [...layout.visibleItemsInMainSlot];
|
|
@@ -1206,42 +1134,50 @@ function updateControlSizing(layout, shouldShowSwitch) {
|
|
|
1206
1134
|
}
|
|
1207
1135
|
|
|
1208
1136
|
const controlItems = [...mainItems, ...layout.itemsToMoveToPopper];
|
|
1137
|
+
let changed = false;
|
|
1209
1138
|
for (const element of controlItems) {
|
|
1210
|
-
applyControlSizing.call(this, element);
|
|
1139
|
+
changed = applyControlSizing.call(this, element) || changed;
|
|
1211
1140
|
}
|
|
1141
|
+
return changed;
|
|
1212
1142
|
}
|
|
1213
1143
|
|
|
1214
1144
|
/**
|
|
1215
1145
|
* @private
|
|
1216
1146
|
* @param {HTMLElement} element
|
|
1217
|
-
* @return {
|
|
1147
|
+
* @return {boolean}
|
|
1218
1148
|
*/
|
|
1219
1149
|
function applyControlSizing(element) {
|
|
1220
|
-
setStylePropertyIfChanged(element, "boxSizing", "border-box");
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1150
|
+
let changed = setStylePropertyIfChanged(element, "boxSizing", "border-box");
|
|
1151
|
+
changed =
|
|
1152
|
+
setStylePropertyIfChanged(
|
|
1153
|
+
element,
|
|
1154
|
+
"height",
|
|
1155
|
+
"var(--monster-control-bar-height)",
|
|
1156
|
+
) || changed;
|
|
1157
|
+
changed =
|
|
1158
|
+
setStylePropertyIfChanged(
|
|
1159
|
+
element,
|
|
1160
|
+
"minHeight",
|
|
1161
|
+
"var(--monster-control-bar-height)",
|
|
1162
|
+
) || changed;
|
|
1231
1163
|
if (isWrapperElement(element)) {
|
|
1232
|
-
setStylePropertyIfChanged(element, "display", "flex");
|
|
1233
|
-
|
|
1164
|
+
changed = setStylePropertyIfChanged(element, "display", "flex") || changed;
|
|
1165
|
+
changed =
|
|
1166
|
+
setStylePropertyIfChanged(element, "alignItems", "stretch") || changed;
|
|
1234
1167
|
}
|
|
1235
1168
|
|
|
1236
1169
|
for (const control of getContainedControlElements(element)) {
|
|
1237
|
-
setStylePropertyIfChanged(control, "display", "flex");
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
setStylePropertyIfChanged(control, "
|
|
1170
|
+
changed = setStylePropertyIfChanged(control, "display", "flex") || changed;
|
|
1171
|
+
changed =
|
|
1172
|
+
setStylePropertyIfChanged(control, "boxSizing", "border-box") || changed;
|
|
1173
|
+
changed = setStylePropertyIfChanged(control, "height", "100%") || changed;
|
|
1174
|
+
changed = setStylePropertyIfChanged(control, "minHeight", "0px") || changed;
|
|
1241
1175
|
if (control.tagName === "MONSTER-INPUT-GROUP") {
|
|
1242
|
-
|
|
1176
|
+
changed =
|
|
1177
|
+
setStylePropertyIfChanged(control, "flex", "1 1 auto") || changed;
|
|
1243
1178
|
}
|
|
1244
1179
|
}
|
|
1180
|
+
return changed;
|
|
1245
1181
|
}
|
|
1246
1182
|
|
|
1247
1183
|
/**
|
|
@@ -1295,7 +1231,7 @@ function isTopLevelContainedControl(container, control) {
|
|
|
1295
1231
|
* @private
|
|
1296
1232
|
* @param {Object} layout
|
|
1297
1233
|
* @param {boolean} shouldShowSwitch
|
|
1298
|
-
* @return {
|
|
1234
|
+
* @return {boolean}
|
|
1299
1235
|
*/
|
|
1300
1236
|
function updateJoinedBorders(layout, shouldShowSwitch) {
|
|
1301
1237
|
const mainItems = [...layout.visibleItemsInMainSlot];
|
|
@@ -1331,7 +1267,11 @@ function updateJoinedBorders(layout, shouldShowSwitch) {
|
|
|
1331
1267
|
"bottom",
|
|
1332
1268
|
"top",
|
|
1333
1269
|
);
|
|
1334
|
-
applyJoinedBorderOffsets.call(
|
|
1270
|
+
return applyJoinedBorderOffsets.call(
|
|
1271
|
+
this,
|
|
1272
|
+
marginLeftByElement,
|
|
1273
|
+
marginTopByElement,
|
|
1274
|
+
);
|
|
1335
1275
|
}
|
|
1336
1276
|
|
|
1337
1277
|
/**
|
|
@@ -1432,21 +1372,26 @@ function collectBlockJoinedBorders(elements, marginTopByElement) {
|
|
|
1432
1372
|
* @private
|
|
1433
1373
|
* @param {Map<HTMLElement, string>} marginLeftByElement
|
|
1434
1374
|
* @param {Map<HTMLElement, string>} marginTopByElement
|
|
1435
|
-
* @return {
|
|
1375
|
+
* @return {boolean}
|
|
1436
1376
|
*/
|
|
1437
1377
|
function applyJoinedBorderOffsets(marginLeftByElement, marginTopByElement) {
|
|
1378
|
+
let changed = false;
|
|
1438
1379
|
for (const element of getJoinedBorderOffsetElements.call(this)) {
|
|
1439
|
-
|
|
1380
|
+
const marginLeft = marginLeftByElement.get(element) || "";
|
|
1381
|
+
changed =
|
|
1382
|
+
setStylePropertyIfChanged(element, "marginLeft", marginLeft) || changed;
|
|
1383
|
+
this[layoutStateSymbol]?.joinedInlineOffsets?.set(
|
|
1440
1384
|
element,
|
|
1441
|
-
|
|
1442
|
-
marginLeftByElement.get(element) || "",
|
|
1443
|
-
);
|
|
1444
|
-
setStylePropertyIfChanged(
|
|
1445
|
-
element,
|
|
1446
|
-
"marginTop",
|
|
1447
|
-
marginTopByElement.get(element) || "",
|
|
1385
|
+
getComputedCssPixels(marginLeft),
|
|
1448
1386
|
);
|
|
1387
|
+
changed =
|
|
1388
|
+
setStylePropertyIfChanged(
|
|
1389
|
+
element,
|
|
1390
|
+
"marginTop",
|
|
1391
|
+
marginTopByElement.get(element) || "",
|
|
1392
|
+
) || changed;
|
|
1449
1393
|
}
|
|
1394
|
+
return changed;
|
|
1450
1395
|
}
|
|
1451
1396
|
|
|
1452
1397
|
/**
|
|
@@ -1472,7 +1417,7 @@ function getJoinedBorderOffsetElements() {
|
|
|
1472
1417
|
* @param {HTMLElement} element
|
|
1473
1418
|
* @param {"marginLeft"|"marginTop"} property
|
|
1474
1419
|
* @param {string} value
|
|
1475
|
-
* @return {
|
|
1420
|
+
* @return {boolean}
|
|
1476
1421
|
*/
|
|
1477
1422
|
function setStylePropertyIfChanged(element, property, value) {
|
|
1478
1423
|
if (property.startsWith("--")) {
|
|
@@ -1482,13 +1427,16 @@ function setStylePropertyIfChanged(element, property, value) {
|
|
|
1482
1427
|
} else {
|
|
1483
1428
|
element.style.setProperty(property, value);
|
|
1484
1429
|
}
|
|
1430
|
+
return true;
|
|
1485
1431
|
}
|
|
1486
|
-
return;
|
|
1432
|
+
return false;
|
|
1487
1433
|
}
|
|
1488
1434
|
|
|
1489
1435
|
if (element.style[property] !== value) {
|
|
1490
1436
|
element.style[property] = value;
|
|
1437
|
+
return true;
|
|
1491
1438
|
}
|
|
1439
|
+
return false;
|
|
1492
1440
|
}
|
|
1493
1441
|
|
|
1494
1442
|
/**
|
|
@@ -1667,10 +1615,13 @@ function calculateControlBarDimensions() {
|
|
|
1667
1615
|
}
|
|
1668
1616
|
|
|
1669
1617
|
if (this[switchElementSymbol]) {
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1618
|
+
let cachedSwitchWidth = 0;
|
|
1619
|
+
try {
|
|
1620
|
+
cachedSwitchWidth =
|
|
1621
|
+
this[dimensionsSymbol].getVia("data.switchWidth") || 0;
|
|
1622
|
+
} catch {}
|
|
1623
|
+
const switchWidth = measureSwitchWidth.call(this, cachedSwitchWidth);
|
|
1624
|
+
this[dimensionsSymbol].setVia("data.switchWidth", switchWidth);
|
|
1674
1625
|
}
|
|
1675
1626
|
|
|
1676
1627
|
this[dimensionsSymbol].setVia("data.calculated", true);
|
|
@@ -1836,17 +1787,101 @@ function suppressLayoutFeedback() {
|
|
|
1836
1787
|
* @param {ResizeObserverEntry[]} entries
|
|
1837
1788
|
* @return {boolean}
|
|
1838
1789
|
*/
|
|
1839
|
-
function
|
|
1790
|
+
function hasLayoutResizeEntry(entries) {
|
|
1840
1791
|
const stackedBreakpointContainer =
|
|
1841
1792
|
resolveStackedBreakpointContainer.call(this);
|
|
1842
1793
|
return entries.some((entry) => {
|
|
1843
|
-
|
|
1794
|
+
if (
|
|
1844
1795
|
entry.target === this.parentElement ||
|
|
1845
1796
|
entry.target === stackedBreakpointContainer
|
|
1797
|
+
) {
|
|
1798
|
+
return true;
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
if (
|
|
1802
|
+
!(entry.target instanceof HTMLElement) ||
|
|
1803
|
+
entry.target.parentElement !== this
|
|
1804
|
+
) {
|
|
1805
|
+
return false;
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
const inlineSize = entry.target.getBoundingClientRect().width;
|
|
1809
|
+
if (!(inlineSize > 0)) {
|
|
1810
|
+
return false;
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
const itemInlineSizes = this[layoutStateSymbol]?.itemInlineSizes;
|
|
1814
|
+
if (!(itemInlineSizes instanceof WeakMap)) {
|
|
1815
|
+
return true;
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
const previousInlineSize = itemInlineSizes.get(entry.target);
|
|
1819
|
+
itemInlineSizes.set(entry.target, inlineSize);
|
|
1820
|
+
return (
|
|
1821
|
+
typeof previousInlineSize !== "number" ||
|
|
1822
|
+
Math.abs(previousInlineSize - inlineSize) > LAYOUT_RESIZE_EPSILON
|
|
1846
1823
|
);
|
|
1847
1824
|
});
|
|
1848
1825
|
}
|
|
1849
1826
|
|
|
1827
|
+
/**
|
|
1828
|
+
* Measure the overflow switch without exposing it visually. A switch hidden
|
|
1829
|
+
* with `display: none` has no layout width, so it must be made measurable for
|
|
1830
|
+
* the duration of the synchronous read.
|
|
1831
|
+
*
|
|
1832
|
+
* @private
|
|
1833
|
+
* @param {number} cachedWidth
|
|
1834
|
+
* @return {number}
|
|
1835
|
+
*/
|
|
1836
|
+
function measureSwitchWidth(cachedWidth = 0) {
|
|
1837
|
+
const element = this[switchElementSymbol];
|
|
1838
|
+
if (!(element instanceof HTMLElement)) {
|
|
1839
|
+
return 0;
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
const visibleWidth = element.offsetWidth;
|
|
1843
|
+
if (visibleWidth > 0) {
|
|
1844
|
+
return visibleWidth;
|
|
1845
|
+
}
|
|
1846
|
+
if (cachedWidth > 0) {
|
|
1847
|
+
return cachedWidth;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
const hadHiddenAttribute = element.hasAttribute("hidden");
|
|
1851
|
+
const hadHiddenClass = element.classList.contains("hidden");
|
|
1852
|
+
const previousVisibility = element.style.getPropertyValue("visibility");
|
|
1853
|
+
const previousVisibilityPriority =
|
|
1854
|
+
element.style.getPropertyPriority("visibility");
|
|
1855
|
+
|
|
1856
|
+
element.style.setProperty("visibility", "hidden", "important");
|
|
1857
|
+
if (hadHiddenAttribute) {
|
|
1858
|
+
element.removeAttribute("hidden");
|
|
1859
|
+
}
|
|
1860
|
+
if (hadHiddenClass) {
|
|
1861
|
+
element.classList.remove("hidden");
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
const measuredWidth = element.offsetWidth;
|
|
1865
|
+
|
|
1866
|
+
if (hadHiddenClass) {
|
|
1867
|
+
element.classList.add("hidden");
|
|
1868
|
+
}
|
|
1869
|
+
if (hadHiddenAttribute) {
|
|
1870
|
+
element.setAttribute("hidden", "");
|
|
1871
|
+
}
|
|
1872
|
+
if (previousVisibility === "") {
|
|
1873
|
+
element.style.removeProperty("visibility");
|
|
1874
|
+
} else {
|
|
1875
|
+
element.style.setProperty(
|
|
1876
|
+
"visibility",
|
|
1877
|
+
previousVisibility,
|
|
1878
|
+
previousVisibilityPriority,
|
|
1879
|
+
);
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
return measuredWidth;
|
|
1883
|
+
}
|
|
1884
|
+
|
|
1850
1885
|
/**
|
|
1851
1886
|
* @private
|
|
1852
1887
|
* @param {boolean} visible
|