| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- (ns frontend.extensions.pdf.utils
- (:require ["/frontend/extensions/pdf/utils" :as js-utils]
- [cljs-bean.core :as bean]
- [clojure.string :as string]
- [frontend.util :as util]
- [logseq.common.uuid :as common-uuid]
- [promesa.core :as p]))
- (defonce MAX-SCALE 5.0)
- (defonce MIN-SCALE 0.25)
- (defonce DELTA_SCALE 1.05)
- (defn hls-file?
- [filename]
- (and filename (string? filename) (string/starts-with? filename "hls__")))
- (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 optimize-client-reacts
- [rects]
- (when (seq rects)
- (bean/->clj (js-utils/optimizeClientRects (bean/->js rects)))))
- (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 (.-div 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 get-meta-data$
- [^js viewer]
- (when-let [^js doc (and viewer (.-pdfDocument viewer))]
- (p/create
- (fn [resolve]
- (p/catch
- (p/then (.getMetadata doc)
- (fn [^js r]
- (js/console.debug "[metadata] " r)
- (when-let [^js info (and r (.-info r))]
- (resolve (bean/->clj info)))))
- (fn [e]
- (resolve nil)
- (js/console.error e)))))))
- (defn clear-all-selection
- ([] (clear-all-selection js/window))
- ([^js win]
- (some-> win (.getSelection) (.removeAllRanges))))
- (def adjust-viewer-size!
- (util/debounce
- (fn [^js viewer] (set! (. viewer -currentScaleValue) "auto"))
- 200))
- (defn fix-nested-js
- [its]
- (when (sequential? its)
- (mapv #(if (map? %) % (bean/->clj %)) its)))
- (defn gen-uuid
- []
- (common-uuid/gen-uuid))
- (defn load-base-assets$
- []
- (p/let [_ (util/js-load$ (str util/JS_ROOT "/pdfjs/pdf.js"))
- _ (util/js-load$ (str util/JS_ROOT "/pdf_viewer2.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 (bean/->clj (.getClientRects r))
- ^js cnt-offset (.getBoundingClientRect page-cnt)]
- (when (seq rge-rects)
- (let [rects (for [rect rge-rects
- :when (and rect (not (zero? (.-width rect))) (not (zero? (.-height rect))))]
- {:top (- (+ (.-top rect) (.-scrollTop page-cnt)) (.-top cnt-offset))
- :left (- (+ (.-left rect) (.-scrollLeft page-cnt)) (.-left cnt-offset))
- :width (.-width rect)
- :height (.-height rect)})]
- (optimize-client-reacts rects)))))
- (defn fix-selection-text-breakline
- [text]
- (when-not (string/blank? text)
- (let [sp "|#|"]
- (-> text
- (string/replace #"[\r\n]+" sp)
- (string/replace (str "-" sp) "")
- (string/replace #"\|#\|([a-zA-Z_])" " $1")
- (string/replace sp "")))))
- (defn fix-local-asset-pagename
- [filename]
- (if (and (string? filename) (not (string/blank? filename)))
- (let [local-asset? (re-find #"[0-9]{13}_\d$" filename)
- hls? (hls-file? filename)
- len (count filename)]
- (if (or local-asset? hls?)
- (-> filename
- (subs 0 (if local-asset? (- len 15) len))
- (string/replace #"^hls__" "")
- (string/replace #"__[-\d]+$" "")
- (string/replace "_" " ")
- (string/trimr))
- filename))
- filename))
- ;; TODO: which viewer instance?
- (defn next-page
- []
- (try
- (js-invoke js/window.lsActivePdfViewer "nextPage")
- (catch :default _e nil)))
- (defn prev-page
- []
- (try
- (js-invoke js/window.lsActivePdfViewer "previousPage")
- (catch :default _e nil)))
- (defn open-finder
- []
- (try
- (when-let [^js el (js/document.querySelector ".extensions__pdf-toolbar a[title=Search]")]
- (.click el))
- (catch js/Error _e nil)))
- (comment
- (fix-selection-text-breakline "this is a\ntest paragraph")
- (fix-selection-text-breakline "he is 1\n8 years old")
- (fix-selection-text-breakline "这是一个\n\n段落")
- (fix-selection-text-breakline "これ\n\nは、段落")
- (fix-selection-text-breakline "this is a te-\nst paragraph"))
|