@glitchr/transparent 1.0.66 → 1.0.70

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 CHANGED
@@ -1,2 +1 @@
1
1
  # TransparentJS
2
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glitchr/transparent",
3
- "version": "1.0.66",
3
+ "version": "1.0.70",
4
4
  "description": "Transparent SPA Application",
5
5
  "main": "src/index.js",
6
6
  "access": "public",
@@ -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
 
@@ -187,7 +184,11 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
187
184
  // (e.g. third-party widgets like Brevo 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
- "headlock": []
187
+ "headlock": [
188
+ "brevo",
189
+ "conversations-widget",
190
+ /brevo/i
191
+ ]
191
192
  };
192
193
 
193
194
  // Set of <head> children present on initial load. Anything added after is treated
@@ -199,10 +200,13 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
199
200
  for(var i = 0; i < head.children.length; i++)
200
201
  originalHeadNodes.add(head.children[i]);
201
202
  }
202
- if(document.readyState === "loading")
203
+ // Snapshot synchronously at module-eval time (scripts at end of <body> run before any
204
+ // async script — e.g. Brevo — can inject <style> tags, so the snapshot is clean).
205
+ // A DOMContentLoaded fallback is kept for the rare case where document.head is null
206
+ // (e.g. script loaded inside <head> before it finishes parsing).
207
+ snapshotHeadNodes();
208
+ if(!document.head)
203
209
  document.addEventListener("DOMContentLoaded", snapshotHeadNodes, { once: true });
204
- else
205
- snapshotHeadNodes();
206
210
 
207
211
  Transparent.isHeadlocked = function(el) {
208
212
  if(!el || el.nodeType !== 1) return false;
@@ -213,10 +217,12 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
213
217
  if(attr !== null && attr !== undefined) return true;
214
218
  // Dynamically injected after initial load
215
219
  if(!originalHeadNodes.has(el)) return true;
216
- // URL pattern match
220
+ // URL pattern match (src/href attributes)
217
221
  var patterns = Settings["headlock"] || [];
218
222
  if(!patterns.length) return false;
219
223
  var url = el.getAttribute && (el.getAttribute("src") || el.getAttribute("href"));
224
+ // <style> elements have no src/href — match against CSS textContent instead
225
+ if(!url && el.tagName === 'STYLE') url = el.textContent || '';
220
226
  if(!url) return false;
221
227
  for(var i = 0; i < patterns.length; i++) {
222
228
  var p = patterns[i];
@@ -224,7 +230,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
224
230
  else if(typeof p === "string" && p.length && url.indexOf(p) !== -1) return true;
225
231
  }
226
232
  return false;
227
- };
233
+ }
228
234
 
229
235
  const State = Transparent.state = {
230
236
 
@@ -323,6 +329,37 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
323
329
  }
324
330
 
325
331
  Transparent.setResponse = function(uuid, responseText, scrollableXY = [], exceptionRaised = false)
332
+ {
333
+ if(isDomEntity(responseText))
334
+ responseText = responseText.outerHTML;
335
+
336
+ var array = JSON.parse(sessionStorage.getItem('transparent')) || [];
337
+ array.push(uuid);
338
+
339
+ while(array.length > Settings["response_limit"])
340
+ sessionStorage.removeItem('transparent['+array.shift()+']');
341
+
342
+ try {
343
+
344
+ if(isLocalStorageNameSupported()) {
345
+
346
+ sessionStorage.setItem('transparent', JSON.stringify(array));
347
+ sessionStorage.setItem('transparent[response]['+uuid+']', responseText);
348
+ sessionStorage.setItem('transparent[position]['+uuid+']', JSON.stringify(scrollableXY));
349
+ }
350
+
351
+ } catch(e) {
352
+
353
+ if (e.name === 'QuotaExceededError')
354
+ sessionStorage.clear();
355
+
356
+ return exceptionRaised === false ? Transparent.setResponse(uuid, responseText, scrollableXY, true) : this;
357
+ }
358
+
359
+ return this;
360
+ }
361
+
362
+ Transparent.setResponse = function(uuid, responseText, scrollableXY, exceptionRaised = false)
326
363
  {
327
364
  if(isDomEntity(responseText))
328
365
  responseText = responseText.outerHTML;
@@ -588,7 +625,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
588
625
  }
589
626
  }
590
627
 
