mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Start work on popup footnote support in the browser viewer
This commit is contained in:
parent
3809604157
commit
41bc26645a
@ -201,6 +201,7 @@ class Container(ContainerBase):
|
||||
'spine_length': 0,
|
||||
'toc_anchor_map': toc_anchor_map(toc),
|
||||
'landmarks': landmarks,
|
||||
'link_to_map': {},
|
||||
}
|
||||
# Mark the spine as dirty since we have to ensure it is normalized
|
||||
for name in data['spine']:
|
||||
@ -328,6 +329,8 @@ class Container(ContainerBase):
|
||||
changed.add(base)
|
||||
return url
|
||||
|
||||
ltm = self.book_render_data['link_to_map']
|
||||
|
||||
for name, mt in self.mime_map.iteritems():
|
||||
mt = mt.lower()
|
||||
if mt in OEB_STYLES:
|
||||
@ -350,7 +353,9 @@ class Container(ContainerBase):
|
||||
if href.startswith(link_uid):
|
||||
a.set('href', 'javascript:void(0)')
|
||||
parts = decode_url(href.split('|')[1])
|
||||
a.set('data-' + link_uid, json.dumps({'name':parts[0], 'frag':parts[1]}, ensure_ascii=False))
|
||||
lname, lfrag = parts[0], parts[1]
|
||||
ltm.setdefault(lname, {}).setdefault(lfrag or '', []).append(name)
|
||||
a.set('data-' + link_uid, json.dumps({'name':lname, 'frag':lfrag}, ensure_ascii=False))
|
||||
else:
|
||||
a.set('target', '_blank')
|
||||
a.set('rel', 'noopener noreferrer')
|
||||
@ -382,7 +387,7 @@ boolean_attributes = frozenset('allowfullscreen,async,autofocus,autoplay,checked
|
||||
|
||||
EPUB_TYPE_MAP = {k:'doc-' + k for k in (
|
||||
'abstract acknowledgements afterword appendix biblioentry bibliography biblioref chapter colophon conclusion cover credit'
|
||||
' credits dedication epigraph epilogue errata footnote footnotes forward glossary glossref index introduction noteref notice'
|
||||
' credits dedication epigraph epilogue errata footnote footnotes forward glossary glossref index introduction link noteref notice'
|
||||
' pagebreak pagelist part preface prologue pullquote qna locator subtitle title toc').split(' ')}
|
||||
for k in 'figure term definition directory list list-item table row cell'.split(' '):
|
||||
EPUB_TYPE_MAP[k] = k
|
||||
|
70
src/pyj/read_book/footnotes.pyj
Normal file
70
src/pyj/read_book/footnotes.pyj
Normal file
@ -0,0 +1,70 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
from __python__ import bound_methods, hash_literals
|
||||
|
||||
|
||||
def elem_roles(elem):
|
||||
return {k.toLowerCase(): True for k in (elem.getAttribute('role') or '').split(' ')}
|
||||
|
||||
|
||||
def get_containing_block(node):
|
||||
while node and node.tagName and get_containing_block.block_names[node.tagName.toLowerCase()] is not True:
|
||||
node = node.parentNode
|
||||
return node
|
||||
get_containing_block.block_names = dict.fromkeys(v"['p', 'div', 'li', 'td', 'h1', 'h2', 'h2', 'h3', 'h4', 'h5', 'h6', 'body']", True).as_object()
|
||||
|
||||
|
||||
def is_footnote_link(a, dest_name, dest_frag, src_name, link_to_map):
|
||||
roles = elem_roles(a)
|
||||
if roles['doc-noteref']:
|
||||
return True
|
||||
if roles['doc-link']:
|
||||
return False
|
||||
|
||||
# Check if node or any of its first few parents have vertical-align set
|
||||
x, num = a, 3
|
||||
while x and num > 0:
|
||||
style = window.getComputedStyle(x)
|
||||
if not is_footnote_link.inline_displays[style.display]:
|
||||
break
|
||||
if is_footnote_link.vert_aligns[style.verticalAlign]:
|
||||
return True
|
||||
x = x.parentNode
|
||||
num -= 1
|
||||
|
||||
# Check if node has a single child with the appropriate css
|
||||
children = [x for x in a.childNodes if x.nodeType is Node.ELEMENT_NODE]
|
||||
if children.length == 1:
|
||||
style = window.getComputedStyle(children[0])
|
||||
if is_footnote_link.inline_displays[style.display] and is_footnote_link.vert_aligns[style.verticalAlign]:
|
||||
text_children = [x for x in a.childNodes if x.nodeType is Node.TEXT_NODE and x.nodeValue and /\S+/.test(x.nodeValue)]
|
||||
if not text_children.length:
|
||||
return True
|
||||
|
||||
eid = a.getAttribute('id') or a.getAttribute('name')
|
||||
files_linking_to_self = link_to_map[src_name]
|
||||
if eid and files_linking_to_self:
|
||||
files_linking_to_anchor = files_linking_to_self[eid]
|
||||
if files_linking_to_anchor.length > 1 or (files_linking_to_anchor.length == 1 and files_linking_to_anchor[0] is not src_name):
|
||||
# An <a href="..." id="..."> link that is linked back from some other
|
||||
# file in the spine, most likely an endnote. We exclude links that are
|
||||
# the only content of their parent block tag, as these are not likely
|
||||
# to be endnotes.
|
||||
cb = get_containing_block(a)
|
||||
if not cb or cb.tagName.toLowerCase() == 'body':
|
||||
return False
|
||||
ltext = a.textContent
|
||||
if not ltext:
|
||||
return False
|
||||
ctext = cb.textContent
|
||||
if not ctext:
|
||||
return False
|
||||
if ctext.strip() is ltext.strip():
|
||||
return False
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
is_footnote_link.inline_displays = {'inline': True, 'inline-block': True}
|
||||
is_footnote_link.vert_aligns = {'sub': True, 'super': True, 'top': True, 'bottom': True}
|
@ -12,6 +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.globals import (
|
||||
current_book, current_layout_mode, current_spine_item, set_boss,
|
||||
set_current_spine_item, set_layout_mode
|
||||
@ -383,6 +384,14 @@ class IframeBoss:
|
||||
name, frag = data.name, data.frag
|
||||
if not name:
|
||||
name = current_spine_item().name
|
||||
try:
|
||||
is_popup = is_footnote_link(evt.currentTarget, name, frag, current_spine_item().name, self.book.manifest.link_to_map or {})
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
is_popup = False
|
||||
if is_popup:
|
||||
pass
|
||||
if name is current_spine_item().name:
|
||||
self.replace_history_on_next_cfi_update = False
|
||||
self.scroll_to_anchor(frag)
|
||||
|
Loading…
x
Reference in New Issue
Block a user