mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-08-11 09:13:57 -04:00
E-book viewer: Make bookmark positioning (and remembering last read location) more robust. Fixes #4812 (E-book viewer not correctly remembering reading position on reopen)
This commit is contained in:
parent
80ad1fa467
commit
cf5ca45531
@ -20,37 +20,8 @@ function selector(elem) {
|
||||
return sel;
|
||||
}
|
||||
|
||||
function find_closest_enclosing_block(top) {
|
||||
var START = top-1000;
|
||||
var STOP = top;
|
||||
var matches = [];
|
||||
var elem, temp;
|
||||
var width = 1000;
|
||||
|
||||
for (y = START; y < STOP; y += 20) {
|
||||
for ( x = 0; x < width; x += 20) {
|
||||
elem = document.elementFromPoint(x, y);
|
||||
try {
|
||||
elem = $(elem);
|
||||
temp = elem.offset().top
|
||||
matches.push(elem);
|
||||
if (Math.abs(temp - START) < 25) { y = STOP; break}
|
||||
} catch(error) {}
|
||||
}
|
||||
}
|
||||
|
||||
var miny = Math.abs(matches[0].offset().top - START), min_elem = matches[0];
|
||||
|
||||
for (i = 1; i < matches.length; i++) {
|
||||
elem = matches[i];
|
||||
temp = Math.abs(elem.offset().top - START);
|
||||
if ( temp < miny ) { miny = temp; min_elem = elem; }
|
||||
}
|
||||
return min_elem;
|
||||
}
|
||||
|
||||
function calculate_bookmark(y) {
|
||||
var elem = find_closest_enclosing_block(y);
|
||||
function calculate_bookmark(y, node) {
|
||||
var elem = $(node);
|
||||
var sel = selector(elem);
|
||||
var ratio = (y - elem.offset().top)/elem.height();
|
||||
if (ratio > 1) { ratio = 1; }
|
||||
|
@ -5,7 +5,7 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
'''
|
||||
'''
|
||||
import os, math, re, glob
|
||||
import os, math, re, glob, sys
|
||||
from base64 import b64encode
|
||||
from PyQt4.Qt import QSize, QSizePolicy, QUrl, SIGNAL, Qt, QTimer, \
|
||||
QPainter, QPalette, QBrush, QFontDatabase, QDialog, \
|
||||
@ -295,8 +295,50 @@ class Document(QWebPage):
|
||||
if r > 0:
|
||||
self.javascript('document.body.style.paddingBottom = "%dpx"'%r)
|
||||
|
||||
def element_ypos(self, elem):
|
||||
ans, ok = elem.evaluateJavaScript('$(this).offset().top').toInt()
|
||||
if not ok:
|
||||
raise ValueError('No ypos found')
|
||||
return ans
|
||||
|
||||
def elem_outer_xml(self, elem):
|
||||
return unicode(elem.toOuterXml())
|
||||
|
||||
def find_bookmark_element(self):
|
||||
mf = self.mainFrame()
|
||||
doc_pos = self.ypos
|
||||
min_delta, min_elem = sys.maxint, None
|
||||
for y in range(10, -500, -10):
|
||||
for x in range(-50, 500, 10):
|
||||
pos = QPoint(x, y)
|
||||
result = mf.hitTestContent(pos)
|
||||
if result.isNull(): continue
|
||||
elem = result.enclosingBlockElement()
|
||||
if elem.isNull(): continue
|
||||
try:
|
||||
ypos = self.element_ypos(elem)
|
||||
except:
|
||||
continue
|
||||
delta = abs(ypos - doc_pos)
|
||||
if delta < 25:
|
||||
return elem
|
||||
if delta < min_delta:
|
||||
min_elem, min_delta = elem, delta
|
||||
return min_elem
|
||||
|
||||
|
||||
def bookmark(self):
|
||||
return self.javascript('calculate_bookmark(%d)'%(self.ypos+25), 'string')
|
||||
elem = self.find_bookmark_element()
|
||||
|
||||
if elem is None or self.element_ypos(elem) < 100:
|
||||
print elem, self.element_ypos(elem)
|
||||
bm = 'body|%f'%(float(self.ypos)/(self.height*0.7))
|
||||
else:
|
||||
bm = unicode(elem.evaluateJavaScript(
|
||||
'calculate_bookmark(%d, this)'%self.ypos).toString())
|
||||
if not bm:
|
||||
bm = 'body|%f'%(float(self.ypos)/(self.height*0.7))
|
||||
return bm
|
||||
|
||||
@property
|
||||
def at_bottom(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user