591
- var closestEl = $(el).closest("a");
628
+ closestEl = $(el).closest("a");
592
629
  if(!closestEl.length) closestEl = $(el).closest("button");
593
630
  if(!closestEl.length) closestEl = $(el).closest("input");
594
631
  if (closestEl.length) el = closestEl[0];
@@ -903,7 +940,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
903
940
  } else {
904
941
 
905
942
  if(dom === undefined)
906
- console.error("Response missing..");
943
+ console.alert("Response missing..");
907
944
 
908
945
  var parent = Transparent.findElementFromParents(dom, $(this).parents(), 3);
909
946
  if (parent === undefined) {
@@ -953,7 +990,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
953
990
  var head = $(dom).find("head").html();
954
991
  var body = $(dom).find("body").html();
955
992
 
956
- if(head == undefined || body == undefined) {
993
+ if(head == undefined || body == "undefined") {
957
994
 
958
995
  $(Settings.identifier).html("<div class='error'></div>");
959
996
 
@@ -967,7 +1004,6 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
967
1004
  Transparent.evalScript($("body")[0]);
968
1005
  }
969
1006
 
970
- Transparent.scrollTo({top:0, left:0, duration:0});
971
1007
  Transparent.activeOut();
972
1008
  }
973
1009
 
@@ -987,19 +1023,18 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
987
1023
  var maxScrollY = $(el).prop("scrollHeight") - Math.round($(el).prop("clientHeight"));
988
1024
  if (maxScrollY == 0) maxScrollY = Math.round($(el).prop("clientHeight"));
989
1025
 
990
- var scrollTop = Math.max(0, Math.min(dict["top"] ?? $(el).prop("scrollTop"), maxScrollY));
991
- var scrollLeft = Math.max(0, Math.min(dict["left"] ?? $(el).prop("scrollLeft"), maxScrollX));
1026
+ scrollTop = Math.max(0, Math.min(dict["top"] ?? $(el).prop("scrollTop"), maxScrollY));
1027
+ scrollLeft = Math.max(0, Math.min(dict["left"] ?? $(el).prop("scrollLeft"), maxScrollX));
992
1028
 
993
- var speed = parseFloat(dict["speed"] ?? 0);
994
- var easing = dict["easing"] ?? "swing";
995
- var debounce = dict["debounce"] ?? 0;
1029
+ speed = parseFloat(dict["speed"] ?? 0);
1030
+ easing = dict["easing"] ?? "swing";
1031
+ debounce = dict["debounce"] ?? 0;
996
1032
 
997
- var duration = 1000*Transparent.parseDuration(dict["duration"] ?? 0);
998
- var durationX = 1000*Transparent.parseDuration(dict["duration-x"] ?? dict["duration"] ?? 0);
999
- var durationY = 1000*Transparent.parseDuration(dict["duration-y"] ?? dict["duration"] ?? 0);
1033
+ duration = 1000*Transparent.parseDuration(dict["duration"] ?? 0);
1034
+ durationX = 1000*Transparent.parseDuration(dict["duration-x"] ?? dict["duration"] ?? 0);
1035
+ durationY = 1000*Transparent.parseDuration(dict["duration-y"] ?? dict["duration"] ?? 0);
1000
1036
 
1001
1037
  if(speed) {
1002
- var distanceX = 0, distanceY = 0;
1003
1038
 
1004
1039
  var currentScrollX = $(el)[0].scrollLeft;
1005
1040
  if(currentScrollX < scrollLeft || scrollLeft == 0) // Going to the right
@@ -1244,6 +1279,15 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1244
1279
 
1245
1280
  // Replace head..
1246
1281
  var head = $(dom).find("head");
1282
+
1283
+ // Snapshot hrefs of already-loaded stylesheets so we can detect new ones
1284
+ // added by the head merge and wait for them to finish loading before
1285
+ // making #page visible (prevents FOUC on cold-cache layout transitions).
1286
+ var _existingStyleHrefs = {};
1287
+ $("head").children("link[rel='stylesheet']").each(function() {
1288
+ var h = this.getAttribute("href"); if(h) _existingStyleHrefs[h] = true;
1289
+ });
1290
+
1247
1291
  $("head").children().each(function() {
1248
1292
 
1249
1293
  var el = this;
@@ -1252,12 +1296,17 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1252
1296
  head.children().each(function() {
1253
1297
 
1254
1298
  found = this.isEqualNode(el);
1299
+ // Also match identical <style> tags by content (Brevo styles are identical across pages)
1300
+ if(!found && el.tagName === 'STYLE' && this.tagName === 'STYLE' &&
1301
+ el.textContent && this.textContent &&
1302
+ el.textContent.length > 100 && this.textContent.length === el.textContent.length) {
1303
+ found = this.textContent === el.textContent;
1304
+ }
1255
1305
  return !found;
1256
1306
  });
1257
1307
 
1258
1308
  // Preserve headlocked nodes (dynamically injected widgets, url-matched, etc.)
1259
1309
  if(!found && Transparent.isHeadlocked(el)) found = true;
1260
-
1261
1310
  if(!found) this.remove();
1262
1311
  });
1263
1312
 
@@ -1269,18 +1318,45 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1269
1318
  $("head").children().each(function() { found |= this.isEqualNode(el); });
1270
1319
  if(!found) {
1271
1320
 
1272
-
1273
- if(this.tagName != "SCRIPT" || Settings["global_code"] == true) {
1274
-
1275
- $("head").append(this.cloneNode(true));
1321
+ if(this.tagName == "SCRIPT" && Settings["global_code"] != true) {
1322
+
1323
+ // For inline scripts (without src), create and execute
1324
+ if(!this.src || this.src === '') {
1325
+ var script = document.createElement("script");
1326
+ script.text = this.innerHTML;
1327
+ var i = -1, attrs = this.attributes, attr;
1328
+ var N = attrs.length;
1329
+ while ( ++i < N ) {
1330
+ if(attrs[i].name !== 'src') {
1331
+ script.setAttribute( attrs[i].name, attrs[i].value );
1332
+ }
1333
+ }
1334
+ $("head").append(script);
1335
+ originalHeadNodes.add(script);
1336
+ } else {
1337
+ $("head").append(this);
1338
+ originalHeadNodes.add(this);
1339
+ }
1276
1340
 
1277
1341
  } else {
1278
1342
 
1279
- $("head").append(this);
1343
+ var clonedEl = this.cloneNode(true);
1344
+ $("head").append(clonedEl);
1345
+ // Register as an "original" node so it falls through to URL-pattern
1346
+ // matching on future transitions — prevents layout CSS added by
1347
+ // Transparent itself from being auto-headlocked as third-party content.
1348
+ originalHeadNodes.add(clonedEl);
1280
1349
  }
1281
1350
  }
1282
1351
  });
1283
1352
 
1353
+ // Collect link[rel="stylesheet"] elements inserted by the head merge above
1354
+ var _newStyleLinks = [];
1355
+ $("head").children("link[rel='stylesheet']").each(function() {
1356
+ var h = this.getAttribute("href");
1357
+ if(h && !_existingStyleHrefs[h]) _newStyleLinks.push(this);
1358
+ });
1359
+
1284
1360
  var bodyScript = $(dom).find("body > script");
1285
1361
  bodyScript.each(function() {
1286
1362
 
@@ -1290,10 +1366,27 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1290
1366
  $("body").children().each(function() { found |= this.isEqualNode(el); });
1291
1367
  if(!found) {
1292
1368
 
1293
- if(this.tagName != "SCRIPT" || Settings["global_code"] == true) {
1294
- $("body").append(this.cloneNode(true));
1369
+ if(this.tagName == "SCRIPT" && Settings["global_code"] != true) {
1370
+
1371
+ // For inline scripts (without src), create and execute
1372
+ if(!this.src || this.src === '') {
1373
+ var script = document.createElement("script");
1374
+ script.text = this.innerHTML;
1375
+ var i = -1, attrs = this.attributes, attr;
1376
+ var N = attrs.length;
1377
+ while ( ++i < N ) {
1378
+ if(attrs[i].name !== 'src') {
1379
+ script.setAttribute( attrs[i].name, attrs[i].value );
1380
+ }
1381
+ }
1382
+ $("body").append(script);
1383
+ } else {
1384
+ $("body").append(this);
1385
+ }
1386
+
1295
1387
  } else {
1296
- $("body").append(this);
1388
+
1389
+ $("body").append(this.cloneNode(true));
1297
1390
  }
1298
1391
  }
1299
1392
  });
@@ -1336,7 +1429,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1336
1429
  var scrollableElements = Transparent.getScrollableElement();
1337
1430
  var scrollableElementsXY = Transparent.getResponsePosition(uuid);
1338
1431
 
1339
- for(var i = 0; i < scrollableElements.length; i++) {
1432
+ for(i = 0; i < scrollableElements.length; i++) {
1340
1433
 
1341
1434
  var el = scrollableElements[i];
1342
1435
  var positionXY = undefined;
@@ -1358,18 +1451,41 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1358
1451
  }
1359
1452
  }
1360
1453
 
1361
- $('head').append(function() {
1362
-
1363
- $(Settings.identifier).append(function() {
1364
-
1365
- // Callback if needed, or any other actions
1366
- callback();
1367
-
1368
- // Trigger onload event
1369
- dispatchEvent(new Event('transparent:load'));
1370
- dispatchEvent(new Event('load'));
1371
- });
1372
- });
1454
+ // Wait for any newly added layout stylesheets to finish loading before
1455
+ // calling callback() / activeOut() — otherwise #page becomes visible while
1456
+ // the new CSS is still being parsed, causing a flash of unstyled content.
1457
+ (function() {
1458
+ function doCallback() {
1459
+ $('head').append(function() {
1460
+ $(Settings.identifier).append(function() {
1461
+ callback();
1462
+ dispatchEvent(new Event('transparent:load'));
1463
+ dispatchEvent(new Event('load'));
1464
+ });
1465
+ });
1466
+ }
1467
+ if(_newStyleLinks.length === 0) {
1468
+ doCallback();
1469
+ } else {
1470
+ var remaining = _newStyleLinks.length;
1471
+ var fired = false;
1472
+ // Safety valve: if a stylesheet fails or stalls, don't block forever.
1473
+ var guard = setTimeout(function() {
1474
+ if(!fired) { fired = true; doCallback(); }
1475
+ }, 3000);
1476
+ _newStyleLinks.forEach(function(link) {
1477
+ function onDone() {
1478
+ if(--remaining <= 0 && !fired) {
1479
+ fired = true;
1480
+ clearTimeout(guard);
1481
+ doCallback();
1482
+ }
1483
+ }
1484
+ link.addEventListener('load', onDone, {once:true});
1485
+ link.addEventListener('error', onDone, {once:true});
1486
+ });
1487
+ }
1488
+ })();
1373
1489
 
1374
1490
  }.bind(this), activeInRemainingTime > 0 ? activeInRemainingTime : 1);
1375
1491
  }
