@schukai/monster 4.148.7 → 4.148.8
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
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.8"}
|
|
@@ -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
|
|
@@ -1439,7 +1439,7 @@ describe("ControlBar", function () {
|
|
|
1439
1439
|
}
|
|
1440
1440
|
});
|
|
1441
1441
|
|
|
1442
|
-
it("should
|
|
1442
|
+
it("should produce the same overflow layout across repeated switch-width threshold crossings", async function () {
|
|
1443
1443
|
const OriginalResizeObserver = window.ResizeObserver;
|
|
1444
1444
|
const originalGlobalResizeObserver = globalThis.ResizeObserver;
|
|
1445
1445
|
const originalRequestAnimationFrame = window.requestAnimationFrame;
|
|
@@ -1524,7 +1524,11 @@ describe("ControlBar", function () {
|
|
|
1524
1524
|
);
|
|
1525
1525
|
Object.defineProperty(switchButton, "offsetWidth", {
|
|
1526
1526
|
configurable: true,
|
|
1527
|
-
|
|
1527
|
+
get: () =>
|
|
1528
|
+
switchButton.hasAttribute("hidden") ||
|
|
1529
|
+
switchButton.classList.contains("hidden")
|
|
1530
|
+
? 0
|
|
1531
|
+
: 20,
|
|
1528
1532
|
});
|
|
1529
1533
|
|
|
1530
1534
|
await flushFrames();
|
|
@@ -1538,25 +1542,25 @@ describe("ControlBar", function () {
|
|
|
1538
1542
|
wrapperWidth = 155;
|
|
1539
1543
|
resizeObserver.triggerResize([{ target: wrapper }]);
|
|
1540
1544
|
await flushFrames();
|
|
1541
|
-
expect(switchButton.hasAttribute("hidden")).to.be.
|
|
1542
|
-
expect(document.getElementById("threshold-three").
|
|
1543
|
-
.
|
|
1545
|
+
expect(switchButton.hasAttribute("hidden")).to.be.true;
|
|
1546
|
+
expect(document.getElementById("threshold-three").hasAttribute("slot")).to
|
|
1547
|
+
.be.false;
|
|
1544
1548
|
|
|
1545
|
-
wrapperWidth =
|
|
1549
|
+
wrapperWidth = 145;
|
|
1546
1550
|
resizeObserver.triggerResize([{ target: wrapper }]);
|
|
1547
1551
|
await flushFrames();
|
|
1548
1552
|
expect(switchButton.hasAttribute("hidden")).to.be.false;
|
|
1549
1553
|
expect(document.getElementById("threshold-three").getAttribute("slot")).to
|
|
1550
1554
|
.equal("popper");
|
|
1551
1555
|
|
|
1552
|
-
wrapperWidth =
|
|
1556
|
+
wrapperWidth = 155;
|
|
1553
1557
|
resizeObserver.triggerResize([{ target: wrapper }]);
|
|
1554
1558
|
await flushFrames();
|
|
1555
1559
|
expect(switchButton.hasAttribute("hidden")).to.be.true;
|
|
1556
1560
|
expect(document.getElementById("threshold-three").hasAttribute("slot")).to
|
|
1557
1561
|
.be.false;
|
|
1558
1562
|
|
|
1559
|
-
wrapperWidth =
|
|
1563
|
+
wrapperWidth = 145;
|
|
1560
1564
|
resizeObserver.triggerResize([{ target: wrapper }]);
|
|
1561
1565
|
await flushFrames();
|
|
1562
1566
|
expect(switchButton.hasAttribute("hidden")).to.be.false;
|
|
@@ -1570,6 +1574,201 @@ describe("ControlBar", function () {
|
|
|
1570
1574
|
}
|
|
1571
1575
|
});
|
|
1572
1576
|
|
|
1577
|
+
it("should not count rendered padding and borders twice when controls fit", async function () {
|
|
1578
|
+
const originalRequestAnimationFrame = window.requestAnimationFrame;
|
|
1579
|
+
const originalGlobalRequestAnimationFrame = globalThis.requestAnimationFrame;
|
|
1580
|
+
const scheduledCallbacks = [];
|
|
1581
|
+
const flushFrames = async () => {
|
|
1582
|
+
while (scheduledCallbacks.length > 0) {
|
|
1583
|
+
scheduledCallbacks.shift()();
|
|
1584
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1585
|
+
}
|
|
1586
|
+
};
|
|
1587
|
+
|
|
1588
|
+
try {
|
|
1589
|
+
window.requestAnimationFrame = (callback) => {
|
|
1590
|
+
scheduledCallbacks.push(callback);
|
|
1591
|
+
return scheduledCallbacks.length;
|
|
1592
|
+
};
|
|
1593
|
+
globalThis.requestAnimationFrame = window.requestAnimationFrame;
|
|
1594
|
+
|
|
1595
|
+
const mocks = document.getElementById("mocks");
|
|
1596
|
+
mocks.innerHTML = `
|
|
1597
|
+
<div id="border-box-wrapper">
|
|
1598
|
+
<monster-control-bar id="border-box-bar">
|
|
1599
|
+
<button id="border-box-one" style="padding: 10px; border: 2px solid">One</button>
|
|
1600
|
+
<button id="border-box-two" style="padding: 10px; border: 2px solid">Two</button>
|
|
1601
|
+
</monster-control-bar>
|
|
1602
|
+
</div>
|
|
1603
|
+
`;
|
|
1604
|
+
|
|
1605
|
+
const wrapper = document.getElementById("border-box-wrapper");
|
|
1606
|
+
const bar = document.getElementById("border-box-bar");
|
|
1607
|
+
const buttons = [
|
|
1608
|
+
document.getElementById("border-box-one"),
|
|
1609
|
+
document.getElementById("border-box-two"),
|
|
1610
|
+
];
|
|
1611
|
+
|
|
1612
|
+
wrapper.style.boxSizing = "border-box";
|
|
1613
|
+
Object.defineProperty(wrapper, "clientWidth", {
|
|
1614
|
+
configurable: true,
|
|
1615
|
+
value: 130,
|
|
1616
|
+
});
|
|
1617
|
+
|
|
1618
|
+
for (const button of buttons) {
|
|
1619
|
+
Object.defineProperty(button, "offsetWidth", {
|
|
1620
|
+
configurable: true,
|
|
1621
|
+
value: 60,
|
|
1622
|
+
});
|
|
1623
|
+
Object.defineProperty(button, "offsetHeight", {
|
|
1624
|
+
configurable: true,
|
|
1625
|
+
value: 30,
|
|
1626
|
+
});
|
|
1627
|
+
button.getBoundingClientRect = () => ({
|
|
1628
|
+
width: 60,
|
|
1629
|
+
height: 30,
|
|
1630
|
+
top: 0,
|
|
1631
|
+
right: 60,
|
|
1632
|
+
bottom: 30,
|
|
1633
|
+
left: 0,
|
|
1634
|
+
x: 0,
|
|
1635
|
+
y: 0,
|
|
1636
|
+
toJSON: () => {},
|
|
1637
|
+
});
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
const switchButton = bar.shadowRoot.querySelector(
|
|
1641
|
+
'[data-monster-role="switch"]',
|
|
1642
|
+
);
|
|
1643
|
+
Object.defineProperty(switchButton, "offsetWidth", {
|
|
1644
|
+
configurable: true,
|
|
1645
|
+
get: () =>
|
|
1646
|
+
switchButton.hasAttribute("hidden") ||
|
|
1647
|
+
switchButton.classList.contains("hidden")
|
|
1648
|
+
? 0
|
|
1649
|
+
: 20,
|
|
1650
|
+
});
|
|
1651
|
+
|
|
1652
|
+
await flushFrames();
|
|
1653
|
+
|
|
1654
|
+
expect(switchButton.hasAttribute("hidden")).to.be.true;
|
|
1655
|
+
expect(buttons.every((button) => !button.hasAttribute("slot"))).to.be.true;
|
|
1656
|
+
} finally {
|
|
1657
|
+
window.requestAnimationFrame = originalRequestAnimationFrame;
|
|
1658
|
+
globalThis.requestAnimationFrame = originalGlobalRequestAnimationFrame;
|
|
1659
|
+
}
|
|
1660
|
+
});
|
|
1661
|
+
|
|
1662
|
+
it("should recalculate overflow when a visible control width changes", async function () {
|
|
1663
|
+
const OriginalResizeObserver = window.ResizeObserver;
|
|
1664
|
+
const originalGlobalResizeObserver = globalThis.ResizeObserver;
|
|
1665
|
+
const originalRequestAnimationFrame = window.requestAnimationFrame;
|
|
1666
|
+
const originalGlobalRequestAnimationFrame = globalThis.requestAnimationFrame;
|
|
1667
|
+
|
|
1668
|
+
class TrackingResizeObserver extends ResizeObserverMock {
|
|
1669
|
+
static instances = [];
|
|
1670
|
+
|
|
1671
|
+
constructor(callback) {
|
|
1672
|
+
super(callback);
|
|
1673
|
+
TrackingResizeObserver.instances.push(this);
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
const scheduledCallbacks = [];
|
|
1678
|
+
const flushFrames = async () => {
|
|
1679
|
+
while (scheduledCallbacks.length > 0) {
|
|
1680
|
+
scheduledCallbacks.shift()();
|
|
1681
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1682
|
+
}
|
|
1683
|
+
};
|
|
1684
|
+
|
|
1685
|
+
try {
|
|
1686
|
+
window.ResizeObserver = TrackingResizeObserver;
|
|
1687
|
+
globalThis.ResizeObserver = TrackingResizeObserver;
|
|
1688
|
+
window.requestAnimationFrame = (callback) => {
|
|
1689
|
+
scheduledCallbacks.push(callback);
|
|
1690
|
+
return scheduledCallbacks.length;
|
|
1691
|
+
};
|
|
1692
|
+
globalThis.requestAnimationFrame = window.requestAnimationFrame;
|
|
1693
|
+
|
|
1694
|
+
const mocks = document.getElementById("mocks");
|
|
1695
|
+
mocks.innerHTML = `
|
|
1696
|
+
<div id="item-resize-wrapper">
|
|
1697
|
+
<monster-control-bar id="item-resize-bar">
|
|
1698
|
+
<button id="item-resize-one">One</button>
|
|
1699
|
+
<button id="item-resize-two">Two</button>
|
|
1700
|
+
</monster-control-bar>
|
|
1701
|
+
</div>
|
|
1702
|
+
`;
|
|
1703
|
+
|
|
1704
|
+
const wrapper = document.getElementById("item-resize-wrapper");
|
|
1705
|
+
const bar = document.getElementById("item-resize-bar");
|
|
1706
|
+
const buttons = [
|
|
1707
|
+
document.getElementById("item-resize-one"),
|
|
1708
|
+
document.getElementById("item-resize-two"),
|
|
1709
|
+
];
|
|
1710
|
+
const widths = [60, 60];
|
|
1711
|
+
|
|
1712
|
+
wrapper.style.boxSizing = "border-box";
|
|
1713
|
+
Object.defineProperty(wrapper, "clientWidth", {
|
|
1714
|
+
configurable: true,
|
|
1715
|
+
value: 160,
|
|
1716
|
+
});
|
|
1717
|
+
|
|
1718
|
+
buttons.forEach((button, index) => {
|
|
1719
|
+
Object.defineProperty(button, "offsetWidth", {
|
|
1720
|
+
configurable: true,
|
|
1721
|
+
get: () => widths[index],
|
|
1722
|
+
});
|
|
1723
|
+
Object.defineProperty(button, "offsetHeight", {
|
|
1724
|
+
configurable: true,
|
|
1725
|
+
value: 30,
|
|
1726
|
+
});
|
|
1727
|
+
button.getBoundingClientRect = () => ({
|
|
1728
|
+
width: widths[index],
|
|
1729
|
+
height: 30,
|
|
1730
|
+
top: 0,
|
|
1731
|
+
right: widths[index],
|
|
1732
|
+
bottom: 30,
|
|
1733
|
+
left: 0,
|
|
1734
|
+
x: 0,
|
|
1735
|
+
y: 0,
|
|
1736
|
+
toJSON: () => {},
|
|
1737
|
+
});
|
|
1738
|
+
});
|
|
1739
|
+
|
|
1740
|
+
const switchButton = bar.shadowRoot.querySelector(
|
|
1741
|
+
'[data-monster-role="switch"]',
|
|
1742
|
+
);
|
|
1743
|
+
Object.defineProperty(switchButton, "offsetWidth", {
|
|
1744
|
+
configurable: true,
|
|
1745
|
+
value: 20,
|
|
1746
|
+
});
|
|
1747
|
+
|
|
1748
|
+
await flushFrames();
|
|
1749
|
+
expect(buttons.every((button) => !button.hasAttribute("slot"))).to.be.true;
|
|
1750
|
+
|
|
1751
|
+
const resizeObserver = TrackingResizeObserver.instances.find((observer) =>
|
|
1752
|
+
observer.elements.includes(wrapper),
|
|
1753
|
+
);
|
|
1754
|
+
expect(resizeObserver).to.exist;
|
|
1755
|
+
|
|
1756
|
+
widths[0] = 110;
|
|
1757
|
+
resizeObserver.triggerResize([{ target: buttons[0] }]);
|
|
1758
|
+
expect(scheduledCallbacks.length).to.equal(1);
|
|
1759
|
+
await flushFrames();
|
|
1760
|
+
|
|
1761
|
+
expect(buttons[0].hasAttribute("slot")).to.be.false;
|
|
1762
|
+
expect(buttons[1].getAttribute("slot")).to.equal("popper");
|
|
1763
|
+
expect(switchButton.hasAttribute("hidden")).to.be.false;
|
|
1764
|
+
} finally {
|
|
1765
|
+
window.ResizeObserver = OriginalResizeObserver;
|
|
1766
|
+
globalThis.ResizeObserver = originalGlobalResizeObserver;
|
|
1767
|
+
window.requestAnimationFrame = originalRequestAnimationFrame;
|
|
1768
|
+
globalThis.requestAnimationFrame = originalGlobalRequestAnimationFrame;
|
|
1769
|
+
}
|
|
1770
|
+
});
|
|
1771
|
+
|
|
1573
1772
|
it("should move spacers with adjacent overflow controls", async function () {
|
|
1574
1773
|
const OriginalResizeObserver = window.ResizeObserver;
|
|
1575
1774
|
const originalGlobalResizeObserver = globalThis.ResizeObserver;
|
|
@@ -1787,7 +1986,7 @@ describe("ControlBar", function () {
|
|
|
1787
1986
|
}
|
|
1788
1987
|
});
|
|
1789
1988
|
|
|
1790
|
-
it("should
|
|
1989
|
+
it("should restore the maximal fitting prefix regardless of resize direction", async function () {
|
|
1791
1990
|
const OriginalResizeObserver = window.ResizeObserver;
|
|
1792
1991
|
const originalGlobalResizeObserver = globalThis.ResizeObserver;
|
|
1793
1992
|
const originalRequestAnimationFrame = window.requestAnimationFrame;
|
|
@@ -1890,13 +2089,22 @@ describe("ControlBar", function () {
|
|
|
1890
2089
|
wrapperWidth = 190;
|
|
1891
2090
|
resizeObserver.triggerResize([{ target: wrapper }]);
|
|
1892
2091
|
await flushFrames();
|
|
2092
|
+
expect(switchButton.hasAttribute("hidden")).to.be.true;
|
|
2093
|
+
expect(document.getElementById("sticky-overflow-wide").hasAttribute("slot"))
|
|
2094
|
+
.to.be.false;
|
|
2095
|
+
expect(document.getElementById("sticky-overflow-small").hasAttribute("slot"))
|
|
2096
|
+
.to.be.false;
|
|
2097
|
+
|
|
2098
|
+
wrapperWidth = 90;
|
|
2099
|
+
resizeObserver.triggerResize([{ target: wrapper }]);
|
|
2100
|
+
await flushFrames();
|
|
1893
2101
|
expect(switchButton.hasAttribute("hidden")).to.be.false;
|
|
1894
2102
|
expect(document.getElementById("sticky-overflow-wide").getAttribute("slot"))
|
|
1895
2103
|
.to.equal("popper");
|
|
1896
2104
|
expect(document.getElementById("sticky-overflow-small").getAttribute("slot"))
|
|
1897
2105
|
.to.equal("popper");
|
|
1898
2106
|
|
|
1899
|
-
wrapperWidth =
|
|
2107
|
+
wrapperWidth = 190;
|
|
1900
2108
|
resizeObserver.triggerResize([{ target: wrapper }]);
|
|
1901
2109
|
await flushFrames();
|
|
1902
2110
|
expect(switchButton.hasAttribute("hidden")).to.be.true;
|