Skip to content

Commit

Permalink
Update foliate-js
Browse files Browse the repository at this point in the history
  • Loading branch information
johnfactotum committed May 15, 2023
1 parent 1613ac8 commit a893796
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 73 deletions.
8 changes: 4 additions & 4 deletions src/book-viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ GObject.registerClass({
Signals: {
'book-ready': { param_types: [GObject.TYPE_JSOBJECT] },
'book-error': { param_types: [GObject.TYPE_JSOBJECT] },
'relocated': { param_types: [GObject.TYPE_JSOBJECT] },
'relocate': { param_types: [GObject.TYPE_JSOBJECT] },
'external-link': { param_types: [GObject.TYPE_JSOBJECT] },
'reference': { param_types: [GObject.TYPE_JSOBJECT] },
'selection': { param_types: [GObject.TYPE_JSOBJECT] },
Expand Down Expand Up @@ -491,8 +491,8 @@ export const BookViewer = GObject.registerClass({
utils.connect(this._view, {
'book-error': (_, x) => this.#onError(x),
'book-ready': (_, x) => this.#onBookReady(x).catch(e => console.error(e)),
'relocated': (_, x) => this.#onRelocated(x),
'external-link': (_, x) => Gtk.show_uri(null, x.uri, Gdk.CURRENT_TIME),
'relocate': (_, x) => this.#onRelocate(x),
'external-link': (_, x) => Gtk.show_uri(null, x.href, Gdk.CURRENT_TIME),
'reference': (_, x) => this.#onReference(x),
'selection': (_, x) => this.#onSelection(x),
'create-overlay': (_, x) => this.#createOverlay(x),
Expand Down Expand Up @@ -727,7 +727,7 @@ export const BookViewer = GObject.registerClass({
}
else await this._view.next()
}
#onRelocated(payload) {
#onRelocate(payload) {
const { section, location, tocItem, cfi } = payload
this._toc_view.setCurrent(tocItem?.id)
this._search_view.index = section.current
Expand Down
2 changes: 1 addition & 1 deletion src/foliate-js
Submodule foliate-js updated 6 files
+20 −5 README.md
+5 −5 fixed-layout.js
+42 −19 paginator.js
+0 −2 reader.html
+13 −15 reader.js
+40 −38 view.js
145 changes: 77 additions & 68 deletions src/reader/reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { View } from '../foliate-js/view.js'
import { Overlayer } from '../foliate-js/overlayer.js'
import { toPangoMarkup } from './markup.js'

customElements.define('foliate-view', View)

// TODO: make this translatable
const format = {
loc: (a, b) => `Loc ${a} of ${b}`,
Expand Down Expand Up @@ -101,7 +103,7 @@ const open = async file => {

const reader = new Reader(book)
globalThis.reader = reader
await reader.display()
await reader.init()
emit({ type: 'book-ready', book, reader })
}

Expand Down Expand Up @@ -212,73 +214,76 @@ class Reader {
this.pageTotal = book.pageList
?.findLast(x => !isNaN(parseInt(x.label)))?.label
}
async display() {
this.view = new View(this.book, this.#handleEvent.bind(this))
document.body.append(await this.view.display())
async init() {
this.view = document.createElement('foliate-view')
this.#handleEvents()
await this.view.open(this.book)
document.body.append(this.view)
}
setAppearance({ style, layout }) {
Object.assign(this.style, style)
Object.assign(this.layout, layout)
this.view?.setAppearance({ css: getCSS(this.style), layout: this.layout })
document.body.classList.toggle('invert', this.style.invert)
}
#handleEvent(obj) {
switch (obj.type) {
case 'relocated': {
const { heads, feet } = this.view.renderer
if (heads) {
const { tocItem } = obj
heads.at(-1).innerText = tocItem?.label ?? ''
if (heads.length > 1)
heads[0].innerText = this.book.metadata.title
}
if (feet) {
const { pageItem, location: { current, next, total } } = obj
if (pageItem) {
// only show page number at the end
// because we only have visible range for the spread,
// not each column
feet.at(-1).innerText = format.page(pageItem.label, this.pageTotal)
if (feet.length > 1)
feet[0].innerText = format.loc(current + 1, total)
}
else {
#handleEvents() {
this.view.addEventListener('relocate', e => {
const { heads, feet } = this.view.renderer
if (heads) {
const { tocItem } = e.detail
heads.at(-1).innerText = tocItem?.label ?? ''
if (heads.length > 1)
heads[0].innerText = this.book.metadata.title
}
if (feet) {
const { pageItem, location: { current, next, total } } = e.detail
if (pageItem) {
// only show page number at the end
// because we only have visible range for the spread,
// not each column
feet.at(-1).innerText = format.page(pageItem.label, this.pageTotal)
if (feet.length > 1)
feet[0].innerText = format.loc(current + 1, total)
if (feet.length > 1) {
const r = 1 - 1 / feet.length
const end = Math.floor((1 - r) * current + r * next)
feet.at(-1).innerText = format.loc(end + 1, total)
}
}
else {
feet[0].innerText = format.loc(current + 1, total)
if (feet.length > 1) {
const r = 1 - 1 / feet.length
const end = Math.floor((1 - r) * current + r * next)
feet.at(-1).innerText = format.loc(end + 1, total)
}
}
emit(obj)
break
}
case 'create-overlay': emit(obj); break
case 'show-annotation': {
const { value, range } = obj
const pos = getPosition(range)
this.#showAnnotation({ range, value, pos })
break
}
case 'draw-annotation': {
const { annotation, doc, range } = obj
const { color } = annotation
if (['underline', 'squiggly', 'strikethrough'].includes(color)) {
const { defaultView } = doc
const node = range.startContainer
const el = node.nodeType === 1 ? node : node.parentElement
const { writingMode } = defaultView.getComputedStyle(el)
return [Overlayer[color], { writingMode }]
}
else return [Overlayer.highlight, { color }]
emit({ type: 'relocate', ...e.detail })
})
this.view.addEventListener('create-overlay', e =>
emit({ type: 'create-overlay', ...e.detail }))
this.view.addEventListener('show-annotation', e => {
const { value, range } = e.detail
const pos = getPosition(range)
this.#showAnnotation({ range, value, pos })
})
this.view.addEventListener('draw-annotation', e => {
const { draw, annotation, doc, range } = e.detail
const { color } = annotation
if (['underline', 'squiggly', 'strikethrough'].includes(color)) {
const { defaultView } = doc
const node = range.startContainer
const el = node.nodeType === 1 ? node : node.parentElement
const { writingMode } = defaultView.getComputedStyle(el)
draw(Overlayer[color], { writingMode })
}
case 'external-link': emit(obj); return true
case 'link': return this.#onLink(obj)
case 'loaded': this.#onLoaded(obj); break
}
else draw(Overlayer.highlight, { color })
})
this.view.addEventListener('external-link', e => {
e.preventDefault()
emit({ type: 'external-link', ...e.detail })
})
this.view.addEventListener('link', e => this.#onLink(e))
this.view.addEventListener('load', e => this.#onLoad(e))
}
#onLoaded({ doc, index }) {
#onLoad(e) {
const { doc, index } = e.detail
for (const img of doc.querySelectorAll('img'))
img.addEventListener('dblclick', () => fetch(img.src)
.then(res => res.blob())
Expand Down Expand Up @@ -314,21 +319,25 @@ class Reader {
this.#showAnnotation({ range, value, pos })
})
}
#onLink({ a, href }) {
#onLink(e) {
const { a, href } = e.detail
const { index, anchor } = this.view.book.resolveHref(href)
if (hasEPUBSSV(a, ['annoref', 'biblioref', 'glossref', 'noteref'])
|| hasRole(a, ['doc-biblioref', 'doc-glossref', 'doc-noteref'])) return Promise
.resolve(this.view.book.sections[index].createDocument())
.then(doc => {
const el = anchor(doc)
if (el) {
const pos = getPosition(a)
const html = toPangoMarkup(el.innerHTML)
emit({ type: 'reference', href, html, pos })
return true
}
})
.catch(e => console.error(e))
|| hasRole(a, ['doc-biblioref', 'doc-glossref', 'doc-noteref'])) {
e.preventDefault()
Promise
.resolve(this.view.book.sections[index].createDocument())
.then(doc => {
const el = anchor(doc)
if (el) {
const pos = getPosition(a)
const html = toPangoMarkup(el.innerHTML)
emit({ type: 'reference', href, html, pos })
return true
}
})
.catch(e => console.error(e))
}
}
async getCover() {
try {
Expand Down

0 comments on commit a893796

Please sign in to comment.