@@ -1474,7 +1590,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1474
1590
  var elementsXY = [];
1475
1591
  var elements = Transparent.getScrollableElement();
1476
1592
 
1477
- for(var i = 0; i < elements.length; i++)
1593
+ for(i = 0; i < elements.length; i++)
1478
1594
  elementsXY.push([$(elements[i]).scrollTop(), $(elements[i]).scrollLeft()]);
1479
1595
 
1480
1596
  return elementsXY;
@@ -1494,7 +1610,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1494
1610
  return;
1495
1611
  }
1496
1612
 
1497
- dispatchEvent(new CustomEvent('transparent:link', {detail: {link: link}}));
1613
+ dispatchEvent(new CustomEvent('transparent:link', {link:link}));
1498
1614
 
1499
1615
  const uuid = uuidv4();
1500
1616
  const type = link[0];
@@ -1506,10 +1622,8 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1506
1622
  // Wait for transparent window event to be triggered
1507
1623
  if (!isReady) return;
1508
1624
 
1509
- const $ctx = (e.type === Transparent.state.SUBMIT) ? $(document) : $(this);
1510
- if (e.type !== Transparent.state.POPSTATE &&
1511
- e.type !== Transparent.state.HASHCHANGE &&
1512
- !$ctx.find(Settings.identifier).length) return;
1625
+ if (e.type != Transparent.state.POPSTATE &&
1626
+ e.type != Transparent.state.HASHCHANGE && !$(this).find(Settings.identifier).length) return;
1513
1627
 
