diff --git a/resources/compiled_coffeescript.zip b/resources/compiled_coffeescript.zip index 257baf3a67..e50a016181 100644 Binary files a/resources/compiled_coffeescript.zip and b/resources/compiled_coffeescript.zip differ diff --git a/src/calibre/ebooks/oeb/polish/choose.coffee b/src/calibre/ebooks/oeb/polish/choose.coffee index 5a9361bf18..9843b29224 100644 --- a/src/calibre/ebooks/oeb/polish/choose.coffee +++ b/src/calibre/ebooks/oeb/polish/choose.coffee @@ -32,7 +32,22 @@ class AnchorLocator # block, if any. event.stopPropagation() frac = window.pageYOffset/document.body.scrollHeight - window.py_bridge.onclick(this, frac) + loc = [] + totals = [] + parent = this + while parent and parent.tagName.toLowerCase() != 'body' + totals.push(parent.parentNode.children.length) + num = 0 + sibling = parent.previousElementSibling + while sibling + num += 1 + sibling = sibling.previousElementSibling + loc.push(num) + parent = parent.parentNode + loc.reverse() + totals.reverse() + + window.py_bridge.onclick(this, JSON.stringify(loc), JSON.stringify(totals), frac) return false calibre_anchor_locator = new AnchorLocator() diff --git a/src/calibre/ebooks/oeb/polish/toc.py b/src/calibre/ebooks/oeb/polish/toc.py index 7a1b94b2ef..5f9232fbdb 100644 --- a/src/calibre/ebooks/oeb/polish/toc.py +++ b/src/calibre/ebooks/oeb/polish/toc.py @@ -359,9 +359,24 @@ def node_from_loc(root, locs, totals=None): node = children[locs[0]] return node -def add_id(container, name, loc): +def add_id(container, name, loc, totals=None): root = container.parsed(name) - node = node_from_loc(root, loc) + try: + node = node_from_loc(root, loc, totals=totals) + except MalformedMarkup: + # The webkit HTML parser and the container parser have yielded + # different node counts, this can happen if the file is valid XML + # but contains constructs like nested

tags. So force parse it + # with the HTML 5 parser and try again. + raw = container.raw_data(name) + root = container.parse_xhtml(raw, fname=name, force_html5_parse=True) + try: + node = node_from_loc(root, loc, totals=totals) + except MalformedMarkup: + raise MalformedMarkup(_('The file %s has malformed markup. Try running the Fix HTML tool' + ' before editing.') % name) + container.replace(name, root) + node.set('id', node.get('id', uuid_id())) container.commit_item(name, keep_parsed=True) return node.get('id') diff --git a/src/calibre/gui2/toc/location.py b/src/calibre/gui2/toc/location.py index 944acc7c8d..c5f78a3d9c 100644 --- a/src/calibre/gui2/toc/location.py +++ b/src/calibre/gui2/toc/location.py @@ -7,6 +7,7 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' __docformat__ = 'restructuredtext en' +import json from base64 import b64encode from PyQt4.Qt import (QWidget, QGridLayout, QListWidget, QSize, Qt, QUrl, @@ -20,7 +21,7 @@ from calibre.utils.logging import default_log class Page(QWebPage): # {{{ - elem_clicked = pyqtSignal(object, object, object, object) + elem_clicked = pyqtSignal(object, object, object, object, object) def __init__(self): self.log = default_log @@ -42,21 +43,11 @@ class Page(QWebPage): # {{{ def shouldInterruptJavaScript(self): return True - @pyqtSlot(QWebElement, float) - def onclick(self, elem, frac): + @pyqtSlot(QWebElement, str, str, float) + def onclick(self, elem, loc, totals, frac): elem_id = unicode(elem.attribute('id')) or None tag = unicode(elem.tagName()).lower() - parent = elem - loc = [] - while unicode(parent.tagName()).lower() != 'body': - num = 0 - sibling = parent.previousSibling() - while not sibling.isNull(): - num += 1 - sibling = sibling.previousSibling() - loc.insert(0, num) - parent = parent.parent() - self.elem_clicked.emit(tag, frac, elem_id, tuple(loc)) + self.elem_clicked.emit(tag, frac, elem_id, json.loads(str(loc)), json.loads(str(totals))) def load_js(self): if self.js is None: @@ -69,7 +60,7 @@ class Page(QWebPage): # {{{ class WebView(QWebView): # {{{ - elem_clicked = pyqtSignal(object, object, object, object) + elem_clicked = pyqtSignal(object, object, object, object, object) def __init__(self, parent): QWebView.__init__(self, parent) @@ -294,8 +285,8 @@ class ItemEdit(QWidget): loctext = _('Approximately %d%% from the top')%frac return loctext - def elem_clicked(self, tag, frac, elem_id, loc): - self.current_frag = elem_id or loc + def elem_clicked(self, tag, frac, elem_id, loc, totals): + self.current_frag = elem_id or (loc, totals) base = _('Location: A <%s> tag inside the file')%tag loctext = base + ' [%s]'%self.get_loctext(frac) self.dest_label.setText(self.base_msg + '
' + diff --git a/src/calibre/gui2/toc/main.py b/src/calibre/gui2/toc/main.py index d9fc3ff955..85526778e5 100644 --- a/src/calibre/gui2/toc/main.py +++ b/src/calibre/gui2/toc/main.py @@ -743,7 +743,7 @@ class TOCView(QWidget): # {{{ def update_item(self, item, where, name, frag, title): if isinstance(frag, tuple): - frag = add_id(self.ebook, name, frag) + frag = add_id(self.ebook, name, *frag) child = TOC(title, name, frag) child.dest_exists = True if item is None: