Skip to content

Commit 57f074a

Browse files
committed
Add highlight-words to several viewers
- Only highlight words when visible
1 parent 066929b commit 57f074a

File tree

6 files changed

+89
-52
lines changed

6 files changed

+89
-52
lines changed

src/portal/ui/html.cljs

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
(ns portal.ui.html
2+
(:require [clojure.string :as str]
3+
[portal.ui.inspector :as ins]))
4+
5+
(defn- ->style [string]
6+
(persistent!
7+
(reduce
8+
(fn [style rule]
9+
(let [[k v] (str/split rule #":")]
10+
(assoc! style (keyword (str/trim k)) (str/trim v))))
11+
(transient {})
12+
(str/split string #";"))))
13+
14+
(defn- dom->hiccup [opts ^js el]
15+
(let [{:keys [text-handler]} opts]
16+
(case (.-nodeType el)
17+
3 (cond-> (.-wholeText el)
18+
text-handler
19+
text-handler)
20+
1 (let [attrs (.-attributes el)]
21+
(into
22+
[(keyword (str/lower-case (.-tagName el)))
23+
(persistent!
24+
(reduce
25+
(fn [attrs ^js attr]
26+
(let [k (keyword (.-name attr))]
27+
(assoc! attrs k
28+
(case k
29+
:style (->style (.-value attr))
30+
(.-value attr)))))
31+
(transient {})
32+
attrs))]
33+
(map (partial dom->hiccup opts))
34+
(.-childNodes el))))))
35+
36+
(defn- parse-dom [string]
37+
(-> (js/DOMParser.)
38+
(.parseFromString string "text/html")
39+
(.getElementsByTagName "body")
40+
(aget 0)
41+
(.-childNodes)))
42+
43+
(defn parse-html
44+
([html]
45+
(parse-html html nil))
46+
([html opts]
47+
(into [:<>]
48+
(map (partial dom->hiccup opts))
49+
(parse-dom html))))
50+
51+
(def ^:private opts
52+
{:text-handler
53+
(fn [text] [ins/highlight-words text])})
54+
55+
(defn html+ [html] (parse-html html opts))

src/portal/ui/inspector.cljs

+11-1
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@
311311
(defn get-background2 []
312312
(get-background (update (use-context) :alt-bg not)))
313313

314-
(defn highlight-words [string]
314+
(defn- highlight-words* [string]
315315
(let [theme (theme/use-theme)
316316
state (state/use-state)
317317
search-words (use-search-words)
@@ -336,6 +336,16 @@
336336
{:default-take 5}]
337337
string)))
338338

339+
(defn highlight-words [string]
340+
(let [[sensor visible?] (l/use-visible)]
341+
(if visible?
342+
[highlight-words* string]
343+
[s/span
344+
{:style {:position :relative}}
345+
string
346+
[s/div {:style {:position :absolute :top 0 :left 0}}
347+
sensor]])))
348+
339349
(defn- ->id [value]
340350
(str (hash value) (pr-str (type value))))
341351

src/portal/ui/lazy.cljs

+7-1
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,17 @@
5757
#(.removeEventListener ^js container "scroll" on-scroll))))
5858
[:div {:ref ref :style {:height "1em" :width "1em"}}]))
5959

60-
(defn visible-sensor [f]
60+
(defn- visible-sensor [f]
6161
(if (exists? js/IntersectionObserver)
6262
[observer-visible-sensor f]
6363
[fallback-visible-sensor f]))
6464

65+
(defn use-visible []
66+
(let [[visible? set-visible!] (react/useState false)]
67+
[(when-not visible?
68+
[visible-sensor #(set-visible! true)])
69+
visible?]))
70+
6571
(defn lazy-seq [_coll opts]
6672
(let [{:keys [default-take step]
6773
:or {default-take 0 step 10}} opts

src/portal/ui/viewer/code.cljs

+8-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
(:require ["highlight.js" :as hljs]
33
[clojure.string :as str]
44
[portal.colors :as c]
5+
[portal.ui.html :as h]
56
[portal.ui.inspector :as ins]
67
[portal.ui.styled :as s]
78
[portal.ui.theme :as theme]))
@@ -108,11 +109,11 @@
108109
:line-height "1rem"
109110
:color (::c/text theme)
110111
:font-size (:font-size theme)
111-
:font-family (:font-family theme)}
112-
:dangerouslySetInnerHTML
113-
{:__html (-> string-value
114-
(hljs/highlight #js {:language "clojure"})
115-
.-value)}}]))
112+
:font-family (:font-family theme)}}
113+
[h/html+
114+
(-> string-value
115+
(hljs/highlight #js {:language "clojure"})
116+
.-value)]]))
116117

117118
(defn inspect-pr-str [value] [highlight-clj (pr-str value)])
118119

@@ -164,8 +165,8 @@
164165
:width :fit-content
165166
:color (::c/text theme)
166167
:font-family (:font-family theme)
167-
:font-size (:font-size theme)}
168-
:dangerouslySetInnerHTML {:__html html}}]])))
168+
:font-size (:font-size theme)}}
169+
[h/html+ html]]])))
169170

