Add malformed markup check when editing ToC as well

This commit is contained in:
Kovid Goyal 2014-02-18 15:47:22 +05:30
parent d9f7968aef
commit 5440e0c377
5 changed files with 42 additions and 21 deletions

Binary file not shown.

View File

@ -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()

View File

@ -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 <p> 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')

View File

@ -7,6 +7,7 @@ __license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
__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 &lt;%s&gt; tag inside the file')%tag
loctext = base + ' [%s]'%self.get_loctext(frac)
self.dest_label.setText(self.base_msg + '<br>' +

View File

@ -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: