diff --git a/src/pyj/dom.pyj b/src/pyj/dom.pyj index 13a7aca3a0..536d6532cb 100644 --- a/src/pyj/dom.pyj +++ b/src/pyj/dom.pyj @@ -47,6 +47,27 @@ def set_css(elem, **kw): s.setProperty('-' + prefix + '-' + name, val) return elem +def set_important_css(elem, **kw): + if jstype(elem) is 'string': + elem = document.querySelector(elem) + s = elem.style + if s: + for prop in kw: + name, val = str.replace(str.rstrip(prop, '_'), '_', '-'), kw[prop] + if val is None or val is undefined: + s.removeProperty(name) + else: + s.setProperty(name, val, 'important') + prefixes = simple_vendor_prefixes[name] + if prefixes: + for prefix in prefixes: + if val is None or val is undefined: + s.removeProperty('-' + prefix + '-' + name) + else: + s.setProperty('-' + prefix + '-' + name, val, 'important') + return elem + + def build_rule(selector, **kw): ans = v'[selector + " { "]' for prop in kw: diff --git a/src/pyj/read_book/paged_mode.pyj b/src/pyj/read_book/paged_mode.pyj index ee8b4dfc45..c868191f5a 100644 --- a/src/pyj/read_book/paged_mode.pyj +++ b/src/pyj/read_book/paged_mode.pyj @@ -26,7 +26,7 @@ from __python__ import hash_literals, bound_methods import traceback from elementmaker import E -from dom import set_css +from dom import set_important_css from read_book.cfi import ( at_current as cfi_at_current, at_point as cfi_at_point, scroll_to as cfi_scroll_to @@ -66,22 +66,34 @@ def handle_rtl_body(body_style): def create_page_div(elem): div = E('blank-page-div', ' \n ') document.body.appendChild(div) - set_css(div, break_before='always', display='block', white_space='pre', background_color='transparent', - background_image='none', border_width='0', float='none', position='static') + # the min-height is needed to get firefox to always insert a column break before this div + set_important_css(div, break_before='column', break_inside='avoid', display='block', white_space='pre', background_color='transparent', + background_image='none', border_width='0', float='none', position='static', min_height='100vh') _in_paged_mode = False def in_paged_mode(): return _in_paged_mode -col_size = screen_inline = screen_block = cols_per_screen = gap = col_and_gap = number_of_cols = last_scrolled_to_column = 0 +col_size = screen_inline = screen_block = cols_per_screen = gap = col_and_gap = last_scrolled_to_column = 0 is_full_screen_layout = False +def get_number_of_cols(dont_return_integer): + # we dont store this because of the chrome resize bug where the document width + # sometimes changes a few milliseconds after layout in paged mode + if is_full_screen_layout: + return 1 + ans = (scroll_viewport.paged_content_inline_size() + gap) / col_and_gap + if not dont_return_integer: + ans = Math.floor(ans) + return ans + + def reset_paged_mode_globals(): - nonlocal _in_paged_mode, col_size, col_and_gap, screen_block, gap, screen_inline, is_full_screen_layout, cols_per_screen, number_of_cols, last_scrolled_to_column + nonlocal _in_paged_mode, col_size, col_and_gap, screen_block, gap, screen_inline, is_full_screen_layout, cols_per_screen, last_scrolled_to_column scroll_viewport.reset_globals() - col_size = screen_inline = screen_block = cols_per_screen = gap = col_and_gap = number_of_cols = last_scrolled_to_column = 0 + col_size = screen_inline = screen_block = cols_per_screen = gap = col_and_gap = last_scrolled_to_column = 0 is_full_screen_layout = _in_paged_mode = False resize_manager.reset() @@ -130,8 +142,8 @@ def fit_images(): if previously_limited or image_block_size > maxb or (image_block_size is maxb and image_inline_size > col_size): block_limited_images.push(img) if previously_limited: - set_css(img, break_before='auto', display=data.display) - set_css(img, break_inside='avoid') + set_important_css(img, break_before='auto', display=data.display) + set_important_css(img, break_inside='avoid') for img_tag, max_inline_size in inline_limited_images: if scroll_viewport.vertical_writing_mode: @@ -142,9 +154,9 @@ def fit_images(): for img_tag in block_limited_images: if scroll_viewport.vertical_writing_mode: - set_css(img_tag, break_before='always', max_width='100vw') + set_important_css(img_tag, break_before='always', max_width='100vw') else: - set_css(img_tag, break_before='always', max_height='100vh') + set_important_css(img_tag, break_before='always', max_height='100vh') set_elem_data(img_tag, 'block-limited', True) @@ -234,7 +246,7 @@ class ScrollResizeBugWatcher: scroll_resize_bug_watcher = ScrollResizeBugWatcher() def layout(is_single_page, on_resize): - nonlocal _in_paged_mode, col_size, col_and_gap, screen_block, gap, screen_inline, is_full_screen_layout, cols_per_screen, number_of_cols + nonlocal _in_paged_mode, col_size, col_and_gap, screen_block, gap, screen_inline, is_full_screen_layout, cols_per_screen line_height(True) rem_size(True) body_style = window.getComputedStyle(document.body) @@ -285,7 +297,7 @@ def layout(is_single_page, on_resize): screen_block = scroll_viewport.block_size() col_and_gap = col_size + gap - set_css(document.body, column_gap=gap + 'px', column_width=col_size + 'px', column_rule='0px inset blue', + set_important_css(document.body, column_gap=gap + 'px', column_width=col_size + 'px', column_rule='0px inset blue', min_width='0', max_width='none', min_height='0', max_height='100vh', column_fill='auto', margin='0', border_width='0', padding='0', box_sizing='content-box', width=scroll_viewport.width() + 'px', height=scroll_viewport.height() + 'px', overflow_wrap='break-word' @@ -298,7 +310,7 @@ def layout(is_single_page, on_resize): if c: # Remove page breaks on the first few elements to prevent blank pages # at the start of a chapter - set_css(c, break_before='avoid') + set_important_css(c, break_before='avoid') if c.tagName.toLowerCase() is 'div': c2 = first_child(c) if c2 and not has_start_text(c): @@ -306,7 +318,7 @@ def layout(is_single_page, on_resize): #