From 07f4878d59a7459472e66a2ba0c1c0413232107e Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 15 Dec 2019 11:57:26 +0300 Subject: [PATCH] workaround for a race condition between dojo.parse() and tt-rss loading proper day/night css on startup because of firefox async CSS loader --- index.php | 16 +++++++++++++--- js/AppBase.js | 44 ++++++++++++++++++++++++++++++-------------- js/prefs.js | 22 ++++++++++++---------- js/tt-rss.js | 46 ++++++++++++++++++++++++---------------------- prefs.php | 16 +++++++++++++--- 5 files changed, 92 insertions(+), 52 deletions(-) diff --git a/index.php b/index.php index 8fb76bc2a..f7ea6178a 100644 --- a/index.php +++ b/index.php @@ -48,8 +48,6 @@ $theme = get_pref("USER_CSS_THEME", false, false); if ($theme && theme_exists("$theme")) { echo stylesheet_tag(get_theme_path($theme), 'theme_css'); - } else { - echo stylesheet_tag("css/default.css", 'theme_css'); } } ?> @@ -116,11 +114,23 @@ ?> + + - +
diff --git a/js/AppBase.js b/js/AppBase.js index a348c95f8..8d42fd382 100644 --- a/js/AppBase.js +++ b/js/AppBase.js @@ -9,7 +9,6 @@ define(["dojo/_base/declare"], function (declare) { hotkey_prefix_timeout: 0, constructor: function() { window.onerror = this.Error.onWindowError; - this.setupNightModeDetection(); }, getInitParam: function(k) { return this._initParams[k]; @@ -17,30 +16,47 @@ define(["dojo/_base/declare"], function (declare) { setInitParam: function(k, v) { this._initParams[k] = v; }, - nightModeChanged: function(is_night) { + nightModeChanged: function(is_night, link) { console.log("night mode changed to", is_night); - const link = $("theme_css"); - if (link) { - - if (link.getAttribute("data-orig-href").indexOf("css/default.css") !== -1) { - const css_override = is_night ? "themes/night.css" : "css/default.css"; - link.setAttribute("href", css_override + "?" + Date.now()); - } + const css_override = is_night ? "themes/night.css" : "css/default.css"; + link.setAttribute("href", css_override + "?" + Date.now()); } }, - setupNightModeDetection: function() { - if (window.matchMedia) { + setupNightModeDetection: function(callback) { + if (!$("theme_css")) { const mql = window.matchMedia('(prefers-color-scheme: dark)'); try { mql.addEventListener("change", () => { - this.nightModeChanged(mql.matches); + this.nightModeChanged(mql.matches, $("theme_auto_css")); }); - } catch (e) {} + } catch (e) { + console.warn("exception while trying to set MQL event listener"); + } - this.nightModeChanged(mql.matches); + const link = new Element("link", { + rel: "stylesheet", + id: "theme_auto_css" + }); + + if (callback) { + link.onload = function () { + document.querySelector("body").removeClassName("css_loading"); + callback(); + }; + + link.onerror = function(event) { + alert("Fatal error while loading application stylesheet: " + link.getAttribute("href")); + } + } + + this.nightModeChanged(mql.matches, link); + + document.querySelector("head").appendChild(link); + } else { + if (callback) callback(); } }, enableCsrfSupport: function() { diff --git a/js/prefs.js b/js/prefs.js index 747eb4105..944e49258 100755 --- a/js/prefs.js +++ b/js/prefs.js @@ -63,19 +63,21 @@ require(["dojo/_base/kernel", try { const _App = declare("fox.App", AppBase, { constructor: function() { - parser.parse(); + this.setupNightModeDetection(() => { + parser.parse(); - this.setLoadingProgress(50); + this.setLoadingProgress(50); - const clientTzOffset = new Date().getTimezoneOffset() * 60; - const params = {op: "rpc", method: "sanityCheck", clientTzOffset: clientTzOffset}; + const clientTzOffset = new Date().getTimezoneOffset() * 60; + const params = {op: "rpc", method: "sanityCheck", clientTzOffset: clientTzOffset}; - xhrPost("backend.php", params, (transport) => { - try { - this.backendSanityCallback(transport); - } catch (e) { - this.Error.report(e); - } + xhrPost("backend.php", params, (transport) => { + try { + this.backendSanityCallback(transport); + } catch (e) { + this.Error.report(e); + } + }); }); }, initSecondStage: function() { diff --git a/js/tt-rss.js b/js/tt-rss.js index 8868fa7a5..84e42bf85 100644 --- a/js/tt-rss.js +++ b/js/tt-rss.js @@ -67,33 +67,35 @@ require(["dojo/_base/kernel", _widescreen_mode: false, hotkey_actions: {}, constructor: function () { - parser.parse(); + this.setupNightModeDetection(() => { + parser.parse(); - if (!this.checkBrowserFeatures()) - return; + if (!this.checkBrowserFeatures()) + return; - this.setLoadingProgress(30); - this.initHotkeyActions(); + this.setLoadingProgress(30); + this.initHotkeyActions(); - const a = document.createElement('audio'); - const hasAudio = !!a.canPlayType; - const hasSandbox = "sandbox" in document.createElement("iframe"); - const hasMp3 = !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, '')); - const clientTzOffset = new Date().getTimezoneOffset() * 60; + const a = document.createElement('audio'); + const hasAudio = !!a.canPlayType; + const hasSandbox = "sandbox" in document.createElement("iframe"); + const hasMp3 = !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, '')); + const clientTzOffset = new Date().getTimezoneOffset() * 60; - const params = { - op: "rpc", method: "sanityCheck", hasAudio: hasAudio, - hasMp3: hasMp3, - clientTzOffset: clientTzOffset, - hasSandbox: hasSandbox - }; + const params = { + op: "rpc", method: "sanityCheck", hasAudio: hasAudio, + hasMp3: hasMp3, + clientTzOffset: clientTzOffset, + hasSandbox: hasSandbox + }; - xhrPost("backend.php", params, (transport) => { - try { - App.backendSanityCallback(transport); - } catch (e) { - App.Error.report(e); - } + xhrPost("backend.php", params, (transport) => { + try { + App.backendSanityCallback(transport); + } catch (e) { + App.Error.report(e); + } + }); }); }, checkBrowserFeatures: function() { diff --git a/prefs.php b/prefs.php index 38e201fec..d75fc5553 100644 --- a/prefs.php +++ b/prefs.php @@ -40,8 +40,6 @@ $theme = get_pref("USER_CSS_THEME", false, false); if ($theme && theme_exists("$theme")) { echo stylesheet_tag(get_theme_path($theme), 'theme_css'); - } else { - echo stylesheet_tag("css/default.css", 'theme_css'); } } ?> @@ -99,10 +97,22 @@ ?> + + - +