diff --git a/examples/themes.html b/examples/themes.html index 171d3ae..4286d2c 100644 --- a/examples/themes.html +++ b/examples/themes.html @@ -89,18 +89,26 @@ rendition.on("locationChanged", function(location){ console.log(location); }); + /* - rendition.themes.register({ - "dark" : "themes.css", - "light" : "themes.css", - "tan" : "themes.css" - }); + rendition.themes.register("dark", "theme.css"); + rendition.themes.register("light", "theme.css"); + rendition.themes.register("tan", "theme.css"); */ - rendition.themes.register("themes.css"); - rendition.themes.apply("tan"); - rendition.themes.fontSize("140%"); + rendition.themes.default({ + h2: { + 'font-size': '32px', + color: 'purple' + }, + p: { + "margin": '10px' + } + }); + + // rendition.themes.apply("tan"); + // rendition.themes.fontSize("140%"); diff --git a/package.json b/package.json index ea8c295..3f1acec 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "minify": "NODE_ENV=production npm run build", "legacy": "NODE_ENV=production LEGACY=true npm run build", "compile": "./node_modules/.bin/babel --optional runtime -d lib/ src/", + "watch": "./node_modules/.bin/babel --watch --optional runtime -d lib/ src/", "prepublish": "npm run compile && npm run build && npm run minify && npm run legacy" }, "author": "fchasen@gmail.com", diff --git a/src/contents.js b/src/contents.js index 6eba0b0..a082cce 100644 --- a/src/contents.js +++ b/src/contents.js @@ -461,13 +461,14 @@ class Contents { }.bind(this)); } - // https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule + // Array: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule + // Object: https://github.com/desirable-objects/json-to-css addStylesheetRules(rules) { var styleEl; var styleSheet; var key = "epubjs-inserted-css"; - if(!this.document) return; + if(!this.document || !rules || rules.length === 0) return; // Check if link already exists styleEl = this.document.getElementById("#"+key); @@ -482,21 +483,33 @@ class Contents { // Grab style sheet styleSheet = styleEl.sheet; - for (var i = 0, rl = rules.length; i < rl; i++) { - var j = 1, rule = rules[i], selector = rules[i][0], propStr = ""; - // If the second argument of a rule is an array of arrays, correct our variables. - if (Object.prototype.toString.call(rule[1][0]) === "[object Array]") { - rule = rule[1]; - j = 0; - } + if (Object.prototype.toString.call(rules) === "[object Array]") { + for (var i = 0, rl = rules.length; i < rl; i++) { + var j = 1, rule = rules[i], selector = rules[i][0], propStr = ""; + // If the second argument of a rule is an array of arrays, correct our variables. + if (Object.prototype.toString.call(rule[1][0]) === "[object Array]") { + rule = rule[1]; + j = 0; + } - for (var pl = rule.length; j < pl; j++) { - var prop = rule[j]; - propStr += prop[0] + ":" + prop[1] + (prop[2] ? " !important" : "") + ";\n"; - } + for (var pl = rule.length; j < pl; j++) { + var prop = rule[j]; + propStr += prop[0] + ":" + prop[1] + (prop[2] ? " !important" : "") + ";\n"; + } - // Insert CSS Rule - styleSheet.insertRule(selector + "{" + propStr + "}", styleSheet.cssRules.length); + // Insert CSS Rule + styleSheet.insertRule(selector + "{" + propStr + "}", styleSheet.cssRules.length); + } + } else { + const selectors = Object.keys(rules); + selectors.forEach((selector) => { + const definition = rules[selector]; + const _rules = Object.keys(definition); + const result = _rules.map((rule) => { + return `${rule}:${definition[rule]}`; + }).join(';'); + styleSheet.insertRule(`${selector}{${result}}`, styleSheet.cssRules.length); + }); } } diff --git a/src/rendition.js b/src/rendition.js index 02c1348..15ef04e 100644 --- a/src/rendition.js +++ b/src/rendition.js @@ -21,6 +21,7 @@ import Contents from "./contents"; * @param {string} options.layout * @param {string} options.spread * @param {int} options.minSpreadWidth overridden by spread: none (never) / both (always) + * @param {string} options.stylesheet url of stylesheet to be injected */ class Rendition { constructor(book, options) { @@ -34,7 +35,8 @@ class Rendition { flow: null, layout: null, spread: null, - minSpreadWidth: 800 + minSpreadWidth: 800, + stylesheet: null }); extend(this.settings, options); @@ -71,6 +73,10 @@ class Rendition { this.hooks.content.register(this.passEvents.bind(this)); this.hooks.content.register(this.adjustImages.bind(this)); + if (this.settings.stylesheet) { + this.book.spine.hooks.content.register(this.injectStylesheet.bind(this)); + } + // this.hooks.display.register(this.afterDisplay.bind(this)); this.themes = new Themes(this); @@ -596,14 +602,14 @@ class Rendition { }); } - contents.addStylesheetRules([ - ["img", - ["max-width", (this._layout.columnWidth) + "px !important"], - ["max-height", (this._layout.height) + "px !important"], - ["object-fit", "contain"], - ["page-break-inside", "avoid"] - ] - ]); + contents.addStylesheetRules({ + "img" : { + "max-width": (this._layout.columnWidth) + "px !important", + "max-width": (this._layout.columnWidth) + "px !important", + "object-fit": "contain", + "page-break-inside": "avoid" + } + }); return new Promise(function(resolve, reject){ // Wait to apply setTimeout(function() { @@ -622,6 +628,14 @@ class Rendition { this.display(relative); }); } + + injectStylesheet(doc, section) { + let style = doc.createElement("link"); + style.setAttribute("type", "text/css"); + style.setAttribute("rel", "stylesheet"); + style.setAttribute("href", this.settings.stylesheet); + doc.getElementsByTagName("head")[0].appendChild(style); + } } //-- Enable binding events to Renderer diff --git a/src/themes.js b/src/themes.js index d4db495..3a2f7ae 100644 --- a/src/themes.js +++ b/src/themes.js @@ -5,7 +5,7 @@ class Themes { this.rendition = rendition; this._themes = { "default" : { - "rules" : [], + "rules" : {}, "url" : "", "serialized" : "" } @@ -97,7 +97,7 @@ class Themes { var theme; for (var name in themes) { - if (themes.hasOwnProperty(name)) { + if (themes.hasOwnProperty(name) && name === this._current) { theme = themes[name]; if(theme.rules || (theme.url && links.indexOf(theme.url) === -1)) { this.add(name, contents); @@ -105,7 +105,7 @@ class Themes { } } - if(this._current) { + if(this._current != "default") { contents.addClass(this._current); } } @@ -121,7 +121,7 @@ class Themes { contents.addStylesheet(theme.url); } else if (theme.serialized) { // TODO: handle serialized - } else if (theme.rules && theme.rules.length) { + } else if (theme.rules) { contents.addStylesheetRules(theme.rules); theme.injected = true; }