summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAsko Nõmm <asko@nmm.ee>2025-09-14 14:51:29 +0300
committerAsko Nõmm <asko@nmm.ee>2025-09-14 14:51:29 +0300
commited2cf33c61816d6dd41cd2133ebcf0aa62a28e01 (patch)
treec55b0d7a05c937818e9917875f04e358d0b387e2
parent37b555f71ea6ebaea9ff183f186abc46cf9b1a67 (diff)
Fix issue where a text node coordinate would not be created if it's the only node in text.
-rw-r--r--src/dompa/coordinates.cljc77
-rw-r--r--test/dompa/coordinates_test.cljc7
2 files changed, 48 insertions, 36 deletions
diff --git a/src/dompa/coordinates.cljc b/src/dompa/coordinates.cljc
index 327f184..8610b8b 100644
--- a/src/dompa/coordinates.cljc
+++ b/src/dompa/coordinates.cljc
@@ -1,39 +1,48 @@
(ns dompa.coordinates
(:require [clojure.string :as str]))
-(defn- compose-reducer
- [{:keys [char-type start-idx coordinates] :as state} [idx c]]
- (cond
- ; we're undecided what to do next,
- ; so we figure it out here
- (nil? char-type)
- {:char-type (if (some #{c} "<>") :tag :text)
- :start-idx idx
- :coordinates coordinates}
-
- ; text ended, tag begins, which means we can
- ; record text node coordinates
- (and (= :text char-type)
- (= \< c))
- {:char-type :tag
- :start-idx idx
- :coordinates (conj coordinates [start-idx (dec idx)])}
-
- ; otherwise don't record anything, just note
- ; the start of a tag
- (and (not= :text char-type)
- (= \< c))
- {:char-type :tag
- :start-idx idx
- :coordinates coordinates}
-
- ; tag ended, record tag node coordinates
- (= \> c)
- {:char-type nil
- :start-idx idx
- :coordinates (conj coordinates [start-idx idx])}
-
- :else state))
+(defn- compose-reducer-fn
+ [total-char-count]
+ (fn [{:keys [char-type start-idx coordinates] :as state} [idx c]]
+ (cond
+ ; we're undecided what to do next,
+ ; so we figure it out here
+ (nil? char-type)
+ {:char-type (if (some #{c} "<>") :tag :text)
+ :start-idx idx
+ :coordinates coordinates}
+
+ ; text ended, tag begins, which means we can
+ ; record text node coordinates
+ (and (= :text char-type)
+ (= \< c))
+ {:char-type :tag
+ :start-idx idx
+ :coordinates (conj coordinates [start-idx (dec idx)])}
+
+ ; text ended by HTML ending, record text node
+ ; coordinates
+ (and (= :text char-type)
+ (= (dec total-char-count) idx))
+ {:char-type nil
+ :start-idx idx
+ :coordinates (conj coordinates [start-idx idx])}
+
+ ; otherwise don't record anything, just note
+ ; the start of a tag
+ (and (not= :text char-type)
+ (= \< c))
+ {:char-type :tag
+ :start-idx idx
+ :coordinates coordinates}
+
+ ; tag ended, record tag node coordinates
+ (= \> c)
+ {:char-type nil
+ :start-idx idx
+ :coordinates (conj coordinates [start-idx idx])}
+
+ :else state)))
(defn compose
"Composes a given `html` string into a vector of coordinates.
@@ -52,7 +61,7 @@
:start-idx 0
:coordinates []}
indexed-html (map-indexed vector html)]
- (-> compose-reducer
+ (-> (compose-reducer-fn (count indexed-html))
(reduce default-state indexed-html)
:coordinates)))
diff --git a/test/dompa/coordinates_test.cljc b/test/dompa/coordinates_test.cljc
index efa6df5..42543b4 100644
--- a/test/dompa/coordinates_test.cljc
+++ b/test/dompa/coordinates_test.cljc
@@ -7,8 +7,11 @@
(is (= [[0 4] [5 9] [10 15]] (coordinates/compose "<div>hello</div>"))))
(testing "Create first-pass coordinates with invalid HTML"
- (is (= [[0 4]] (coordinates/compose "<div>hello")))
+ (is (= [[0 4] [5 9]] (coordinates/compose "<div>hello")))
(is (= [] (coordinates/compose "<div"))))
(testing "Create first-pass coordinates with just text"
- (is (= [[0 4]] (coordinates/compose "hello"))))) \ No newline at end of file
+ (is (= [[0 4]] (coordinates/compose "hello"))))
+
+ (testing "Create first-pass coordinates with text starting"
+ (is (= [[0 4] [5 9] [10 15]] (coordinates/compose "hello<div></div>"))))) \ No newline at end of file