mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Wire up the footnote popup
This commit is contained in:
parent
cad17a5785
commit
9ed99e752f
@ -7,6 +7,7 @@ from gettext import gettext as _
|
||||
|
||||
from dom import add_extra_css, build_rule, clear, svgicon
|
||||
from read_book.comm import IframeWrapper
|
||||
from read_book.resources import load_resources
|
||||
|
||||
CLASS_NAME = 'book-content-popup-container'
|
||||
TOP_LEVEL_DISPLAY = 'flex'
|
||||
@ -22,7 +23,7 @@ add_extra_css(def():
|
||||
sel += ' > div'
|
||||
style += build_rule(sel, padding_bottom='1ex', margin_bottom='1ex', border_bottom='solid currentColor 2px', display='flex', justify_content='space-between', align_items='center')
|
||||
|
||||
sel += ' > div' # button container
|
||||
sel += ' > div' # button container
|
||||
style += build_rule(sel, display='flex', justify_content='space-between', align_items='center')
|
||||
|
||||
sel += ' > a' # buttons
|
||||
@ -37,9 +38,10 @@ class ContentPopupOverlay:
|
||||
|
||||
def __init__(self, view):
|
||||
self.view = view
|
||||
self.loaded_resources = {}
|
||||
c = self.container
|
||||
c.classList.add(CLASS_NAME)
|
||||
iframe = E.iframe(seamless=True, sandbox='allow-scripts')
|
||||
iframe = E.iframe(seamless=True, sandbox='allow-scripts', style='width: 100%; max-height: 70vh')
|
||||
|
||||
c.appendChild(E.div(
|
||||
E.div(),
|
||||
@ -51,6 +53,8 @@ class ContentPopupOverlay:
|
||||
)
|
||||
handlers = {
|
||||
'ready': self.on_iframe_ready,
|
||||
'error': self.view.on_iframe_error,
|
||||
'content_loaded': self.on_content_loaded,
|
||||
}
|
||||
self.iframe_wrapper = IframeWrapper(handlers, iframe, 'popup', _('Loading data, please wait...'))
|
||||
self.pending_load = None
|
||||
@ -98,6 +102,12 @@ class ContentPopupOverlay:
|
||||
bc.lastChild.addEventListener('click', self.hide)
|
||||
header.appendChild(bc)
|
||||
|
||||
def load_doc(self, name, done_callback):
|
||||
def cb(resource_data):
|
||||
self.loaded_resources = resource_data
|
||||
done_callback(resource_data)
|
||||
load_resources(self.view.ui.db, self.view.book, name, self.loaded_resources, cb)
|
||||
|
||||
def show_footnote(self, data):
|
||||
self.current_footnote_data = data
|
||||
width = 100 // data.cols_per_screen
|
||||
@ -105,3 +115,27 @@ class ContentPopupOverlay:
|
||||
c.style.width = f'{width}vw'
|
||||
header = c.firstChild
|
||||
self.create_footnote_header(header)
|
||||
self.load_doc(data.name, self.show_footnote_item)
|
||||
self.iframe.style.height = '12ex'
|
||||
self.iframe_wrapper.send_message('clear', text=_('Loading note, please wait...'))
|
||||
|
||||
def show_footnote_item(self, resource_data):
|
||||
self.pending_load = resource_data, self.show_footnote_item_stage2
|
||||
if self.iframe_wrapper.ready:
|
||||
self.do_pending_load()
|
||||
else:
|
||||
self.iframe_wrapper.init()
|
||||
|
||||
def do_pending_load(self):
|
||||
if self.pending_load:
|
||||
data, func = self.pending_load
|
||||
self.pending_load = None
|
||||
func(data)
|
||||
|
||||
def show_footnote_item_stage2(self, resource_data):
|
||||
self.iframe_wrapper.send_unencrypted_message('display',
|
||||
resource_data=resource_data, book=self.view.book, name=self.current_footnote_data.name,
|
||||
frag=self.current_footnote_data.frag)
|
||||
|
||||
def on_content_loaded(self, data):
|
||||
self.iframe.style.height = f'{data.height}px'
|
||||
|
@ -2,6 +2,10 @@
|
||||
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
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
|
||||
|
||||
|
||||
def elem_roles(elem):
|
||||
return {k.toLowerCase(): True for k in (elem.getAttribute('role') or '').split(' ')}
|
||||
@ -68,3 +72,48 @@ def is_footnote_link(a, dest_name, dest_frag, src_name, link_to_map):
|
||||
|
||||
is_footnote_link.inline_displays = {'inline': True, 'inline-block': True}
|
||||
is_footnote_link.vert_aligns = {'sub': True, 'super': True, 'top': True, 'bottom': True}
|
||||
|
||||
|
||||
class PopupIframeBoss:
|
||||
|
||||
def __init__(self):
|
||||
handlers = {
|
||||
'initialize': self.initialize,
|
||||
'clear': self.on_clear,
|
||||
'display': self.display,
|
||||
}
|
||||
self.comm = IframeClient(handlers)
|
||||
self.blob_url_map = {}
|
||||
self.name = None
|
||||
self.frag = None
|
||||
|
||||
def initialize(self, data):
|
||||
window.onerror = self.onerror
|
||||
|
||||
def onerror(self, msg, script_url, line_number, column_number, error_object):
|
||||
if error_object is None:
|
||||
# This happens for cross-domain errors (probably javascript injected
|
||||
# into the browser via extensions/ userscripts and the like). It also
|
||||
# happens all the time when using Chrome on Safari
|
||||
console.log(f'Unhandled error from external javascript, ignoring: {msg} {script_url} {line_number}')
|
||||
else:
|
||||
console.log(error_object)
|
||||
|
||||
def display(self, data):
|
||||
self.book = data.book
|
||||
self.name = data.name
|
||||
self.frag = data.frag
|
||||
for name in self.blob_url_map:
|
||||
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)
|
||||
|
||||
def on_clear(self, data):
|
||||
clear(document.head)
|
||||
clear(document.body)
|
||||
document.body.textContent = data.text
|
||||
self.name = None
|
||||
self.frag = None
|
||||
|
||||
def content_loaded(self):
|
||||
self.comm.send_message('content_loaded', height=document.documentElement.scrollHeight + 25)
|
||||
|
@ -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
|
||||
from read_book.footnotes import is_footnote_link, PopupIframeBoss
|
||||
from read_book.globals import (
|
||||
current_book, current_layout_mode, current_spine_item, set_boss,
|
||||
set_current_spine_item, set_layout_mode
|
||||
@ -104,7 +104,7 @@ class IframeBoss:
|
||||
if error_object is None:
|
||||
# This happens for cross-domain errors (probably javascript injected
|
||||
# into the browser via extensions/ userscripts and the like). It also
|
||||
# happens all the time when using Chrom on Safari, so ignore this
|
||||
# happens all the time when using Chrome on Safari, so ignore this
|
||||
# type of error
|
||||
console.log(f'Unhandled error from external javascript, ignoring: {msg} {script_url} {line_number}')
|
||||
return
|
||||
@ -387,5 +387,5 @@ def init():
|
||||
script = document.getElementById('bootstrap')
|
||||
script.parentNode.removeChild(script) # free up some memory
|
||||
IframeBoss()
|
||||
# elif window.iframe_type is 'popup':
|
||||
# PopupIframeBoss()
|
||||
elif window.iframe_type is 'popup':
|
||||
PopupIframeBoss()
|
||||
|
@ -326,9 +326,10 @@ class View:
|
||||
if not is_current_book:
|
||||
self.iframe_wrapper.reset()
|
||||
self.content_popup_overlay.iframe_wrapper.reset()
|
||||
self.loaded_resources = {}
|
||||
self.content_popup_overlay.loaded_resources = {}
|
||||
self.book = current_book.book = book
|
||||
self.ui.db.update_last_read_time(book)
|
||||
self.loaded_resources = {}
|
||||
pos = {'replace_history':True}
|
||||
unkey = username_key(get_interface_data().username)
|
||||
name = book.manifest.spine[0]
|
||||
@ -374,7 +375,13 @@ class View:
|
||||
if idx > -1:
|
||||
self.currently_showing.bookpos = 'epubcfi(/{})'.format(2 * (idx +1))
|
||||
self.set_margins()
|
||||
load_resources(self.ui.db, self.book, name, self.loaded_resources, self.show_spine_item)
|
||||
self.load_doc(name, self.show_spine_item)
|
||||
|
||||
def load_doc(self, name, done_callback):
|
||||
def cb(resource_data):
|
||||
self.loaded_resources = resource_data
|
||||
done_callback(resource_data)
|
||||
load_resources(self.ui.db, self.book, name, self.loaded_resources, cb)
|
||||
|
||||
def goto_doc_boundary(self, start):
|
||||
name = self.book.manifest.spine[0 if start else self.book.manifest.spine.length - 1]
|
||||
@ -467,7 +474,6 @@ class View:
|
||||
update_visible_toc_nodes(data.visible_anchors)
|
||||
|
||||
def show_spine_item(self, resource_data):
|
||||
self.loaded_resources = resource_data
|
||||
self.pending_load = resource_data
|
||||
if self.iframe_wrapper.ready:
|
||||
self.do_pending_load()
|
||||
|
Loading…
x
Reference in New Issue
Block a user