Files
logseq/src/main/frontend/extensions/pdf/utils.cljs
2021-07-21 17:43:41 +08:00

136 lines
4.2 KiB
Clojure

(ns frontend.extensions.pdf.utils
(:require [promesa.core :as p]
[cljs-bean.core :as bean]
[frontend.util :as front-utils]
["/frontend/extensions/pdf/utils" :as js-utils]
[frontend.loader :refer [load]]))
(defonce MAX-SCALE 5.0)
(defonce MIN-SCALE 0.25)
(defonce DELTA_SCALE 1.1)
(defn get-bounding-rect
[rects]
(bean/->clj (js-utils/getBoundingRect (bean/->js rects))))
(defn viewport-to-scaled
[bounding ^js viewport]
(bean/->clj (js-utils/viewportToScaled (bean/->js bounding) viewport)))
(defn scaled-to-viewport
[bounding ^js viewport]
(bean/->clj (js-utils/scaledToViewport (bean/->js bounding) viewport)))
(defn vw-to-scaled-pos
[^js viewer {:keys [page bounding rects]}]
(when-let [^js viewport (.. viewer (getPageView (dec page)) -viewport)]
{:bounding (viewport-to-scaled bounding viewport)
:rects (for [rect rects] (viewport-to-scaled rect viewport))
:page page}))
(defn scaled-to-vw-pos
[^js viewer {:keys [page bounding rects]}]
(when-let [^js viewport (.. viewer (getPageView (dec page)) -viewport)]
{:bounding (scaled-to-viewport bounding viewport)
:rects (for [rect rects] (scaled-to-viewport rect viewport))
:page page}))
(defn get-page-bounding
[^js viewer page-number]
(when-let [^js el (and page-number (.. viewer (getPageView (dec page-number)) -div))]
(bean/->clj (.toJSON (.getBoundingClientRect el)))))
(defn resolve-hls-layer!
[^js viewer page]
(when-let [^js text-layer (.. viewer (getPageView (dec page)) -textLayer)]
(let [cnt (.-textLayerDiv text-layer)
cls "extensions__pdf-hls-layer"
doc js/document
layer (.querySelector cnt (str "." cls))]
(if-not layer
(let [layer (.createElement doc "div")]
(set! (. layer -className) cls)
(.appendChild cnt layer)
layer)
layer))))
(defn scroll-to-highlight
[^js viewer hl]
(when-let [js-hl (bean/->js hl)]
(js-utils/scrollToHighlight viewer js-hl)))
(defn zoom-in-viewer
[^js viewer]
(let [cur-scale (.-currentScale viewer)]
(when (< cur-scale MAX-SCALE)
(let [new-scale (.toFixed (* cur-scale DELTA_SCALE) 2)
new-scale (/ (js/Math.ceil (* new-scale 10)) 10)
new-scale (min MAX-SCALE new-scale)]
(set! (.-currentScale viewer) new-scale)))))
(defn zoom-out-viewer
[^js viewer]
(let [cur-scale (.-currentScale viewer)]
(when (> cur-scale MIN-SCALE)
(let [new-scale (.toFixed (/ cur-scale DELTA_SCALE) 2)
new-scale (/ (js/Math.floor (* new-scale 10)) 10)
new-scale (max MIN-SCALE new-scale)]
(set! (.-currentScale viewer) new-scale)))))
(defn clear-all-selection
[]
(.removeAllRanges (js/window.getSelection)))
(def adjust-viewer-size!
(front-utils/debounce
200 (fn [^js viewer] (set! (. viewer -currentScaleValue) "auto"))))
(defn fix-nested-js
[its]
(when (sequential? its)
(mapv #(if (map? %) % (bean/->clj %)) its)))
(defn gen-id []
(str (.toString (js/Date.now) 36)
(.. (js/Math.random) (toString 36) (substr 2 4))))
(defn js-load$
[url]
(p/create
(fn [resolve]
(load url resolve))))
(def PDFJS_ROOT
(if (= js/location.protocol "file:")
"./js"
"./static/js"))
(defn load-base-assets$
[]
(p/let [_ (js-load$ (str PDFJS_ROOT "/pdfjs/pdf.js"))
_ (js-load$ (str PDFJS_ROOT "/pdfjs/pdf_viewer.js"))]))
(defn get-page-from-el
[^js/HTMLElement el]
(when-let [^js page-el (and el (.closest el ".page"))]
{:page-number (.. page-el -dataset -pageNumber)
:page-el page-el}))
(defn get-page-from-range
[^js/Range r]
(when-let [parent-el (and r (.. r -startContainer -parentElement))]
(get-page-from-el parent-el)))
(defn get-range-rects<-page-cnt
[^js/Range r ^js page-cnt]
(let [rge-rects (js->clj (.getClientRects r))
^js cnt-offset (.getBoundingClientRect page-cnt)]
(if (seq rge-rects)
(for [rect rge-rects]
{:top (- (+ (.-top rect) (.-scrollTop page-cnt)) (.-top cnt-offset))
:left (- (+ (.-left rect) (.-scrollLeft page-cnt)) (.-left cnt-offset))
:width (.-width rect)
:height (.-height rect)}))))