FB2: only check <binary>s when getting data

Fixes https://github.com/johnfactotum/foliate/issues/1492
This commit is contained in:
John Factotum
2025-03-12 17:28:30 +08:00
parent e2014ee753
commit d4696cea4b
+16 -13
View File
@@ -70,27 +70,30 @@ const BODY = {
'section': ['section', SECTION], 'section': ['section', SECTION],
} }
const getImageSrc = el => {
const href = el.getAttributeNS(NS.XLINK, 'href')
if (!href) return 'data:,'
const [, id] = href.split('#')
if (!id) return href
const bin = el.getRootNode().getElementById(id)
return bin
? `data:${bin.getAttribute('content-type')};base64,${bin.textContent}`
: href
}
class FB2Converter { class FB2Converter {
constructor(fb2) { constructor(fb2) {
this.fb2 = fb2 this.fb2 = fb2
this.doc = document.implementation.createDocument(NS.XHTML, 'html') this.doc = document.implementation.createDocument(NS.XHTML, 'html')
// use this instead of `getElementById` to allow images like
// `<image l:href="#img1.jpg" id="img1.jpg" />`
this.bins = new Map(Array.from(this.fb2.getElementsByTagName('binary'),
el => [el.id, el]))
}
getImageSrc(el) {
const href = el.getAttributeNS(NS.XLINK, 'href')
if (!href) return 'data:,'
const [, id] = href.split('#')
if (!id) return href
const bin = this.bins.get(id)
return bin
? `data:${bin.getAttribute('content-type')};base64,${bin.textContent}`
: href
} }
image(node) { image(node) {
const el = this.doc.createElement('img') const el = this.doc.createElement('img')
el.alt = node.getAttribute('alt') el.alt = node.getAttribute('alt')
el.title = node.getAttribute('title') el.title = node.getAttribute('title')
el.setAttribute('src', getImageSrc(node)) el.setAttribute('src', this.getImageSrc(node))
return el return el
} }
anchor(node) { anchor(node) {
@@ -267,7 +270,7 @@ export const makeFB2 = async blob => {
subject: $$('title-info genre').map(getElementText), subject: $$('title-info genre').map(getElementText),
} }
if ($('coverpage image')) { if ($('coverpage image')) {
const src = getImageSrc($('coverpage image')) const src = converter.getImageSrc($('coverpage image'))
book.getCover = () => fetch(src).then(res => res.blob()) book.getCover = () => fetch(src).then(res => res.blob())
} else book.getCover = () => null } else book.getCover = () => null