@glitchr/transparent 1.0.66 → 1.0.71
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 +0 -1
- package/package.json +1 -1
- package/src/js/transparent.js +259 -110
package/README.md
CHANGED
package/package.json
CHANGED
package/src/js/transparent.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import $ from 'jquery';
|
|
2
|
-
|
|
3
1
|
// Modern browser: use passive event listeners where appropriate for better performance
|
|
4
2
|
jQuery.event.special.touchstart = { setup: function( _, ns, handle ) { this.addEventListener("touchstart", handle, { passive: !ns.includes("noPreventDefault") }); } };
|
|
5
3
|
jQuery.event.special.touchmove = { setup: function( _, ns, handle ) { this.addEventListener("touchmove", handle, { passive: !ns.includes("noPreventDefault") }); } };
|
|
@@ -14,7 +12,6 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
14
12
|
} else if (typeof exports === 'object') {
|
|
15
13
|
module.exports = factory();
|
|
16
14
|
} else {
|
|
17
|
-
root = window;
|
|
18
15
|
root.Transparent = factory();
|
|
19
16
|
}
|
|
20
17
|
|
|
@@ -184,14 +181,14 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
184
181
|
"smoothscroll_easing" : "swing",
|
|
185
182
|
"exceptions": [],
|
|
186
183
|
// headlock: list of url substrings/regex to preserve in <head> across page transitions
|
|
187
|
-
// (e.g. third-party widgets
|
|
184
|
+
// (e.g. third-party widgets that inject <style>/<link> dynamically).
|
|
188
185
|
// In addition, head nodes injected dynamically AFTER initial DOMContentLoaded are
|
|
189
186
|
// preserved automatically. Use data-headlock="false" on a head element to opt-out.
|
|
190
187
|
"headlock": []
|
|
191
188
|
};
|
|
192
189
|
|
|
193
190
|
// Set of <head> children present on initial load. Anything added after is treated
|
|
194
|
-
// as dynamically injected
|
|
191
|
+
// as dynamically injected and preserved across transitions.
|
|
195
192
|
var originalHeadNodes = new WeakSet();
|
|
196
193
|
function snapshotHeadNodes() {
|
|
197
194
|
var head = document.head;
|
|
@@ -199,10 +196,13 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
199
196
|
for(var i = 0; i < head.children.length; i++)
|
|
200
197
|
originalHeadNodes.add(head.children[i]);
|
|
201
198
|
}
|
|
202
|
-
|
|
199
|
+
// Snapshot synchronously at module-eval time (scripts at end of <body> run before any
|
|
200
|
+
// async script can inject <style> tags, so the snapshot is clean).
|
|
201
|
+
// A DOMContentLoaded fallback is kept for the rare case where document.head is null
|
|
202
|
+
// (e.g. script loaded inside <head> before it finishes parsing).
|
|
203
|
+
snapshotHeadNodes();
|
|
204
|
+
if(!document.head)
|
|
203
205
|
document.addEventListener("DOMContentLoaded", snapshotHeadNodes, { once: true });
|
|
204
|
-
else
|
|
205
|
-
snapshotHeadNodes();
|
|
206
206
|
|
|
207
207
|
Transparent.isHeadlocked = function(el) {
|
|
208
208
|
if(!el || el.nodeType !== 1) return false;
|
|
@@ -213,10 +213,12 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
213
213
|
if(attr !== null && attr !== undefined) return true;
|
|
214
214
|
// Dynamically injected after initial load
|
|
215
215
|
if(!originalHeadNodes.has(el)) return true;
|
|
216
|
-
// URL pattern match
|
|
216
|
+
// URL pattern match (src/href attributes)
|
|
217
217
|
var patterns = Settings["headlock"] || [];
|
|
218
218
|
if(!patterns.length) return false;
|
|
219
219
|
var url = el.getAttribute && (el.getAttribute("src") || el.getAttribute("href"));
|
|
220
|
+
// <style> elements have no src/href — match against CSS textContent instead
|
|
221
|
+
if(!url && el.tagName === 'STYLE') url = el.textContent || '';
|
|
220
222
|
if(!url) return false;
|
|
221
223
|
for(var i = 0; i < patterns.length; i++) {
|
|
222
224
|
var p = patterns[i];
|
|
@@ -224,7 +226,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
224
226
|
else if(typeof p === "string" && p.length && url.indexOf(p) !== -1) return true;
|
|
225
227
|
}
|
|
226
228
|
return false;
|
|
227
|
-
}
|
|
229
|
+
}
|
|
228
230
|
|
|
229
231
|
const State = Transparent.state = {
|
|
230
232
|
|
|
@@ -244,9 +246,9 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
244
246
|
CLICK : "click",
|
|
245
247
|
|
|
246
248
|
PREACTIVE : "pre-active",
|
|
247
|
-
|
|
249
|
+
FADEIN : "fade-in",
|
|
248
250
|
ACTIVE : "active",
|
|
249
|
-
|
|
251
|
+
FADEOUT : "fade-out",
|
|
250
252
|
POSTACTIVE : "post-active",
|
|
251
253
|
|
|
252
254
|
NOTIFICATION: "notification"
|
|
@@ -323,6 +325,37 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
323
325
|
}
|
|
324
326
|
|
|
325
327
|
Transparent.setResponse = function(uuid, responseText, scrollableXY = [], exceptionRaised = false)
|
|
328
|
+
{
|
|
329
|
+
if(isDomEntity(responseText))
|
|
330
|
+
responseText = responseText.outerHTML;
|
|
331
|
+
|
|
332
|
+
var array = JSON.parse(sessionStorage.getItem('transparent')) || [];
|
|
333
|
+
array.push(uuid);
|
|
334
|
+
|
|
335
|
+
while(array.length > Settings["response_limit"])
|
|
336
|
+
sessionStorage.removeItem('transparent['+array.shift()+']');
|
|
337
|
+
|
|
338
|
+
try {
|
|
339
|
+
|
|
340
|
+
if(isLocalStorageNameSupported()) {
|
|
341
|
+
|
|
342
|
+
sessionStorage.setItem('transparent', JSON.stringify(array));
|
|
343
|
+
sessionStorage.setItem('transparent[response]['+uuid+']', responseText);
|
|
344
|
+
sessionStorage.setItem('transparent[position]['+uuid+']', JSON.stringify(scrollableXY));
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
} catch(e) {
|
|
348
|
+
|
|
349
|
+
if (e.name === 'QuotaExceededError')
|
|
350
|
+
sessionStorage.clear();
|
|
351
|
+
|
|
352
|
+
return exceptionRaised === false ? Transparent.setResponse(uuid, responseText, scrollableXY, true) : this;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return this;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
Transparent.setResponse = function(uuid, responseText, scrollableXY, exceptionRaised = false)
|
|
326
359
|
{
|
|
327
360
|
if(isDomEntity(responseText))
|
|
328
361
|
responseText = responseText.outerHTML;
|
|
@@ -462,7 +495,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
462
495
|
|
|
463
496
|
if($(Transparent.html).hasClass(Transparent.state.FIRST)) {
|
|
464
497
|
Transparent.scrollToHash(location.hash, {}, function() {
|
|
465
|
-
Transparent.
|
|
498
|
+
Transparent.fadeOut(() => Transparent.html.removeClass(Transparent.state.FIRST));
|
|
466
499
|
});
|
|
467
500
|
}
|
|
468
501
|
|
|
@@ -588,7 +621,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
588
621
|
}
|
|
589
622
|
}
|
|
590
623
|
|
|
591
|
-
|
|
624
|
+
closestEl = $(el).closest("a");
|
|
592
625
|
if(!closestEl.length) closestEl = $(el).closest("button");
|
|
593
626
|
if(!closestEl.length) closestEl = $(el).closest("input");
|
|
594
627
|
if (closestEl.length) el = closestEl[0];
|
|
@@ -803,9 +836,10 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
803
836
|
|
|
804
837
|
return {delay:delay, duration:duration};
|
|
805
838
|
}
|
|
806
|
-
|
|
807
|
-
var
|
|
808
|
-
|
|
839
|
+
|
|
840
|
+
var fadeInTime = 0;
|
|
841
|
+
var fadeInRemainingTime = 0;
|
|
842
|
+
Transparent.fadeIn = function(activeCallback = function() {}) {
|
|
809
843
|
|
|
810
844
|
if(!Transparent.html.hasClass(Transparent.state.PREACTIVE)) {
|
|
811
845
|
Transparent.html.addClass(Transparent.state.PREACTIVE);
|
|
@@ -813,18 +847,18 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
813
847
|
}
|
|
814
848
|
|
|
815
849
|
var active = Transparent.activeTime();
|
|
816
|
-
|
|
817
|
-
|
|
850
|
+
fadeInTime = Date.now();
|
|
851
|
+
fadeInRemainingTime = active.delay+active.duration;
|
|
818
852
|
|
|
819
853
|
Transparent.html.removeClass(Transparent.state.PREACTIVE);
|
|
820
|
-
if(!Transparent.html.hasClass(Transparent.state.
|
|
821
|
-
Transparent.html.addClass(Transparent.state.
|
|
822
|
-
dispatchEvent(new Event('transparent:'+Transparent.state.
|
|
854
|
+
if(!Transparent.html.hasClass(Transparent.state.FADEIN)) {
|
|
855
|
+
Transparent.html.addClass(Transparent.state.FADEIN);
|
|
856
|
+
dispatchEvent(new Event('transparent:'+Transparent.state.FADEIN));
|
|
823
857
|
}
|
|
824
858
|
|
|
825
859
|
Transparent.callback(function() {
|
|
826
860
|
|
|
827
|
-
Transparent.html.removeClass(Transparent.state.
|
|
861
|
+
Transparent.html.removeClass(Transparent.state.FADEIN);
|
|
828
862
|
if(!Transparent.html.hasClass(Transparent.state.ACTIVE)) {
|
|
829
863
|
Transparent.html.addClass(Transparent.state.ACTIVE);
|
|
830
864
|
dispatchEvent(new Event('transparent:'+Transparent.state.ACTIVE));
|
|
@@ -834,23 +868,23 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
834
868
|
Transparent.callback(function() {
|
|
835
869
|
|
|
836
870
|
activeCallback();
|
|
837
|
-
|
|
871
|
+
fadeInRemainingTime = 0;
|
|
838
872
|
|
|
839
873
|
}.bind(this), active.duration);
|
|
840
874
|
|
|
841
875
|
}.bind(this), active.delay);
|
|
842
876
|
}
|
|
843
877
|
|
|
844
|
-
Transparent.
|
|
878
|
+
Transparent.fadeOut = function(activeCallback = function() {}) {
|
|
845
879
|
|
|
846
880
|
if(!Transparent.html.hasClass(Transparent.state.ACTIVE)) {
|
|
847
881
|
Transparent.html.addClass(Transparent.state.ACTIVE);
|
|
848
882
|
dispatchEvent(new Event('transparent:'+Transparent.state.ACTIVE));
|
|
849
883
|
}
|
|
850
884
|
|
|
851
|
-
if(!Transparent.html.hasClass(Transparent.state.
|
|
852
|
-
Transparent.html.addClass(Transparent.state.
|
|
853
|
-
dispatchEvent(new Event('transparent:'+Transparent.state.
|
|
885
|
+
if(!Transparent.html.hasClass(Transparent.state.FADEOUT)) {
|
|
886
|
+
Transparent.html.addClass(Transparent.state.FADEOUT);
|
|
887
|
+
dispatchEvent(new Event('transparent:'+Transparent.state.FADEOUT));
|
|
854
888
|
}
|
|
855
889
|
|
|
856
890
|
var active = Transparent.activeTime();
|
|
@@ -862,7 +896,9 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
862
896
|
var active = Transparent.activeTime();
|
|
863
897
|
Transparent.callback(function() {
|
|
864
898
|
|
|
865
|
-
Transparent.html.removeClass(Transparent.state.
|
|
899
|
+
Transparent.html.removeClass(Transparent.state.FADEOUT);
|
|
900
|
+
ajaxSemaphore = false;
|
|
901
|
+
|
|
866
902
|
if(Transparent.html.hasClass(Transparent.state.LOADING)) {
|
|
867
903
|
|
|
868
904
|
dispatchEvent(new Event('transparent:'+Transparent.state.LOADING));
|
|
@@ -870,7 +906,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
870
906
|
Object.values(Transparent.state).forEach(e => Transparent.html.removeClass(e));
|
|
871
907
|
Transparent.html.addClass(Transparent.state.ROOT + " " + Transparent.state.READY);
|
|
872
908
|
}
|
|
873
|
-
|
|
909
|
+
|
|
874
910
|
Transparent.html.addClass(Transparent.state.POSTACTIVE);
|
|
875
911
|
|
|
876
912
|
var active = Transparent.activeTime();
|
|
@@ -903,7 +939,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
903
939
|
} else {
|
|
904
940
|
|
|
905
941
|
if(dom === undefined)
|
|
906
|
-
console.
|
|
942
|
+
console.alert("Response missing..");
|
|
907
943
|
|
|
908
944
|
var parent = Transparent.findElementFromParents(dom, $(this).parents(), 3);
|
|
909
945
|
if (parent === undefined) {
|
|
@@ -953,7 +989,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
953
989
|
var head = $(dom).find("head").html();
|
|
954
990
|
var body = $(dom).find("body").html();
|
|
955
991
|
|
|
956
|
-
if(head == undefined || body == undefined) {
|
|
992
|
+
if(head == undefined || body == "undefined") {
|
|
957
993
|
|
|
958
994
|
$(Settings.identifier).html("<div class='error'></div>");
|
|
959
995
|
|
|
@@ -967,8 +1003,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
967
1003
|
Transparent.evalScript($("body")[0]);
|
|
968
1004
|
}
|
|
969
1005
|
|
|
970
|
-
Transparent.
|
|
971
|
-
Transparent.activeOut();
|
|
1006
|
+
Transparent.fadeOut();
|
|
972
1007
|
}
|
|
973
1008
|
|
|
974
1009
|
Transparent.userScroll = function(el = undefined) { return $(el === undefined ? document.documentElement : el).closestScrollable().prop("user-scroll") ?? true; }
|
|
@@ -987,19 +1022,18 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
987
1022
|
var maxScrollY = $(el).prop("scrollHeight") - Math.round($(el).prop("clientHeight"));
|
|
988
1023
|
if (maxScrollY == 0) maxScrollY = Math.round($(el).prop("clientHeight"));
|
|
989
1024
|
|
|
990
|
-
|
|
991
|
-
|
|
1025
|
+
scrollTop = Math.max(0, Math.min(dict["top"] ?? $(el).prop("scrollTop"), maxScrollY));
|
|
1026
|
+
scrollLeft = Math.max(0, Math.min(dict["left"] ?? $(el).prop("scrollLeft"), maxScrollX));
|
|
992
1027
|
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1028
|
+
speed = parseFloat(dict["speed"] ?? 0);
|
|
1029
|
+
easing = dict["easing"] ?? "swing";
|
|
1030
|
+
debounce = dict["debounce"] ?? 0;
|
|
996
1031
|
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1032
|
+
duration = 1000*Transparent.parseDuration(dict["duration"] ?? 0);
|
|
1033
|
+
durationX = 1000*Transparent.parseDuration(dict["duration-x"] ?? dict["duration"] ?? 0);
|
|
1034
|
+
durationY = 1000*Transparent.parseDuration(dict["duration-y"] ?? dict["duration"] ?? 0);
|
|
1000
1035
|
|
|
1001
1036
|
if(speed) {
|
|
1002
|
-
var distanceX = 0, distanceY = 0;
|
|
1003
1037
|
|
|
1004
1038
|
var currentScrollX = $(el)[0].scrollLeft;
|
|
1005
1039
|
if(currentScrollX < scrollLeft || scrollLeft == 0) // Going to the right
|
|
@@ -1236,7 +1270,6 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1236
1270
|
$(this).stop();
|
|
1237
1271
|
});
|
|
1238
1272
|
|
|
1239
|
-
activeInRemainingTime = activeInRemainingTime - (Date.now() - activeInTime);
|
|
1240
1273
|
setTimeout(function() {
|
|
1241
1274
|
|
|
1242
1275
|
// Transfert attributes
|
|
@@ -1244,6 +1277,15 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1244
1277
|
|
|
1245
1278
|
// Replace head..
|
|
1246
1279
|
var head = $(dom).find("head");
|
|
1280
|
+
|
|
1281
|
+
// Snapshot hrefs of already-loaded stylesheets so we can detect new ones
|
|
1282
|
+
// added by the head merge and wait for them to finish loading before
|
|
1283
|
+
// making #page visible (prevents FOUC on cold-cache layout transitions).
|
|
1284
|
+
var _existingStyleHrefs = {};
|
|
1285
|
+
$("head").children("link[rel='stylesheet']").each(function() {
|
|
1286
|
+
var h = this.getAttribute("href"); if(h) _existingStyleHrefs[h] = true;
|
|
1287
|
+
});
|
|
1288
|
+
|
|
1247
1289
|
$("head").children().each(function() {
|
|
1248
1290
|
|
|
1249
1291
|
var el = this;
|
|
@@ -1252,12 +1294,17 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1252
1294
|
head.children().each(function() {
|
|
1253
1295
|
|
|
1254
1296
|
found = this.isEqualNode(el);
|
|
1297
|
+
// Also match identical <style> tags by content
|
|
1298
|
+
if(!found && el.tagName === 'STYLE' && this.tagName === 'STYLE' &&
|
|
1299
|
+
el.textContent && this.textContent &&
|
|
1300
|
+
el.textContent.length > 100 && this.textContent.length === el.textContent.length) {
|
|
1301
|
+
found = this.textContent === el.textContent;
|
|
1302
|
+
}
|
|
1255
1303
|
return !found;
|
|
1256
1304
|
});
|
|
1257
1305
|
|
|
1258
1306
|
// Preserve headlocked nodes (dynamically injected widgets, url-matched, etc.)
|
|
1259
1307
|
if(!found && Transparent.isHeadlocked(el)) found = true;
|
|
1260
|
-
|
|
1261
1308
|
if(!found) this.remove();
|
|
1262
1309
|
});
|
|
1263
1310
|
|
|
@@ -1269,18 +1316,45 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1269
1316
|
$("head").children().each(function() { found |= this.isEqualNode(el); });
|
|
1270
1317
|
if(!found) {
|
|
1271
1318
|
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1319
|
+
if(this.tagName == "SCRIPT" && Settings["global_code"] != true) {
|
|
1320
|
+
|
|
1321
|
+
// For inline scripts (without src), create and execute
|
|
1322
|
+
if(!this.src || this.src === '') {
|
|
1323
|
+
var script = document.createElement("script");
|
|
1324
|
+
script.text = this.innerHTML;
|
|
1325
|
+
var i = -1, attrs = this.attributes, attr;
|
|
1326
|
+
var N = attrs.length;
|
|
1327
|
+
while ( ++i < N ) {
|
|
1328
|
+
if(attrs[i].name !== 'src') {
|
|
1329
|
+
script.setAttribute( attrs[i].name, attrs[i].value );
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
$("head").append(script);
|
|
1333
|
+
originalHeadNodes.add(script);
|
|
1334
|
+
} else {
|
|
1335
|
+
$("head").append(this);
|
|
1336
|
+
originalHeadNodes.add(this);
|
|
1337
|
+
}
|
|
1276
1338
|
|
|
1277
1339
|
} else {
|
|
1278
1340
|
|
|
1279
|
-
|
|
1341
|
+
var clonedEl = this.cloneNode(true);
|
|
1342
|
+
$("head").append(clonedEl);
|
|
1343
|
+
// Register as an "original" node so it falls through to URL-pattern
|
|
1344
|
+
// matching on future transitions — prevents layout CSS added by
|
|
1345
|
+
// Transparent itself from being auto-headlocked as third-party content.
|
|
1346
|
+
originalHeadNodes.add(clonedEl);
|
|
1280
1347
|
}
|
|
1281
1348
|
}
|
|
1282
1349
|
});
|
|
1283
1350
|
|
|
1351
|
+
// Collect link[rel="stylesheet"] elements inserted by the head merge above
|
|
1352
|
+
var _newStyleLinks = [];
|
|
1353
|
+
$("head").children("link[rel='stylesheet']").each(function() {
|
|
1354
|
+
var h = this.getAttribute("href");
|
|
1355
|
+
if(h && !_existingStyleHrefs[h]) _newStyleLinks.push(this);
|
|
1356
|
+
});
|
|
1357
|
+
|
|
1284
1358
|
var bodyScript = $(dom).find("body > script");
|
|
1285
1359
|
bodyScript.each(function() {
|
|
1286
1360
|
|
|
@@ -1290,10 +1364,27 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1290
1364
|
$("body").children().each(function() { found |= this.isEqualNode(el); });
|
|
1291
1365
|
if(!found) {
|
|
1292
1366
|
|
|
1293
|
-
if(this.tagName
|
|
1294
|
-
|
|
1367
|
+
if(this.tagName == "SCRIPT" && Settings["global_code"] != true) {
|
|
1368
|
+
|
|
1369
|
+
// For inline scripts (without src), create and execute
|
|
1370
|
+
if(!this.src || this.src === '') {
|
|
1371
|
+
var script = document.createElement("script");
|
|
1372
|
+
script.text = this.innerHTML;
|
|
1373
|
+
var i = -1, attrs = this.attributes, attr;
|
|
1374
|
+
var N = attrs.length;
|
|
1375
|
+
while ( ++i < N ) {
|
|
1376
|
+
if(attrs[i].name !== 'src') {
|
|
1377
|
+
script.setAttribute( attrs[i].name, attrs[i].value );
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
$("body").append(script);
|
|
1381
|
+
} else {
|
|
1382
|
+
$("body").append(this);
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1295
1385
|
} else {
|
|
1296
|
-
|
|
1386
|
+
|
|
1387
|
+
$("body").append(this.cloneNode(true));
|
|
1297
1388
|
}
|
|
1298
1389
|
}
|
|
1299
1390
|
});
|
|
@@ -1336,7 +1427,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1336
1427
|
var scrollableElements = Transparent.getScrollableElement();
|
|
1337
1428
|
var scrollableElementsXY = Transparent.getResponsePosition(uuid);
|
|
1338
1429
|
|
|
1339
|
-
for(
|
|
1430
|
+
for(i = 0; i < scrollableElements.length; i++) {
|
|
1340
1431
|
|
|
1341
1432
|
var el = scrollableElements[i];
|
|
1342
1433
|
var positionXY = undefined;
|
|
@@ -1358,20 +1449,43 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1358
1449
|
}
|
|
1359
1450
|
}
|
|
1360
1451
|
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1452
|
+
// Wait for any newly added layout stylesheets to finish loading before
|
|
1453
|
+
// calling callback() / fadeOut() — otherwise #page becomes visible while
|
|
1454
|
+
// the new CSS is still being parsed, causing a flash of unstyled content.
|
|
1455
|
+
(function() {
|
|
1456
|
+
function doCallback() {
|
|
1457
|
+
$('head').append(function() {
|
|
1458
|
+
$(Settings.identifier).append(function() {
|
|
1459
|
+
callback();
|
|
1460
|
+
dispatchEvent(new Event('transparent:load'));
|
|
1461
|
+
dispatchEvent(new Event('load'));
|
|
1462
|
+
});
|
|
1463
|
+
});
|
|
1464
|
+
}
|
|
1465
|
+
if(_newStyleLinks.length === 0) {
|
|
1466
|
+
doCallback();
|
|
1467
|
+
} else {
|
|
1468
|
+
var remaining = _newStyleLinks.length;
|
|
1469
|
+
var fired = false;
|
|
1470
|
+
// Safety valve: if a stylesheet fails or stalls, don't block forever.
|
|
1471
|
+
var guard = setTimeout(function() {
|
|
1472
|
+
if(!fired) { fired = true; doCallback(); }
|
|
1473
|
+
}, 3000);
|
|
1474
|
+
_newStyleLinks.forEach(function(link) {
|
|
1475
|
+
function onDone() {
|
|
1476
|
+
if(--remaining <= 0 && !fired) {
|
|
1477
|
+
fired = true;
|
|
1478
|
+
clearTimeout(guard);
|
|
1479
|
+
doCallback();
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
link.addEventListener('load', onDone, {once:true});
|
|
1483
|
+
link.addEventListener('error', onDone, {once:true});
|
|
1484
|
+
});
|
|
1485
|
+
}
|
|
1486
|
+
})();
|
|
1373
1487
|
|
|
1374
|
-
}.bind(this),
|
|
1488
|
+
}.bind(this), 1);
|
|
1375
1489
|
}
|
|
1376
1490
|
|
|
1377
1491
|
function uuidv4() {
|
|
@@ -1474,7 +1588,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1474
1588
|
var elementsXY = [];
|
|
1475
1589
|
var elements = Transparent.getScrollableElement();
|
|
1476
1590
|
|
|
1477
|
-
for(
|
|
1591
|
+
for(i = 0; i < elements.length; i++)
|
|
1478
1592
|
elementsXY.push([$(elements[i]).scrollTop(), $(elements[i]).scrollLeft()]);
|
|
1479
1593
|
|
|
1480
1594
|
return elementsXY;
|
|
@@ -1494,7 +1608,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1494
1608
|
return;
|
|
1495
1609
|
}
|
|
1496
1610
|
|
|
1497
|
-
dispatchEvent(new CustomEvent('transparent:link', {
|
|
1611
|
+
dispatchEvent(new CustomEvent('transparent:link', {link:link}));
|
|
1498
1612
|
|
|
1499
1613
|
const uuid = uuidv4();
|
|
1500
1614
|
const type = link[0];
|
|
@@ -1506,10 +1620,8 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1506
1620
|
// Wait for transparent window event to be triggered
|
|
1507
1621
|
if (!isReady) return;
|
|
1508
1622
|
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
e.type !== Transparent.state.HASHCHANGE &&
|
|
1512
|
-
!$ctx.find(Settings.identifier).length) return;
|
|
1623
|
+
if (e.type != Transparent.state.POPSTATE &&
|
|
1624
|
+
e.type != Transparent.state.HASHCHANGE && !$(this).find(Settings.identifier).length) return;
|
|
1513
1625
|
|
|
1514
1626
|
var form = target != undefined && target.tagName == "FORM" ? target : undefined;
|
|
1515
1627
|
var formTrigger = undefined;
|
|
@@ -1602,41 +1714,59 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1602
1714
|
$(Transparent.html).stop();
|
|
1603
1715
|
|
|
1604
1716
|
Transparent.html.addClass(Transparent.state.LOADING);
|
|
1605
|
-
|
|
1717
|
+
|
|
1718
|
+
var fadeInDone = false;
|
|
1719
|
+
var pendingResponseArgs = null;
|
|
1720
|
+
|
|
1721
|
+
function tryDispatch(args) {
|
|
1722
|
+
if (args !== undefined) pendingResponseArgs = args;
|
|
1723
|
+
if (fadeInDone && pendingResponseArgs !== null)
|
|
1724
|
+
handleResponse(...pendingResponseArgs);
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
// Lock navigation for the full transition (fadeIn + page swap + fadeOut).
|
|
1728
|
+
// Released inside Transparent.fadeOut's final cleanup, covering both the
|
|
1729
|
+
// AJAX path and the popstate/cached-response path.
|
|
1730
|
+
ajaxSemaphore = true;
|
|
1731
|
+
|
|
1732
|
+
Transparent.fadeIn(function() {
|
|
1733
|
+
fadeInDone = true;
|
|
1734
|
+
tryDispatch();
|
|
1735
|
+
});
|
|
1606
1736
|
|
|
1607
1737
|
function isJsonResponse(str) {
|
|
1608
1738
|
try { JSON.parse(str); return true; }
|
|
1609
1739
|
catch (e) { return false; }
|
|
1610
1740
|
}
|
|
1611
1741
|
|
|
1612
|
-
function handleResponse(uuid, status = 200, method = null, data = null,
|
|
1742
|
+
function handleResponse(uuid, status = 200, method = null, data = null, xhr = null, request = null) {
|
|
1613
1743
|
|
|
1614
|
-
ajaxSemaphore = false;
|
|
1615
1744
|
|
|
1616
|
-
|
|
1745
|
+
var responseURL;
|
|
1746
|
+
responseURL = xhr !== null ? xhr.responseURL : url.href;
|
|
1617
1747
|
|
|
1618
|
-
|
|
1748
|
+
responseText = Transparent.getResponseText(uuid);
|
|
1619
1749
|
|
|
1620
|
-
|
|
1621
|
-
var strippedResponseUrl = (
|
|
1750
|
+
var fragmentPos = responseURL.indexOf("#");
|
|
1751
|
+
var strippedResponseUrl = (fragmentPos < 0 ? responseURL : responseURL.substring(0, fragmentPos)).trimEnd("/");
|
|
1622
1752
|
|
|
1623
|
-
|
|
1624
|
-
var strippedUrlHref = (
|
|
1753
|
+
var fragmentPos = url.href.indexOf("#");
|
|
1754
|
+
var strippedUrlHref = (fragmentPos < 0 ? url.href : url.href.substring(0, fragmentPos)).trimEnd("/");
|
|
1625
1755
|
if( strippedUrlHref == strippedResponseUrl )
|
|
1626
|
-
responseURL = url.href; // NB:
|
|
1756
|
+
responseURL = url.href; // NB: xhr.responseURL strips away #fragments
|
|
1627
1757
|
|
|
1628
1758
|
if(!responseText) {
|
|
1629
1759
|
|
|
1630
|
-
if(!
|
|
1760
|
+
if(!request && responseText === null) {
|
|
1631
1761
|
|
|
1632
1762
|
setTimeout(function() { window.location.href = responseURL; }, Settings["throttle"]);
|
|
1633
1763
|
return;
|
|
1634
1764
|
}
|
|
1635
1765
|
|
|
1636
|
-
responseText =
|
|
1766
|
+
responseText = request.responseText;
|
|
1637
1767
|
if(status >= 500) {
|
|
1638
1768
|
|
|
1639
|
-
console.error("Unexpected response from "+uuid+": error code "+status);
|
|
1769
|
+
console.error("Unexpected XHR response from "+uuid+": error code "+request.status);
|
|
1640
1770
|
console.error(sessionStorage);
|
|
1641
1771
|
}
|
|
1642
1772
|
|
|
@@ -1645,7 +1775,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1645
1775
|
}
|
|
1646
1776
|
|
|
1647
1777
|
var dom = new DOMParser().parseFromString(responseText, "text/html");
|
|
1648
|
-
if(
|
|
1778
|
+
if(request && request.getResponseHeader("Content-Type") == "application/json") {
|
|
1649
1779
|
|
|
1650
1780
|
if(!isJsonResponse(responseText)) {
|
|
1651
1781
|
console.error("Invalid response received for "+ responseURL);
|
|
@@ -1667,11 +1797,12 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1667
1797
|
else location.reload();
|
|
1668
1798
|
}
|
|
1669
1799
|
|
|
1800
|
+
ajaxSemaphore = false;
|
|
1670
1801
|
return dispatchEvent(new Event('load'));
|
|
1671
1802
|
}
|
|
1672
1803
|
|
|
1673
1804
|
// Invalid html page returned
|
|
1674
|
-
if(
|
|
1805
|
+
if(request && request.getResponseHeader("Content-Type") == "text/html") {
|
|
1675
1806
|
|
|
1676
1807
|
if (!responseText.includes("<html") && !responseText.includes("<body") && !responseText.includes("<head"))
|
|
1677
1808
|
return Transparent.rescue(dom);
|
|
@@ -1690,7 +1821,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1690
1821
|
|
|
1691
1822
|
// From here the page is valid..
|
|
1692
1823
|
// so the new page is added to history..
|
|
1693
|
-
if(
|
|
1824
|
+
if(xhr)
|
|
1694
1825
|
history.pushState({uuid: uuid, status:status, method: method, data: {}, href: responseURL}, '', responseURL);
|
|
1695
1826
|
|
|
1696
1827
|
// Page not recognized.. just go fetch by yourself.. no POST information transmitted..
|
|
@@ -1734,9 +1865,28 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1734
1865
|
if($(dom).find("html").hasClass(Transparent.state.RELOAD) || $(dom).find("html").hasClass(Transparent.state.DISABLE))
|
|
1735
1866
|
return window.location.reload();
|
|
1736
1867
|
|
|
1868
|
+
// Kick off preloads for stylesheets the new page needs but aren't yet in <head>.
|
|
1869
|
+
// They download in parallel during the fadeIn animation so onLoad() finds them
|
|
1870
|
+
// already cached — eliminating FOUC on cold-cache layout transitions.
|
|
1871
|
+
(function() {
|
|
1872
|
+
var loaded = {};
|
|
1873
|
+
$("head").children("link[rel='stylesheet']").each(function() {
|
|
1874
|
+
var h = this.getAttribute("href"); if(h) loaded[h] = true;
|
|
1875
|
+
});
|
|
1876
|
+
|
|
1877
|
+
$(dom).find("head").children("link[rel='stylesheet']").each(function() {
|
|
1878
|
+
var h = this.getAttribute("href");
|
|
1879
|
+
if(!h || loaded[h]) return;
|
|
1880
|
+
if($("head").find("link[rel='preload'][href='" + h.replace(/'/g, "\\'") + "']").length) return;
|
|
1881
|
+
var pl = document.createElement("link");
|
|
1882
|
+
pl.rel = "preload"; pl.as = "style"; pl.href = h;
|
|
1883
|
+
document.head.appendChild(pl);
|
|
1884
|
+
});
|
|
1885
|
+
})();
|
|
1886
|
+
|
|
1737
1887
|
return Transparent.onLoad(uuid, dom, function() {
|
|
1738
1888
|
|
|
1739
|
-
Transparent.
|
|
1889
|
+
Transparent.fadeOut(function() {
|
|
1740
1890
|
|
|
1741
1891
|
Transparent.html
|
|
1742
1892
|
.removeClass(switchLayout)
|
|
@@ -1759,27 +1909,26 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1759
1909
|
if(history.state)
|
|
1760
1910
|
Transparent.setResponse(history.state.uuid, Transparent.html[0], Transparent.getScrollableElementXY());
|
|
1761
1911
|
|
|
1762
|
-
$(Transparent.html).prop("user-scroll", false); // make sure to avoid page jump during transition (cancelled in
|
|
1912
|
+
$(Transparent.html).prop("user-scroll", false); // make sure to avoid page jump during transition (cancelled in fadeIn callback)
|
|
1763
1913
|
|
|
1764
1914
|
// Submit ajax request..
|
|
1765
|
-
ajaxSemaphore = true; // Raise before dispatching synthetic submit to prevent double-submission
|
|
1766
1915
|
if(form) form.dispatchEvent(new SubmitEvent("submit", { submitter: formTrigger }));
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1916
|
+
var xhr = new XMLHttpRequest();
|
|
1917
|
+
|
|
1918
|
+
return jQuery.ajax({
|
|
1919
|
+
url: url.href,
|
|
1920
|
+
type: type,
|
|
1921
|
+
data: data,
|
|
1922
|
+
contentType: false,
|
|
1923
|
+
processData: false,
|
|
1924
|
+
headers: Settings["headers"] || {},
|
|
1925
|
+
xhr: function () { return xhr; },
|
|
1926
|
+
success: function (html, status, request) { return tryDispatch([uuid, request.status, type, data, xhr, request]); },
|
|
1927
|
+
error: function (request, ajaxOptions, thrownError) { return tryDispatch([uuid, request.status, type, data, xhr, request]); }
|
|
1779
1928
|
});
|
|
1780
1929
|
}
|
|
1781
1930
|
|
|
1782
|
-
return
|
|
1931
|
+
return tryDispatch([history.state.uuid, history.state.status, history.state.method, history.state.data]);
|
|
1783
1932
|
}
|
|
1784
1933
|
|
|
1785
1934
|
// Update history if not refreshing page or different page (avoid double pushState)
|
|
@@ -1795,8 +1944,8 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1795
1944
|
|
|
1796
1945
|
if(Settings.debug) console.debug("Transparent is disabled..");
|
|
1797
1946
|
|
|
1798
|
-
|
|
1799
|
-
|
|
1947
|
+
var states = Object.values(Transparent.state);
|
|
1948
|
+
var htmlClass = Array.from(($("html").attr("class") || "").split(" ")).filter(x => !states.includes(x));
|
|
1800
1949
|
Transparent.html.removeClass(states).addClass(htmlClass.join(" ")+" "+Transparent.state.ROOT+" "+Transparent.state.READY+" "+Transparent.state.DISABLE);
|
|
1801
1950
|
|
|
1802
1951
|
} else {
|
|
@@ -1882,7 +2031,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1882
2031
|
var fieldValueBefore = formDataBefore[fieldName];
|
|
1883
2032
|
if(fieldValueBefore instanceof File) {
|
|
1884
2033
|
|
|
1885
|
-
if(!
|
|
2034
|
+
if(!fieldValueAfter instanceof File) preventDefault = true;
|
|
1886
2035
|
else if (fieldValueBefore.size != fieldValueAfter.size) preventDefault = true;
|
|
1887
2036
|
|
|
1888
2037
|
} else if(fieldValueBefore != fieldValueAfter) {
|
|
@@ -1894,7 +2043,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1894
2043
|
if(Settings.debug || preventDefault) {
|
|
1895
2044
|
|
|
1896
2045
|
if(preventDefault) Transparent.html.addClass(Transparent.state.READY);
|
|
1897
|
-
if(preventDefault) Transparent.
|
|
2046
|
+
if(preventDefault) Transparent.fadeOut();
|
|
1898
2047
|
if(preventDefault) dispatchEvent(new Event('load'));
|
|
1899
2048
|
|
|
1900
2049
|
return "Dude, are you sure you want to leave? Think of the kittens!";
|
|
@@ -1903,7 +2052,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1903
2052
|
|
|
1904
2053
|
document.addEventListener('click', __main__, false);
|
|
1905
2054
|
|
|
1906
|
-
$(
|
|
2055
|
+
$("form").on("submit", __main__);
|
|
1907
2056
|
}
|
|
1908
2057
|
|
|
1909
2058
|
|