rytm-webflow 1.1.3 → 2.0.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/README.md +15 -1
- package/package.json +1 -2
- package/scripts/aswap/ASwap.js +17 -19
- package/scripts/aswap/ASwapDispatcher.js +152 -109
- package/scripts/aswap/Controller.js +5 -7
- package/scripts/aswap/ControllerImgLoad.js +2 -2
- package/scripts/aswap/View.js +0 -1
- package/scripts/bootstrap/v5/Bootstrap5.js +45 -0
- package/scripts/index.js +4 -0
- package/scripts/showup/ShowUp.js +18 -4
package/README.md
CHANGED
|
@@ -11,7 +11,6 @@ $ npm install rytm-webflow --save
|
|
|
11
11
|
## Dependencies
|
|
12
12
|
- gsap
|
|
13
13
|
- imagesloaded
|
|
14
|
-
- jquery
|
|
15
14
|
- scrollmagic
|
|
16
15
|
- scrollmagic-plugin-gsap
|
|
17
16
|
|
|
@@ -154,6 +153,7 @@ RytmWebflow.aswap.init({
|
|
|
154
153
|
| ```refreshOnSameUrl``` | ```true``` | When ```true``` each request on same URL will refresh browser's window |
|
|
155
154
|
| ```routes``` | ```{}``` | The routes object where you can define controllers and views |
|
|
156
155
|
| ```swapSelector``` | ```'#stage'``` | ASwap wrapper selector |
|
|
156
|
+
| ```defaultDocumentScrollBehavior``` | ```'smooth'``` | Default document scroll behaviour |
|
|
157
157
|
| ```trace``` | ```(message) => {}``` | A function to log stuff, eg in console |
|
|
158
158
|
|
|
159
159
|
### Controller class
|
|
@@ -204,6 +204,20 @@ RytmWebflow.aswap.init(params, {
|
|
|
204
204
|
| ```onViewShow()``` | fired when the new scene is loaded and the show transition is being started |
|
|
205
205
|
| ```onViewShown()``` | fired within ```animationTimeShow``` ms from show transition start |
|
|
206
206
|
|
|
207
|
+
### Bootstrap integration ###
|
|
208
|
+
#### Bootstrap v5 ####
|
|
209
|
+
A common situation is to hide all Bootstrap offcanvases or modals when an ASwap page transition is in made. To do so just call the `RytmWebflow.bootsrap5.hideFlyovers()` method. You can also hide offcanvases or modals separatly by calling the `RytmWebflow.bootsrap5.hideOffcanvases()` or `RytmWebflow.bootsrap5.hideModals()` methods.
|
|
210
|
+
A basic usage example:
|
|
211
|
+
```js
|
|
212
|
+
import RytmWebflow from 'rytm-webflow'
|
|
213
|
+
|
|
214
|
+
RytmWebflow.aswap.init(params, {
|
|
215
|
+
onViewHide: () => {
|
|
216
|
+
RytmWebflow.bootsrap5.hideFlyovers()
|
|
217
|
+
},
|
|
218
|
+
})
|
|
219
|
+
```
|
|
220
|
+
|
|
207
221
|
## ShowUp ##
|
|
208
222
|
ShowUp makes creating gsap scroll-triggered-animations much faster. It can be used to show content while user scrolls down the page. It can also be used for parallax like animations. ShowUp comes with the **Webflow syntax** - a minified way to describe an animation, it's duration (time), easing, delay or the trigger. Eg. `y:100,o:0` will animate an element from: `y:100px` and `opacity: 0` to it's current state. Go to [Webflow syntax](#markdown-header-webflow-syntax) for more.
|
|
209
223
|
### Webflow usage example
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rytm-webflow",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "rytm webflow pack - ASwap, ShowUp",
|
|
5
5
|
"main": "scripts/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"gsap": "^3.5.1",
|
|
20
20
|
"imagesloaded": "^4.1.4",
|
|
21
|
-
"jquery": "^3.1.1",
|
|
22
21
|
"scrollmagic": "^2.0.7",
|
|
23
22
|
"scrollmagic-plugin-gsap": "^1.0.4"
|
|
24
23
|
}
|
package/scripts/aswap/ASwap.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import $ from "jquery"
|
|
2
1
|
|
|
3
2
|
import ASwapDispatcher from "./ASwapDispatcher";
|
|
4
3
|
import Events from "./Events";
|
|
@@ -25,6 +24,7 @@ class ASwap {
|
|
|
25
24
|
refreshOnSameUrl: true, // refresh window if same URL is requested
|
|
26
25
|
routes: {},
|
|
27
26
|
swapSelector: '#stage', // swap wrapper selector
|
|
27
|
+
defaultDocumentScrollBehavior: 'smooth',
|
|
28
28
|
trace: () => {}, // a function to trace progress in console
|
|
29
29
|
}
|
|
30
30
|
// public events
|
|
@@ -102,7 +102,7 @@ class ASwap {
|
|
|
102
102
|
this.events.onRequestLoad()
|
|
103
103
|
}
|
|
104
104
|
onRequestLoaded(e) {
|
|
105
|
-
this.getControllersFromContainer(e.target
|
|
105
|
+
this.getControllersFromContainer(e.target.freshContent).forEach( (c, index)=> {
|
|
106
106
|
c.onRequestLoaded(e);
|
|
107
107
|
});
|
|
108
108
|
document.documentElement.classList.remove("as-request-loading");
|
|
@@ -112,7 +112,7 @@ class ASwap {
|
|
|
112
112
|
document.documentElement.classList.add('as-hide');
|
|
113
113
|
this.getActiveControlles().forEach( (c, index)=> {
|
|
114
114
|
// if view is not present in fresh content then call controller hide
|
|
115
|
-
if (!c.getViewContainer(e.target
|
|
115
|
+
if (!c.getViewContainer(e.target.freshContent)) {
|
|
116
116
|
c.onViewHide(e);
|
|
117
117
|
}
|
|
118
118
|
});
|
|
@@ -122,34 +122,34 @@ class ASwap {
|
|
|
122
122
|
document.documentElement.classList.remove('as-hide');
|
|
123
123
|
this.getActiveControlles().forEach( (c, index)=> {
|
|
124
124
|
// if view is not present in fresh content then call controller hidden
|
|
125
|
-
if (!c.getViewContainer(e.target
|
|
125
|
+
if (!c.getViewContainer(e.target.freshContent)) {
|
|
126
126
|
c.onViewHidden(e);
|
|
127
127
|
}
|
|
128
128
|
});
|
|
129
129
|
this.events.onViewHidden()
|
|
130
130
|
}
|
|
131
131
|
onViewSwapStart(e) {
|
|
132
|
-
this.getControllersFromContainer(e.target
|
|
132
|
+
this.getControllersFromContainer(e.target.freshContent).forEach( (c, index)=> {
|
|
133
133
|
c.onViewSwapStart(e);
|
|
134
134
|
});
|
|
135
135
|
this.events.onViewSwapStart()
|
|
136
136
|
}
|
|
137
137
|
onViewSwapComplete(e) {
|
|
138
|
-
this.getControllersFromContainer(e.target
|
|
138
|
+
this.getControllersFromContainer(e.target.freshContent).forEach( (c, index)=> {
|
|
139
139
|
c.onViewSwapComplete(e);
|
|
140
140
|
});
|
|
141
141
|
this.events.onViewSwapComplete()
|
|
142
142
|
}
|
|
143
143
|
onViewShow(e) {
|
|
144
144
|
document.documentElement.classList.add('as-show');
|
|
145
|
-
this.getControllersFromContainer(e.target
|
|
145
|
+
this.getControllersFromContainer(e.target.freshContent).forEach( (c, index)=> {
|
|
146
146
|
c.onViewShow(e);
|
|
147
147
|
});
|
|
148
148
|
this.events.onViewShow()
|
|
149
149
|
}
|
|
150
150
|
onViewShown(e) {
|
|
151
151
|
document.documentElement.classList.add('as-show');
|
|
152
|
-
this.getControllersFromContainer(e.target
|
|
152
|
+
this.getControllersFromContainer(e.target.freshContent).forEach( (c, index)=> {
|
|
153
153
|
c.onViewShown(e);
|
|
154
154
|
});
|
|
155
155
|
document.documentElement.classList.remove('as-in-progress');
|
|
@@ -172,22 +172,20 @@ class ASwap {
|
|
|
172
172
|
}
|
|
173
173
|
/**
|
|
174
174
|
* get controllers from container based on view's included in the container
|
|
175
|
-
* @param
|
|
175
|
+
* @param container
|
|
176
176
|
* @returns {Array}
|
|
177
177
|
**/
|
|
178
|
-
getControllersFromContainer(
|
|
178
|
+
getControllersFromContainer(container) {
|
|
179
179
|
let arr = [];
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
let c = this.getController(name, id);
|
|
180
|
+
const list = [...container.querySelectorAll("*[data-as-view]")]
|
|
181
|
+
list.forEach((el, index) => {
|
|
182
|
+
const name = el.dataset.asView
|
|
183
|
+
const id = el.dataset.asId ? el.dataset.asId : name
|
|
184
|
+
const c = this.getController(name, id)
|
|
187
185
|
if (c) {
|
|
188
|
-
arr.push(c)
|
|
186
|
+
arr.push(c)
|
|
189
187
|
}
|
|
190
|
-
})
|
|
188
|
+
})
|
|
191
189
|
return arr;
|
|
192
190
|
}
|
|
193
191
|
/**
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import $ from "jquery"
|
|
2
1
|
import Events from "./Events"
|
|
3
2
|
import EventDispatcher from "./EventDispatcher"
|
|
4
3
|
|
|
@@ -24,7 +23,7 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
24
23
|
this.prevUrl = null;
|
|
25
24
|
this.ajaxStore = [];
|
|
26
25
|
this.asHistory = [];
|
|
27
|
-
this
|
|
26
|
+
this.freshContent = document.querySelector(this.swapSelector);
|
|
28
27
|
|
|
29
28
|
}
|
|
30
29
|
|
|
@@ -65,48 +64,61 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
65
64
|
* @param tag {String} the tag name, eg. body
|
|
66
65
|
* @returns {String|Boolean}
|
|
67
66
|
**/
|
|
68
|
-
getTagFromResult(result, tag) {
|
|
67
|
+
getTagFromResult(result, tag, index = 0) {
|
|
69
68
|
let regex = new RegExp('<' + tag + '[^>]*>((.|[\n\r])*)<\/' + tag + '>');
|
|
70
69
|
let body = regex.exec(result);
|
|
71
|
-
if (body) {
|
|
72
|
-
return body[
|
|
70
|
+
if (body && body[index]) {
|
|
71
|
+
return body[index];
|
|
73
72
|
} else {
|
|
74
|
-
this.warning("AS problem - " + tag + " could not be extracted");
|
|
73
|
+
this.warning("AS problem - " + tag + " could not be extracted, index:", idnex);
|
|
75
74
|
return false;
|
|
76
75
|
}
|
|
77
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* ###
|
|
79
|
+
*/
|
|
80
|
+
getElementFromResult(result, tagName) {
|
|
81
|
+
let htmlStr = this.getTagFromResult(result, tagName, 1)
|
|
82
|
+
let el = document.createElement(tagName)
|
|
83
|
+
el.innerHTML = htmlStr.trim()
|
|
84
|
+
return el
|
|
85
|
+
}
|
|
78
86
|
|
|
79
87
|
/**
|
|
80
88
|
* swap the meta and title tags in document's <head>
|
|
81
89
|
* @param result {String} the ajax request result
|
|
82
90
|
**/
|
|
83
91
|
swapHeadMeta(result) {
|
|
84
|
-
|
|
85
|
-
if (!
|
|
92
|
+
const freshHead = this.getElementFromResult(result, "head")
|
|
93
|
+
if (!freshHead) {
|
|
86
94
|
this.warning("AS problem - head was not found in result");
|
|
87
95
|
return false;
|
|
88
96
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
// swap
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
97
|
+
const list = [...freshHead.querySelectorAll("*")]
|
|
98
|
+
list.forEach((el, index) => {
|
|
99
|
+
// swap if TITLE or META
|
|
100
|
+
switch (el.nodeName.toLowerCase()) {
|
|
101
|
+
case "title":
|
|
102
|
+
document.title = el.innerHTML
|
|
103
|
+
break;
|
|
104
|
+
case "meta":
|
|
105
|
+
const name = el.getAttribute("name")
|
|
106
|
+
const property = el.getAttribute("property")
|
|
107
|
+
const itemprop = el.getAttribute("itemprop")
|
|
108
|
+
const content = el.getAttribute("content")
|
|
109
|
+
// get the meta query string
|
|
110
|
+
let query = 'html head meta'
|
|
111
|
+
query += (name ? '[name="' + name + '"' : '')
|
|
112
|
+
query += (property ? '[property="' + property + '"' : '')
|
|
113
|
+
query += (itemprop ? '[itemprop="' + itemprop + '"' : '')
|
|
114
|
+
let metaEl = document.querySelector(query)
|
|
115
|
+
if (metaEl && content) {
|
|
116
|
+
metaEl.setAttribute("content", content)
|
|
117
|
+
}
|
|
118
|
+
break;
|
|
108
119
|
}
|
|
109
|
-
})
|
|
120
|
+
})
|
|
121
|
+
|
|
110
122
|
}
|
|
111
123
|
/**
|
|
112
124
|
* swap the HTML class names
|
|
@@ -134,8 +146,7 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
134
146
|
}
|
|
135
147
|
let html = document.createElement('html');
|
|
136
148
|
html.innerHTML = body;
|
|
137
|
-
|
|
138
|
-
return $resultBody.find(this.swapSelector);
|
|
149
|
+
return html.querySelector(this.swapSelector)
|
|
139
150
|
}
|
|
140
151
|
|
|
141
152
|
/**
|
|
@@ -144,8 +155,8 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
144
155
|
**/
|
|
145
156
|
handleResult(result) {
|
|
146
157
|
// store fresh content in public variable
|
|
147
|
-
this
|
|
148
|
-
|
|
158
|
+
this.freshContent = this.getFreshContentFromResult(result);
|
|
159
|
+
const swap = document.querySelector(this.swapSelector)
|
|
149
160
|
// dispatch event
|
|
150
161
|
this.dispatch(Events.NAV_REQUEST_LOADED);
|
|
151
162
|
this.dispatch(Events.NAV_VIEW_HIDE);
|
|
@@ -155,17 +166,17 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
155
166
|
this.asAnimTimeout1 = setTimeout(()=> {
|
|
156
167
|
this.dispatch(Events.NAV_VIEW_HIDDEN);
|
|
157
168
|
this.dispatch(Events.NAV_SWAP_START);
|
|
158
|
-
if (this
|
|
159
|
-
|
|
160
|
-
|
|
169
|
+
if (this.freshContent) {
|
|
170
|
+
// swap stage classes
|
|
171
|
+
swap.setAttribute("class", this.freshContent.getAttribute("class"))
|
|
172
|
+
// swap content
|
|
173
|
+
swap.innerHTML = this.freshContent.innerHTML
|
|
161
174
|
}
|
|
162
175
|
// swap head (meta)
|
|
163
176
|
this.swapHeadMeta(result);
|
|
164
177
|
setTimeout(() => {
|
|
165
178
|
this.swapBodyToHtmlClasses(result);
|
|
166
179
|
}, 10)
|
|
167
|
-
|
|
168
|
-
|
|
169
180
|
// scroll up
|
|
170
181
|
if (!this.currentTrigger || !this.currentTrigger.classList.contains(this.noScrollClassName)) {
|
|
171
182
|
this.resetScrollPosition();
|
|
@@ -179,6 +190,7 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
179
190
|
this.dispatch(Events.NAV_VIEW_SHOWN);
|
|
180
191
|
}, this.animationTimeShow);
|
|
181
192
|
}, this.animationTimeHide);
|
|
193
|
+
|
|
182
194
|
}
|
|
183
195
|
/**
|
|
184
196
|
* get current URL
|
|
@@ -231,9 +243,18 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
231
243
|
* scroll back up
|
|
232
244
|
**/
|
|
233
245
|
resetScrollPosition() {
|
|
234
|
-
//
|
|
235
|
-
|
|
246
|
+
// set scrollBehavior to auto
|
|
247
|
+
document.documentElement.style.scrollBehavior = 'auto';
|
|
248
|
+
// scroll without animation
|
|
249
|
+
setTimeout(() => {
|
|
250
|
+
window.scrollTo(0, 0)
|
|
251
|
+
}, 5)
|
|
252
|
+
// set scrollBehavior to it's default value
|
|
253
|
+
setTimeout(() => {
|
|
254
|
+
document.documentElement.style.scrollBehavior = this.defaultDocumentScrollBehavior ? this.defaultDocumentScrollBehavior : 'smooth';
|
|
255
|
+
}, 5)
|
|
236
256
|
}
|
|
257
|
+
|
|
237
258
|
/**
|
|
238
259
|
* Preload URL
|
|
239
260
|
* @param url {String}
|
|
@@ -246,12 +267,15 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
246
267
|
if (result) {
|
|
247
268
|
return false
|
|
248
269
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
this.
|
|
270
|
+
let xhr = new XMLHttpRequest();
|
|
271
|
+
xhr.onreadystatechange = () => {
|
|
272
|
+
if (xhr.readyState === 4) {
|
|
273
|
+
// this.trace('URL was preloaded', url, xhr.responseText)
|
|
274
|
+
this.storeResult(url, xhr.responseText);
|
|
253
275
|
}
|
|
254
|
-
}
|
|
276
|
+
};
|
|
277
|
+
xhr.open('GET', url);
|
|
278
|
+
xhr.send();
|
|
255
279
|
|
|
256
280
|
}
|
|
257
281
|
/**
|
|
@@ -301,22 +325,21 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
301
325
|
loadURL(url, data = {}, method = 'get', useCache = true) {
|
|
302
326
|
// dispatch event
|
|
303
327
|
this.dispatch(Events.NAV_REQUEST_LOAD);
|
|
304
|
-
this.trace("ASwap load: ", url);
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
});
|
|
328
|
+
this.trace("ASwap load: ", url);
|
|
329
|
+
|
|
330
|
+
let xhr = new XMLHttpRequest();
|
|
331
|
+
xhr.onreadystatechange = () => {
|
|
332
|
+
if (xhr.readyState === 4) {
|
|
333
|
+
if (useCache) {
|
|
334
|
+
this.storeResult(url, xhr.responseText);
|
|
335
|
+
}
|
|
336
|
+
this.handleResult(xhr.responseText);
|
|
337
|
+
} else {
|
|
338
|
+
this.warning("AS problem - GET", url, "returned no result");
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
xhr.open(method, url);
|
|
342
|
+
xhr.send(data);
|
|
320
343
|
}
|
|
321
344
|
/**
|
|
322
345
|
* history pushState (URL)
|
|
@@ -337,7 +360,9 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
337
360
|
* @param e {Event}
|
|
338
361
|
**/
|
|
339
362
|
onHistoryBack(e) {
|
|
363
|
+
e.preventDefault();
|
|
340
364
|
let url = window.location.pathname + window.location.search;
|
|
365
|
+
console.log("HISTORY BACK", url)
|
|
341
366
|
this.openURL(url, true);
|
|
342
367
|
}
|
|
343
368
|
/**
|
|
@@ -349,76 +374,94 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
349
374
|
this.storeResult(url, result);
|
|
350
375
|
this.currentUrl = url;
|
|
351
376
|
}
|
|
352
|
-
isLinkElementValid(
|
|
377
|
+
isLinkElementValid(a) {
|
|
353
378
|
let result = false
|
|
354
|
-
if (
|
|
355
|
-
if (
|
|
379
|
+
if (a) {
|
|
380
|
+
if (!a.classList.contains(this.noSwapClassName) && a.getAttribute("target") != "_blank") {
|
|
356
381
|
result = true
|
|
357
382
|
}
|
|
358
383
|
}
|
|
359
384
|
return result
|
|
360
385
|
}
|
|
361
|
-
isFormElementValid(
|
|
386
|
+
isFormElementValid(f) {
|
|
362
387
|
let result = false
|
|
363
|
-
if (
|
|
364
|
-
if (
|
|
388
|
+
if (f) {
|
|
389
|
+
if (!f.classList.contains(this.noSwapClassName)) {
|
|
365
390
|
result = true
|
|
366
391
|
}
|
|
367
392
|
}
|
|
368
393
|
return result
|
|
369
394
|
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* ### Event handlers ###
|
|
398
|
+
*/
|
|
399
|
+
onDocumentClick(e) {
|
|
400
|
+
if (e.target.tagName !== 'A') {
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
const a = e.target
|
|
404
|
+
if (this.isLinkElementValid(a) && !e.metaKey & !e.ctrlKey) {
|
|
405
|
+
const useCache = !a.classList.contains(this.noCacheClassName);
|
|
406
|
+
const url = a.getAttribute("href");
|
|
407
|
+
if (url.indexOf('://') < 0) {
|
|
408
|
+
e.preventDefault()
|
|
409
|
+
this.currentTrigger = a
|
|
410
|
+
this.openURL(url, false, useCache);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
onDocumentMouseover(e) {
|
|
416
|
+
if (e.target.tagName !== 'A') {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
const a = e.target
|
|
420
|
+
if (this.isLinkElementValid(a)) {
|
|
421
|
+
const useCache = !a.classList.contains(this.noCacheClassName);
|
|
422
|
+
if (useCache) {
|
|
423
|
+
const url = a.getAttribute("href");
|
|
424
|
+
this.preloadURL(url)
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
onDocumentSubmit(e) {
|
|
429
|
+
e.preventDefault();
|
|
430
|
+
if (e.target.tagName !== 'FORM') {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
const f = e.target
|
|
434
|
+
if (this.isFormElementValid(f)) {
|
|
435
|
+
const useCache = !f.classList.contains(this.noCacheClassName);
|
|
436
|
+
const url = f.getAttribute("action");
|
|
437
|
+
if (url.indexOf('://') < 0) {
|
|
438
|
+
e.preventDefault()
|
|
439
|
+
this.currentTrigger = f
|
|
440
|
+
const method = f.getAttribute('method') ? f.getAttribute('method') : 'get'
|
|
441
|
+
const dataStr = new URLSearchParams(new FormData(f)).toString()
|
|
442
|
+
const requestUrl = method == 'get' ? (url + '?' + dataStr) : url
|
|
443
|
+
this.submit(requestUrl, dataStr, method, false, useCache)
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
}
|
|
370
449
|
/**
|
|
371
450
|
* add event listeners
|
|
372
451
|
**/
|
|
373
452
|
addEventListeners() {
|
|
374
453
|
// catch all a click events
|
|
375
|
-
|
|
376
|
-
let $a = $(e.currentTarget);
|
|
377
|
-
// check black list, target _blank and if ctrl or cmd is not pressed
|
|
378
|
-
if (this.isLinkElementValid($a) && !e.metaKey & !e.ctrlKey) {
|
|
379
|
-
let useCache = !$a.hasClass(this.noCacheClassName);
|
|
380
|
-
let url = $a.attr("href");
|
|
381
|
-
if (url.indexOf('://') < 0) {
|
|
382
|
-
e.preventDefault();
|
|
383
|
-
this.currentTrigger = e.currentTarget
|
|
384
|
-
this.openURL(url, false, useCache);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
});
|
|
454
|
+
document.addEventListener('click', this.onDocumentClick.bind(this), false)
|
|
388
455
|
// preload on hover
|
|
389
456
|
if (this.preloadOnHover) {
|
|
390
|
-
|
|
391
|
-
let $a = $(e.currentTarget);
|
|
392
|
-
if (this.isLinkElementValid($a)) {
|
|
393
|
-
let useCache = !$a.hasClass(this.noCacheClassName);
|
|
394
|
-
let url = $a.attr("href");
|
|
395
|
-
if (useCache) {
|
|
396
|
-
this.preloadURL(url)
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
})
|
|
457
|
+
document.addEventListener('mouseover', this.onDocumentMouseover.bind(this), false)
|
|
400
458
|
}
|
|
401
459
|
// forms?
|
|
402
460
|
if (this.formsEnabled) {
|
|
403
|
-
|
|
404
|
-
let $f = $(e.currentTarget)
|
|
405
|
-
if (this.isFormElementValid($f)) {
|
|
406
|
-
let useCache = !$f.hasClass(this.noCacheClassName)
|
|
407
|
-
let url = $f.attr('action')
|
|
408
|
-
if (url.indexOf('://') < 0) {
|
|
409
|
-
e.preventDefault()
|
|
410
|
-
this.currentTrigger = e.currentTarget
|
|
411
|
-
const data = $f.serialize()
|
|
412
|
-
const method = $f.attr('method') ? $f.attr('method') : 'get'
|
|
413
|
-
const requestUrl = method == 'get' ? (url + '?' + data) : url
|
|
414
|
-
this.submit(requestUrl, data, method, false, useCache)
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
})
|
|
461
|
+
document.addEventListener('submit', this.onDocumentSubmit.bind(this), false)
|
|
419
462
|
}
|
|
420
|
-
//
|
|
421
|
-
|
|
463
|
+
// browser back button
|
|
464
|
+
window.addEventListener('popstate', this.onHistoryBack.bind(this), false)
|
|
422
465
|
}
|
|
423
466
|
|
|
424
467
|
initialDispatch() {
|
|
@@ -479,8 +522,8 @@ class ASwapDispatcher extends EventDispatcher {
|
|
|
479
522
|
* init
|
|
480
523
|
**/
|
|
481
524
|
init() {
|
|
482
|
-
|
|
483
|
-
if (
|
|
525
|
+
const swap = document.querySelector(this.swapSelector)
|
|
526
|
+
if (!swap) {
|
|
484
527
|
this.warning("AS problem - swap container not found!", this.swapSelector);
|
|
485
528
|
return false;
|
|
486
529
|
}
|
|
@@ -29,12 +29,10 @@ class Controller {
|
|
|
29
29
|
return this.active;
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
|
-
* find my
|
|
33
|
-
* @param {jQuery} $wrapper - search within this element
|
|
34
|
-
* @retunrs {jQuery|Boolean} $view | false
|
|
32
|
+
* find my view container in wrapper
|
|
35
33
|
**/
|
|
36
|
-
getViewContainer(
|
|
37
|
-
return
|
|
34
|
+
getViewContainer(wrapper) {
|
|
35
|
+
return wrapper.querySelector('*[data-as-id="' + this.id + '"]');
|
|
38
36
|
}
|
|
39
37
|
|
|
40
38
|
getContainerSelector() {
|
|
@@ -72,13 +70,13 @@ class Controller {
|
|
|
72
70
|
**/
|
|
73
71
|
onRequestLoaded(e) {
|
|
74
72
|
if (!this.active && this.view) {
|
|
75
|
-
this.view.prepare(e.target
|
|
73
|
+
this.view.prepare(e.target.freshContent.get(0));
|
|
76
74
|
}
|
|
77
75
|
}
|
|
78
76
|
/**
|
|
79
77
|
* on view hide - animation out / hide start
|
|
80
78
|
* request is loaded and fresh content is ready to init
|
|
81
|
-
* loaded content available <code>e.target
|
|
79
|
+
* loaded content available <code>e.target.freshContent</code>
|
|
82
80
|
* @param {Event} e
|
|
83
81
|
**/
|
|
84
82
|
onViewHide(e) {
|
|
@@ -24,7 +24,7 @@ class ControllerImgLoad extends Controller {
|
|
|
24
24
|
container.classList.add("as-images-loading")
|
|
25
25
|
this.view.loadImagesStart(container);
|
|
26
26
|
}
|
|
27
|
-
imagesLoaded(this.getContainerSelector(),
|
|
27
|
+
imagesLoaded(this.getContainerSelector(), this.loadImagesComplete.bind(this));
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* load images complete
|
|
@@ -44,7 +44,7 @@ class ControllerImgLoad extends Controller {
|
|
|
44
44
|
/**
|
|
45
45
|
* on view hide - animation out / hide start
|
|
46
46
|
* request is loaded and fresh content is ready to init
|
|
47
|
-
* loaded content available <code>e.target
|
|
47
|
+
* loaded content available <code>e.target.freshContent</code>
|
|
48
48
|
* @param {Event} e
|
|
49
49
|
**/
|
|
50
50
|
onViewHide(e) {
|
package/scripts/aswap/View.js
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Offcanvas, Modal } from 'bootstrap'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Bootstrap v5 helpers
|
|
5
|
+
*/
|
|
6
|
+
class Bootstrap5 {
|
|
7
|
+
/**
|
|
8
|
+
* @constructor
|
|
9
|
+
**/
|
|
10
|
+
constructor() {
|
|
11
|
+
}
|
|
12
|
+
// # Hide all modals, offcanvases, etc.
|
|
13
|
+
hideFlyovers() {
|
|
14
|
+
this.hideModals()
|
|
15
|
+
this.hideOffcanvases()
|
|
16
|
+
}
|
|
17
|
+
// # Hide all modals #
|
|
18
|
+
hideModals() {
|
|
19
|
+
const list = [...document.querySelectorAll(".modal")]
|
|
20
|
+
list.forEach(this.hdieModal.bind(this))
|
|
21
|
+
}
|
|
22
|
+
// # Hide offcanvas element
|
|
23
|
+
hdieModal(el) {
|
|
24
|
+
const modal = Modal.getInstance(el)
|
|
25
|
+
if (modal) {
|
|
26
|
+
modal.hide()
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// # Hide all offcanvases #
|
|
30
|
+
hideOffcanvases() {
|
|
31
|
+
const list = [...document.querySelectorAll(".offcanvas")]
|
|
32
|
+
list.forEach(this.hdieOffcanvas.bind(this))
|
|
33
|
+
}
|
|
34
|
+
// # Hide offcanvas element
|
|
35
|
+
hdieOffcanvas(el) {
|
|
36
|
+
const offcanvas = Offcanvas.getInstance(el)
|
|
37
|
+
if (offcanvas) {
|
|
38
|
+
offcanvas.hide()
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const bootstrap5 = new Bootstrap5();
|
|
45
|
+
export default bootstrap5;
|
package/scripts/index.js
CHANGED
|
@@ -2,6 +2,8 @@ import aswapInstance from './aswap/ASwap'
|
|
|
2
2
|
import Controller from './aswap/Controller'
|
|
3
3
|
import ControllerImgLoad from './aswap/ControllerImgLoad'
|
|
4
4
|
import View from './aswap/View'
|
|
5
|
+
// Bootstrap v5 helper
|
|
6
|
+
import bootsrap5 from './bootstrap/v5/Bootstrap5'
|
|
5
7
|
// showup
|
|
6
8
|
import scrollController from './showup/ScrollController'
|
|
7
9
|
import showUp from './showup/ShowUp'
|
|
@@ -13,6 +15,8 @@ export default {
|
|
|
13
15
|
Controller,
|
|
14
16
|
ControllerImgLoad,
|
|
15
17
|
View,
|
|
18
|
+
// boottstrap
|
|
19
|
+
bootsrap5,
|
|
16
20
|
// showup
|
|
17
21
|
scrollController,
|
|
18
22
|
showUp,
|
package/scripts/showup/ShowUp.js
CHANGED
|
@@ -24,21 +24,35 @@ class ShowUp {
|
|
|
24
24
|
this.buildParallaxScenes()
|
|
25
25
|
this.addEventListeners()
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Class event handlers
|
|
29
|
+
*/
|
|
30
|
+
handleEvent(e) {
|
|
31
|
+
switch (e.type) {
|
|
32
|
+
case 'resize':
|
|
33
|
+
this.onWindowUpdate(e)
|
|
34
|
+
break;
|
|
35
|
+
case 'DOMContentLoaded':
|
|
36
|
+
this.onWindowUpdate(e)
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
27
40
|
/**
|
|
28
41
|
* Add event listeners
|
|
29
42
|
*/
|
|
30
43
|
addEventListeners() {
|
|
31
|
-
|
|
32
|
-
|
|
44
|
+
window.addEventListener('resize', this)
|
|
45
|
+
document.addEventListener('DOMContentLoaded', this)
|
|
33
46
|
}
|
|
34
47
|
/**
|
|
35
48
|
* Remove event listeners
|
|
36
49
|
*/
|
|
37
50
|
removeEventListeners() {
|
|
38
|
-
|
|
39
|
-
|
|
51
|
+
window.removeEventListener('resize', this)
|
|
52
|
+
document.removeEventListener('DOMContentLoaded', this)
|
|
40
53
|
}
|
|
41
54
|
onWindowUpdate(e) {
|
|
55
|
+
console.log("show up WINDOW UPDATE,", this)
|
|
42
56
|
if (this.scenes.length > 0) {
|
|
43
57
|
scrollController.refresh()
|
|
44
58
|
}
|