diff --git a/lib/builtin-rules.js b/lib/builtin-rules.js index 0969997..7f7d068 100644 --- a/lib/builtin-rules.js +++ b/lib/builtin-rules.js @@ -33,7 +33,7 @@ d35aaqx5ub95lt.cloudfront.net/js/app-*.js$script ! -- github.com gist.github.com - std-PerformanceObserver,std-queueMicrotask,gh-compat,gh-main-csp,sm-gh-extra,sm-cookie + std-PerformanceObserver,std-queueMicrotask,gh-compat,gh-turbo,gh-main-csp,sm-gh-extra,sm-cookie github.com/socket-worker.js$script gist.github.com/socket-worker.js$script github.com/assets-cdn/worker/socket-worker-*.js$script diff --git a/lib/main.js b/lib/main.js index f530672..345c1ad 100644 --- a/lib/main.js +++ b/lib/main.js @@ -97,6 +97,9 @@ function evaluateFix(fix, script, csp, contentReplace) { contentReplace.push([`this.matchFields?.join("-")`, `((y)=>y?y.join("-"):y)(this.matchFields)`]); contentReplace.push([`H.integrity=S.sriHashes[t],`, ``]); break; + case "gh-turbo": + script.push(pf.Github_disableTurbo); + break; case "gh-main-csp": csp["connect-src"] = ["objects.githubusercontent.com", "codeload.github.com"]; break; @@ -210,6 +213,14 @@ function supersededFixes(service) { superseded.add("google-regexp"); superseded.add("notion-regexp"); } + if (service.isWebComponentsSupported) { + superseded.add("gh-compat"); + superseded.add("pkg-WebComponents"); + superseded.add("std-ShadowDOM"); + } + if (service.isLogicalAssignSupported) { + superseded.add("wordpress-logicalassign"); + } return superseded; } @@ -615,6 +626,21 @@ class MergedFix { } } +const gWindowOpenListener = { + onOpenWindow: function(xulWindow) + { + const window = xulWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindow); + const onWindowLoad = () => { + window.removeEventListener("load", onWindowLoad); + if (window.document.documentElement.getAttribute("windowtype") == "navigator:browser") { + gService._checkWindowFeatures(window); + } + } + window.addEventListener("load", onWindowLoad); + } +} + class PolyfillService { constructor() { @@ -624,6 +650,17 @@ class PolyfillService { this.isNullishCoalescingSupported = this._checkSyntax("foo??bar"); this.isNamedCapturingGroupSupported = this._checkSyntax("/(?x)/"); this.isPropertyEscapeSupported = this._checkSyntax("/\\p{L}/u"); + this.isLogicalAssignSupported = this._checkSyntax("let a=3;a||=false;a??=true"); + // Features that need a Window global to be checked + this.isWebComponentsSupported = false; + const win = Services.wm.getMostRecentWindow("navigator:browser"); + if (win) { + this._checkWindowFeatures(win); + } else { + // Addons get loaded before the first Window is created. Instead, delay the check + // until the first navigator window is opened. + Services.wm.addListener(gWindowOpenListener); + } this.fixCache = new Map(); this.rules = new RuleEngine(); this.exclusion = new RuleEngine(); @@ -633,6 +670,7 @@ class PolyfillService { destroy() { settings.onPrefChanged.remove(this._prefChanged, this); + Services.wm.removeListener(gWindowOpenListener); } _loadRules() { @@ -682,6 +720,15 @@ class PolyfillService { return true; } + _checkWindowFeatures(window) { + this.isWebComponentsSupported = typeof window.ShadowRoot !== "undefined" && + typeof window.Element.prototype.attachShadow !== "undefined" && + typeof window.Node.prototype.getRootNode !== "undefined" && + typeof window.customElements !== "undefined" && + typeof window.customElements.define !== "undefined"; + Services.wm.removeListener(gWindowOpenListener); + } + isSiteEnabled(URI) { return this.rules.isSiteEnabled(URI.host); } diff --git a/lib/polyfills.js b/lib/polyfills.js index 0e35de9..0197a08 100644 --- a/lib/polyfills.js +++ b/lib/polyfills.js @@ -310,6 +310,9 @@ exports.Github_enableDiffButton = jss` for (let button of document.getElementsByClassName("load-diff-button")) button.removeAttribute("disabled"); }, {once: true}); +`; + +exports.Github_disableTurbo = jss` // TEMPORARY: hard-disable Turbo navigation to prevent memory leaks in Pale Moon document.addEventListener("DOMContentLoaded", () => { Turbo.session.elementIsNavigatable = (e) => false;