From 127fc7cffad132de031113577c1c9129482f3cc6 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 29 Dec 2019 20:07:07 +0530 Subject: [PATCH] Viewer: Fix svg links not working. Fixes #1857812 [Private bug](https://bugs.launchpad.net/calibre/+bug/1857812) --- src/calibre/srv/render_book.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/calibre/srv/render_book.py b/src/calibre/srv/render_book.py index 1bd1487edd..4e0c5fb6bd 100644 --- a/src/calibre/srv/render_book.py +++ b/src/calibre/srv/render_book.py @@ -369,6 +369,7 @@ def transform_svg_image(container, name, link_uid, virtualize_resources, virtual def transform_html(container, name, virtualize_resources, link_uid, link_to_map, virtualized_names): link_xpath = XPath('//h:a[@href]') + svg_link_xpath = XPath('//svg:a') img_xpath = XPath('//h:img[@src]') res_link_xpath = XPath('//h:link[@href]') root = container.parsed(name) @@ -404,15 +405,24 @@ def transform_html(container, name, virtualize_resources, link_uid, link_to_map, if virtualize_resources: virtualize_html(container, name, link_uid, link_to_map, virtualized_names) else: - for a in link_xpath(root): - href = link_replacer(name, a.get('href')) + + def handle_link(a, attr='href'): + href = a.get(attr) + if href: + href = link_replacer(name, href) if href and href.startswith(link_uid): - a.set('href', 'javascript:void(0)') + a.set(attr, 'javascript:void(0)') parts = decode_url(href.split('|')[1]) lname, lfrag = parts[0], parts[1] link_to_map.setdefault(lname, {}).setdefault(lfrag or '', set()).add(name) a.set('data-' + link_uid, json.dumps({'name':lname, 'frag':lfrag}, ensure_ascii=False)) + for a in link_xpath(root): + handle_link(a) + xhref = XLINK('href') + for a in svg_link_xpath(root): + handle_link(a, xhref) + shtml = html_as_json(root) with container.open(name, 'wb') as f: f.write(shtml) @@ -518,23 +528,31 @@ def virtualize_html(container, name, link_uid, link_to_map, virtualized_names): changed = set() link_xpath = XPath('//h:a[@href]') + svg_link_xpath = XPath('//svg:a') link_replacer = create_link_replacer(container, link_uid, changed) virtualized_names.add(name) root = container.parsed(name) rewrite_links(root, partial(link_replacer, name)) - for a in link_xpath(root): - href = a.get('href') + + def handle_link(a, attr='href'): + href = a.get(attr) or '' if href.startswith(link_uid): - a.set('href', 'javascript:void(0)') + a.set(attr, 'javascript:void(0)') parts = decode_url(href.split('|')[1]) lname, lfrag = parts[0], parts[1] link_to_map.setdefault(lname, {}).setdefault(lfrag or '', set()).add(name) a.set('data-' + link_uid, json.dumps({'name':lname, 'frag':lfrag}, ensure_ascii=False)) - else: + elif href: a.set('target', '_blank') a.set('rel', 'noopener noreferrer') + for a in link_xpath(root): + handle_link(a) + xhref = XLINK('href') + for a in svg_link_xpath(root): + handle_link(a, xhref) + return name in changed