mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Refactor preview panel JS into CS
This commit is contained in:
parent
20e0781b80
commit
b71674436e
@ -93,6 +93,17 @@ class CalibreUtils
|
||||
return this.viewport_to_document(r.left, 0, elem.ownerDocument)[0]
|
||||
# }}}
|
||||
|
||||
abstop: (elem) -> # {{{
|
||||
# The left edge of elem in document co-ords. Works in all
|
||||
# circumstances, including column layout. Note that this will cause
|
||||
# a relayout if the render tree is dirty. Also, because of a bug in the
|
||||
# version of WebKit bundled with Qt 4.8, this does not always work, see
|
||||
# https://bugs.launchpad.net/bugs/1132641 for a test case.
|
||||
r = elem.getBoundingClientRect()
|
||||
return this.viewport_to_document(r.top, 0, elem.ownerDocument)[0]
|
||||
# }}}
|
||||
|
||||
|
||||
if window?
|
||||
window.calibre_utils = new CalibreUtils()
|
||||
|
||||
|
67
src/calibre/ebooks/oeb/polish/preview.coffee
Normal file
67
src/calibre/ebooks/oeb/polish/preview.coffee
Normal file
@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env coffee
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
|
||||
###
|
||||
Copyright 2013, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
Released under the GPLv3 License
|
||||
###
|
||||
|
||||
|
||||
if window?.calibre_utils
|
||||
log = window.calibre_utils.log
|
||||
|
||||
is_hidden = (elem) ->
|
||||
while elem
|
||||
if (elem.style && (elem.style.visibility == 'hidden' || elem.style.display == 'none'))
|
||||
return true
|
||||
elem = elem.parentNode
|
||||
return false
|
||||
|
||||
class PreviewIntegration
|
||||
|
||||
###
|
||||
# Namespace to expose all the functions used for integration with the Tweak
|
||||
# Book Preview Panel.
|
||||
###
|
||||
|
||||
constructor: () ->
|
||||
if not this instanceof arguments.callee
|
||||
throw new Error('PreviewIntegration constructor called as function')
|
||||
|
||||
go_to_line: (lnum) ->
|
||||
for node in document.querySelectorAll('[data-lnum="' + lnum + '"]')
|
||||
if is_hidden(node)
|
||||
continue
|
||||
top = window.calibre_utils.abstop(node) - (window.innerHeight / 2)
|
||||
if (top < 0)
|
||||
top = 0
|
||||
window.scrollTo(0, top)
|
||||
return
|
||||
|
||||
line_numbers: () ->
|
||||
found_body = false
|
||||
ans = []
|
||||
for node in document.getElementsByTagName('*')
|
||||
if not found_body and node.tagName.toLowerCase() == "body"
|
||||
found_body = true
|
||||
if found_body
|
||||
ans.push(node.getAttribute("data-lnum"))
|
||||
return ans
|
||||
|
||||
find_blocks: () =>
|
||||
for elem in document.body.getElementsByTagName('*')
|
||||
style = window.getComputedStyle(elem)
|
||||
if style.display in ['block', 'flex-box', 'box']
|
||||
elem.setAttribute('data-is-block', '1')
|
||||
elem.onclick = this.onclick
|
||||
|
||||
onload: () ->
|
||||
window.document.body.addEventListener('click', window.calibre_preview_integration.onclick, true)
|
||||
|
||||
onclick: (event) ->
|
||||
event.preventDefault()
|
||||
window.py_bridge.request_sync(event.target.getAttribute("data-lnum"))
|
||||
|
||||
window.calibre_preview_integration = new PreviewIntegration()
|
||||
window.onload = window.calibre_preview_integration.onload
|
||||
|
@ -19,7 +19,7 @@ from PyQt4.Qt import (
|
||||
from PyQt4.QtWebKit import QWebView, QWebInspector, QWebPage
|
||||
|
||||
from calibre import prints
|
||||
from calibre.constants import iswindows
|
||||
from calibre.constants import iswindows, DEBUG
|
||||
from calibre.ebooks.oeb.polish.parsing import parse
|
||||
from calibre.ebooks.oeb.base import serialize, OEB_DOCS
|
||||
from calibre.ptempfile import PersistentTemporaryDirectory
|
||||
@ -220,66 +220,6 @@ class NetworkAccessManager(QNetworkAccessManager):
|
||||
|
||||
# }}}
|
||||
|
||||
JS = '''
|
||||
function handle_click(event) {
|
||||
event.preventDefault();
|
||||
window.py_bridge.request_sync(event.target.getAttribute("data-lnum"));
|
||||
}
|
||||
|
||||
function line_numbers() {
|
||||
var elements = document.getElementsByTagName('*'), found_body = false, ans = [], node, i;
|
||||
var found_body = false;
|
||||
var ans = [];
|
||||
for (i = 0; i < elements.length; i++) {
|
||||
node = elements[i];
|
||||
if (!found_body && node.tagName.toLowerCase() === "body") {
|
||||
found_body = true;
|
||||
}
|
||||
if (found_body) {
|
||||
ans.push(node.getAttribute("data-lnum"));
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
function document_offset_top(obj) {
|
||||
var curtop = 0;
|
||||
if (obj.offsetParent) {
|
||||
do {
|
||||
curtop += obj.offsetTop;
|
||||
} while (obj = obj.offsetParent);
|
||||
return curtop;
|
||||
}
|
||||
}
|
||||
|
||||
function is_hidden(elem) {
|
||||
var p = elem;
|
||||
while (p) {
|
||||
if (p.style && (p.style.visibility === 'hidden' || p.style.display === 'none'))
|
||||
return true;
|
||||
p = p.parentNode;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function go_to_line(lnum) {
|
||||
var elements = document.querySelectorAll('[data-lnum="' + lnum + '"]');
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
var node = elements[i];
|
||||
if (is_hidden(node)) continue;
|
||||
var top = document_offset_top(node) - (window.innerHeight / 2);
|
||||
if (top < 0) top = 0;
|
||||
window.scrollTo(0, top);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
document.body.addEventListener('click', handle_click, true);
|
||||
}
|
||||
|
||||
'''
|
||||
|
||||
def uniq(vals):
|
||||
''' Remove all duplicates from vals, while preserving order. '''
|
||||
vals = vals or ()
|
||||
@ -321,10 +261,14 @@ class WebPage(QWebPage):
|
||||
prints('preview js:%s:%s:'%(unicode(source_id), lineno), unicode(msg))
|
||||
|
||||
def init_javascript(self):
|
||||
if not hasattr(self, 'js'):
|
||||
from calibre.utils.resources import compiled_coffeescript
|
||||
self.js = compiled_coffeescript('ebooks.oeb.display.utils', dynamic=DEBUG)
|
||||
self.js += compiled_coffeescript('ebooks.oeb.polish.preview', dynamic=DEBUG)
|
||||
self._line_numbers = None
|
||||
mf = self.mainFrame()
|
||||
mf.addToJavaScriptWindowObject("py_bridge", self)
|
||||
mf.evaluateJavaScript(JS)
|
||||
mf.evaluateJavaScript(self.js)
|
||||
|
||||
@pyqtSlot(str)
|
||||
def request_sync(self, lnum):
|
||||
@ -341,7 +285,8 @@ class WebPage(QWebPage):
|
||||
if not ok:
|
||||
ans = None
|
||||
return ans
|
||||
self._line_numbers = sorted(uniq(filter(lambda x:x is not None, map(atoi, self.mainFrame().evaluateJavaScript('line_numbers()').toStringList()))))
|
||||
self._line_numbers = sorted(uniq(filter(lambda x:x is not None, map(atoi, self.mainFrame().evaluateJavaScript(
|
||||
'window.calibre_preview_integration.line_numbers()').toStringList()))))
|
||||
return self._line_numbers
|
||||
|
||||
def go_to_line(self, lnum):
|
||||
@ -349,7 +294,8 @@ class WebPage(QWebPage):
|
||||
lnum = find_le(self.line_numbers, lnum)
|
||||
except ValueError:
|
||||
return
|
||||
self.mainFrame().evaluateJavaScript('go_to_line(%d)' % lnum)
|
||||
self.mainFrame().evaluateJavaScript(
|
||||
'window.calibre_preview_integration.go_to_line(%d)' % lnum)
|
||||
|
||||
class WebView(QWebView):
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user