170171
(def viewer
171172
{:predicate string?

src/portal/ui/viewer/markdown.cljs

+3-40
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
(:require ["marked" :refer [marked]]
33
[clojure.string :as str]
44
[portal.colors :as c]
5+
[portal.ui.html :as h]
56
[portal.ui.icons :as icons]
67
[portal.ui.inspector :as ins]
78
[portal.ui.lazy :as l]
@@ -26,44 +27,6 @@
2627
(defn- ->text [^js token]
2728
(unescape (.-text token)))
2829

29-
(defn- ->style [string]
30-
(persistent!
31-
(reduce
32-
(fn [style rule]
33-
(let [[k v] (str/split rule #":")]
34-
(assoc! style (keyword (str/trim k)) (str/trim v))))
35-
(transient {})
36-
(str/split string #";"))))
37-
38-
(defn- dom->hiccup [^js el]
39-
(case (.-nodeType el)
40-
3 (.-wholeText el)
41-
1 (let [attrs (.-attributes el)]
42-
(into
43-
[(keyword (str/lower-case (.-tagName el)))
44-
(persistent!
45-
(reduce
46-
(fn [attrs ^js attr]
47-
(let [k (keyword (.-name attr))]
48-
(assoc! attrs k
49-
(case k
50-
:style (->style (.-value attr))
51-
(.-value attr)))))
52-
(transient {})
53-
attrs))]
54-
(map dom->hiccup)
55-
(.-childNodes el)))))
56-
57-
(defn- parse-dom [string]
58-
(-> (js/DOMParser.)
59-
(.parseFromString string "text/html")
60-
(.getElementsByTagName "body")
61-
(aget 0)
62-
(.-childNodes)))
63-
64-
(defn- parse-html [html]
65-
(into [:<>] (map dom->hiccup) (parse-dom html)))
66-
6730
(defn- absolute-link? [href]
6831
(or (str/starts-with? href "http")
6932
(str/starts-with? href "https")))
@@ -182,7 +145,7 @@
182145
(fn [out ^js token]
183146
(case (.-type token)
184147
"escape" (conj out (->text token))
185-
"html" (conj out (parse-html (.-text token)))
148+
"html" (conj out (h/parse-html (.-text token)))
186149
"link" (conj out (->link token))
187150
"image" (conj out (->image token))
188151
"strong" (conj out (->strong token))
@@ -208,7 +171,7 @@
208171
"table" (conj out (->table token))
209172
"blockquote" (conj out (->blockquote token))
210173
"list" (conj out (->list token))
211-
"html" (conj out (parse-html (->text token)))
174+
"html" (conj out (h/parse-html (->text token)))
212175
"paragraph" (conj out (->paragraph token))
213176
"text" (if-let [tokens (.-tokens token)]
214177
(->inline out tokens)

src/portal/ui/viewer/prepl.cljs

+5-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
[portal.colors :as c]
55
[portal.runtime.edn :as edn]
66
[portal.ui.filter :as f]
7+
[portal.ui.html :as h]
78
[portal.ui.icons :as icons]
89
[portal.ui.inspector :as ins]
910
[portal.ui.select :as select]
@@ -210,9 +211,10 @@
210211
{:color
211212
(if (= (:tag value) :err)
212213
(::c/exception theme)
213-
(::c/text theme))}
214-
:dangerouslySetInnerHTML
215-
{:__html (anser/ansiToHtml (:val value) #js {:use_classes true})}}])
214+
(::c/text theme))}}
215+
[h/html+ (anser/ansiToHtml
216+
(:val value)
217+
#js {:use_classes true})]])
216218
{:key index})))
217219
value))]]]]))
218220

0 commit comments

Comments
 (0)