Ebook viewer: Use a more stable, though less accurate algorithm for calculating bookmarks. Add a --debug-javascript option. Fixes #2653 (Ebook Viewer Sometimes Has Two Scrollbars)

This commit is contained in:
Kovid Goyal 2009-06-18 15:30:16 -07:00
parent e35ac4441e
commit e757bedb50
3 changed files with 53 additions and 25 deletions

View File

@ -16,6 +16,7 @@ from calibre.gui2.viewer.config_ui import Ui_Dialog
from calibre.gui2.viewer.js import bookmarks, referencing from calibre.gui2.viewer.js import bookmarks, referencing
from calibre.ptempfile import PersistentTemporaryFile from calibre.ptempfile import PersistentTemporaryFile
from calibre.constants import iswindows from calibre.constants import iswindows
from calibre import prints
def load_builtin_fonts(): def load_builtin_fonts():
from calibre.ebooks.lrf.fonts.liberation import LiberationMono_BoldItalic from calibre.ebooks.lrf.fonts.liberation import LiberationMono_BoldItalic
@ -124,6 +125,7 @@ class Document(QWebPage):
def __init__(self, *args): def __init__(self, *args):
QWebPage.__init__(self, *args) QWebPage.__init__(self, *args)
self.debug_javascript = False
self.setLinkDelegationPolicy(self.DelegateAllLinks) self.setLinkDelegationPolicy(self.DelegateAllLinks)
self.scroll_marks = [] self.scroll_marks = []
pal = self.palette() pal = self.palette()
@ -187,6 +189,20 @@ class Document(QWebPage):
return unicode(ans.toString()) return unicode(ans.toString())
return ans return ans
def javaScriptConsoleMessage(self, msg, lineno, msgid):
if self.debug_javascript:
prints( 'JS:', msgid, lineno)
prints(msg)
prints(' ')
else:
return QWebPage.javaScriptConsoleMessage(self, msg, lineno, msgid)
def javaScriptAlert(self, frame, msg):
if self.debug_javascript:
prints(msg)
else:
return QWebPage.javaScriptAlert(self, frame, msg)
def scroll_by(self, dx=0, dy=0): def scroll_by(self, dx=0, dy=0):
self.mainFrame().scroll(dx, dy) self.mainFrame().scroll(dx, dy)
@ -272,6 +288,7 @@ class DocumentView(QWebView):
def __init__(self, *args): def __init__(self, *args):
QWidget.__init__(self, *args) QWidget.__init__(self, *args)
self.debug_javascript = False
self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
self._size_hint = QSize(510, 680) self._size_hint = QSize(510, 680)
self.initial_pos = 0.0 self.initial_pos = 0.0

View File

@ -1,27 +1,5 @@
bookmarks = ''' bookmarks = '''
function find_enclosing_block(y) {
var elements = $("*", document.body);
var min = 0;
var temp, left, top, elem, width, height, ratio;
for (i = 0; i < elements.length; i++) {
elem = $(elements[i]);
temp = elem.offset();
left = temp.left; top = temp.top;
width = elem.width(); height = elem.height();
if (top > y+50) break;
for ( x = 40; x < window.innerWidth; x += 20) {
if (x >= left && x <= left+width && y >= top && y <= top+height) {
if (min == 0 || min.height() > height) { min = elem; break; }
}
}
if (min != 0 && min.height() < 200) break;
}
if (y <= 0) return document.body;
if (min == 0) { return find_enclosing_block(y-20); }
return min;
}
function selector_in_parent(elem) { function selector_in_parent(elem) {
var num = elem.prevAll().length; var num = elem.prevAll().length;
var sel = " > *:eq("+num+") "; var sel = " > *:eq("+num+") ";
@ -38,8 +16,37 @@ function selector(elem) {
return sel; 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) { function calculate_bookmark(y) {
var elem = find_enclosing_block(y); var elem = find_closest_enclosing_block(y);
var sel = selector(elem); var sel = selector(elem);
var ratio = (y - elem.offset().top)/elem.height(); var ratio = (y - elem.offset().top)/elem.height();
if (ratio > 1) { ratio = 1; } if (ratio > 1) { ratio = 1; }

View File

@ -189,7 +189,7 @@ class HelpfulLineEdit(QLineEdit):
class EbookViewer(MainWindow, Ui_EbookViewer): class EbookViewer(MainWindow, Ui_EbookViewer):
def __init__(self, pathtoebook=None): def __init__(self, pathtoebook=None, debug_javascript=False):
MainWindow.__init__(self, None) MainWindow.__init__(self, None)
self.setupUi(self) self.setupUi(self)
self.iterator = None self.iterator = None
@ -219,6 +219,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.search.setToolTip(_('Search for text in book')) self.search.setToolTip(_('Search for text in book'))
self.tool_bar2.insertWidget(self.action_find_next, self.search) self.tool_bar2.insertWidget(self.action_find_next, self.search)
self.view.set_manager(self) self.view.set_manager(self)
self.view.document.debug_javascript = debug_javascript
self.pi = ProgressIndicator(self) self.pi = ProgressIndicator(self)
self.toc.setVisible(False) self.toc.setVisible(False)
self.action_quit = QAction(self) self.action_quit = QAction(self)
@ -630,6 +631,8 @@ def config(defaults=None):
'front when started.')) 'front when started.'))
c.add_opt('remember_window_size', default=False, c.add_opt('remember_window_size', default=False,
help=_('Remember last used window size')) help=_('Remember last used window size'))
c.add_opt('debug_javascript', ['--debug-javascript'], default=False,
help=_('Print javascript alert and console messages to the console'))
return c return c
@ -651,7 +654,8 @@ def main(args=sys.argv):
app.setWindowIcon(QIcon(':/images/viewer.svg')) app.setWindowIcon(QIcon(':/images/viewer.svg'))
QApplication.setOrganizationName(ORG_NAME) QApplication.setOrganizationName(ORG_NAME)
QApplication.setApplicationName(APP_UID) QApplication.setApplicationName(APP_UID)
main = EbookViewer(args[1] if len(args) > 1 else None) main = EbookViewer(args[1] if len(args) > 1 else None,
debug_javascript=opts.debug_javascript)
sys.excepthook = main.unhandled_exception sys.excepthook = main.unhandled_exception
main.show() main.show()
if opts.raise_window: if opts.raise_window: