Bundling JS with ESBuild (#702)
* add npm dependencies used in this theme * implement helper to configure JS and ESBuild * migrate jquery popper.js bootstrap fontawesome to js bundle * refactor main.js into smaller pieces, and moved navbar.js to assets * remove list.js. It adjusts post card height to be the same, but is actually not needed. * refactored notes.js, search.js, single.js into application.js * move ityped to js asset, implement experiences horizontal vertical line in css * align recent post height via css * migrated home.js and refactored into various sections * migrated darkMode feature to js bundle * moved mermaid feature to js bundle * migrate syntax highlight to js bundle * migrate katex ( js portion ) to js bundle * migrate pdf-js to js bundle by delegating to cdn * set explicit comparisions for feature envvars so js can properly optimize * removed goat-counter * more fixes for broken achievements and small bugs * more bug fixes * allow configuration of hightlight.js, fix video-player shortcode * remove jquery all together * add null handling and fix merge conflicts Co-authored-by: Aaron Qian <aaron@yeet.io>
This commit is contained in:
parent
fe14b0fbf5
commit
02db3d3044
491 changed files with 4919 additions and 151344 deletions
165
assets/scripts/features/embedpdf/index.js
Normal file
165
assets/scripts/features/embedpdf/index.js
Normal file
|
@ -0,0 +1,165 @@
|
|||
import { insertScript } from '../../core'
|
||||
|
||||
const PDFJS_BUNDLE = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.0.279/build/pdf.min.js'
|
||||
const WORKER_BUNDLE = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.0.279/build/pdf.worker.min.js'
|
||||
|
||||
class PDFViewer {
|
||||
constructor (el) {
|
||||
const {
|
||||
url,
|
||||
hidePaginator,
|
||||
hideLoader,
|
||||
scale,
|
||||
pageNum
|
||||
} = el.dataset
|
||||
|
||||
if (url == null) {
|
||||
throw new Error('Cannot load PDF! Attribute `data-url` is not set.')
|
||||
}
|
||||
|
||||
// props
|
||||
this.url = url
|
||||
this.hidePaginator = hidePaginator !== 'false'
|
||||
this.hideLoader = hideLoader !== 'false'
|
||||
this.scale = scale || 3
|
||||
|
||||
// initial state
|
||||
this.pageNum = parseInt(pageNum, 10) || 1
|
||||
this.loaded = false
|
||||
this.pageRendering = false
|
||||
this.pageNumPending = null
|
||||
|
||||
// DOM elements
|
||||
this.canvas = el.getElementsByClassName('pdf-canvas')[0]
|
||||
if (this.canvas == null) {
|
||||
throw new Error('canvas element not found!')
|
||||
};
|
||||
this.paginator = el.getElementsByClassName('paginator')[0]
|
||||
this.loadingWrapper = el.getElementsByClassName('loading-wrapper')[0]
|
||||
this.next = el.getElementsByClassName('next')[0]
|
||||
this.prev = el.getElementsByClassName('prev')[0]
|
||||
this.pageNum = el.getElementsByClassName('page-num')[0]
|
||||
this.pageCount = el.getElementsByClassName('page-count')[0]
|
||||
|
||||
// context
|
||||
this.ctx = this.canvas.getContext('2d')
|
||||
|
||||
// events
|
||||
this.next.addEventListener('click', this.handleNextPage.bind(this))
|
||||
this.prev.addEventListener('click', this.handlePrevPage.bind(this))
|
||||
|
||||
this.showPaginator()
|
||||
this.showLoader()
|
||||
this.loadPDF()
|
||||
}
|
||||
|
||||
/**
|
||||
* If we haven't disabled the loader, show loader and hide canvas
|
||||
*/
|
||||
showLoader () {
|
||||
if (this.hideLoader) return
|
||||
this.loadingWrapper.style.display = 'flex'
|
||||
this.canvas.style.display = 'none'
|
||||
}
|
||||
|
||||
/**
|
||||
* If we haven't disabled the paginator, show paginator
|
||||
*/
|
||||
showPaginator () {
|
||||
if (this.hidePaginator) return
|
||||
this.paginator.style.display = 'block'
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides loader and shows canvas
|
||||
*/
|
||||
showContent () {
|
||||
this.loadingWrapper.style.display = 'none'
|
||||
this.canvas.style.display = 'block'
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously downloads PDF.
|
||||
*/
|
||||
async loadPDF () {
|
||||
this.pdfDoc = await window.pdfjsLib.getDocument(this.url).promise
|
||||
|
||||
this.pageCount.textContent = this.pdfDoc.numPages
|
||||
|
||||
// If the user passed in a number that is out of range, render the last page.
|
||||
if (this.pageNum > this.pdfDoc.numPages) {
|
||||
this.pageNum = this.pdfDoc.numPages
|
||||
}
|
||||
|
||||
this.renderPage(this.pageNum)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get page info from document, resize canvas accordingly, and render page.
|
||||
* @param num Page number.
|
||||
*/
|
||||
async renderPage (num) {
|
||||
this.pageRendering = true
|
||||
|
||||
const page = await this.pdfDoc.getPage(num)
|
||||
const viewport = page.getViewport({ scale: this.scale })
|
||||
this.canvas.height = viewport.height
|
||||
this.canvas.width = viewport.width
|
||||
|
||||
// Wait for rendering to finish
|
||||
await page.render({
|
||||
canvasContext: this.ctx,
|
||||
viewport
|
||||
}).promise
|
||||
|
||||
this.pageRendering = false
|
||||
this.showContent()
|
||||
|
||||
if (this.pageNumPending !== null) {
|
||||
// New page rendering is pending
|
||||
this.renderPage(this.pageNumPending)
|
||||
this.pageNumPending = null
|
||||
}
|
||||
// Update page counters
|
||||
this.pageNum.textContent = num
|
||||
}
|
||||
|
||||
/**
|
||||
* If another page rendering in progress, waits until the rendering is
|
||||
* finished. Otherwise, executes rendering immediately.
|
||||
*/
|
||||
queueRenderPage (num) {
|
||||
if (this.pageRendering) {
|
||||
this.pageNumPending = num
|
||||
} else {
|
||||
this.renderPage(num)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays previous page.
|
||||
*/
|
||||
handlePrevPage () {
|
||||
if (this.pageNum <= 1) {
|
||||
return
|
||||
}
|
||||
this.pageNum--
|
||||
this.queueRenderPage(this.pageNum)
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays next page.
|
||||
*/
|
||||
handleNextPage () {
|
||||
if (this.pageNum >= this.pdfDoc.numPages) {
|
||||
return
|
||||
}
|
||||
this.pageNum++
|
||||
this.queueRenderPage(this.pageNum)
|
||||
}
|
||||
}
|
||||
|
||||
insertScript('pdfjs', PDFJS_BUNDLE, () => {
|
||||
window.pdfjsLib.GlobalWorkerOptions.workerSrc = WORKER_BUNDLE
|
||||
Array.from(document.getElementsByClassName('pdf-viewer')).forEach(el => new PDFViewer(el))
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue