E-book viewer: Make the detection of note boundaries for popup footnotes a little more robust

This commit is contained in:
Kovid Goyal 2016-03-31 10:48:13 +05:30
parent 7d465cb62b
commit b177a6931f
2 changed files with 40 additions and 24 deletions

Binary file not shown.

View File

@ -105,6 +105,16 @@ is_epub_footnote = (node) ->
return true return true
return false return false
block_tags = ['p', 'div', 'li', 'td', 'h1', 'h2', 'h2', 'h3', 'h4', 'h5', 'h6', 'body']
block_display_styles = ['block', 'list-item', 'table-cell', 'table']
get_note_container = (node) ->
until node.tagName.toLowerCase() in block_tags or is_epub_footnote(node) or getComputedStyle(node).display in block_display_styles
node = node.parentNode
if not node
break
return node
get_parents_and_self = (node) -> get_parents_and_self = (node) ->
ans = [] ans = []
while node and node isnt document.body while node and node isnt document.body
@ -124,9 +134,15 @@ hide_children = (node) ->
if child.nodeType == Node.ELEMENT_NODE if child.nodeType == Node.ELEMENT_NODE
if child.do_not_hide if child.do_not_hide
hide_children(child) hide_children(child)
delete child.do_not_hide
else else
child.style.display = 'none' child.style.display = 'none'
unhide_tree = (elem) ->
elem.do_not_hide = true
for c in elem.getElementsByTagName('*')
c.do_not_hide = true
class CalibreExtract class CalibreExtract
# This class is a namespace to expose functions via the # This class is a namespace to expose functions via the
# window.calibre_extract object. # window.calibre_extract object.
@ -154,8 +170,7 @@ class CalibreExtract
start_elem = document.getElementById(target) start_elem = document.getElementById(target)
if not start_elem if not start_elem
return return
in_note = false start_elem = get_note_container(start_elem)
is_footnote_container = is_epub_footnote(start_elem)
for elem in get_parents_and_self(start_elem) for elem in get_parents_and_self(start_elem)
elem.do_not_hide = true elem.do_not_hide = true
style = window.getComputedStyle(elem) style = window.getComputedStyle(elem)
@ -163,31 +178,32 @@ class CalibreExtract
# We cannot display list numbers since they will be # We cannot display list numbers since they will be
# incorrect as we are removing siblings of this element. # incorrect as we are removing siblings of this element.
elem.style.listStyleType = 'none' elem.style.listStyleType = 'none'
if is_epub_footnote(start_elem)
unhide_tree(start_elem)
else
# Try to detect natural boundaries based on markup for this note
found_note_start = false
for elem in document.body.getElementsByTagName('*') for elem in document.body.getElementsByTagName('*')
if in_note if found_note_start
if known_targets.hasOwnProperty(elem.getAttribute('id')) eid = elem.getAttribute('id')
in_note = false if eid != target and known_targets.hasOwnProperty(eid) and get_note_container(elem) != start_elem
continue console.log('Breaking footnote on anchor: ' + elem.getAttribute('id'))
delete get_note_container(elem).do_not_hide
break
pb = get_page_break(elem) pb = get_page_break(elem)
if pb['before'] if pb['before']
in_note = false console.log('Breaking footnote on page break before')
else if pb['after'] break
in_note = false if pb['after']
unhide_tree(elem)
console.log('Breaking footnote on page break after')
break
elem.do_not_hide = true elem.do_not_hide = true
for child in elem.getElementsByTagName('*') else if elem is start_elem
child.do_not_hide = true found_note_start = true
else
elem.do_not_hide = true
else
if elem is start_elem
in_note = not is_footnote_container and not get_page_break(elem)['after']
if not in_note
for child in elem.getElementsByTagName('*')
child.do_not_hide = true
hide_children(document.body) hide_children(document.body)
location.hash = '#' + target location.hash = '#' + target
if window? if window?
window.calibre_extract = new CalibreExtract() window.calibre_extract = new CalibreExtract()