From 17bcedd4cbbbb52b4d6a44605ca32aaa3bf32b0e Mon Sep 17 00:00:00 2001 From: Robert Gersak Date: Fri, 25 Sep 2026 14:29:58 +0200 Subject: [PATCH] There is a difference between element ns and children ns that get-ns doesn't cover --- src/replicant/core.cljc | 22 +++++++++++++++------- test/replicant/core_test.cljc | 16 ++++++++++++++++ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/replicant/core.cljc b/src/replicant/core.cljc index 8dc848b..c58bd47 100644 --- a/src/replicant/core.cljc +++ b/src/replicant/core.cljc @@ -598,11 +598,19 @@ :data-replicant-sexp (pr-str (hiccup/sexp headers))}] (get-hiccup-headers nil))))))))) -(defn get-ns [headers] +(defn element-ns + "The namespace the element described by `headers` is created in." + [headers] + (or (hiccup/html-ns headers) + (when (= "svg" (hiccup/tag-name headers)) + "http://www.w3.org/2000/svg"))) + +(defn children-ns + "The namespace the children of `headers` inherit. `foreignObject` is an SVG + element whose children are HTML, so it's the one place the two differ." + [headers] (when-not (= "foreignObject" (hiccup/tag-name headers)) - (or (hiccup/html-ns headers) - (when (= "svg" (hiccup/tag-name headers)) - "http://www.w3.org/2000/svg")))) + (element-ns headers))) (defn create-node "Create DOM node according to virtual DOM in `headers`. Register relevant @@ -627,12 +635,12 @@ [child-node vdom])) (let [tag-name (hiccup/tag-name headers) - ns (get-ns headers) + ns (element-ns headers) node (r/create-element renderer tag-name (when ns {:ns ns})) [attrs mounting-attrs] (get-mounting-attrs headers) _ (set-attributes renderer node (or mounting-attrs attrs)) [children ks n-children] - (->> (get-children headers ns) + (->> (get-children headers (children-ns headers)) (reduce (fn [[children ks n] child-headers] (if child-headers (let [[child-node vdom] (create-node impl child-headers) @@ -940,7 +948,7 @@ attrs-changed? (reconcile-attributes renderer child attrs vdom-attrs) [new-children new-ks inner-html?] (if (:innerHTML (hiccup/attrs headers)) [nil nil true] - (get-children-ks headers (get-ns headers))) + (get-children-ks headers (children-ns headers))) [old-children old-ks old-nc] (cond (:contenteditable vdom-attrs) diff --git a/test/replicant/core_test.cljc b/test/replicant/core_test.cljc index e38bf59..fcfa172 100644 --- a/test/replicant/core_test.cljc +++ b/test/replicant/core_test.cljc @@ -327,6 +327,22 @@ first) [:create-element "g" "http://www.w3.org/2000/svg"]))) + (testing "Creates foreignObject itself in the SVG namespace" + (is (= (-> (h/render [:svg [:foreignObject [:div "Hello World"]]]) + h/get-mutation-log-events + h/summarize + (nth 1)) + [:create-element "foreignObject" "http://www.w3.org/2000/svg"]))) + + (testing "Creates foreignObject added during reconcile in the SVG namespace" + (is (= (->> (-> (h/render [:svg [:g]]) + (h/render [:svg [:g] [:foreignObject [:div "Hello World"]]]) + h/get-mutation-log-events + h/summarize) + (filter (comp #{:create-element} first))) + [[:create-element "foreignObject" "http://www.w3.org/2000/svg"] + [:create-element "div"]]))) + (testing "Does not force SVG namespace on foreignObject child nodes" (is (= (-> (h/render [:svg [:foreignObject [:div "Hello World"]]]) h/get-mutation-log-events