This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/lib/theme-selector.js.es6
David Taylor 98fbc019a3
FIX: Ensure live-reloading of theme CSS works first time (#8052)
The client-side theme-selector would always apply the first in a series of file change notifications. This has been fixed, so it now applies the most recent notification.

Duplicate notifications were being sent because
- The remote_theme autosave was causing every change notification to be doubled
- Color scheme change notifications were being sent every time a theme was uploaded, even if the colors were unchanged

These duplicate notifications have been fixed, and a spec added to ensure it does not regress in future
2019-08-29 15:47:08 +01:00

126 lines
2.8 KiB
JavaScript

import { ajax } from "discourse/lib/ajax";
import deprecated from "discourse-common/lib/deprecated";
const keySelector = "meta[name=discourse_theme_ids]";
export function currentThemeKey() {
// eslint-disable-next-line no-console
if (console && console.warn && console.trace) {
// TODO: Remove this code Jan 2019
deprecated(
"'currentThemeKey' is is deprecated use 'currentThemeId' instead. A theme component may require updating."
);
}
}
export function currentThemeIds() {
const themeIds = [];
const elem = _.first($(keySelector));
if (elem) {
elem.content.split(",").forEach(num => {
num = parseInt(num, 10);
if (!isNaN(num)) {
themeIds.push(num);
}
});
}
return themeIds;
}
export function currentThemeId() {
return currentThemeIds()[0];
}
export function setLocalTheme(ids, themeSeq) {
ids = ids.reject(id => !id);
if (ids && ids.length > 0) {
$.cookie("theme_ids", `${ids.join(",")}|${themeSeq}`, {
path: "/",
expires: 9999
});
} else {
$.removeCookie("theme_ids", { path: "/", expires: 1 });
}
}
export function refreshCSS(node, hash, newHref) {
let $orig = $(node);
if ($orig.data("reloading")) {
clearTimeout($orig.data("timeout"));
$orig.data("copy").remove();
}
if (!$orig.data("orig")) {
$orig.data("orig", node.href);
}
$orig.data("reloading", true);
const orig = $(node).data("orig");
let reloaded = $orig.clone(true);
if (hash) {
reloaded[0].href =
orig + (orig.indexOf("?") >= 0 ? "&hash=" : "?hash=") + hash;
} else {
reloaded[0].href = newHref;
}
$orig.after(reloaded);
let timeout = setTimeout(() => {
$orig.remove();
reloaded.data("reloading", false);
}, 2000);
$orig.data("timeout", timeout);
$orig.data("copy", reloaded);
}
export function previewTheme(ids = []) {
ids = ids.reject(id => !id);
if (!ids.includes(currentThemeId())) {
Discourse.set("assetVersion", "forceRefresh");
ajax(`/themes/assets/${ids.length > 0 ? ids.join("-") : "default"}`).then(
results => {
const elem = _.first($(keySelector));
if (elem) {
elem.content = ids.join(",");
}
results.themes.forEach(theme => {
const node = $(
`link[rel=stylesheet][data-target=${theme.target}]`
)[0];
if (node) {
refreshCSS(node, null, theme.new_href);
}
});
}
);
}
}
export function listThemes(site) {
let themes = site.get("user_themes");
if (!themes) {
return null;
}
let hasDefault = !!themes.findBy("default", true);
let results = [];
if (!hasDefault) {
results.push({ name: I18n.t("themes.default_description"), id: null });
}
themes.forEach(t => {
results.push({ name: t.name, id: t.theme_id });
});
return results.length === 0 ? null : results;
}