🐛 Fix MCP media uploads and SVG data URI image parsing (#9201)

* 🐛 Fix MCP media uploads and SVG data URI image parsing

Signed-off-by: Clayton <claytonlin1110@gmail.com>

* 🐛 Fix lint

Signed-off-by: Clayton <claytonlin1110@gmail.com>

* 🐛 Fix test

Signed-off-by: Clayton <claytonlin1110@gmail.com>

---------

Signed-off-by: Clayton <claytonlin1110@gmail.com>
This commit is contained in:
Clayton 2026-05-04 06:33:58 -05:00 committed by GitHub
parent a2bcbe81dd
commit 4ce56e96fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 69 additions and 12 deletions

View File

@ -284,7 +284,23 @@
{:file-id file-id
:local? false
:name name
:blobs [(js/Blob. #js [data] #js {:type mime-type})]
:blobs [(js/Blob.
#js [(cond
(instance? js/Uint8Array data)
data
(instance? js/ArrayBuffer data)
(js/Uint8Array. data)
(array? data)
(js/Uint8Array.from data)
(and (some? data) (= (type data) js/Object))
(js/Uint8Array.from (js/Object.values data))
:else
data)]
#js {:type mime-type})]
:on-image identity
:on-svg identity})
(rx/take 1)

View File

@ -97,17 +97,22 @@
(defn data-uri->blob
[data-uri]
(let [[mtype b64-data] (str/split data-uri ";base64," 2)
mtype (subs mtype (inc (str/index-of mtype ":")))
decoded (.atob js/window b64-data)
size (.-length ^js decoded)
content (js/Uint8Array. size)]
(loop [i 0]
(when (< i size)
(aset content i (.charCodeAt ^js decoded i))
(recur (inc i))))
(let [[meta data] (str/split data-uri "," 2)
mtype-end (or (str/index-of meta ";") (count meta))
mtype (subs meta (inc (str/index-of meta ":")) mtype-end)
base64? (str/includes? meta ";base64")
content (if base64?
(let [decoded (.atob js/globalThis data)
size (.-length ^js decoded)
bytes (js/Uint8Array. size)]
(loop [i 0]
(when (< i size)
(aset bytes i (.charCodeAt ^js decoded i))
(recur (inc i))))
bytes)
;; Data URIs can be plain/URL-encoded (e.g. ;utf8,<svg...>).
;; Encode into UTF-8 bytes before creating the Blob.
(.encode (js/TextEncoder.) (.decodeURIComponent js/globalThis data)))]
(create-blob content mtype)))
(defn get-current-selected-text

View File

@ -34,6 +34,7 @@
[frontend-tests.util-object-test]
[frontend-tests.util-range-tree-test]
[frontend-tests.util-simple-math-test]
[frontend-tests.util-webapi-test]
[frontend-tests.worker-snap-test]))
(enable-console-print!)
@ -79,4 +80,5 @@
'frontend-tests.util-object-test
'frontend-tests.util-range-tree-test
'frontend-tests.util-simple-math-test
'frontend-tests.util-webapi-test
'frontend-tests.worker-snap-test))

View File

@ -0,0 +1,34 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns frontend-tests.util-webapi-test
(:require
[app.util.webapi :as wapi]
[cljs.test :as t :include-macros true]))
(t/deftest data-uri->blob-supports-base64
(t/async done
(let [blob (wapi/data-uri->blob "data:text/plain;base64,SGVsbG8=")]
(-> (.text blob)
(.then (fn [text]
(t/is (= "text/plain" (.-type blob)))
(t/is (= "Hello" text))
(done)))
(.catch (fn [err]
(t/is false (str "unexpected error: " err))
(done)))))))
(t/deftest data-uri->blob-supports-utf8-data
(t/async done
(let [blob (wapi/data-uri->blob "data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3C%2Fsvg%3E")]
(-> (.text blob)
(.then (fn [text]
(t/is (= "image/svg+xml" (.-type blob)))
(t/is (= "<svg xmlns=\"http://www.w3.org/2000/svg\"></svg>" text))
(done)))
(.catch (fn [err]
(t/is false (str "unexpected error: " err))
(done)))))))