@schukai/monster 4.148.6 → 4.148.7
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.7"}
|
|
@@ -2110,6 +2110,7 @@ function finishTrackedFetch(token) {
|
|
|
2110
2110
|
function fetchIt(url, controlOptions) {
|
|
2111
2111
|
const self = this;
|
|
2112
2112
|
const lifecycleVersion = getRemoteLifecycleVersion.call(this);
|
|
2113
|
+
const lazyLoadRequest = controlOptions?.lazyLoad === true;
|
|
2113
2114
|
|
|
2114
2115
|
if (url instanceof URL) {
|
|
2115
2116
|
url = url.toString();
|
|
@@ -2144,6 +2145,11 @@ function fetchIt(url, controlOptions) {
|
|
|
2144
2145
|
}
|
|
2145
2146
|
|
|
2146
2147
|
new Processing(10, () => {
|
|
2148
|
+
if (lazyLoadRequest && shouldLazyLoadOptions.call(this) !== true) {
|
|
2149
|
+
resolve(false);
|
|
2150
|
+
return;
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2147
2153
|
fetchData
|
|
2148
2154
|
.call(this, url)
|
|
2149
2155
|
.then((map) => {
|
|
@@ -2190,7 +2196,7 @@ function fetchIt(url, controlOptions) {
|
|
|
2190
2196
|
updatePopper.call(this);
|
|
2191
2197
|
setStatusOrRemoveBadges.call(this, "closed");
|
|
2192
2198
|
|
|
2193
|
-
resolve();
|
|
2199
|
+
resolve(lazyLoadRequest ? true : undefined);
|
|
2194
2200
|
});
|
|
2195
2201
|
|
|
2196
2202
|
return;
|
|
@@ -4001,10 +4007,7 @@ function handleFilterKeyboardEvents(event) {
|
|
|
4001
4007
|
event.preventDefault();
|
|
4002
4008
|
break;
|
|
4003
4009
|
default:
|
|
4004
|
-
if (
|
|
4005
|
-
this.getOption("features.lazyLoad") === true &&
|
|
4006
|
-
this[lazyLoadDoneSymbol] !== true
|
|
4007
|
-
) {
|
|
4010
|
+
if (shouldLazyLoadOptions.call(this)) {
|
|
4008
4011
|
this.click();
|
|
4009
4012
|
}
|
|
4010
4013
|
}
|
|
@@ -4322,6 +4325,14 @@ function getFilterMode() {
|
|
|
4322
4325
|
}
|
|
4323
4326
|
}
|
|
4324
4327
|
|
|
4328
|
+
function shouldLazyLoadOptions() {
|
|
4329
|
+
return (
|
|
4330
|
+
getFilterMode.call(this) !== FILTER_MODE_REMOTE &&
|
|
4331
|
+
this.getOption("features.lazyLoad") === true &&
|
|
4332
|
+
this[lazyLoadDoneSymbol] !== true
|
|
4333
|
+
);
|
|
4334
|
+
}
|
|
4335
|
+
|
|
4325
4336
|
function getCurrentFilterValue() {
|
|
4326
4337
|
if (this.getOption("filter.position") === FILTER_POSITION_INLINE) {
|
|
4327
4338
|
if (this[inlineFilterElementSymbol] instanceof HTMLInputElement) {
|
|
@@ -4652,8 +4663,7 @@ function areOptionsAvailableAndInitInternal() {
|
|
|
4652
4663
|
msg = this.getOption("labels.cannot-be-loaded");
|
|
4653
4664
|
} else if (
|
|
4654
4665
|
this.getOption("url") !== null &&
|
|
4655
|
-
|
|
4656
|
-
this[lazyLoadDoneSymbol] !== true
|
|
4666
|
+
shouldLazyLoadOptions.call(this)
|
|
4657
4667
|
) {
|
|
4658
4668
|
msg = this.getOption("labels.click-to-load-options");
|
|
4659
4669
|
}
|
|
@@ -5122,10 +5132,7 @@ function show() {
|
|
|
5122
5132
|
|
|
5123
5133
|
focusFilter.call(this);
|
|
5124
5134
|
|
|
5125
|
-
|
|
5126
|
-
this.getOption("features.lazyLoad") && this[lazyLoadDoneSymbol] !== true;
|
|
5127
|
-
|
|
5128
|
-
if (lazyLoadFlag === true) {
|
|
5135
|
+
if (shouldLazyLoadOptions.call(this)) {
|
|
5129
5136
|
if (this[lazyLoadRequestSymbol] instanceof Promise) {
|
|
5130
5137
|
return;
|
|
5131
5138
|
}
|
|
@@ -5141,17 +5148,20 @@ function show() {
|
|
|
5141
5148
|
const lazyLoadRequest = new Processing(200, () => {
|
|
5142
5149
|
if (
|
|
5143
5150
|
!isRemoteLifecycleCurrent.call(this, lifecycleVersion) ||
|
|
5144
|
-
this.isConnected !== true
|
|
5151
|
+
this.isConnected !== true ||
|
|
5152
|
+
shouldLazyLoadOptions.call(this) !== true
|
|
5145
5153
|
) {
|
|
5146
|
-
return;
|
|
5154
|
+
return false;
|
|
5147
5155
|
}
|
|
5148
5156
|
|
|
5149
|
-
return
|
|
5157
|
+
return fetchIt.call(this, undefined, {
|
|
5158
|
+
lazyLoad: true,
|
|
5159
|
+
});
|
|
5150
5160
|
}).run();
|
|
5151
5161
|
this[lazyLoadRequestSymbol] = lazyLoadRequest;
|
|
5152
5162
|
|
|
5153
5163
|
lazyLoadRequest
|
|
5154
|
-
.then(() => {
|
|
5164
|
+
.then((lazyLoadCompleted) => {
|
|
5155
5165
|
if (
|
|
5156
5166
|
this[lazyLoadRequestSymbol] !== lazyLoadRequest ||
|
|
5157
5167
|
!isRemoteLifecycleCurrent.call(this, lifecycleVersion) ||
|
|
@@ -5161,6 +5171,19 @@ function show() {
|
|
|
5161
5171
|
}
|
|
5162
5172
|
|
|
5163
5173
|
delete this[lazyLoadRequestSymbol];
|
|
5174
|
+
if (lazyLoadCompleted !== true) {
|
|
5175
|
+
checkOptionState.call(this);
|
|
5176
|
+
requestAnimationFrame(() => {
|
|
5177
|
+
if (
|
|
5178
|
+
isRemoteLifecycleCurrent.call(this, lifecycleVersion) &&
|
|
5179
|
+
this.isConnected === true
|
|
5180
|
+
) {
|
|
5181
|
+
show.call(this);
|
|
5182
|
+
}
|
|
5183
|
+
});
|
|
5184
|
+
return;
|
|
5185
|
+
}
|
|
5186
|
+
|
|
5164
5187
|
this[lazyLoadDoneSymbol] = true;
|
|
5165
5188
|
delete this[lazyLoadErrorSymbol];
|
|
5166
5189
|
checkOptionState.call(this);
|
|
@@ -97,6 +97,23 @@ function configureRemotePaginatedSelect(select) {
|
|
|
97
97
|
select.setOption('mapping.objectsPerPage', 'pagination.perPage');
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
function configureInteractiveRemoteSelect(select) {
|
|
101
|
+
configureRemotePaginatedSelect(select);
|
|
102
|
+
select.setOption('filter.position', 'popper');
|
|
103
|
+
select.setOption('filter.defaultValue', '');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function createRemotePageResponse() {
|
|
107
|
+
return createJsonResponse({
|
|
108
|
+
items: [{id: 'alpha', name: 'Alpha'}],
|
|
109
|
+
pagination: {
|
|
110
|
+
total: 1,
|
|
111
|
+
page: 1,
|
|
112
|
+
perPage: 10
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
100
117
|
function configureLazySelect(select) {
|
|
101
118
|
select.setOption('url', 'https://example.com/lazy-options');
|
|
102
119
|
select.setOption('features.lazyLoad', true);
|
|
@@ -660,6 +677,128 @@ describe('Select', function () {
|
|
|
660
677
|
global['fetch'] = fetchReference;
|
|
661
678
|
});
|
|
662
679
|
|
|
680
|
+
it('should use the remote lifecycle when lazy loading is configured before connection', async function () {
|
|
681
|
+
const requests = [];
|
|
682
|
+
global['fetch'] = function (url) {
|
|
683
|
+
requests.push(String(url));
|
|
684
|
+
return createRemotePageResponse();
|
|
685
|
+
};
|
|
686
|
+
|
|
687
|
+
const mocks = document.getElementById('mocks');
|
|
688
|
+
const select = document.createElement('monster-select');
|
|
689
|
+
configureInteractiveRemoteSelect(select);
|
|
690
|
+
select.setOption('features.lazyLoad', true);
|
|
691
|
+
mocks.appendChild(select);
|
|
692
|
+
|
|
693
|
+
await waitForCondition(() => {
|
|
694
|
+
return select.shadowRoot.querySelector('[data-monster-role=container]') instanceof HTMLElement;
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
expect(select.getOption('features.lazyLoad')).to.equal(false);
|
|
698
|
+
select.shadowRoot.querySelector('[data-monster-role=container]').click();
|
|
699
|
+
|
|
700
|
+
await waitForCondition(() => requests.length === 1);
|
|
701
|
+
expect(requests).to.deep.equal([
|
|
702
|
+
'https://example.com/items?filter=&page=1'
|
|
703
|
+
]);
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
it('should ignore lazy loading reapplied to a connected remote select', async function () {
|
|
707
|
+
const requests = [];
|
|
708
|
+
global['fetch'] = function (url) {
|
|
709
|
+
requests.push(String(url));
|
|
710
|
+
return createRemotePageResponse();
|
|
711
|
+
};
|
|
712
|
+
|
|
713
|
+
const mocks = document.getElementById('mocks');
|
|
714
|
+
const select = document.createElement('monster-select');
|
|
715
|
+
configureInteractiveRemoteSelect(select);
|
|
716
|
+
select.setOption('features.lazyLoad', true);
|
|
717
|
+
mocks.appendChild(select);
|
|
718
|
+
|
|
719
|
+
await waitForCondition(() => {
|
|
720
|
+
return select.getOption('features.lazyLoad') === false &&
|
|
721
|
+
select.shadowRoot.querySelector('[data-monster-role=container]') instanceof HTMLElement;
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
select.setOption('features', {
|
|
725
|
+
...select.getOption('features'),
|
|
726
|
+
lazyLoad: true
|
|
727
|
+
});
|
|
728
|
+
select.setOption('filter', {
|
|
729
|
+
...select.getOption('filter'),
|
|
730
|
+
mode: 'remote'
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
expect(select.getOption('features.lazyLoad')).to.equal(true);
|
|
734
|
+
select.shadowRoot.querySelector('[data-monster-role=container]').click();
|
|
735
|
+
|
|
736
|
+
await waitForCondition(() => requests.length === 1);
|
|
737
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
738
|
+
expect(requests).to.deep.equal([
|
|
739
|
+
'https://example.com/items?filter=&page=1'
|
|
740
|
+
]);
|
|
741
|
+
expect(select.getOption('options').map(option => option.value)).to.deep.equal(['alpha']);
|
|
742
|
+
expect(select.getAttribute('data-monster-error') ?? '').to.not.contain('No options available.');
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
it('should switch from lazy option loading to remote loading before interaction', async function () {
|
|
746
|
+
const requests = [];
|
|
747
|
+
global['fetch'] = function (url) {
|
|
748
|
+
requests.push(String(url));
|
|
749
|
+
return createRemotePageResponse();
|
|
750
|
+
};
|
|
751
|
+
|
|
752
|
+
const mocks = document.getElementById('mocks');
|
|
753
|
+
const select = document.createElement('monster-select');
|
|
754
|
+
configureInteractiveRemoteSelect(select);
|
|
755
|
+
select.setOption('filter.mode', 'options');
|
|
756
|
+
select.setOption('features.lazyLoad', true);
|
|
757
|
+
mocks.appendChild(select);
|
|
758
|
+
|
|
759
|
+
await waitForCondition(() => {
|
|
760
|
+
return select.shadowRoot.querySelector('[data-monster-role=container]') instanceof HTMLElement;
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
select.setOption('filter.mode', 'remote');
|
|
764
|
+
select.shadowRoot.querySelector('[data-monster-role=container]').click();
|
|
765
|
+
|
|
766
|
+
await waitForCondition(() => requests.length === 1);
|
|
767
|
+
expect(requests).to.deep.equal([
|
|
768
|
+
'https://example.com/items?filter=&page=1'
|
|
769
|
+
]);
|
|
770
|
+
});
|
|
771
|
+
|
|
772
|
+
it('should cancel a delayed lazy branch after switching to remote mode', async function () {
|
|
773
|
+
const requests = [];
|
|
774
|
+
global['fetch'] = function (url) {
|
|
775
|
+
requests.push(String(url));
|
|
776
|
+
return createRemotePageResponse();
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
const mocks = document.getElementById('mocks');
|
|
780
|
+
const select = document.createElement('monster-select');
|
|
781
|
+
configureInteractiveRemoteSelect(select);
|
|
782
|
+
select.setOption('filter.mode', 'options');
|
|
783
|
+
select.setOption('features.lazyLoad', true);
|
|
784
|
+
mocks.appendChild(select);
|
|
785
|
+
|
|
786
|
+
await waitForCondition(() => {
|
|
787
|
+
return select.shadowRoot.querySelector('[data-monster-role=container]') instanceof HTMLElement;
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
select.shadowRoot.querySelector('[data-monster-role=container]').click();
|
|
791
|
+
select.setOption('filter.mode', 'remote');
|
|
792
|
+
|
|
793
|
+
await waitForCondition(() => requests.length === 1);
|
|
794
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
795
|
+
expect(requests).to.deep.equal([
|
|
796
|
+
'https://example.com/items?filter=&page=1'
|
|
797
|
+
]);
|
|
798
|
+
expect(select.getOption('options').map(option => option.value)).to.deep.equal(['alpha']);
|
|
799
|
+
expect(select.getAttribute('data-monster-error') ?? '').to.not.contain('No options available.');
|
|
800
|
+
});
|
|
801
|
+
|
|
663
802
|
it('should open from the first click after a delayed lazy response renders', async function () {
|
|
664
803
|
const deferredResponse = createDeferred();
|
|
665
804
|
let requestCount = 0;
|
|
@@ -476,7 +476,7 @@ describe("Tabs", function () {
|
|
|
476
476
|
});
|
|
477
477
|
|
|
478
478
|
it("should move overflowing tabs into the popper without losing them", function (done) {
|
|
479
|
-
this.timeout(
|
|
479
|
+
this.timeout(15000);
|
|
480
480
|
|
|
481
481
|
let mocks = document.getElementById("mocks");
|
|
482
482
|
const OriginalResizeObserver = window.ResizeObserver;
|
|
@@ -624,7 +624,7 @@ describe("Tabs", function () {
|
|
|
624
624
|
});
|
|
625
625
|
|
|
626
626
|
it("should preserve the overflow split and recalculate widths while rebuilding tab buttons", async function () {
|
|
627
|
-
this.timeout(
|
|
627
|
+
this.timeout(15000);
|
|
628
628
|
|
|
629
629
|
const mocks = document.getElementById("mocks");
|
|
630
630
|
restoreBoundingClientRect = installOverflowTabGeometryMock();
|