Preview panel: Allow syncing of position more accurately when there are multiple tags on the same source code line

This commit is contained in:
Kovid Goyal 2014-05-25 14:29:25 +05:30
parent 70a1748deb
commit f8e8d9caa0
4 changed files with 33 additions and 16 deletions

Binary file not shown.

View File

@ -226,6 +226,11 @@ get_matched_css = (node, is_ancestor, all_properties) ->
return ans.reverse()
scroll_to_node = (node) ->
if node is document.body
window.scrollTo(0, 0)
else
node.scrollIntoView()
class PreviewIntegration
@ -244,11 +249,15 @@ class PreviewIntegration
for node in document.querySelectorAll('[data-lnum="' + lnum + '"]')
if is_hidden(node)
continue
if node is document.body
window.scrollTo(0, 0)
else
node.scrollIntoView()
return
scroll_to_node(node)
go_to_sourceline_address: (sourceline, tags) =>
for node, index in document.querySelectorAll('[data-lnum="' + sourceline + '"]')
if index >= tags.length or node.tagName.toLowerCase() != tags[index]
break
if index == tags.length - 1 and not is_hidden(node)
return scroll_to_node(node)
this.go_to_line(sourceline)
line_numbers: () =>
found_body = false
@ -300,14 +309,14 @@ class PreviewIntegration
this.report_split(event.target)
else
e = event.target
address = get_sourceline_address(e)
# Find the closest containing link, if any
lnum = e.getAttribute('data-lnum')
href = tn = ''
while e and e != document.body and e != document and (tn != 'a' or not href)
tn = e.tagName?.toLowerCase()
href = e.getAttribute('href')
e = e.parentNode
window.py_bridge.request_sync(tn, href, lnum)
window.py_bridge.request_sync(tn, href, JSON.stringify(address))
return false
go_to_anchor: (anchor, lnum) =>

View File

@ -1014,11 +1014,11 @@ class Boss(QObject):
mt = current_container().mime_map.get(name, guess_type(name))
self.edit_file_requested(name, None, mt)
def sync_editor_to_preview(self, name, lnum):
def sync_editor_to_preview(self, name, sourceline_address):
editor = self.edit_file(name, 'html')
self.ignore_preview_to_editor_sync = True
try:
editor.current_line = lnum
editor.goto_sourceline(*sourceline_address)
finally:
self.ignore_preview_to_editor_sync = False
@ -1029,7 +1029,7 @@ class Boss(QObject):
if ed is not None:
name = editor_name(ed)
if name is not None and getattr(ed, 'syntax', None) == 'html':
self.gui.preview.sync_to_editor(name, ed.current_line)
self.gui.preview.sync_to_editor(name, ed.current_tag())
def sync_live_css_to_editor(self):
ed = self.gui.central.current_editor

View File

@ -330,9 +330,9 @@ class WebPage(QWebPage):
mf.evaluateJavaScript(self.js)
@pyqtSlot(str, str, str)
def request_sync(self, tag_name, href, lnum):
def request_sync(self, tag_name, href, sourceline_address):
try:
self.sync_requested.emit(unicode(tag_name), unicode(href), int(unicode(lnum)))
self.sync_requested.emit(unicode(tag_name), unicode(href), json.loads(unicode(sourceline_address)))
except (TypeError, ValueError, OverflowError, AttributeError):
pass
@ -369,6 +369,14 @@ class WebPage(QWebPage):
self.mainFrame().evaluateJavaScript(
'window.calibre_preview_integration.go_to_line(%d)' % lnum)
def go_to_sourceline_address(self, sourceline_address):
lnum, tags = sourceline_address
if lnum is None:
return
tags = [x.lower() for x in tags]
self.mainFrame().evaluateJavaScript(
'window.calibre_preview_integration.go_to_sourceline_address(%d, %s)' % (lnum, json.dumps(tags)))
def split_mode(self, enabled):
self.mainFrame().evaluateJavaScript(
'window.calibre_preview_integration.split_mode(%s)' % (
@ -538,8 +546,8 @@ class Preview(QWidget):
if self.current_name:
self.split_requested.emit(self.current_name, loc, totals)
def sync_to_editor(self, name, lnum):
self.current_sync_request = (name, lnum)
def sync_to_editor(self, name, sourceline_address):
self.current_sync_request = (name, sourceline_address)
QTimer.singleShot(100, self._sync_to_editor)
def _sync_to_editor(self):
@ -550,9 +558,9 @@ class Preview(QWidget):
return QTimer.singleShot(100, self._sync_to_editor)
except TypeError:
return # Happens if current_sync_request is None
lnum = self.current_sync_request[1]
sourceline_address = self.current_sync_request[1]
self.current_sync_request = None
self.view.page().go_to_line(lnum)
self.view.page().go_to_sourceline_address(sourceline_address)
def show(self, name):
if name != self.current_name: