@glitchr/transparent 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/js/transparent.js +68 -23
package/package.json
CHANGED
package/src/js/transparent.js
CHANGED
|
@@ -500,8 +500,14 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
500
500
|
if (!array.includes(uuid)) {
|
|
501
501
|
|
|
502
502
|
array.push(uuid);
|
|
503
|
+
// Enforce the LRU cap. NB: entries are stored under
|
|
504
|
+
// `transparent[response][<uuid>]` / `transparent[position][<uuid>]`,
|
|
505
|
+
// so eviction must remove THOSE keys — the previous code removed
|
|
506
|
+
// `transparent[<uuid>]`, which never existed, leaving the real
|
|
507
|
+
// response/position blobs orphaned. They then accumulated past the
|
|
508
|
+
// cap until QuotaExceededError forced a full sessionStorage.clear().
|
|
503
509
|
while(array.length > Settings["response_limit"])
|
|
504
|
-
|
|
510
|
+
removeResponseEntry(array.shift());
|
|
505
511
|
}
|
|
506
512
|
|
|
507
513
|
try {
|
|
@@ -515,15 +521,42 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
515
521
|
|
|
516
522
|
} catch(e) {
|
|
517
523
|
|
|
524
|
+
// On quota, evict the oldest cached pages (targeted) and retry
|
|
525
|
+
// once, instead of nuking ALL sessionStorage — sessionStorage.clear()
|
|
526
|
+
// also wipes unrelated app state and the entire page cache.
|
|
527
|
+
if (e.name === 'QuotaExceededError' && exceptionRaised === false) {
|
|
528
|
+
evictOldestResponses(Math.max(1, Math.ceil(array.length / 2)));
|
|
529
|
+
return Transparent.setResponse(uuid, responseText, scrollableXY, true);
|
|
530
|
+
}
|
|
531
|
+
// Last resort if a single page is itself too big to ever fit.
|
|
518
532
|
if (e.name === 'QuotaExceededError')
|
|
519
533
|
sessionStorage.clear();
|
|
520
534
|
|
|
521
|
-
return
|
|
535
|
+
return this;
|
|
522
536
|
}
|
|
523
537
|
|
|
524
538
|
return this;
|
|
525
539
|
}
|
|
526
540
|
|
|
541
|
+
// Remove both blobs for a cached page uuid (response HTML + scroll position).
|
|
542
|
+
function removeResponseEntry(uuid) {
|
|
543
|
+
try {
|
|
544
|
+
sessionStorage.removeItem('transparent[response]['+uuid+']');
|
|
545
|
+
sessionStorage.removeItem('transparent[position]['+uuid+']');
|
|
546
|
+
} catch (e) {}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// Drop the N oldest cached pages and rewrite the index. Used to recover
|
|
550
|
+
// from a QuotaExceededError without discarding the whole cache.
|
|
551
|
+
function evictOldestResponses(count) {
|
|
552
|
+
try {
|
|
553
|
+
var array = JSON.parse(sessionStorage.getItem('transparent')) || [];
|
|
554
|
+
for (var i = 0; i < count && array.length; i++)
|
|
555
|
+
removeResponseEntry(array.shift());
|
|
556
|
+
sessionStorage.setItem('transparent', JSON.stringify(array));
|
|
557
|
+
} catch (e) {}
|
|
558
|
+
}
|
|
559
|
+
|
|
527
560
|
Transparent.setResponseText = function(uuid, responseText, exceptionRaised = false)
|
|
528
561
|
{
|
|
529
562
|
if(isDomEntity(responseText))
|
|
@@ -1771,6 +1804,14 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
1771
1804
|
// double-prompt. The existing `formSubmission` flag already handles
|
|
1772
1805
|
// the synchronous prompt path; this clears state for any follow-up.
|
|
1773
1806
|
document.addEventListener('submit', function() { formDirty = false; }, true);
|
|
1807
|
+
// Reset on every navigation. transparent.js re-dispatches DOMContentLoaded
|
|
1808
|
+
// after each SPA swap (see _doSwap, ~line 1567), so this fires on the
|
|
1809
|
+
// initial load AND on each in-place navigation. Without it the flag leaks
|
|
1810
|
+
// across SPA navigations: typing on page A, then navigating to a form
|
|
1811
|
+
// page B, would leave formDirty=true and wrongly prompt on reload of B
|
|
1812
|
+
// even though the user never touched B. A freshly-loaded page is never
|
|
1813
|
+
// dirty until the user types on it (any restored draft is already saved).
|
|
1814
|
+
document.addEventListener('DOMContentLoaded', function() { formDirty = false; });
|
|
1774
1815
|
|
|
1775
1816
|
// ── Transparent.formMemory ──────────────────────────────────────────────
|
|
1776
1817
|
//
|
|
@@ -2394,9 +2435,26 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
2394
2435
|
window.onpopstate = __main__; // Onpopstate pop out straight to previous page.. this creates a jump while changing pages with hash..
|
|
2395
2436
|
window.onhashchange = __main__;
|
|
2396
2437
|
|
|
2397
|
-
// onbeforeunload
|
|
2398
|
-
//
|
|
2399
|
-
//
|
|
2438
|
+
// onbeforeunload confirmation REMOVED. It produced spurious "are you
|
|
2439
|
+
// sure you want to leave?" blocks on any page with a form even when the
|
|
2440
|
+
// user never typed: the dirty flag was flipped by any trusted change
|
|
2441
|
+
// event (a <select>/checkbox toggle, Select2/datepicker init firing a
|
|
2442
|
+
// real change, browser autofill, …), and the `e.currentTarget == window`
|
|
2443
|
+
// guard below is unreliable across browsers. More importantly it's now
|
|
2444
|
+
// obsolete: Transparent.formMemory persists every form's content to
|
|
2445
|
+
// localStorage (debounced on input + saved synchronously on unload) and
|
|
2446
|
+
// restores it on the next load, so reloading or closing the tab never
|
|
2447
|
+
// loses typed input. The draft save on beforeunload (in the formMemory
|
|
2448
|
+
// IIFE above) is kept; only the blocking confirmation is gone.
|
|
2449
|
+
var __onbeforeunload_disabled = function(e) {
|
|
2450
|
+
if(Settings.debug) console.log("Transparent onbeforeunload (no-op; drafts auto-saved)");
|
|
2451
|
+
if(formSubmission) return;
|
|
2452
|
+
if(Settings.disable) return;
|
|
2453
|
+
// No return value → browser never shows the leave/reload confirmation.
|
|
2454
|
+
};
|
|
2455
|
+
|
|
2456
|
+
// Legacy snapshot-and-compare confirm (formDataBefore vs formDataAfter)
|
|
2457
|
+
// gave
|
|
2400
2458
|
// false positives because JS init code mutates form values after
|
|
2401
2459
|
// load — Select2 writes selected text to hidden fields, Editor.js
|
|
2402
2460
|
// serializes its JSON to a <textarea>, datepicker normalizes
|
|
@@ -2404,24 +2462,11 @@ jQuery.event.special.mousewheel = { setup: function( _, ns, handle ) { this.addE
|
|
|
2404
2462
|
// and the current state always differed, and the browser always
|
|
2405
2463
|
// prompted even on read-only pages.
|
|
2406
2464
|
//
|
|
2407
|
-
//
|
|
2408
|
-
//
|
|
2409
|
-
//
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
if(Settings.debug) console.log("Transparent onbeforeunload event called..");
|
|
2413
|
-
|
|
2414
|
-
if(formSubmission) return; // Do not display on form submission
|
|
2415
|
-
if(Settings.disable) return;
|
|
2416
|
-
if(e.currentTarget == window) return;
|
|
2417
|
-
if(!formDirty) return; // ← user hasn't modified anything; no prompt
|
|
2418
|
-
|
|
2419
|
-
Transparent.html.addClass(Transparent.state.READY);
|
|
2420
|
-
Transparent.activeOut();
|
|
2421
|
-
dispatchEvent(new Event('load'));
|
|
2422
|
-
|
|
2423
|
-
return "Dude, are you sure you want to leave? Think of the kittens!";
|
|
2424
|
-
}
|
|
2465
|
+
// false positives because JS init code mutated form values after load.
|
|
2466
|
+
// Both that and the formDirty replacement are gone: the content is
|
|
2467
|
+
// already in localStorage (saved on input + on unload), so leaving the
|
|
2468
|
+
// page never loses it and a confirmation only gets in the way.
|
|
2469
|
+
window.onbeforeunload = __onbeforeunload_disabled;
|
|
2425
2470
|
|
|
2426
2471
|
document.addEventListener('click', __main__, false);
|
|
2427
2472
|
|