@cocreate/scroll 1.13.3 → 1.14.0
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/.github/workflows/automated.yml +5 -6
- package/CHANGELOG.md +19 -0
- package/package.json +1 -9
- package/src/index.js +352 -325
|
@@ -22,13 +22,13 @@ jobs:
|
|
|
22
22
|
runs-on: ubuntu-latest
|
|
23
23
|
steps:
|
|
24
24
|
- name: Checkout
|
|
25
|
-
uses: actions/checkout@
|
|
25
|
+
uses: actions/checkout@v4
|
|
26
26
|
- name: Setup Node.js
|
|
27
|
-
uses: actions/setup-node@
|
|
27
|
+
uses: actions/setup-node@v4
|
|
28
28
|
with:
|
|
29
|
-
node-version:
|
|
29
|
+
node-version: 22 # Required for the latest semantic-release plugins
|
|
30
30
|
- name: Semantic Release
|
|
31
|
-
uses: cycjimmy/semantic-release-action@
|
|
31
|
+
uses: cycjimmy/semantic-release-action@v4 # Update to v4 for better Node 20+ support
|
|
32
32
|
id: semantic
|
|
33
33
|
with:
|
|
34
34
|
extra_plugins: |
|
|
@@ -36,9 +36,8 @@ jobs:
|
|
|
36
36
|
@semantic-release/git
|
|
37
37
|
@semantic-release/github
|
|
38
38
|
env:
|
|
39
|
-
GITHUB_TOKEN: "${{ secrets.
|
|
39
|
+
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" # Use the built-in token if possible
|
|
40
40
|
NPM_TOKEN: "${{ secrets.NPM_TOKEN }}"
|
|
41
41
|
outputs:
|
|
42
42
|
new_release_published: "${{ steps.semantic.outputs.new_release_published }}"
|
|
43
43
|
new_release_version: "${{ steps.semantic.outputs.new_release_version }}"
|
|
44
|
-
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
# [1.14.0](https://github.com/CoCreate-app/CoCreate-scroll/compare/v1.13.4...v1.14.0) (2026-01-15)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* update worklow ([ac9e74a](https://github.com/CoCreate-app/CoCreate-scroll/commit/ac9e74a15fd8c7d27dc5809130ea0ee99c46777f))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* comprehensive initalization of ([cecbfce](https://github.com/CoCreate-app/CoCreate-scroll/commit/cecbfcec1d9d7f34b9d4a339d5e5ed3e8f38c363))
|
|
12
|
+
|
|
13
|
+
## [1.13.4](https://github.com/CoCreate-app/CoCreate-scroll/compare/v1.13.3...v1.13.4) (2025-09-07)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* improve scroll event handling by adding checks for values before updating attributes ([6411e3c](https://github.com/CoCreate-app/CoCreate-scroll/commit/6411e3cfed01ce2d135352a1b31b090b067a90e2))
|
|
19
|
+
|
|
1
20
|
## [1.13.3](https://github.com/CoCreate-app/CoCreate-scroll/compare/v1.13.2...v1.13.3) (2025-05-01)
|
|
2
21
|
|
|
3
22
|
|
package/package.json
CHANGED
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/scroll",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "A simple scroll component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"scroll",
|
|
7
|
-
"cocreate",
|
|
8
|
-
"low-code-framework",
|
|
9
|
-
"no-code-framework",
|
|
10
|
-
"cocreatejs",
|
|
11
|
-
"cocreatejs-component",
|
|
12
|
-
"cocreate-framework",
|
|
13
|
-
"no-code",
|
|
14
7
|
"low-code",
|
|
15
|
-
"collaborative-framework",
|
|
16
8
|
"realtime",
|
|
17
9
|
"realtime-framework",
|
|
18
10
|
"collaboration",
|
package/src/index.js
CHANGED
|
@@ -1,347 +1,374 @@
|
|
|
1
1
|
import Observer from "@cocreate/observer";
|
|
2
2
|
import Actions from "@cocreate/actions";
|
|
3
3
|
|
|
4
|
+
const selector =
|
|
5
|
+
"[scroll], [scroll-to], [scrollable-x], [scrollable-y], [scroll-up], [scroll-down], [scroll-top], [scroll-bottom], [scroll-limbo], [scroll-intersect], [scrolling]";
|
|
6
|
+
|
|
4
7
|
const CoCreateScroll = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
8
|
+
delta: 3,
|
|
9
|
+
observer: null,
|
|
10
|
+
// timer: null, // Removed: Timer needs to be instance-specific, not global
|
|
11
|
+
firedEvents: new Map(),
|
|
12
|
+
|
|
13
|
+
init: function () {
|
|
14
|
+
let elements = document.querySelectorAll(selector);
|
|
15
|
+
this.__initIntersectionObserver();
|
|
16
|
+
this.initElements(elements);
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
initElements: function (elements) {
|
|
20
|
+
for (let el of elements) this.initElement(el);
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
initElement: function (element) {
|
|
24
|
+
const self = this;
|
|
25
|
+
const upSize = this.__getSize(element.getAttribute("scroll-up"));
|
|
26
|
+
const downSize = this.__getSize(element.getAttribute("scroll-down"));
|
|
27
|
+
const attrName = element.getAttribute("scroll-attribute") || "class";
|
|
28
|
+
const targetSelector = element.getAttribute("scroll-query");
|
|
29
|
+
const scrollSelector = element.getAttribute("scroll-element");
|
|
30
|
+
const intersectValue = element.getAttribute("scroll-intersect");
|
|
31
|
+
const scrollTo = element.getAttribute("scroll-to");
|
|
32
|
+
|
|
33
|
+
updateScrollableAttributes(element);
|
|
34
|
+
|
|
35
|
+
let values =
|
|
36
|
+
element.getAttribute("scroll") ||
|
|
37
|
+
element.getAttribute("scroll-value");
|
|
38
|
+
if (values || values === "")
|
|
39
|
+
values = values.split(",").map((x) => x.trim());
|
|
40
|
+
|
|
41
|
+
let scrollInfo = {
|
|
42
|
+
attrName: attrName,
|
|
43
|
+
values: values,
|
|
44
|
+
upSize: upSize,
|
|
45
|
+
downSize: downSize,
|
|
46
|
+
scrollTop: element.getAttribute("scroll-top"),
|
|
47
|
+
scrollLimbo: element.getAttribute("scroll-limbo"),
|
|
48
|
+
scrollBottom: element.getAttribute("scroll-bottom"),
|
|
49
|
+
scrolling: element.getAttribute("scrolling"),
|
|
50
|
+
scrollTo,
|
|
51
|
+
timer: null // Added: Store timer here to persist across events
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
let elements = [element];
|
|
55
|
+
if (targetSelector) {
|
|
56
|
+
elements = document.querySelectorAll(targetSelector);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
elements.forEach((el) => {
|
|
60
|
+
el.scrollStatus = { currentPos: 0 };
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// this.__runScrollEvent(element, scrollInfo);
|
|
64
|
+
|
|
65
|
+
let scrollableElements;
|
|
66
|
+
if (scrollSelector)
|
|
67
|
+
scrollableElements = document.querySelectorAll(scrollSelector);
|
|
68
|
+
else if (element.hasAttribute("scroll-element"))
|
|
69
|
+
scrollableElements = [element];
|
|
70
|
+
|
|
71
|
+
if (scrollableElements) {
|
|
72
|
+
for (let scrollableEl of scrollableElements) {
|
|
73
|
+
scrollableEl.addEventListener("scroll", function (event) {
|
|
74
|
+
self._scrollEvent(
|
|
75
|
+
elements,
|
|
76
|
+
element,
|
|
77
|
+
scrollInfo,
|
|
78
|
+
scrollableEl
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
// this.WindowInit = true;
|
|
84
|
+
window.addEventListener("scroll", function (event) {
|
|
85
|
+
self._scrollEvent(elements, element, scrollInfo);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (intersectValue && window.IntersectionObserver && this.observer) {
|
|
90
|
+
this.observer.observe(element);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (scrollTo) {
|
|
94
|
+
this.setScrollPosition(element, scrollTo);
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
_scrollEvent: function (elements, element, scrollInfo, scrollableEl) {
|
|
99
|
+
const self = this;
|
|
100
|
+
if (!element.scrollStatus) return;
|
|
101
|
+
let scrollEl = scrollableEl || window;
|
|
102
|
+
if (
|
|
103
|
+
Math.abs(
|
|
104
|
+
scrollEl.scrollTop ||
|
|
105
|
+
scrollEl.scrollY - element.scrollStatus.currentPos
|
|
106
|
+
) <= self.delta
|
|
107
|
+
) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Fix: Use the timer stored in scrollInfo so it persists
|
|
112
|
+
if (scrollInfo.timer != null) {
|
|
113
|
+
clearTimeout(scrollInfo.timer);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
elements.forEach((el) => {
|
|
117
|
+
self.__setScrolling(el, scrollInfo, false);
|
|
118
|
+
self.__runScrollEvent(el, scrollInfo, scrollableEl);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
scrollInfo.timer = setTimeout(function () {
|
|
122
|
+
elements.forEach((el) => {
|
|
123
|
+
self.__setScrolling(el, scrollInfo, true);
|
|
124
|
+
});
|
|
125
|
+
}, 500);
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
setScrollPosition: function (element, scrollTo) {
|
|
129
|
+
if (!scrollTo) return;
|
|
130
|
+
if (scrollTo.includes("top")) {
|
|
131
|
+
element.scrollTop = 0;
|
|
132
|
+
} else if (scrollTo.includes("bottom")) {
|
|
133
|
+
element.scrollTop = element.scrollHeight;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (scrollTo.includes("left")) {
|
|
137
|
+
element.scrollLeft = 0;
|
|
138
|
+
} else if (scrollTo.includes("right")) {
|
|
139
|
+
element.scrollLeft = element.scrollWidth;
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
__initIntersectionObserver: function () {
|
|
144
|
+
const self = this;
|
|
145
|
+
this.observer = new IntersectionObserver((entries) => {
|
|
146
|
+
// Deduplicate: Keep only the latest entry for each target element
|
|
147
|
+
const uniqueEntries = new Map();
|
|
148
|
+
entries.forEach((entry) => {
|
|
149
|
+
uniqueEntries.set(entry.target, entry);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Process only the unique, latest entries
|
|
153
|
+
uniqueEntries.forEach((entry) => {
|
|
154
|
+
let element = entry.target;
|
|
155
|
+
const attrName =
|
|
156
|
+
element.getAttribute("scroll-attribute") || "class";
|
|
157
|
+
const targetSelector = element.getAttribute("scroll-query");
|
|
158
|
+
const intersectValue = element.getAttribute("scroll-intersect");
|
|
159
|
+
|
|
160
|
+
let targetElements = [element];
|
|
161
|
+
if (targetSelector) {
|
|
162
|
+
targetElements = document.querySelectorAll(targetSelector);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (entry.isIntersecting) {
|
|
166
|
+
targetElements.forEach((el) =>
|
|
167
|
+
self.__addAttributeValue(el, attrName, intersectValue)
|
|
168
|
+
);
|
|
169
|
+
} else {
|
|
170
|
+
targetElements.forEach((el) =>
|
|
171
|
+
self.__removeAttributeValue(el, attrName, intersectValue)
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
},
|
|
177
|
+
|
|
178
|
+
__setScrolling: function (element, info, stopped = false) {
|
|
179
|
+
const { scrolling, attrName } = info;
|
|
180
|
+
if (stopped) {
|
|
181
|
+
this.__removeAttributeValue(element, attrName, scrolling);
|
|
182
|
+
} else {
|
|
183
|
+
this.__addAttributeValue(element, attrName, scrolling);
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
__runScrollEvent: function (element, info, scrollableEl) {
|
|
188
|
+
if (!element.scrollStatus) return;
|
|
189
|
+
const currentPos = element.scrollStatus.currentPos;
|
|
190
|
+
let scrollY, scrollHeight, innerHeight;
|
|
191
|
+
if (scrollableEl) {
|
|
192
|
+
scrollY = scrollableEl.scrollTop;
|
|
193
|
+
scrollHeight = scrollableEl.scrollHeight;
|
|
194
|
+
innerHeight = scrollableEl.clientHeight;
|
|
195
|
+
} else {
|
|
196
|
+
scrollY = window.scrollY;
|
|
197
|
+
scrollHeight = document.body.scrollHeight;
|
|
198
|
+
innerHeight = window.innerHeight;
|
|
199
|
+
}
|
|
200
|
+
const {
|
|
201
|
+
upSize,
|
|
202
|
+
downSize,
|
|
203
|
+
attrName,
|
|
204
|
+
values,
|
|
205
|
+
scrollTop,
|
|
206
|
+
scrollBottom,
|
|
207
|
+
scrollLimbo
|
|
208
|
+
} = info;
|
|
209
|
+
|
|
210
|
+
let newTime = new Date().getTime();
|
|
211
|
+
if ((values && !info.datetime) || newTime - info.datetime > 200) {
|
|
212
|
+
info["datetime"] = newTime;
|
|
213
|
+
|
|
214
|
+
if (upSize <= currentPos - scrollY) {
|
|
215
|
+
this.__addAttributeValue(element, attrName, values[0]);
|
|
216
|
+
this.__removeAttributeValue(element, attrName, values[1]);
|
|
217
|
+
} else if (downSize <= scrollY - currentPos) {
|
|
218
|
+
this.__removeAttributeValue(element, attrName, values[0]);
|
|
219
|
+
this.__addAttributeValue(element, attrName, values[1]);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
//. scroll top case
|
|
224
|
+
if (scrollY <= this.delta) {
|
|
225
|
+
if (values) {
|
|
226
|
+
this.__removeAttributeValue(element, attrName, values[0]);
|
|
227
|
+
this.__removeAttributeValue(element, attrName, values[1]);
|
|
228
|
+
}
|
|
229
|
+
this.__addAttributeValue(element, attrName, scrollTop);
|
|
230
|
+
} else {
|
|
231
|
+
this.__removeAttributeValue(element, attrName, scrollTop);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
//. scroll bottom case
|
|
235
|
+
// if ((window.innerHeight + scrollY) >= document.body.scrollHeight) {
|
|
236
|
+
if (innerHeight + scrollY >= scrollHeight) {
|
|
237
|
+
// this.__removeAttributeValue(element, attrName, values[0]);
|
|
238
|
+
// this.__removeAttributeValue(element, attrName, values[1]);
|
|
239
|
+
|
|
240
|
+
this.__addAttributeValue(element, attrName, scrollBottom);
|
|
241
|
+
} else {
|
|
242
|
+
this.__removeAttributeValue(element, attrName, scrollBottom);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// if (scrollY != 0 && (scrollY + window.innerHeight) != document.body.scrollHeight){
|
|
246
|
+
if (scrollY != 0 && scrollY + innerHeight != scrollHeight) {
|
|
247
|
+
this.__addAttributeValue(element, attrName, scrollLimbo);
|
|
248
|
+
} else {
|
|
249
|
+
this.__removeAttributeValue(element, attrName, scrollLimbo);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
element.scrollStatus.currentPos = scrollY;
|
|
253
|
+
},
|
|
254
|
+
|
|
255
|
+
__addAttributeValue: function (element, attrName, value) {
|
|
256
|
+
if (!value) return;
|
|
257
|
+
// Optimization: Use classList if the attribute is 'class'
|
|
258
|
+
if (attrName === "class") {
|
|
259
|
+
element.classList.add(value);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
let check = new RegExp("(\\s|^)" + value + "(\\s|$)");
|
|
264
|
+
let attrValue = element.getAttribute(attrName) || "";
|
|
265
|
+
|
|
266
|
+
if (!check.test(attrValue)) {
|
|
267
|
+
// Logic note: For non-class attributes, we append with a space
|
|
268
|
+
// This mimics class-like behavior for custom attributes
|
|
269
|
+
if (attrValue.length > 0) attrValue += " " + value;
|
|
270
|
+
else attrValue = value;
|
|
271
|
+
element.setAttribute(attrName, attrValue);
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
|
|
275
|
+
__removeAttributeValue: function (element, attrName, value) {
|
|
276
|
+
if (!value) return;
|
|
277
|
+
// Optimization: Use classList if the attribute is 'class'
|
|
278
|
+
if (attrName === "class") {
|
|
279
|
+
element.classList.remove(value);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
let check = new RegExp("(\\s|^)" + value + "(\\s|$)");
|
|
284
|
+
let attrValue = element.getAttribute(attrName) || "";
|
|
285
|
+
|
|
286
|
+
if (check.test(attrValue)) {
|
|
287
|
+
attrValue = attrValue.replace(check, " ").trim();
|
|
288
|
+
element.setAttribute(attrName, attrValue);
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
|
|
292
|
+
__getSize: function (attrValue, isWidth) {
|
|
293
|
+
let size = 0;
|
|
294
|
+
if (!attrValue) {
|
|
295
|
+
return 0;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (attrValue.includes("%")) {
|
|
299
|
+
size = attrValue.replace("%", "").trim();
|
|
300
|
+
size = Number(size) || 0;
|
|
301
|
+
|
|
302
|
+
// Fix: Logic was inverted (dividing screen by size).
|
|
303
|
+
// Changed to standard percentage calculation: size% of screen.
|
|
304
|
+
size = isWidth
|
|
305
|
+
? window.innerWidth * (size / 100)
|
|
306
|
+
: window.innerHeight * (size / 100);
|
|
307
|
+
} else {
|
|
308
|
+
size = attrValue.replace("px", "").trim();
|
|
309
|
+
size = Number(size) || 0;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return size;
|
|
313
|
+
}
|
|
287
314
|
};
|
|
288
315
|
|
|
289
316
|
function updateScrollableAttributes(element) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
317
|
+
if (element.hasAttribute("scrollable-y")) {
|
|
318
|
+
if (element.scrollWidth > element.clientWidth)
|
|
319
|
+
element.setAttribute("scrollable-y", "true");
|
|
320
|
+
else element.setAttribute("scrollable-y", "false");
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (element.hasAttribute("scrollable-x")) {
|
|
324
|
+
if (element.scrollHeight > element.clientHeight)
|
|
325
|
+
element.setAttribute("scrollable-x", "true");
|
|
326
|
+
else element.setAttribute("scrollable-x", "false");
|
|
327
|
+
}
|
|
301
328
|
}
|
|
302
329
|
|
|
303
330
|
Observer.init({
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
331
|
+
name: "CoCreateScrollCreate",
|
|
332
|
+
types: ["addedNodes"],
|
|
333
|
+
selector: selector,
|
|
334
|
+
callback: function (mutation) {
|
|
335
|
+
CoCreateScroll.initElement(mutation.target);
|
|
336
|
+
}
|
|
310
337
|
});
|
|
311
338
|
|
|
312
339
|
Observer.init({
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
340
|
+
name: "CoCreateScrollAttributes",
|
|
341
|
+
types: ["attributes"],
|
|
342
|
+
attributeFilter: ["scroll-to"],
|
|
343
|
+
// target: selector, // blocks mutations when applied
|
|
344
|
+
callback: function (mutation) {
|
|
345
|
+
CoCreateScroll.setScrollPosition(
|
|
346
|
+
mutation.target,
|
|
347
|
+
mutation.target.getAttribute("scroll-to")
|
|
348
|
+
);
|
|
349
|
+
}
|
|
323
350
|
});
|
|
324
351
|
Observer.init({
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
352
|
+
name: "CoCreateScrollAttributes",
|
|
353
|
+
types: ["attributes"],
|
|
354
|
+
attributeFilter: ["scrollable-x", "scrollable-y"],
|
|
355
|
+
// target: selector, // blocks mutations when applied
|
|
356
|
+
callback: function (mutation) {
|
|
357
|
+
if (
|
|
358
|
+
mutation.oldValue !==
|
|
359
|
+
mutation.target.getAttribute(mutation.attributeName)
|
|
360
|
+
)
|
|
361
|
+
updateScrollableAttributes(mutation.target);
|
|
362
|
+
}
|
|
336
363
|
});
|
|
337
364
|
|
|
338
365
|
Actions.init({
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
366
|
+
name: "scroll-to",
|
|
367
|
+
callback: (action) => {
|
|
368
|
+
// CoCreateScroll.setScrollPosition(mutation.target)
|
|
369
|
+
}
|
|
343
370
|
});
|
|
344
371
|
|
|
345
372
|
CoCreateScroll.init();
|
|
346
373
|
|
|
347
|
-
export default CoCreateScroll;
|
|
374
|
+
export default CoCreateScroll;
|