mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-07-10 11:21:36 +00:00
268 lines
5.7 KiB
JavaScript
268 lines
5.7 KiB
JavaScript
import Url from "./utils/url";
|
|
|
|
/**
|
|
* Themes to apply to displayed content
|
|
* @class
|
|
* @param {Rendition} rendition
|
|
*/
|
|
class Themes {
|
|
constructor(rendition) {
|
|
this.rendition = rendition;
|
|
this._themes = {
|
|
"default" : {
|
|
"rules" : {},
|
|
"url" : "",
|
|
"serialized" : ""
|
|
}
|
|
};
|
|
this._overrides = {};
|
|
this._current = "default";
|
|
this._injected = [];
|
|
this.rendition.hooks.content.register(this.inject.bind(this));
|
|
this.rendition.hooks.content.register(this.overrides.bind(this));
|
|
|
|
}
|
|
|
|
/**
|
|
* Add themes to be used by a rendition
|
|
* @param {object | Array<object> | string}
|
|
* @example themes.register("light", "http://example.com/light.css")
|
|
* @example themes.register("light", { "body": { "color": "purple"}})
|
|
* @example themes.register({ "light" : {...}, "dark" : {...}})
|
|
*/
|
|
register () {
|
|
if (arguments.length === 0) {
|
|
return;
|
|
}
|
|
if (arguments.length === 1 && typeof(arguments[0]) === "object") {
|
|
return this.registerThemes(arguments[0]);
|
|
}
|
|
if (arguments.length === 1 && typeof(arguments[0]) === "string") {
|
|
return this.default(arguments[0]);
|
|
}
|
|
if (arguments.length === 2 && typeof(arguments[1]) === "string") {
|
|
return this.registerUrl(arguments[0], arguments[1]);
|
|
}
|
|
if (arguments.length === 2 && typeof(arguments[1]) === "object") {
|
|
return this.registerRules(arguments[0], arguments[1]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a default theme to be used by a rendition
|
|
* @param {object | string} theme
|
|
* @example themes.register("http://example.com/default.css")
|
|
* @example themes.register({ "body": { "color": "purple"}})
|
|
*/
|
|
default (theme) {
|
|
if (!theme) {
|
|
return;
|
|
}
|
|
if (typeof(theme) === "string") {
|
|
return this.registerUrl("default", theme);
|
|
}
|
|
if (typeof(theme) === "object") {
|
|
return this.registerRules("default", theme);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register themes object
|
|
* @param {object} themes
|
|
*/
|
|
registerThemes (themes) {
|
|
for (var theme in themes) {
|
|
if (themes.hasOwnProperty(theme)) {
|
|
if (typeof(themes[theme]) === "string") {
|
|
this.registerUrl(theme, themes[theme]);
|
|
} else {
|
|
this.registerRules(theme, themes[theme]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register a theme by passing its css as string
|
|
* @param {string} name
|
|
* @param {string} css
|
|
*/
|
|
registerCss (name, css) {
|
|
this._themes[name] = { "serialized" : css };
|
|
if (this._injected[name] || name == 'default') {
|
|
this.update(name);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register a url
|
|
* @param {string} name
|
|
* @param {string} input
|
|
*/
|
|
registerUrl (name, input) {
|
|
var url = new Url(input);
|
|
this._themes[name] = { "url": url.toString() };
|
|
if (this._injected[name] || name == 'default') {
|
|
this.update(name);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register rule
|
|
* @param {string} name
|
|
* @param {object} rules
|
|
*/
|
|
registerRules (name, rules) {
|
|
this._themes[name] = { "rules": rules };
|
|
// TODO: serialize css rules
|
|
if (this._injected[name] || name == 'default') {
|
|
this.update(name);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Select a theme
|
|
* @param {string} name
|
|
*/
|
|
select (name) {
|
|
var prev = this._current;
|
|
var contents;
|
|
|
|
this._current = name;
|
|
this.update(name);
|
|
|
|
contents = this.rendition.getContents();
|
|
contents.forEach( (content) => {
|
|
content.removeClass(prev);
|
|
content.addClass(name);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Update a theme
|
|
* @param {string} name
|
|
*/
|
|
update (name) {
|
|
var contents = this.rendition.getContents();
|
|
contents.forEach( (content) => {
|
|
this.add(name, content);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Inject all themes into contents
|
|
* @param {Contents} contents
|
|
*/
|
|
inject (contents) {
|
|
var links = [];
|
|
var themes = this._themes;
|
|
var theme;
|
|
|
|
for (var name in themes) {
|
|
if (themes.hasOwnProperty(name) && (name === this._current || name === "default")) {
|
|
theme = themes[name];
|
|
if((theme.rules && Object.keys(theme.rules).length > 0) || (theme.url && links.indexOf(theme.url) === -1)) {
|
|
this.add(name, contents);
|
|
}
|
|
this._injected.push(name);
|
|
}
|
|
}
|
|
|
|
if(this._current != "default") {
|
|
contents.addClass(this._current);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add Theme to contents
|
|
* @param {string} name
|
|
* @param {Contents} contents
|
|
*/
|
|
add (name, contents) {
|
|
var theme = this._themes[name];
|
|
|
|
if (!theme || !contents) {
|
|
return;
|
|
}
|
|
|
|
if (theme.url) {
|
|
contents.addStylesheet(theme.url);
|
|
} else if (theme.serialized) {
|
|
contents.addStylesheetCss(theme.serialized, name);
|
|
theme.injected = true;
|
|
} else if (theme.rules) {
|
|
contents.addStylesheetRules(theme.rules, name);
|
|
theme.injected = true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add override
|
|
* @param {string} name
|
|
* @param {string} value
|
|
* @param {boolean} priority
|
|
*/
|
|
override (name, value, priority) {
|
|
var contents = this.rendition.getContents();
|
|
|
|
this._overrides[name] = {
|
|
value: value,
|
|
priority: priority === true
|
|
};
|
|
|
|
contents.forEach( (content) => {
|
|
content.css(name, this._overrides[name].value, this._overrides[name].priority);
|
|
});
|
|
}
|
|
|
|
removeOverride (name) {
|
|
var contents = this.rendition.getContents();
|
|
|
|
delete this._overrides[name];
|
|
|
|
contents.forEach( (content) => {
|
|
content.css(name);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Add all overrides
|
|
* @param {Content} content
|
|
*/
|
|
overrides (contents) {
|
|
var overrides = this._overrides;
|
|
|
|
for (var rule in overrides) {
|
|
if (overrides.hasOwnProperty(rule)) {
|
|
contents.css(rule, overrides[rule].value, overrides[rule].priority);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adjust the font size of a rendition
|
|
* @param {number} size
|
|
*/
|
|
fontSize (size) {
|
|
this.override("font-size", size);
|
|
}
|
|
|
|
/**
|
|
* Adjust the font-family of a rendition
|
|
* @param {string} f
|
|
*/
|
|
font (f) {
|
|
this.override("font-family", f, true);
|
|
}
|
|
|
|
destroy() {
|
|
this.rendition = undefined;
|
|
this._themes = undefined;
|
|
this._overrides = undefined;
|
|
this._current = undefined;
|
|
this._injected = undefined;
|
|
}
|
|
|
|
}
|
|
|
|
export default Themes;
|