utils.cljs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. (ns frontend.extensions.pdf.utils
  2. (:require ["/frontend/extensions/pdf/utils" :as js-utils]
  3. [cljs-bean.core :as bean]
  4. [clojure.string :as string]
  5. [frontend.util :as util]
  6. [logseq.common.uuid :as common-uuid]
  7. [promesa.core :as p]))
  8. (defonce MAX-SCALE 5.0)
  9. (defonce MIN-SCALE 0.25)
  10. (defonce DELTA_SCALE 1.05)
  11. (defn hls-file?
  12. [filename]
  13. (and filename (string? filename) (string/starts-with? filename "hls__")))
  14. (defn get-bounding-rect
  15. [rects]
  16. (bean/->clj (js-utils/getBoundingRect (bean/->js rects))))
  17. (defn viewport-to-scaled
  18. [bounding ^js viewport]
  19. (bean/->clj (js-utils/viewportToScaled (bean/->js bounding) viewport)))
  20. (defn scaled-to-viewport
  21. [bounding ^js viewport]
  22. (bean/->clj (js-utils/scaledToViewport (bean/->js bounding) viewport)))
  23. (defn optimize-client-reacts
  24. [rects]
  25. (when (seq rects)
  26. (bean/->clj (js-utils/optimizeClientRects (bean/->js rects)))))
  27. (defn vw-to-scaled-pos
  28. [^js viewer {:keys [page bounding rects]}]
  29. (when-let [^js viewport (.. viewer (getPageView (dec page)) -viewport)]
  30. {:bounding (viewport-to-scaled bounding viewport)
  31. :rects (for [rect rects] (viewport-to-scaled rect viewport))
  32. :page page}))
  33. (defn scaled-to-vw-pos
  34. [^js viewer {:keys [page bounding rects]}]
  35. (when-let [^js viewport (.. viewer (getPageView (dec page)) -viewport)]
  36. {:bounding (scaled-to-viewport bounding viewport)
  37. :rects (for [rect rects] (scaled-to-viewport rect viewport))
  38. :page page}))
  39. (defn get-page-bounding
  40. [^js viewer page-number]
  41. (when-let [^js el (and page-number (.. viewer (getPageView (dec page-number)) -div))]
  42. (bean/->clj (.toJSON (.getBoundingClientRect el)))))
  43. (defn resolve-hls-layer!
  44. [^js viewer page]
  45. (when-let [^js text-layer (.. viewer (getPageView (dec page)) -textLayer)]
  46. (let [cnt (.-div text-layer)
  47. cls "extensions__pdf-hls-layer"
  48. doc js/document
  49. layer (.querySelector cnt (str "." cls))]
  50. (if-not layer
  51. (let [layer (.createElement doc "div")]
  52. (set! (. layer -className) cls)
  53. (.appendChild cnt layer)
  54. layer)
  55. layer))))
  56. (defn scroll-to-highlight
  57. [^js viewer hl]
  58. (when-let [js-hl (bean/->js hl)]
  59. (js-utils/scrollToHighlight viewer js-hl)))
  60. (defn zoom-in-viewer
  61. [^js viewer]
  62. (let [cur-scale (.-currentScale viewer)]
  63. (when (< cur-scale MAX-SCALE)
  64. (let [new-scale (.toFixed (* cur-scale DELTA_SCALE) 2)
  65. new-scale (/ (js/Math.ceil (* new-scale 10)) 10)
  66. new-scale (min MAX-SCALE new-scale)]
  67. (set! (.-currentScale viewer) new-scale)))))
  68. (defn zoom-out-viewer
  69. [^js viewer]
  70. (let [cur-scale (.-currentScale viewer)]
  71. (when (> cur-scale MIN-SCALE)
  72. (let [new-scale (.toFixed (/ cur-scale DELTA_SCALE) 2)
  73. new-scale (/ (js/Math.floor (* new-scale 10)) 10)
  74. new-scale (max MIN-SCALE new-scale)]
  75. (set! (.-currentScale viewer) new-scale)))))
  76. (defn get-meta-data$
  77. [^js viewer]
  78. (when-let [^js doc (and viewer (.-pdfDocument viewer))]
  79. (p/create
  80. (fn [resolve]
  81. (p/catch
  82. (p/then (.getMetadata doc)
  83. (fn [^js r]
  84. (js/console.debug "[metadata] " r)
  85. (when-let [^js info (and r (.-info r))]
  86. (resolve (bean/->clj info)))))
  87. (fn [e]
  88. (resolve nil)
  89. (js/console.error e)))))))
  90. (defn clear-all-selection
  91. ([] (clear-all-selection js/window))
  92. ([^js win]
  93. (some-> win (.getSelection) (.removeAllRanges))))
  94. (def adjust-viewer-size!
  95. (util/debounce
  96. (fn [^js viewer] (set! (. viewer -currentScaleValue) "auto"))
  97. 200))
  98. (defn fix-nested-js
  99. [its]
  100. (when (sequential? its)
  101. (mapv #(if (map? %) % (bean/->clj %)) its)))
  102. (defn gen-uuid
  103. []
  104. (common-uuid/gen-uuid))
  105. (defn load-base-assets$
  106. []
  107. (p/let [_ (util/js-load$ (str util/JS_ROOT "/pdfjs/pdf.js"))
  108. _ (util/js-load$ (str util/JS_ROOT "/pdf_viewer2.js"))]))
  109. (defn get-page-from-el
  110. [^js/HTMLElement el]
  111. (when-let [^js page-el (and el (.closest el ".page"))]
  112. {:page-number (.. page-el -dataset -pageNumber)
  113. :page-el page-el}))
  114. (defn get-page-from-range
  115. [^js/Range r]
  116. (when-let [parent-el (and r (.. r -startContainer -parentElement))]
  117. (get-page-from-el parent-el)))
  118. (defn get-range-rects<-page-cnt
  119. [^js/Range r ^js page-cnt]
  120. (let [rge-rects (bean/->clj (.getClientRects r))
  121. ^js cnt-offset (.getBoundingClientRect page-cnt)]
  122. (when (seq rge-rects)
  123. (let [rects (for [rect rge-rects
  124. :when (and rect (not (zero? (.-width rect))) (not (zero? (.-height rect))))]
  125. {:top (- (+ (.-top rect) (.-scrollTop page-cnt)) (.-top cnt-offset))
  126. :left (- (+ (.-left rect) (.-scrollLeft page-cnt)) (.-left cnt-offset))
  127. :width (.-width rect)
  128. :height (.-height rect)})]
  129. (optimize-client-reacts rects)))))
  130. (defn fix-selection-text-breakline
  131. [text]
  132. (when-not (string/blank? text)
  133. (let [sp "|#|"]
  134. (-> text
  135. (string/replace #"[\r\n]+" sp)
  136. (string/replace (str "-" sp) "")
  137. (string/replace #"\|#\|([a-zA-Z_])" " $1")
  138. (string/replace sp "")))))
  139. (defn fix-local-asset-pagename
  140. [filename]
  141. (if (and (string? filename) (not (string/blank? filename)))
  142. (let [local-asset? (re-find #"[0-9]{13}_\d$" filename)
  143. hls? (hls-file? filename)
  144. len (count filename)]
  145. (if (or local-asset? hls?)
  146. (-> filename
  147. (subs 0 (if local-asset? (- len 15) len))
  148. (string/replace #"^hls__" "")
  149. (string/replace #"__[-\d]+$" "")
  150. (string/replace "_" " ")
  151. (string/trimr))
  152. filename))
  153. filename))
  154. ;; TODO: which viewer instance?
  155. (defn next-page
  156. []
  157. (try
  158. (js-invoke js/window.lsActivePdfViewer "nextPage")
  159. (catch :default _e nil)))
  160. (defn prev-page
  161. []
  162. (try
  163. (js-invoke js/window.lsActivePdfViewer "previousPage")
  164. (catch :default _e nil)))
  165. (defn open-finder
  166. []
  167. (try
  168. (when-let [^js el (js/document.querySelector ".extensions__pdf-toolbar a[title=Search]")]
  169. (.click el))
  170. (catch js/Error _e nil)))
  171. (comment
  172. (fix-selection-text-breakline "this is a\ntest paragraph")
  173. (fix-selection-text-breakline "he is 1\n8 years old")
  174. (fix-selection-text-breakline "这是一个\n\n段落")
  175. (fix-selection-text-breakline "これ\n\nは、段落")
  176. (fix-selection-text-breakline "this is a te-\nst paragraph"))