diff --git a/src/pyj/read_book/footnotes.pyj b/src/pyj/read_book/footnotes.pyj index 2f17ff6bfb..8726c8d51c 100644 --- a/src/pyj/read_book/footnotes.pyj +++ b/src/pyj/read_book/footnotes.pyj @@ -5,8 +5,7 @@ from __python__ import bound_methods, hash_literals from dom import clear from read_book.comm import IframeClient from read_book.resources import finalize_resources, unserialize_html -from read_book.settings import apply_settings, opts - +from read_book.settings import apply_settings, update_settings block_names = dict.fromkeys(v"['p', 'div', 'li', 'td', 'h1', 'h2', 'h2', 'h3', 'h4', 'h5', 'h6', 'body']", True).as_object() block_display_styles = dict.fromkeys(v"['block', 'list-item', 'table-cell', 'table']", True).as_object() @@ -201,7 +200,7 @@ class PopupIframeBoss: window.URL.revokeObjectURL(self.blob_url_map[name]) root_data, self.mathjax, self.blob_url_map = finalize_resources(self.book, data.name, data.resource_data) self.resource_urls = unserialize_html(root_data, self.content_loaded, self.show_only_footnote) - apply_settings(data.settings) + update_settings(data.settings) def on_clear(self, data): clear(document.head) @@ -218,14 +217,5 @@ class PopupIframeBoss: show_footnote(self.frag, known_anchors) def content_loaded(self): - self.apply_colors() - self.apply_font_size() + apply_settings() self.comm.send_message('content_loaded', height=document.documentElement.scrollHeight + 25) - - def apply_font_size(self): - document.documentElement.style.fontSize = document.body.style.fontSize = '{}px'.format(opts.base_font_size) - - def apply_colors(self): - for elem in (document.documentElement, document.body): - elem.style.color = opts.color_scheme.foreground - elem.style.backgroundColor = opts.color_scheme.background diff --git a/src/pyj/read_book/iframe.pyj b/src/pyj/read_book/iframe.pyj index 20caace186..aec381c4c9 100644 --- a/src/pyj/read_book/iframe.pyj +++ b/src/pyj/read_book/iframe.pyj @@ -12,7 +12,7 @@ from read_book.flow_mode import ( flow_to_scroll_fraction, handle_gesture as flow_handle_gesture, layout as flow_layout, scroll_by_page as flow_scroll_by_page ) -from read_book.footnotes import is_footnote_link, PopupIframeBoss +from read_book.footnotes import PopupIframeBoss, is_footnote_link from read_book.globals import ( current_book, current_layout_mode, current_spine_item, set_boss, set_current_spine_item, set_layout_mode @@ -27,7 +27,10 @@ from read_book.paged_mode import ( snap_to_selection ) from read_book.resources import finalize_resources, unserialize_html -from read_book.settings import apply_settings, opts +from read_book.settings import ( + apply_colors, apply_font_size, apply_settings, apply_stylesheet, opts, + update_settings +) from read_book.toc import update_visible_toc_anchors from read_book.touch import create_handlers as create_touch_handlers from read_book.viewport import scroll_viewport @@ -147,7 +150,7 @@ class IframeBoss: self.jump_to_cfi = paged_jump_to_cfi self._handle_gesture = paged_handle_gesture self.anchor_funcs = paged_anchor_funcs - apply_settings(data.settings) + update_settings(data.settings) set_current_spine_item({'name':data.name, 'is_first':index is 0, 'is_last':index is spine.length - 1, 'initial_position':data.initial_position}) self.last_cfi = None for name in self.blob_url_map: @@ -180,23 +183,19 @@ class IframeBoss: else: paged_scroll_by_page(backwards, True) - def apply_font_size(self): - document.documentElement.style.fontSize = document.body.style.fontSize = '{}px'.format(opts.base_font_size) - - def apply_colors(self): - for elem in (document.documentElement, document.body): - elem.style.color = opts.color_scheme.foreground - elem.style.backgroundColor = opts.color_scheme.background - def change_font_size(self, data): if data.base_font_size? and data.base_font_size != opts.base_font_size: opts.base_font_size = data.base_font_size - self.apply_font_size() + apply_font_size() + + def change_stylesheet(self, data): + opts.user_stylesheet = data.sheet or '' + apply_stylesheet() def change_color_scheme(self, data): if data.color_scheme and data.color_scheme.foreground and data.color_scheme.background: opts.color_scheme = data.color_scheme - self.apply_colors() + apply_colors() def content_loaded(self): document.documentElement.style.overflow = 'hidden' @@ -204,8 +203,7 @@ class IframeBoss: # E.style() # TODO: User style sheet # ) self.last_window_width, self.last_window_height = scroll_viewport.width(), scroll_viewport.height() - self.apply_colors() - self.apply_font_size() + apply_settings() self.do_layout() if self.mathjax: return apply_mathjax(self.mathjax, self.book.manifest.link_uid, self.content_loaded_stage2) diff --git a/src/pyj/read_book/settings.pyj b/src/pyj/read_book/settings.pyj index 2519f2c1d3..d481134ecc 100644 --- a/src/pyj/read_book/settings.pyj +++ b/src/pyj/read_book/settings.pyj @@ -2,14 +2,42 @@ # License: GPL v3 Copyright: 2016, Kovid Goyal from __python__ import hash_literals +from elementmaker import E + opts = {} -def apply_settings(settings): +def update_settings(settings): settings = settings or {} opts.columns_per_screen = settings.columns_per_screen or {'portrait':0, 'landscape':0} opts.margin_left = max(0, settings.margin_left or 0) opts.margin_right = max(0, settings.margin_right or 0) opts.color_scheme = settings.color_scheme opts.base_font_size = max(8, min(settings.base_font_size or 16, 64)) + opts.user_stylesheet = settings.user_stylesheet or '' -apply_settings() +update_settings() + + +def apply_font_size(): + document.documentElement.style.fontSize = document.body.style.fontSize = '{}px'.format(opts.base_font_size) + + +def apply_colors(): + for elem in (document.documentElement, document.body): + elem.style.color = opts.color_scheme.foreground + elem.style.backgroundColor = opts.color_scheme.background + + +def apply_stylesheet(): + sid = 'calibre-browser-viewer-user-stylesheet' + style = document.getElementById(sid) + if not style: + style = E.style(type='text/css', id=sid) + document.body.appendChild(style) + style.textContent = opts.user_stylesheet or '' + + +def apply_settings(): + apply_font_size() + apply_colors() + apply_stylesheet() diff --git a/src/pyj/read_book/view.pyj b/src/pyj/read_book/view.pyj index e0e881d6e1..c1d3005b47 100644 --- a/src/pyj/read_book/view.pyj +++ b/src/pyj/read_book/view.pyj @@ -362,6 +362,7 @@ class View: 'columns_per_screen': sd.get('columns_per_screen'), 'color_scheme': self.get_color_scheme(True), 'base_font_size': sd.get('base_font_size'), + 'user_stylesheet': sd.get('user_stylesheet'), } def show_name(self, name, initial_position=None): diff --git a/src/pyj/session.pyj b/src/pyj/session.pyj index 0a77ed96b0..c37e3ba61d 100644 --- a/src/pyj/session.pyj +++ b/src/pyj/session.pyj @@ -31,6 +31,7 @@ defaults = { 'max_text_height': 0, 'max_text_width': 0, 'columns_per_screen': {'portrait':0, 'landscape':0}, + 'user_stylesheet': '', 'current_color_scheme': 'white', 'user_color_schemes': {}, 'base_font_size': 16, @@ -46,6 +47,7 @@ is_local_setting = { 'max_text_height': True, 'max_text_width': True, 'columns_per_screen': True, + 'user_stylesheet': True, 'current_color_scheme': True, 'base_font_size': True, 'controls_help_shown_count': True,