1514
1628
  var form = target != undefined && target.tagName == "FORM" ? target : undefined;
1515
1629
  var formTrigger = undefined;
@@ -1609,34 +1723,35 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1609
1723
  catch (e) { return false; }
1610
1724
  }
1611
1725
 
1612
- function handleResponse(uuid, status = 200, method = null, data = null, responseURL = null, contentType = null, fetchedResponseText = null) {
1726
+ function handleResponse(uuid, status = 200, method = null, data = null, xhr = null, request = null) {
1613
1727
 
1614
1728
  ajaxSemaphore = false;
1729
+
1730
+ var responseURL;
1731
+ responseURL = xhr !== null ? xhr.responseURL : url.href;
1615
1732
 
1616
- responseURL = responseURL ?? url.href;
1617
-
1618
- var responseText = Transparent.getResponseText(uuid);
1733
+ responseText = Transparent.getResponseText(uuid);
1619
1734
 
1620
- const fragmentPosResp = responseURL.indexOf("#");
1621
- var strippedResponseUrl = (fragmentPosResp < 0 ? responseURL : responseURL.substring(0, fragmentPosResp)).trimEnd("/");
1735
+ var fragmentPos = responseURL.indexOf("#");
1736
+ var strippedResponseUrl = (fragmentPos < 0 ? responseURL : responseURL.substring(0, fragmentPos)).trimEnd("/");
1622
1737
 
1623
- const fragmentPosReq = url.href.indexOf("#");
1624
- var strippedUrlHref = (fragmentPosReq < 0 ? url.href : url.href.substring(0, fragmentPosReq)).trimEnd("/");
1738
+ var fragmentPos = url.href.indexOf("#");
1739
+ var strippedUrlHref = (fragmentPos < 0 ? url.href : url.href.substring(0, fragmentPos)).trimEnd("/");
1625
1740
  if( strippedUrlHref == strippedResponseUrl )
1626
- responseURL = url.href; // NB: fetch response.url strips away #fragments
1741
+ responseURL = url.href; // NB: xhr.responseURL strips away #fragments
1627
1742
 
1628
1743
  if(!responseText) {
1629
1744
 
1630
- if(!fetchedResponseText && responseText === null) {
1745
+ if(!request && responseText === null) {
1631
1746
 
1632
1747
  setTimeout(function() { window.location.href = responseURL; }, Settings["throttle"]);
1633
1748
  return;
1634
1749
  }
1635
1750
 
1636
- responseText = fetchedResponseText;
1751
+ responseText = request.responseText;
1637
1752
  if(status >= 500) {
1638
1753
 
1639
- console.error("Unexpected response from "+uuid+": error code "+status);
1754
+ console.error("Unexpected XHR response from "+uuid+": error code "+request.status);
1640
1755
  console.error(sessionStorage);
1641
1756
  }
1642
1757
 
@@ -1645,7 +1760,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1645
1760
  }
1646
1761
 
1647
1762
  var dom = new DOMParser().parseFromString(responseText, "text/html");
1648
- if(contentType && contentType.includes("application/json")) {
1763
+ if(request && request.getResponseHeader("Content-Type") == "application/json") {
1649
1764
 
1650
1765
  if(!isJsonResponse(responseText)) {
1651
1766
  console.error("Invalid response received for "+ responseURL);
@@ -1671,7 +1786,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1671
1786
  }
1672
1787
 
1673
1788
  // Invalid html page returned
1674
- if(contentType && contentType.includes("text/html")) {
1789
+ if(request && request.getResponseHeader("Content-Type") == "text/html") {
1675
1790
 
1676
1791
  if (!responseText.includes("<html") && !responseText.includes("<body") && !responseText.includes("<head"))
1677
1792
  return Transparent.rescue(dom);
@@ -1690,7 +1805,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1690
1805
 
1691
1806
  // From here the page is valid..
1692
1807
  // so the new page is added to history..
1693
- if(fetchedResponseText !== null)
1808
+ if(xhr)
1694
1809
  history.pushState({uuid: uuid, status:status, method: method, data: {}, href: responseURL}, '', responseURL);
1695
1810
 
1696
1811
  // Page not recognized.. just go fetch by yourself.. no POST information transmitted..
@@ -1734,6 +1849,24 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1734
1849
  if($(dom).find("html").hasClass(Transparent.state.RELOAD) || $(dom).find("html").hasClass(Transparent.state.DISABLE))
1735
1850
  return window.location.reload();
1736
1851
 
1852
+ // Kick off preloads for stylesheets the new page needs but aren't yet in <head>.
1853
+ // They download in parallel during the activeIn animation so onLoad() finds them
1854
+ // already cached — eliminating FOUC on cold-cache layout transitions.
1855
+ (function() {
1856
+ var loaded = {};
1857
+ $("head").children("link[rel='stylesheet']").each(function() {
1858
+ var h = this.getAttribute("href"); if(h) loaded[h] = true;
1859
+ });
1860
+ $(dom).find("head").children("link[rel='stylesheet']").each(function() {
1861
+ var h = this.getAttribute("href");
1862
+ if(!h || loaded[h]) return;
1863
+ if($("head").find("link[rel='preload'][href='" + h.replace(/'/g, "\\'") + "']").length) return;
1864
+ var pl = document.createElement("link");
1865
+ pl.rel = "preload"; pl.as = "style"; pl.href = h;
1866
+ document.head.appendChild(pl);
1867
+ });
1868
+ })();
1869
+
1737
1870
  return Transparent.onLoad(uuid, dom, function() {
1738
1871
 
1739
1872
  Transparent.activeOut(function() {
@@ -1762,20 +1895,20 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1762
1895
  $(Transparent.html).prop("user-scroll", false); // make sure to avoid page jump during transition (cancelled in activeIn callback)
1763
1896
 
1764
1897
  // Submit ajax request..
1765
- ajaxSemaphore = true; // Raise before dispatching synthetic submit to prevent double-submission
1766
1898
  if(form) form.dispatchEvent(new SubmitEvent("submit", { submitter: formTrigger }));
1767
-
1768
- return fetch(url.href, {
1769
- method: type,
1770
- body: type === "GET" ? undefined : data,
1771
- headers: Settings["headers"] || {}
1772
- })
1773
- .then(async (response) => {
1774
- const responseText = await response.text();
1775
- return handleResponse(uuid, response.status, type, data, response.url, response.headers.get("Content-Type"), responseText);
1776
- })
1777
- .catch(() => {
1778
- handleResponse(uuid, 500, type, data, url.href, null, null);
1899
+ var xhr = new XMLHttpRequest();
1900
+
1901
+ ajaxSemaphore = true;
1902
+ return jQuery.ajax({
1903
+ url: url.href,
1904
+ type: type,
1905
+ data: data,
1906
+ contentType: false,
1907
+ processData: false,
1908
+ headers: Settings["headers"] || {},
1909
+ xhr: function () { return xhr; },
1910
+ success: function (html, status, request) { return handleResponse(uuid, request.status, type, data, xhr, request); },
1911
+ error: function (request, ajaxOptions, thrownError) { return handleResponse(uuid, request.status, type, data, xhr, request); }
1779
1912
  });
1780
1913
  }
1781
1914
 
@@ -1795,8 +1928,8 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1795
1928
 
1796
1929
  if(Settings.debug) console.debug("Transparent is disabled..");
1797
1930
 
1798
- const statesSet = new Set(Object.values(Transparent.state));
1799
- const htmlClass = ($("html").attr("class") || "").split(" ").filter(x => !statesSet.has(x));
1931
+ var states = Object.values(Transparent.state);
1932
+ var htmlClass = Array.from(($("html").attr("class") || "").split(" ")).filter(x => !states.includes(x));
1800
1933
  Transparent.html.removeClass(states).addClass(htmlClass.join(" ")+" "+Transparent.state.ROOT+" "+Transparent.state.READY+" "+Transparent.state.DISABLE);
1801
1934
 
1802
1935
  } else {
@@ -1882,7 +2015,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1882
2015
  var fieldValueBefore = formDataBefore[fieldName];
1883
2016
  if(fieldValueBefore instanceof File) {
1884
2017
 
1885
- if(!(fieldValueAfter instanceof File)) preventDefault = true;
2018
+ if(!fieldValueAfter instanceof File) preventDefault = true;
1886
2019
  else if (fieldValueBefore.size != fieldValueAfter.size) preventDefault = true;
1887
2020
 
1888
2021
  } else if(fieldValueBefore != fieldValueAfter) {
@@ -1903,7 +2036,7 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
1903
2036
 
1904
2037
  document.addEventListener('click', __main__, false);
1905
2038
 
1906
- $(document).on("submit", "form", __main__);
2039
+ $("form").on("submit", __main__);
1907
2040
  }
1908
2041
 
1909
2042