E-book viewer: Allow going to links from the pagelist in the book via the Goto action in the viewer controls.

Typically, these are locations in the book corresponding to paper edition page
boundaries.
This commit is contained in:
Kovid Goyal 2024-08-19 22:14:26 +05:30
parent 4b8dec5a50
commit 26d1126c62
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 44 additions and 3 deletions

View File

@ -16,7 +16,7 @@ from read_book.toc import get_border_nodes, get_toc_maps
from widgets import create_button
def create_goto_list(onclick, current_position_data):
def create_goto_list(onclick, current_position_data, page_list):
ans = E.div()
items = v'[]'
location_text = format_pos(current_position_data.progress_frac, current_position_data.book_length) + ' :: '
@ -40,6 +40,8 @@ def create_goto_list(onclick, current_position_data):
view.open_book_page()
)))
items.push(create_item(_('Location'), subtitle=location_text, action=onclick.bind(None, def(view): view.overlay.show_ask_for_location();)))
if page_list and page_list.length > 0:
items.push(create_item(_('Page number'), subtitle=_('Typically the page number from a paper edition of this book'), action=onclick.bind(None, def(view): view.overlay.show_page_list(page_list);)))
for l in landmarks:
items.push(create_item(l.title, action=onclick.bind(None, l.dest, l.frag)))
build_list(ans, items)
@ -54,12 +56,23 @@ def get_next_section(forward):
def create_goto_panel(current_position_data, book, container, onclick):
panel = create_goto_list(onclick, current_position_data)
panel = create_goto_list(onclick, current_position_data, book.manifest.page_list)
set_css(container, display='flex', flex_direction='column')
set_css(panel, flex_grow='10')
container.appendChild(panel)
def create_page_list_overlay(book, overlay, container):
page_list = book.manifest.page_list or v'[]'
items = v'[]'
for x in page_list:
items.push(create_item(x['pagenum'], action=def():
overlay.view.goto_pagelist_item(x)
overlay.hide()
))
build_list(container, items)
def create_location_overlay(current_position_data, book, overlay, container):
container_id = ensure_id(container)
container.appendChild(E.div(style='margin: 0 1rem'))

View File

@ -480,6 +480,8 @@ class IframeBoss:
, 5)
elif ipos.type is 'smil_id':
self.audio_ebook_msg_received({'type': 'play', 'anchor': ipos.anchor})
elif ipos.type is 'pagelist_ref':
self.scroll_to_pagelist_ref(ipos.anchor)
spine = self.book.manifest.spine
files = self.book.manifest.files
spine_index = csi.index
@ -758,6 +760,21 @@ class IframeBoss:
else:
scroll_viewport.scroll_to(0, 0)
def scroll_to_pagelist_ref(self, frag):
elem = document.getElementById(frag)
if not elem:
c = document.getElementsByName(frag)
if c and c.length:
elem = c[0]
if elem:
# The stupid EPUB 3 examples have page list links pointing to
# display:none divs. Sigh.
if window.getComputedStyle(elem).display is 'none':
elem.textContent = ''
elem.setAttribute('style', 'all: revert')
elem.style.display = 'block'
scroll_to_elem(elem)
def scroll_to_ref(self, refnum):
refnum = int(refnum)
elem = elem_for_ref(refnum)

View File

@ -20,7 +20,7 @@ from gettext import gettext as _
from modals import error_dialog, question_dialog
from read_book.bookmarks import create_bookmarks_panel
from read_book.globals import runtime, ui_operations
from read_book.goto import create_goto_panel, create_location_overlay
from read_book.goto import create_goto_panel, create_location_overlay, create_page_list_overlay
from read_book.highlights import create_highlights_panel
from read_book.profiles import create_profiles_panel
from read_book.open_book import create_open_book
@ -854,6 +854,12 @@ class Overlay:
self, create_location_overlay.bind(None, self.view.current_position_data, self.view.book), _('Go to location, position or reference…')))
self.show_current_panel()
def show_page_list(self):
self.hide_current_panel()
self.panels.push(SimpleOverlay(
self, create_page_list_overlay.bind(None, self.view.book), _('Go to page')))
self.show_current_panel()
def show_search(self):
self.hide()
self.view.show_search()

View File

@ -1115,6 +1115,11 @@ class View:
val = max(0, min(1000 * float(bpos) / self.current_position_data.book_length, 1))
return self.goto_frac(val)
def goto_pagelist_item(self, item):
name = item.dest
frag = item.frag or ''
self.show_name(name, initial_position={'type':'pagelist_ref', 'anchor':frag, 'replace_history':False})
def on_scroll_to_anchor(self, data):
self.show_name(data.name, initial_position={'type':'anchor', 'anchor':data.frag, 'replace_history':False})