From a7b1603085e7e825e9b3334745a7537ccf4488ee Mon Sep 17 00:00:00 2001 From: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com> Date: Sun, 20 Sep 2026 12:59:28 -0700 Subject: [PATCH 01/11] feat(mobile): spike Enriched as the only markdown renderer --- .../react-native-nitro-markdown-0.5.0.tgz | Bin 180007 -> 0 bytes .../modules/t3-markdown-text/UPSTREAM.md | 2 +- apps/mobile/modules/t3-markdown-text/index.ts | 15 +- .../modules/t3-markdown-text/package.json | 6 +- .../src/NativeMarkdownBlock.tsx | 665 ---------- .../src/NativeMarkdownSelectableText.tsx | 438 ------ .../src/SelectableMarkdownText.tsx | 121 -- .../src/SelectableMarkdownText.types.ts | 26 - .../src/composerChipPresentation.ts | 87 ++ .../src/nativeMarkdownText.ts | 964 -------------- .../src/pendingCodeHighlight.test.ts | 28 - .../src/pendingCodeHighlight.ts | 19 - .../src/useHighlightedCode.test.tsx | 189 --- .../src/useHighlightedCode.ts | 149 --- apps/mobile/package.json | 7 +- .../features/files/FileMarkdownPreview.tsx | 142 +- .../src/features/threads/ThreadFeed.tsx | 618 +-------- .../src/lib/composerChipPresentation.test.ts | 85 ++ .../mobile/src/lib/nativeMarkdownText.test.ts | 1176 ----------------- .../src/native/EnrichedMarkdownText.tsx | 152 +++ .../native/SelectableMarkdownText.android.tsx | 40 - .../src/native/SelectableMarkdownText.ios.tsx | 25 - .../src/native/SelectableMarkdownText.tsx | 26 +- package.json | 5 +- ...own@1.1.0-nightly-20260918-bb2b0942a.patch | 112 ++ pnpm-lock.yaml | 50 +- pnpm-workspace.yaml | 2 + vite.config.ts | 2 +- 28 files changed, 516 insertions(+), 4635 deletions(-) delete mode 100644 apps/mobile/deps/react-native-nitro-markdown-0.5.0.tgz delete mode 100644 apps/mobile/modules/t3-markdown-text/src/NativeMarkdownBlock.tsx delete mode 100644 apps/mobile/modules/t3-markdown-text/src/NativeMarkdownSelectableText.tsx delete mode 100644 apps/mobile/modules/t3-markdown-text/src/SelectableMarkdownText.tsx create mode 100644 apps/mobile/modules/t3-markdown-text/src/composerChipPresentation.ts delete mode 100644 apps/mobile/modules/t3-markdown-text/src/nativeMarkdownText.ts delete mode 100644 apps/mobile/modules/t3-markdown-text/src/pendingCodeHighlight.test.ts delete mode 100644 apps/mobile/modules/t3-markdown-text/src/pendingCodeHighlight.ts delete mode 100644 apps/mobile/modules/t3-markdown-text/src/useHighlightedCode.test.tsx delete mode 100644 apps/mobile/modules/t3-markdown-text/src/useHighlightedCode.ts create mode 100644 apps/mobile/src/lib/composerChipPresentation.test.ts delete mode 100644 apps/mobile/src/lib/nativeMarkdownText.test.ts create mode 100644 apps/mobile/src/native/EnrichedMarkdownText.tsx delete mode 100644 apps/mobile/src/native/SelectableMarkdownText.android.tsx delete mode 100644 apps/mobile/src/native/SelectableMarkdownText.ios.tsx create mode 100644 patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch diff --git a/apps/mobile/deps/react-native-nitro-markdown-0.5.0.tgz b/apps/mobile/deps/react-native-nitro-markdown-0.5.0.tgz deleted file mode 100644 index 8fafc3896813974532ce67ef0969b487045aa8d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180007 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%0DoW8ullU@$ zL|!u|h=WPDMV1ZAojp8wbp(j$@nzEH$fEd%7o1&uz}_EBqZtD@mk$On_FwM4J3Ldg z2Z#GF^*>JzUcJ`;-os!Fk*lVXgVcJkEycS9NTD`Ts;WAT{J{Ri(^2oHs9&c@vJKG^ zkb9kFi}kH-D35wX;PvjPEt>@E%U2`WK^GD7yb*obUZ^i&0^y!)Xl%a1=5$+|C>=i? z{=+AF(|jQWtm3x@hXZ+;W&o~DMszrdvPfnesjM}kWvwM?HjO5Oi%B}X6Q%%YPX4?& zh4bK4vv_`Zy!R6xVh97lM2^YZ?sn0#<)A~@ADQHa6bEN7YUEZbKygFe(C`6Glx*;# zuj(0E%=0Fh(D;-=qpFYL?+$Mmk}Qq&W<*h1T2OcRn}%H1FaoD=uuX01ShA$DnCND$ z@&#wflkBqG)AC4J=u@B}=0T{&ukbQNmR{H62S;4`k3~~38j^IFP6oqto)lr$Iez(a zh0Nj^9i-!NZlq44WNVXO+vH=LBq469y?T(~g@+iLC_v3a38`>Za=5_8BLK)6-@tJM z-68;e77YuU0gyu~QVZb*!aNEZAj^#x5yyu7F;<*eA6sT+RDpSs(J93;k9I?V*AgdW zk`AK@;b!3rI*jJRt+`@&RY-mX={FaUy*US;#%P{lNkkwiI8nGf^fFP2uo8zrV^&2p zy1s%Yarb@@uEZL@gF65}VouZPym{eSA)yYMqW( zd*_{As}VB(dk!sj1}b@kg5~|k)z$O1PT2g5HPg~(4m4!x6ohimuo-9qK6hjH(@!)3 z_aE-Id6rRuvxR#kiW8YwT%;)((`%m8Je9M}jwfT1jBNeej&>d3b^K?8XGPu90TTAr z(g>0~}l2uv6p5wgH^oJdi8&79Pf%teNzu|F-$E({LkT@lI(mx6Lalt>k0 z)#NJw==;f38#cGzh`1Se(FRM`L;NRO}V~ zS5t^DJfSZF6Uut1nlYwT|G9L2O(RNhw%w^Qkuww=mMs?9UBADm^};n?JO^=BX}ef6 z;Hp{g_l}Rwb`OsBMO9Y;PBw|OwwNe zy#B;}@pPYAX!mzth>om(UjHK;3RvMzzF0(;q<2CQi z(OD`$UoRSGAnNoR-}*Y|DMnY^hXoA<6uqk3mJcRrno~A&e{`SX;`*Orks#|giC~}D zPlPIDJjKDFrgU*rpaQ3%07dyn7P)QwoTqaz+u{_!r~_Kqy;-14fJ)+k(N^AuZNx(i zTW^(|?j>KhEZr9ja~Y+~Pe!M+G>ftuh^vAcl8o(1UZfcvp`sQiBu}RT%*e#KHSUPB zg2NzUed(%ep*o=9%<;zC$6~-P`Gpm1;X5o{TrcXCw&wayuUdPt+_TBJjIisfpm`;Nx6zNp4jGGTD*cNCt!W4liZ z>4gzn--GJQ-^4oTX4wVq$i%<`_Eu!zU8%dNpur(PojI-n0cB5n+e4-ASl*L@bhh0$ z1H}wwH`iOY?T&wn@NN&�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

wPV^_We&X?zHTYUu+f~AMy^_J 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�-zJZg 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%0DxM&eeB0&wM%ab$&k!K$0E=wGvjPp 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�kl8G8CK}$RZ_- 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

    GSFKNfL=vbs1tX+q|JO@rvf=l^ZCpM zY8*vcV*NXo)^xH`@BaY80N2Q3QI?3;t9Ob^{}RLm&qLAy^%QlAgHxokH?gPpO+*jT z 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�H&mT1#V0S=aCN2Sl0iUS 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 extends ViewManagerWithGeneratedInterface { -+ void setEnableImageSourceResolution(T view, boolean value); -+ void setImageSourcesRevision(T view, int value); -+ void setImageSourcesContinuityStart(T view, int value); -+ void setImageSources(T view, @Nullable ReadableArray value); -+ void setDocumentRevision(T view, int value); -+ void setEnableDocumentAssets(T view, boolean value); -+ void setEnableMediaSlots(T view, boolean value); -+ void setMediaOverridesRevision(T view, int value); -+ void setMediaOverrides(T view, @Nullable ReadableArray value); -+ void setLinkRegex(T view, @Nullable ReadableMap value); -+ void setInlineCodeLinkRegex(T view, @Nullable ReadableMap value); - void setMarkdown(T view, @Nullable String value); - void setMarkdownStyle(T view, @Nullable ReadableMap value); - void setEnableImagePress(T view, boolean value); -diff --git a/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java b/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java -index 8bcb475fc2b7edbfd8407e49ad2a045aa9939419..ce923d6a17c82cbafaf11dd802b88c67cbcbdc79 100644 ---- a/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java -+++ b/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java -@@ -26,6 +26,12 @@ public class EnrichedMarkdownTextManagerDelegate extends ViewManagerWithGeneratedInterface { -+ void setLinkRegex(T view, @Nullable ReadableMap value); -+ void setInlineCodeLinkRegex(T view, @Nullable ReadableMap value); - void setMarkdown(T view, @Nullable String value); - void setMarkdownStyle(T view, @Nullable ReadableMap value); - void setEnableImagePress(T view, boolean value); -diff --git a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp -index 1b1b96234e8313e1e1fb2f033a19df84434255f0..e854371ae92d15228fb65133108ce2f4bd4c234d 100644 ---- a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp -+++ b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp -@@ -13,6 +13,55 @@ - - namespace facebook::react { - -+void EnrichedMarkdownEventEmitter::onDocumentAssets(OnDocumentAssets event) const { -+ dispatchEvent("documentAssets", [event=std::move(event)](jsi::Runtime &runtime) { -+ auto payload = jsi::Object(runtime); -+ payload.setProperty(runtime, "revision", event.revision); -+ -+ auto assets = jsi::Array(runtime, event.assets.size()); -+ size_t assetsIndex = 0; -+ for (auto assetsValue : event.assets) { -+ auto assetsObject = jsi::Object(runtime); -+ assetsObject.setProperty(runtime, "anchor", assetsValue.anchor); -+assetsObject.setProperty(runtime, "id", assetsValue.id); -+assetsObject.setProperty(runtime, "kind", assetsValue.kind); -+assetsObject.setProperty(runtime, "url", assetsValue.url); -+assetsObject.setProperty(runtime, "altText", assetsValue.altText); -+assetsObject.setProperty(runtime, "title", assetsValue.title); -+assetsObject.setProperty(runtime, "placement", assetsValue.placement); -+assetsObject.setProperty(runtime, "eligible", assetsValue.eligible); -+ assets.setValueAtIndex(runtime, assetsIndex++, assetsObject); -+ } -+ payload.setProperty(runtime, "assets", assets); -+ -+ return payload; -+ }); -+} -+ -+ -+void EnrichedMarkdownEventEmitter::onMediaLayout(OnMediaLayout event) const { -+ dispatchEvent("mediaLayout", [event=std::move(event)](jsi::Runtime &runtime) { -+ auto payload = jsi::Object(runtime); -+ payload.setProperty(runtime, "revision", event.revision); -+ -+ auto frames = jsi::Array(runtime, event.frames.size()); -+ size_t framesIndex = 0; -+ for (auto framesValue : event.frames) { -+ auto framesObject = jsi::Object(runtime); -+ framesObject.setProperty(runtime, "id", framesValue.id); -+framesObject.setProperty(runtime, "x", framesValue.x); -+framesObject.setProperty(runtime, "y", framesValue.y); -+framesObject.setProperty(runtime, "width", framesValue.width); -+framesObject.setProperty(runtime, "height", framesValue.height); -+ frames.setValueAtIndex(runtime, framesIndex++, framesObject); -+ } -+ payload.setProperty(runtime, "frames", frames); -+ -+ return payload; -+ }); -+} -+ -+ - void EnrichedMarkdownEventEmitter::onLinkPress(OnLinkPress event) const { - dispatchEvent("linkPress", [event=std::move(event)](jsi::Runtime &runtime) { - auto payload = jsi::Object(runtime); -diff --git a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h -index 3fda20ba6e4d253545401f9a4d76fabdebe4126f..0aa908394302b7753305f324d8165aaea3b24d08 100644 ---- a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h -+++ b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h -@@ -17,6 +17,35 @@ class EnrichedMarkdownEventEmitter : public ViewEventEmitter { - public: - using ViewEventEmitter::ViewEventEmitter; - -+ struct OnDocumentAssetsAssets { -+ std::string anchor; -+ std::string id; -+ std::string kind; -+ std::string url; -+ std::string altText; -+ std::string title; -+ std::string placement; -+ bool eligible; -+ }; -+ -+ struct OnDocumentAssets { -+ int revision; -+ std::vector assets; -+ }; -+ -+ struct OnMediaLayoutFrames { -+ std::string id; -+ Float x; -+ Float y; -+ Float width; -+ Float height; -+ }; -+ -+ struct OnMediaLayout { -+ int revision; -+ std::vector frames; -+ }; -+ - struct OnLinkPress { - std::string url; - }; -@@ -58,6 +87,10 @@ class EnrichedMarkdownEventEmitter : public ViewEventEmitter { - int selectionStart; - int selectionEnd; - }; -+ void onDocumentAssets(OnDocumentAssets value) const; -+ -+ void onMediaLayout(OnMediaLayout value) const; -+ - void onLinkPress(OnLinkPress value) const; - - void onLinkLongPress(OnLinkLongPress value) const; -diff --git a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp -index fe3cfc5c95ceafbdbf32ea2fbbf1cba8989157e8..5bc5b43908ad3ce0b80f061d491a75058a59872f 100644 ---- a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp -+++ b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp -@@ -19,6 +19,17 @@ EnrichedMarkdownProps::EnrichedMarkdownProps( - const EnrichedMarkdownProps &sourceProps, - const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), - -+ enableImageSourceResolution(convertRawProp(context, rawProps, "enableImageSourceResolution", sourceProps.enableImageSourceResolution, {false})), -+ imageSourcesRevision(convertRawProp(context, rawProps, "imageSourcesRevision", sourceProps.imageSourcesRevision, {-1})), -+ imageSourcesContinuityStart(convertRawProp(context, rawProps, "imageSourcesContinuityStart", sourceProps.imageSourcesContinuityStart, {1})), -+ imageSources(convertRawProp(context, rawProps, "imageSources", sourceProps.imageSources, {})), -+ documentRevision(convertRawProp(context, rawProps, "documentRevision", sourceProps.documentRevision, {0})), -+ enableDocumentAssets(convertRawProp(context, rawProps, "enableDocumentAssets", sourceProps.enableDocumentAssets, {false})), -+ enableMediaSlots(convertRawProp(context, rawProps, "enableMediaSlots", sourceProps.enableMediaSlots, {false})), -+ mediaOverridesRevision(convertRawProp(context, rawProps, "mediaOverridesRevision", sourceProps.mediaOverridesRevision, {-1})), -+ mediaOverrides(convertRawProp(context, rawProps, "mediaOverrides", sourceProps.mediaOverrides, {})), -+ linkRegex(convertRawProp(context, rawProps, "linkRegex", sourceProps.linkRegex, {})), -+ inlineCodeLinkRegex(convertRawProp(context, rawProps, "inlineCodeLinkRegex", sourceProps.inlineCodeLinkRegex, {})), - markdown(convertRawProp(context, rawProps, "markdown", sourceProps.markdown, {})), - markdownStyle(convertRawProp(context, rawProps, "markdownStyle", sourceProps.markdownStyle, {})), - enableImagePress(convertRawProp(context, rawProps, "enableImagePress", sourceProps.enableImagePress, {false})), -@@ -63,6 +74,50 @@ folly::dynamic EnrichedMarkdownProps::getDiffProps( - } - folly::dynamic result = HostPlatformViewProps::getDiffProps(prevProps); - -+ if (enableImageSourceResolution != oldProps->enableImageSourceResolution) { -+ result["enableImageSourceResolution"] = enableImageSourceResolution; -+ } -+ -+ if (imageSourcesRevision != oldProps->imageSourcesRevision) { -+ result["imageSourcesRevision"] = imageSourcesRevision; -+ } -+ -+ if (imageSourcesContinuityStart != oldProps->imageSourcesContinuityStart) { -+ result["imageSourcesContinuityStart"] = imageSourcesContinuityStart; -+ } -+ -+ if (imageSources != oldProps->imageSources) { -+ result["imageSources"] = toDynamic(imageSources); -+ } -+ -+ if (documentRevision != oldProps->documentRevision) { -+ result["documentRevision"] = documentRevision; -+ } -+ -+ if (enableDocumentAssets != oldProps->enableDocumentAssets) { -+ result["enableDocumentAssets"] = enableDocumentAssets; -+ } -+ -+ if (enableMediaSlots != oldProps->enableMediaSlots) { -+ result["enableMediaSlots"] = enableMediaSlots; -+ } -+ -+ if (mediaOverridesRevision != oldProps->mediaOverridesRevision) { -+ result["mediaOverridesRevision"] = mediaOverridesRevision; -+ } -+ -+ if (mediaOverrides != oldProps->mediaOverrides) { -+ result["mediaOverrides"] = toDynamic(mediaOverrides); -+ } -+ -+ if (linkRegex != oldProps->linkRegex) { -+ result["linkRegex"] = toDynamic(linkRegex); -+ } -+ -+ if (inlineCodeLinkRegex != oldProps->inlineCodeLinkRegex) { -+ result["inlineCodeLinkRegex"] = toDynamic(inlineCodeLinkRegex); -+ } -+ - if (markdown != oldProps->markdown) { - result["markdown"] = markdown; - } -@@ -317,6 +372,8 @@ EnrichedMarkdownTextProps::EnrichedMarkdownTextProps( - const EnrichedMarkdownTextProps &sourceProps, - const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), - -+ linkRegex(convertRawProp(context, rawProps, "linkRegex", sourceProps.linkRegex, {})), -+ inlineCodeLinkRegex(convertRawProp(context, rawProps, "inlineCodeLinkRegex", sourceProps.inlineCodeLinkRegex, {})), - markdown(convertRawProp(context, rawProps, "markdown", sourceProps.markdown, {})), - markdownStyle(convertRawProp(context, rawProps, "markdownStyle", sourceProps.markdownStyle, {})), - enableImagePress(convertRawProp(context, rawProps, "enableImagePress", sourceProps.enableImagePress, {false})), -@@ -361,6 +418,14 @@ folly::dynamic EnrichedMarkdownTextProps::getDiffProps( - } - folly::dynamic result = HostPlatformViewProps::getDiffProps(prevProps); - -+ if (linkRegex != oldProps->linkRegex) { -+ result["linkRegex"] = toDynamic(linkRegex); -+ } -+ -+ if (inlineCodeLinkRegex != oldProps->inlineCodeLinkRegex) { -+ result["inlineCodeLinkRegex"] = toDynamic(inlineCodeLinkRegex); -+ } -+ - if (markdown != oldProps->markdown) { - result["markdown"] = markdown; - } -diff --git a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h -index ed3b4bf2507500ee012b6412e85b48f11214b364..9c8f8139bbbbff277c0b10eb541723e366fb6015 100644 ---- a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h -+++ b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h -@@ -18,6 +18,320 @@ - - namespace facebook::react { - -+struct EnrichedMarkdownImageSourcesHeadersStruct { -+ std::string name{}; -+ std::string value{}; -+ -+ -+#ifdef RN_SERIALIZABLE_STATE -+ bool operator==(const EnrichedMarkdownImageSourcesHeadersStruct&) const = default; -+ -+ folly::dynamic toDynamic() const { -+ folly::dynamic result = folly::dynamic::object(); -+ result["name"] = name; -+ result["value"] = value; -+ return result; -+ } -+#endif -+}; -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownImageSourcesHeadersStruct &result) { -+ auto map = (std::unordered_map)value; -+ -+ auto tmp_name = map.find("name"); -+ if (tmp_name != map.end()) { -+ fromRawValue(context, tmp_name->second, result.name); -+ } -+ auto tmp_value = map.find("value"); -+ if (tmp_value != map.end()) { -+ fromRawValue(context, tmp_value->second, result.value); -+ } -+} -+ -+static inline std::string toString(const EnrichedMarkdownImageSourcesHeadersStruct &value) { -+ return "[Object EnrichedMarkdownImageSourcesHeadersStruct]"; -+} -+ -+#ifdef RN_SERIALIZABLE_STATE -+static inline folly::dynamic toDynamic(const EnrichedMarkdownImageSourcesHeadersStruct &value) { -+ return value.toDynamic(); -+} -+#endif -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, std::vector &result) { -+ auto items = (std::vector)value; -+ for (const auto &item : items) { -+ EnrichedMarkdownImageSourcesHeadersStruct newItem; -+ fromRawValue(context, item, newItem); -+ result.emplace_back(newItem); -+ } -+} -+ -+ -+struct EnrichedMarkdownImageSourcesStruct { -+ std::string id{}; -+ std::string url{}; -+ std::string anchor{}; -+ std::string uri{}; -+ std::vector headers{}; -+ bool useDefault{false}; -+ -+ -+#ifdef RN_SERIALIZABLE_STATE -+ bool operator==(const EnrichedMarkdownImageSourcesStruct&) const = default; -+ -+ folly::dynamic toDynamic() const { -+ folly::dynamic result = folly::dynamic::object(); -+ result["id"] = id; -+ result["url"] = url; -+ result["anchor"] = anchor; -+ result["uri"] = uri; -+ result["headers"] = ::facebook::react::toDynamic(headers); -+ result["useDefault"] = useDefault; -+ return result; -+ } -+#endif -+}; -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownImageSourcesStruct &result) { -+ auto map = (std::unordered_map)value; -+ -+ auto tmp_id = map.find("id"); -+ if (tmp_id != map.end()) { -+ fromRawValue(context, tmp_id->second, result.id); -+ } -+ auto tmp_url = map.find("url"); -+ if (tmp_url != map.end()) { -+ fromRawValue(context, tmp_url->second, result.url); -+ } -+ auto tmp_anchor = map.find("anchor"); -+ if (tmp_anchor != map.end()) { -+ fromRawValue(context, tmp_anchor->second, result.anchor); -+ } -+ auto tmp_uri = map.find("uri"); -+ if (tmp_uri != map.end()) { -+ fromRawValue(context, tmp_uri->second, result.uri); -+ } -+ auto tmp_headers = map.find("headers"); -+ if (tmp_headers != map.end()) { -+ fromRawValue(context, tmp_headers->second, result.headers); -+ } -+ auto tmp_useDefault = map.find("useDefault"); -+ if (tmp_useDefault != map.end()) { -+ fromRawValue(context, tmp_useDefault->second, result.useDefault); -+ } -+} -+ -+static inline std::string toString(const EnrichedMarkdownImageSourcesStruct &value) { -+ return "[Object EnrichedMarkdownImageSourcesStruct]"; -+} -+ -+#ifdef RN_SERIALIZABLE_STATE -+static inline folly::dynamic toDynamic(const EnrichedMarkdownImageSourcesStruct &value) { -+ return value.toDynamic(); -+} -+#endif -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, std::vector &result) { -+ auto items = (std::vector)value; -+ for (const auto &item : items) { -+ EnrichedMarkdownImageSourcesStruct newItem; -+ fromRawValue(context, item, newItem); -+ result.emplace_back(newItem); -+ } -+} -+ -+ -+struct EnrichedMarkdownMediaOverridesStruct { -+ std::string url{}; -+ std::string kind{}; -+ std::string anchor{}; -+ std::string id{}; -+ Float height{0.0}; -+ Float width{0.0}; -+ -+ -+#ifdef RN_SERIALIZABLE_STATE -+ bool operator==(const EnrichedMarkdownMediaOverridesStruct&) const = default; -+ -+ folly::dynamic toDynamic() const { -+ folly::dynamic result = folly::dynamic::object(); -+ result["url"] = url; -+ result["kind"] = kind; -+ result["anchor"] = anchor; -+ result["id"] = id; -+ result["height"] = height; -+ result["width"] = width; -+ return result; -+ } -+#endif -+}; -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownMediaOverridesStruct &result) { -+ auto map = (std::unordered_map)value; -+ -+ auto tmp_url = map.find("url"); -+ if (tmp_url != map.end()) { -+ fromRawValue(context, tmp_url->second, result.url); -+ } -+ auto tmp_kind = map.find("kind"); -+ if (tmp_kind != map.end()) { -+ fromRawValue(context, tmp_kind->second, result.kind); -+ } -+ auto tmp_anchor = map.find("anchor"); -+ if (tmp_anchor != map.end()) { -+ fromRawValue(context, tmp_anchor->second, result.anchor); -+ } -+ auto tmp_id = map.find("id"); -+ if (tmp_id != map.end()) { -+ fromRawValue(context, tmp_id->second, result.id); -+ } -+ auto tmp_height = map.find("height"); -+ if (tmp_height != map.end()) { -+ fromRawValue(context, tmp_height->second, result.height); -+ } -+ auto tmp_width = map.find("width"); -+ if (tmp_width != map.end()) { -+ fromRawValue(context, tmp_width->second, result.width); -+ } -+} -+ -+static inline std::string toString(const EnrichedMarkdownMediaOverridesStruct &value) { -+ return "[Object EnrichedMarkdownMediaOverridesStruct]"; -+} -+ -+#ifdef RN_SERIALIZABLE_STATE -+static inline folly::dynamic toDynamic(const EnrichedMarkdownMediaOverridesStruct &value) { -+ return value.toDynamic(); -+} -+#endif -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, std::vector &result) { -+ auto items = (std::vector)value; -+ for (const auto &item : items) { -+ EnrichedMarkdownMediaOverridesStruct newItem; -+ fromRawValue(context, item, newItem); -+ result.emplace_back(newItem); -+ } -+} -+ -+ -+struct EnrichedMarkdownLinkRegexStruct { -+ std::string pattern{}; -+ bool caseInsensitive{false}; -+ bool dotAll{false}; -+ bool isDisabled{false}; -+ bool isDefault{false}; -+ -+ -+#ifdef RN_SERIALIZABLE_STATE -+ bool operator==(const EnrichedMarkdownLinkRegexStruct&) const = default; -+ -+ folly::dynamic toDynamic() const { -+ folly::dynamic result = folly::dynamic::object(); -+ result["pattern"] = pattern; -+ result["caseInsensitive"] = caseInsensitive; -+ result["dotAll"] = dotAll; -+ result["isDisabled"] = isDisabled; -+ result["isDefault"] = isDefault; -+ return result; -+ } -+#endif -+}; -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownLinkRegexStruct &result) { -+ auto map = (std::unordered_map)value; -+ -+ auto tmp_pattern = map.find("pattern"); -+ if (tmp_pattern != map.end()) { -+ fromRawValue(context, tmp_pattern->second, result.pattern); -+ } -+ auto tmp_caseInsensitive = map.find("caseInsensitive"); -+ if (tmp_caseInsensitive != map.end()) { -+ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); -+ } -+ auto tmp_dotAll = map.find("dotAll"); -+ if (tmp_dotAll != map.end()) { -+ fromRawValue(context, tmp_dotAll->second, result.dotAll); -+ } -+ auto tmp_isDisabled = map.find("isDisabled"); -+ if (tmp_isDisabled != map.end()) { -+ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); -+ } -+ auto tmp_isDefault = map.find("isDefault"); -+ if (tmp_isDefault != map.end()) { -+ fromRawValue(context, tmp_isDefault->second, result.isDefault); -+ } -+} -+ -+static inline std::string toString(const EnrichedMarkdownLinkRegexStruct &value) { -+ return "[Object EnrichedMarkdownLinkRegexStruct]"; -+} -+ -+#ifdef RN_SERIALIZABLE_STATE -+static inline folly::dynamic toDynamic(const EnrichedMarkdownLinkRegexStruct &value) { -+ return value.toDynamic(); -+} -+#endif -+ -+struct EnrichedMarkdownInlineCodeLinkRegexStruct { -+ std::string pattern{}; -+ bool caseInsensitive{false}; -+ bool dotAll{false}; -+ bool isDisabled{false}; -+ bool isDefault{false}; -+ -+ -+#ifdef RN_SERIALIZABLE_STATE -+ bool operator==(const EnrichedMarkdownInlineCodeLinkRegexStruct&) const = default; -+ -+ folly::dynamic toDynamic() const { -+ folly::dynamic result = folly::dynamic::object(); -+ result["pattern"] = pattern; -+ result["caseInsensitive"] = caseInsensitive; -+ result["dotAll"] = dotAll; -+ result["isDisabled"] = isDisabled; -+ result["isDefault"] = isDefault; -+ return result; -+ } -+#endif -+}; -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownInlineCodeLinkRegexStruct &result) { -+ auto map = (std::unordered_map)value; -+ -+ auto tmp_pattern = map.find("pattern"); -+ if (tmp_pattern != map.end()) { -+ fromRawValue(context, tmp_pattern->second, result.pattern); -+ } -+ auto tmp_caseInsensitive = map.find("caseInsensitive"); -+ if (tmp_caseInsensitive != map.end()) { -+ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); -+ } -+ auto tmp_dotAll = map.find("dotAll"); -+ if (tmp_dotAll != map.end()) { -+ fromRawValue(context, tmp_dotAll->second, result.dotAll); -+ } -+ auto tmp_isDisabled = map.find("isDisabled"); -+ if (tmp_isDisabled != map.end()) { -+ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); -+ } -+ auto tmp_isDefault = map.find("isDefault"); -+ if (tmp_isDefault != map.end()) { -+ fromRawValue(context, tmp_isDefault->second, result.isDefault); -+ } -+} -+ -+static inline std::string toString(const EnrichedMarkdownInlineCodeLinkRegexStruct &value) { -+ return "[Object EnrichedMarkdownInlineCodeLinkRegexStruct]"; -+} -+ -+#ifdef RN_SERIALIZABLE_STATE -+static inline folly::dynamic toDynamic(const EnrichedMarkdownInlineCodeLinkRegexStruct &value) { -+ return value.toDynamic(); -+} -+#endif -+ - struct EnrichedMarkdownMarkdownStyleParagraphStruct { - Float fontSize{0.0}; - std::string fontFamily{}; -@@ -1313,6 +1627,17 @@ struct EnrichedMarkdownMarkdownStyleLinkVariantsStruct { - SharedColor color{}; - bool underline{false}; - SharedColor backgroundColor{}; -+ std::string fontFamily{}; -+ bool pill{false}; -+ std::string label{}; -+ std::string iconUri{}; -+ SharedColor iconTintColor{}; -+ Float borderRadius{0.0}; -+ Float paddingHorizontal{0.0}; -+ Float paddingVertical{0.0}; -+ Float borderWidth{0.0}; -+ SharedColor borderColor{}; -+ Float maxWidth{0.0}; - - - #ifdef RN_SERIALIZABLE_STATE -@@ -1324,6 +1649,17 @@ struct EnrichedMarkdownMarkdownStyleLinkVariantsStruct { - result["color"] = ::facebook::react::toDynamic(color); - result["underline"] = underline; - result["backgroundColor"] = ::facebook::react::toDynamic(backgroundColor); -+ result["fontFamily"] = fontFamily; -+ result["pill"] = pill; -+ result["label"] = label; -+ result["iconUri"] = iconUri; -+ result["iconTintColor"] = ::facebook::react::toDynamic(iconTintColor); -+ result["borderRadius"] = borderRadius; -+ result["paddingHorizontal"] = paddingHorizontal; -+ result["paddingVertical"] = paddingVertical; -+ result["borderWidth"] = borderWidth; -+ result["borderColor"] = ::facebook::react::toDynamic(borderColor); -+ result["maxWidth"] = maxWidth; - return result; - } - #endif -@@ -1348,6 +1684,50 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu - if (tmp_backgroundColor != map.end()) { - fromRawValue(context, tmp_backgroundColor->second, result.backgroundColor); - } -+ auto tmp_fontFamily = map.find("fontFamily"); -+ if (tmp_fontFamily != map.end()) { -+ fromRawValue(context, tmp_fontFamily->second, result.fontFamily); -+ } -+ auto tmp_pill = map.find("pill"); -+ if (tmp_pill != map.end()) { -+ fromRawValue(context, tmp_pill->second, result.pill); -+ } -+ auto tmp_label = map.find("label"); -+ if (tmp_label != map.end()) { -+ fromRawValue(context, tmp_label->second, result.label); -+ } -+ auto tmp_iconUri = map.find("iconUri"); -+ if (tmp_iconUri != map.end()) { -+ fromRawValue(context, tmp_iconUri->second, result.iconUri); -+ } -+ auto tmp_iconTintColor = map.find("iconTintColor"); -+ if (tmp_iconTintColor != map.end()) { -+ fromRawValue(context, tmp_iconTintColor->second, result.iconTintColor); -+ } -+ auto tmp_borderRadius = map.find("borderRadius"); -+ if (tmp_borderRadius != map.end()) { -+ fromRawValue(context, tmp_borderRadius->second, result.borderRadius); -+ } -+ auto tmp_paddingHorizontal = map.find("paddingHorizontal"); -+ if (tmp_paddingHorizontal != map.end()) { -+ fromRawValue(context, tmp_paddingHorizontal->second, result.paddingHorizontal); -+ } -+ auto tmp_paddingVertical = map.find("paddingVertical"); -+ if (tmp_paddingVertical != map.end()) { -+ fromRawValue(context, tmp_paddingVertical->second, result.paddingVertical); -+ } -+ auto tmp_borderWidth = map.find("borderWidth"); -+ if (tmp_borderWidth != map.end()) { -+ fromRawValue(context, tmp_borderWidth->second, result.borderWidth); -+ } -+ auto tmp_borderColor = map.find("borderColor"); -+ if (tmp_borderColor != map.end()) { -+ fromRawValue(context, tmp_borderColor->second, result.borderColor); -+ } -+ auto tmp_maxWidth = map.find("maxWidth"); -+ if (tmp_maxWidth != map.end()) { -+ fromRawValue(context, tmp_maxWidth->second, result.maxWidth); -+ } - } - - static inline std::string toString(const EnrichedMarkdownMarkdownStyleLinkVariantsStruct &value) { -@@ -3116,6 +3496,17 @@ class EnrichedMarkdownProps final : public ViewProps { - - #pragma mark - Props - -+ bool enableImageSourceResolution{false}; -+ int imageSourcesRevision{-1}; -+ int imageSourcesContinuityStart{1}; -+ std::vector imageSources{}; -+ int documentRevision{0}; -+ bool enableDocumentAssets{false}; -+ bool enableMediaSlots{false}; -+ int mediaOverridesRevision{-1}; -+ std::vector mediaOverrides{}; -+ EnrichedMarkdownLinkRegexStruct linkRegex{}; -+ EnrichedMarkdownInlineCodeLinkRegexStruct inlineCodeLinkRegex{}; - std::string markdown{}; - EnrichedMarkdownMarkdownStyleStruct markdownStyle{}; - bool enableImagePress{false}; -@@ -4078,6 +4469,122 @@ class EnrichedMarkdownTextInputProps final : public ViewProps { - - }; - -+struct EnrichedMarkdownTextLinkRegexStruct { -+ std::string pattern{}; -+ bool caseInsensitive{false}; -+ bool dotAll{false}; -+ bool isDisabled{false}; -+ bool isDefault{false}; -+ -+ -+#ifdef RN_SERIALIZABLE_STATE -+ bool operator==(const EnrichedMarkdownTextLinkRegexStruct&) const = default; -+ -+ folly::dynamic toDynamic() const { -+ folly::dynamic result = folly::dynamic::object(); -+ result["pattern"] = pattern; -+ result["caseInsensitive"] = caseInsensitive; -+ result["dotAll"] = dotAll; -+ result["isDisabled"] = isDisabled; -+ result["isDefault"] = isDefault; -+ return result; -+ } -+#endif -+}; -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownTextLinkRegexStruct &result) { -+ auto map = (std::unordered_map)value; -+ -+ auto tmp_pattern = map.find("pattern"); -+ if (tmp_pattern != map.end()) { -+ fromRawValue(context, tmp_pattern->second, result.pattern); -+ } -+ auto tmp_caseInsensitive = map.find("caseInsensitive"); -+ if (tmp_caseInsensitive != map.end()) { -+ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); -+ } -+ auto tmp_dotAll = map.find("dotAll"); -+ if (tmp_dotAll != map.end()) { -+ fromRawValue(context, tmp_dotAll->second, result.dotAll); -+ } -+ auto tmp_isDisabled = map.find("isDisabled"); -+ if (tmp_isDisabled != map.end()) { -+ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); -+ } -+ auto tmp_isDefault = map.find("isDefault"); -+ if (tmp_isDefault != map.end()) { -+ fromRawValue(context, tmp_isDefault->second, result.isDefault); -+ } -+} -+ -+static inline std::string toString(const EnrichedMarkdownTextLinkRegexStruct &value) { -+ return "[Object EnrichedMarkdownTextLinkRegexStruct]"; -+} -+ -+#ifdef RN_SERIALIZABLE_STATE -+static inline folly::dynamic toDynamic(const EnrichedMarkdownTextLinkRegexStruct &value) { -+ return value.toDynamic(); -+} -+#endif -+ -+struct EnrichedMarkdownTextInlineCodeLinkRegexStruct { -+ std::string pattern{}; -+ bool caseInsensitive{false}; -+ bool dotAll{false}; -+ bool isDisabled{false}; -+ bool isDefault{false}; -+ -+ -+#ifdef RN_SERIALIZABLE_STATE -+ bool operator==(const EnrichedMarkdownTextInlineCodeLinkRegexStruct&) const = default; -+ -+ folly::dynamic toDynamic() const { -+ folly::dynamic result = folly::dynamic::object(); -+ result["pattern"] = pattern; -+ result["caseInsensitive"] = caseInsensitive; -+ result["dotAll"] = dotAll; -+ result["isDisabled"] = isDisabled; -+ result["isDefault"] = isDefault; -+ return result; -+ } -+#endif -+}; -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownTextInlineCodeLinkRegexStruct &result) { -+ auto map = (std::unordered_map)value; -+ -+ auto tmp_pattern = map.find("pattern"); -+ if (tmp_pattern != map.end()) { -+ fromRawValue(context, tmp_pattern->second, result.pattern); -+ } -+ auto tmp_caseInsensitive = map.find("caseInsensitive"); -+ if (tmp_caseInsensitive != map.end()) { -+ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); -+ } -+ auto tmp_dotAll = map.find("dotAll"); -+ if (tmp_dotAll != map.end()) { -+ fromRawValue(context, tmp_dotAll->second, result.dotAll); -+ } -+ auto tmp_isDisabled = map.find("isDisabled"); -+ if (tmp_isDisabled != map.end()) { -+ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); -+ } -+ auto tmp_isDefault = map.find("isDefault"); -+ if (tmp_isDefault != map.end()) { -+ fromRawValue(context, tmp_isDefault->second, result.isDefault); -+ } -+} -+ -+static inline std::string toString(const EnrichedMarkdownTextInlineCodeLinkRegexStruct &value) { -+ return "[Object EnrichedMarkdownTextInlineCodeLinkRegexStruct]"; -+} -+ -+#ifdef RN_SERIALIZABLE_STATE -+static inline folly::dynamic toDynamic(const EnrichedMarkdownTextInlineCodeLinkRegexStruct &value) { -+ return value.toDynamic(); -+} -+#endif -+ - struct EnrichedMarkdownTextMarkdownStyleParagraphStruct { - Float fontSize{0.0}; - std::string fontFamily{}; -@@ -5373,6 +5880,17 @@ struct EnrichedMarkdownTextMarkdownStyleLinkVariantsStruct { - SharedColor color{}; - bool underline{false}; - SharedColor backgroundColor{}; -+ std::string fontFamily{}; -+ bool pill{false}; -+ std::string label{}; -+ std::string iconUri{}; -+ SharedColor iconTintColor{}; -+ Float borderRadius{0.0}; -+ Float paddingHorizontal{0.0}; -+ Float paddingVertical{0.0}; -+ Float borderWidth{0.0}; -+ SharedColor borderColor{}; -+ Float maxWidth{0.0}; - - - #ifdef RN_SERIALIZABLE_STATE -@@ -5384,6 +5902,17 @@ struct EnrichedMarkdownTextMarkdownStyleLinkVariantsStruct { - result["color"] = ::facebook::react::toDynamic(color); - result["underline"] = underline; - result["backgroundColor"] = ::facebook::react::toDynamic(backgroundColor); -+ result["fontFamily"] = fontFamily; -+ result["pill"] = pill; -+ result["label"] = label; -+ result["iconUri"] = iconUri; -+ result["iconTintColor"] = ::facebook::react::toDynamic(iconTintColor); -+ result["borderRadius"] = borderRadius; -+ result["paddingHorizontal"] = paddingHorizontal; -+ result["paddingVertical"] = paddingVertical; -+ result["borderWidth"] = borderWidth; -+ result["borderColor"] = ::facebook::react::toDynamic(borderColor); -+ result["maxWidth"] = maxWidth; - return result; - } - #endif -@@ -5408,6 +5937,50 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu - if (tmp_backgroundColor != map.end()) { - fromRawValue(context, tmp_backgroundColor->second, result.backgroundColor); - } -+ auto tmp_fontFamily = map.find("fontFamily"); -+ if (tmp_fontFamily != map.end()) { -+ fromRawValue(context, tmp_fontFamily->second, result.fontFamily); -+ } -+ auto tmp_pill = map.find("pill"); -+ if (tmp_pill != map.end()) { -+ fromRawValue(context, tmp_pill->second, result.pill); -+ } -+ auto tmp_label = map.find("label"); -+ if (tmp_label != map.end()) { -+ fromRawValue(context, tmp_label->second, result.label); -+ } -+ auto tmp_iconUri = map.find("iconUri"); -+ if (tmp_iconUri != map.end()) { -+ fromRawValue(context, tmp_iconUri->second, result.iconUri); -+ } -+ auto tmp_iconTintColor = map.find("iconTintColor"); -+ if (tmp_iconTintColor != map.end()) { -+ fromRawValue(context, tmp_iconTintColor->second, result.iconTintColor); -+ } -+ auto tmp_borderRadius = map.find("borderRadius"); -+ if (tmp_borderRadius != map.end()) { -+ fromRawValue(context, tmp_borderRadius->second, result.borderRadius); -+ } -+ auto tmp_paddingHorizontal = map.find("paddingHorizontal"); -+ if (tmp_paddingHorizontal != map.end()) { -+ fromRawValue(context, tmp_paddingHorizontal->second, result.paddingHorizontal); -+ } -+ auto tmp_paddingVertical = map.find("paddingVertical"); -+ if (tmp_paddingVertical != map.end()) { -+ fromRawValue(context, tmp_paddingVertical->second, result.paddingVertical); -+ } -+ auto tmp_borderWidth = map.find("borderWidth"); -+ if (tmp_borderWidth != map.end()) { -+ fromRawValue(context, tmp_borderWidth->second, result.borderWidth); -+ } -+ auto tmp_borderColor = map.find("borderColor"); -+ if (tmp_borderColor != map.end()) { -+ fromRawValue(context, tmp_borderColor->second, result.borderColor); -+ } -+ auto tmp_maxWidth = map.find("maxWidth"); -+ if (tmp_maxWidth != map.end()) { -+ fromRawValue(context, tmp_maxWidth->second, result.maxWidth); -+ } - } - - static inline std::string toString(const EnrichedMarkdownTextMarkdownStyleLinkVariantsStruct &value) { -@@ -7176,6 +7749,8 @@ class EnrichedMarkdownTextProps final : public ViewProps { - - #pragma mark - Props - -+ EnrichedMarkdownTextLinkRegexStruct linkRegex{}; -+ EnrichedMarkdownTextInlineCodeLinkRegexStruct inlineCodeLinkRegex{}; - std::string markdown{}; - EnrichedMarkdownTextMarkdownStyleStruct markdownStyle{}; - bool enableImagePress{false}; -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt -index b6b38b4cc1a37eacf53f48f940608ed7ead26f93..5031b3b10dc9675b54b9f36701aadc3ae074bc70 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt -@@ -9,9 +9,20 @@ import android.util.Log - import android.view.View - import com.facebook.react.bridge.Arguments - import com.facebook.react.bridge.ReadableMap -+import com.facebook.react.uimanager.PixelUtil - import com.facebook.react.uimanager.StateWrapper - import com.swmansion.enriched.markdown.accessibility.AccessibilityLabels -+import com.swmansion.enriched.markdown.input.autolink.LinkRegexConfig - import com.swmansion.enriched.markdown.math.LatexErrorReporter -+import com.swmansion.enriched.markdown.media.DocumentAsset -+import com.swmansion.enriched.markdown.media.DocumentAssets -+import com.swmansion.enriched.markdown.media.ImageSourceDecision -+import com.swmansion.enriched.markdown.media.MediaOverride -+import com.swmansion.enriched.markdown.media.MediaSlotView -+import com.swmansion.enriched.markdown.media.documentAssetsEventData -+import com.swmansion.enriched.markdown.media.emitMediaEvent -+import com.swmansion.enriched.markdown.media.mediaSlotsForDocument -+import com.swmansion.enriched.markdown.media.withImageSources - import com.swmansion.enriched.markdown.parser.Md4cFlags - import com.swmansion.enriched.markdown.parser.Parser - import com.swmansion.enriched.markdown.segments.BlockquoteContainerView -@@ -57,6 +68,87 @@ class EnrichedMarkdown( - private val videoContainerClass: Class<*>? by lazy { SegmentViewCreators.videoContainerClass() } - - private var currentRenderId = 0L -+ private var enableImageSourceResolution = false -+ private var imageSourcesRevision = -1 -+ private var imageSourcesContinuityStart = 1 -+ private var imageSources = emptyList() -+ private var documentRevision = 0 -+ private var mediaOverridesRevision = -1 -+ private var enableDocumentAssets = false -+ private var enableMediaSlots = false -+ private var mediaOverrides = emptyList() -+ private var acceptedRevision = -1 -+ private var acceptedAssets = emptyList() -+ private var lastAssetManifest: Pair>? = null -+ private var lastMediaFrames: String? = null -+ -+ fun setEnableImageSourceResolution(value: Boolean) { -+ if (enableImageSourceResolution == value) return -+ enableImageSourceResolution = value -+ dirtyFlags += DirtyFlag.RECREATE_SEGMENTS -+ dirtyFlags += DirtyFlag.FORCE_HEIGHT -+ renderPending = true -+ } -+ -+ fun setImageSourcesRevision(value: Int) { -+ if (imageSourcesRevision == value) return -+ imageSourcesRevision = value -+ dirtyFlags += DirtyFlag.RECREATE_SEGMENTS -+ dirtyFlags += DirtyFlag.FORCE_HEIGHT -+ renderPending = true -+ } -+ -+ fun setImageSourcesContinuityStart(value: Int) { -+ if (imageSourcesContinuityStart == value) return -+ imageSourcesContinuityStart = value -+ dirtyFlags += DirtyFlag.RECREATE_SEGMENTS -+ dirtyFlags += DirtyFlag.FORCE_HEIGHT -+ renderPending = true -+ } -+ -+ fun setImageSources(value: List) { -+ if (imageSources == value) return -+ imageSources = value -+ dirtyFlags += DirtyFlag.RECREATE_SEGMENTS -+ dirtyFlags += DirtyFlag.FORCE_HEIGHT -+ renderPending = true -+ } -+ -+ fun setDocumentRevision(value: Int) { -+ if (documentRevision == value) return -+ documentRevision = value -+ ++currentRenderId -+ renderPending = true -+ } -+ -+ fun setMediaOverridesRevision(value: Int) { -+ if (mediaOverridesRevision == value) return -+ mediaOverridesRevision = value -+ dirtyFlags += DirtyFlag.FORCE_HEIGHT -+ renderPending = true -+ } -+ -+ fun setEnableDocumentAssets(value: Boolean) { -+ if (enableDocumentAssets == value) return -+ enableDocumentAssets = value -+ lastAssetManifest = null -+ renderPending = true -+ } -+ -+ fun setEnableMediaSlots(value: Boolean) { -+ if (enableMediaSlots == value) return -+ enableMediaSlots = value -+ dirtyFlags += DirtyFlag.FORCE_HEIGHT -+ renderPending = true -+ } -+ -+ fun setMediaOverrides(value: List) { -+ if (mediaOverrides == value) return -+ mediaOverrides = value -+ dirtyFlags += DirtyFlag.FORCE_HEIGHT -+ renderPending = true -+ } -+ - private val dirtyFlags = EnumSet.noneOf(DirtyFlag::class.java) - var streamingAnimation: Boolean = false - -@@ -79,6 +171,8 @@ class EnrichedMarkdown( - - var md4cFlags: Md4cFlags = Md4cFlags.DEFAULT - private set -+ private var linkRegex: LinkRegexConfig? = null -+ private var inlineCodeLinkRegex: LinkRegexConfig? = null - private var isGFM: Boolean = true - private var allowFontScaling: Boolean = true - private var maxFontSizeMultiplier: Float = 0f -@@ -143,6 +237,7 @@ class EnrichedMarkdown( - fun setMarkdownContent(markdown: String) { - if (currentMarkdown == markdown) return - currentMarkdown = markdown -+ ++currentRenderId - renderPending = true - } - -@@ -188,6 +283,18 @@ class EnrichedMarkdown( - } - } - -+ fun setLinkRegex(config: LinkRegexConfig?) { -+ if (linkRegex == config) return -+ linkRegex = config -+ renderPending = true -+ } -+ -+ fun setInlineCodeLinkRegex(config: LinkRegexConfig?) { -+ if (inlineCodeLinkRegex == config) return -+ inlineCodeLinkRegex = config -+ renderPending = true -+ } -+ - fun setMd4cFlags(flags: Md4cFlags) { - if (md4cFlags == flags) return - md4cFlags = flags -@@ -362,7 +469,11 @@ class EnrichedMarkdown( - } - - private fun scheduleRenderIfNeeded() { -- if (currentMarkdown.isNotEmpty()) scheduleRender() -+ if (currentMarkdown.isNotEmpty()) { -+ scheduleRender() -+ } else { -+ applyEmptyDocument(documentRevision) -+ } - } - - private fun scheduleRender() { -@@ -372,6 +483,19 @@ class EnrichedMarkdown( - val tableMode = tableStreamingMode - val codeBlockMode = codeBlockStreamingMode - -+ val sourcesEnabled = enableImageSourceResolution && isGFM -+ val sourcesRevision = imageSourcesRevision -+ val sourcesContinuityStart = imageSourcesContinuityStart -+ val sources = imageSources -+ val revision = documentRevision -+ val assetEventsEnabled = enableDocumentAssets -+ val slotsEnabled = enableMediaSlots -+ val overrideRevision = mediaOverridesRevision -+ val overrides = mediaOverrides -+ val flags = md4cFlags -+ val gfm = isGFM -+ val textLinkRegex = linkRegex -+ val codeLinkRegex = inlineCodeLinkRegex - val renderId = ++currentRenderId - - executor.execute { -@@ -386,17 +510,20 @@ class EnrichedMarkdown( - val hasPendingCodeBlock = filtered?.endsInsideOpenCodeFence ?: false - - if (renderableMarkdown.isEmpty()) { -- postToMain(renderId) { applyRenderedSegments(emptyList(), false) } -+ postToMain(renderId) { applyEmptyDocument(revision) } - return@execute - } - - val ast = -- parser.parseMarkdown(renderableMarkdown, md4cFlags, isGFM) ?: run { -- postToMain(renderId) { applyRenderedSegments(emptyList(), false) } -+ parser.parseMarkdown(renderableMarkdown, flags, gfm, textLinkRegex, codeLinkRegex) ?: run { -+ postToMain(renderId) { applyEmptyDocument(revision) } - return@execute - } - -- val segments = splitASTIntoSegments(ast) -+ val sourceAST = withImageSources(ast, sourcesEnabled, revision, sourcesRevision, sourcesContinuityStart, sources) -+ val assets = DocumentAssets.collect(sourceAST) -+ val mediaSlots = mediaSlotsForDocument(assets, slotsEnabled, revision, overrideRevision, overrides) -+ val segments = splitASTIntoSegments(sourceAST, mediaSlots, assets) - val renderedSegments = - MarkdownSegmentRenderer.render( - segments, -@@ -407,10 +534,19 @@ class EnrichedMarkdown( - onLatexError = latexErrorReporter, - ) - -- postToMain(renderId) { applyRenderedSegments(renderedSegments, hasPendingCodeBlock) } -+ postToMain(renderId) { -+ if (revision != documentRevision) return@postToMain -+ acceptedRevision = revision -+ acceptedAssets = assets.assets -+ val forceHeight = DirtyFlag.FORCE_HEIGHT in dirtyFlags -+ applyRenderedSegments(renderedSegments, hasPendingCodeBlock) -+ if (assetEventsEnabled) publishAssets(revision, assets.assets) -+ publishMediaFrames() -+ if (forceHeight) onImageLayoutChanged() -+ } - } catch (e: Exception) { - Log.e(TAG, "Render failed", e) -- postToMain(renderId) { applyRenderedSegments(emptyList(), false) } -+ postToMain(renderId) { applyEmptyDocument(revision) } - } - } - } -@@ -493,7 +629,7 @@ class EnrichedMarkdown( - is RenderedSegment.Math -> isMathContainerView(view) - is RenderedSegment.CodeBlock -> view is CodeBlockContainerView - is RenderedSegment.Blockquote -> view is BlockquoteContainerView -- is RenderedSegment.Video -> isVideoContainerView(view) -+ is RenderedSegment.Video -> if (segment.mediaSlot != null) view is MediaSlotView else isVideoContainerView(view) - } - - override fun createView(segment: RenderedSegment): View { -@@ -563,7 +699,7 @@ class EnrichedMarkdown( - } - - is RenderedSegment.Blockquote -> { -- (view as BlockquoteContainerView).applyBlockquoteNode(segment.node) -+ (view as BlockquoteContainerView).applyBlockquoteNode(segment.node, segment.mediaSlots, segment.assets) - } - - is RenderedSegment.Video -> { -@@ -628,6 +764,8 @@ class EnrichedMarkdown( - b: Int, - ) { - layoutSegments() -+ if (acceptedRevision == documentRevision) publishAssets(acceptedRevision, acceptedAssets) -+ publishMediaFrames() - } - - fun onImageLayoutChanged() { -@@ -642,7 +780,60 @@ class EnrichedMarkdown( - wrapper.updateState(state) - } - -+ private fun applyEmptyDocument(revision: Int) { -+ if (revision != documentRevision) return -+ acceptedRevision = revision -+ acceptedAssets = emptyList() -+ applyRenderedSegments(emptyList(), false) -+ publishAssets(revision, emptyList()) -+ publishMediaFrames() -+ onImageLayoutChanged() -+ } -+ -+ private fun publishAssets( -+ revision: Int, -+ assets: List, -+ ) { -+ if (!enableDocumentAssets) return -+ val manifest = revision to assets -+ if (lastAssetManifest == manifest) return -+ if (emitMediaEvent(this, "onDocumentAssets", documentAssetsEventData(revision, assets))) { -+ lastAssetManifest = manifest -+ } -+ } -+ -+ private fun publishMediaFrames() { -+ if (acceptedRevision != documentRevision || width <= 0) return -+ val slots = mediaSlotFrames() -+ val key = -+ "$acceptedRevision:" + -+ slots.joinToString(";") { -+ "${it.id},${it.x},${it.y},${it.width},${it.height}" -+ } -+ if (lastMediaFrames == key) return -+ val frames = Arguments.createArray() -+ slots.forEach { view -> -+ frames.pushMap( -+ Arguments.createMap().apply { -+ putString("id", view.id) -+ putDouble("x", PixelUtil.toDIPFromPixel(view.x.toFloat()).toDouble()) -+ putDouble("y", PixelUtil.toDIPFromPixel(view.y.toFloat()).toDouble()) -+ putDouble("width", PixelUtil.toDIPFromPixel(view.width.toFloat()).toDouble()) -+ putDouble("height", PixelUtil.toDIPFromPixel(view.height.toFloat()).toDouble()) -+ }, -+ ) -+ } -+ val data = -+ Arguments.createMap().apply { -+ putInt("revision", acceptedRevision) -+ putArray("frames", frames) -+ } -+ if (emitMediaEvent(this, "onMediaLayout", data)) lastMediaFrames = key -+ } -+ - fun cleanup() { -+ ++currentRenderId -+ mainHandler.removeCallbacksAndMessages(null) - executor.shutdownNow() - } - -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt -index 61eed4b3119e1a802b5f99eb36a5ee815b8269b6..93fffcd9fcc2e5373b3928a6621403f2863e8103 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt -@@ -13,6 +13,9 @@ import com.facebook.react.uimanager.annotations.ReactProp - import com.facebook.react.viewmanagers.EnrichedMarkdownManagerDelegate - import com.facebook.react.viewmanagers.EnrichedMarkdownManagerInterface - import com.facebook.yoga.YogaMeasureMode -+import com.swmansion.enriched.markdown.media.parseImageSources -+import com.swmansion.enriched.markdown.media.parseMediaOverrides -+import com.swmansion.enriched.markdown.parser.parseTextLinkRegex - import com.swmansion.enriched.markdown.spoiler.SpoilerOverlay - import com.swmansion.enriched.markdown.utils.common.CodeBlockStreamingMode - import com.swmansion.enriched.markdown.utils.common.TableStreamingMode -@@ -112,7 +115,83 @@ class EnrichedMarkdownManager : - MeasurementStore.clearFontScalingSettings(view.id) - } - -- override fun getExportedCustomDirectEventTypeConstants(): MutableMap = markdownEventTypeConstants() -+ override fun getExportedCustomDirectEventTypeConstants(): MutableMap = -+ markdownEventTypeConstants().apply { -+ put("onDocumentAssets", mapOf("registrationName" to "onDocumentAssets")) -+ put("onMediaLayout", mapOf("registrationName" to "onMediaLayout")) -+ } -+ -+ @ReactProp(name = "enableImageSourceResolution", defaultBoolean = false) -+ override fun setEnableImageSourceResolution( -+ view: EnrichedMarkdown?, -+ value: Boolean, -+ ) { -+ view?.setEnableImageSourceResolution(value) -+ } -+ -+ @ReactProp(name = "imageSourcesRevision", defaultInt = -1) -+ override fun setImageSourcesRevision( -+ view: EnrichedMarkdown?, -+ value: Int, -+ ) { -+ view?.setImageSourcesRevision(value) -+ } -+ -+ @ReactProp(name = "imageSourcesContinuityStart", defaultInt = 1) -+ override fun setImageSourcesContinuityStart( -+ view: EnrichedMarkdown?, -+ value: Int, -+ ) { -+ view?.setImageSourcesContinuityStart(value) -+ } -+ -+ @ReactProp(name = "imageSources") -+ override fun setImageSources( -+ view: EnrichedMarkdown?, -+ value: ReadableArray?, -+ ) { -+ view?.setImageSources(parseImageSources(value)) -+ } -+ -+ @ReactProp(name = "documentRevision", defaultInt = 0) -+ override fun setDocumentRevision( -+ view: EnrichedMarkdown?, -+ value: Int, -+ ) { -+ view?.setDocumentRevision(value) -+ } -+ -+ @ReactProp(name = "mediaOverridesRevision", defaultInt = -1) -+ override fun setMediaOverridesRevision( -+ view: EnrichedMarkdown?, -+ value: Int, -+ ) { -+ view?.setMediaOverridesRevision(value) -+ } -+ -+ @ReactProp(name = "enableDocumentAssets", defaultBoolean = false) -+ override fun setEnableDocumentAssets( -+ view: EnrichedMarkdown?, -+ value: Boolean, -+ ) { -+ view?.setEnableDocumentAssets(value) -+ } -+ -+ @ReactProp(name = "enableMediaSlots", defaultBoolean = false) -+ override fun setEnableMediaSlots( -+ view: EnrichedMarkdown?, -+ value: Boolean, -+ ) { -+ view?.setEnableMediaSlots(value) -+ } -+ -+ @ReactProp(name = "mediaOverrides") -+ override fun setMediaOverrides( -+ view: EnrichedMarkdown?, -+ value: ReadableArray?, -+ ) { -+ view?.setMediaOverrides(parseMediaOverrides(value)) -+ } - - @ReactProp(name = "markdown") - override fun setMarkdown( -@@ -152,6 +231,22 @@ class EnrichedMarkdownManager : - view?.setSelectionHandleColor(value) - } - -+ @ReactProp(name = "linkRegex") -+ override fun setLinkRegex( -+ view: EnrichedMarkdown?, -+ value: ReadableMap?, -+ ) { -+ view?.setLinkRegex(parseTextLinkRegex(value)) -+ } -+ -+ @ReactProp(name = "inlineCodeLinkRegex") -+ override fun setInlineCodeLinkRegex( -+ view: EnrichedMarkdown?, -+ value: ReadableMap?, -+ ) { -+ view?.setInlineCodeLinkRegex(parseTextLinkRegex(value)) -+ } -+ - @ReactProp(name = "md4cFlags") - override fun setMd4cFlags( - view: EnrichedMarkdown?, -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt -index f3bb9122d27d80746b9b8ed07ca5247f080a25d0..90b6e38cc0c8429d0702bfb33c7115bd1e68e551 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt -@@ -20,6 +20,7 @@ import com.facebook.react.uimanager.StateWrapper - import com.facebook.react.uimanager.style.LogicalEdge - import com.swmansion.enriched.markdown.accessibility.AccessibilityLabels - import com.swmansion.enriched.markdown.accessibility.AccessibleMarkdownTextView -+import com.swmansion.enriched.markdown.input.autolink.LinkRegexConfig - import com.swmansion.enriched.markdown.math.LatexErrorReporter - import com.swmansion.enriched.markdown.parser.Md4cFlags - import com.swmansion.enriched.markdown.parser.Parser -@@ -102,6 +103,8 @@ class EnrichedMarkdownText - - var md4cFlags: Md4cFlags = Md4cFlags.DEFAULT - private set -+ private var linkRegex: LinkRegexConfig? = null -+ private var inlineCodeLinkRegex: LinkRegexConfig? = null - private var isGFM: Boolean = false - - private var lastKnownFontScale: Float = context.resources.configuration.fontScale -@@ -185,6 +188,18 @@ class EnrichedMarkdownText - } - } - -+ fun setLinkRegex(config: LinkRegexConfig?) { -+ if (linkRegex == config) return -+ linkRegex = config -+ scheduleRenderIfNeeded() -+ } -+ -+ fun setInlineCodeLinkRegex(config: LinkRegexConfig?) { -+ if (inlineCodeLinkRegex == config) return -+ inlineCodeLinkRegex = config -+ scheduleRenderIfNeeded() -+ } -+ - fun setMd4cFlags(flags: Md4cFlags) { - if (md4cFlags == flags) return - md4cFlags = flags -@@ -271,12 +286,14 @@ class EnrichedMarkdownText - val markdown = currentMarkdown - if (markdown.isEmpty()) return - -+ val textLinkRegex = linkRegex -+ val codeLinkRegex = inlineCodeLinkRegex - val renderId = ++currentRenderId - - executor.execute { - try { - val ast = -- parser.parseMarkdown(markdown, md4cFlags, isGFM) ?: run { -+ parser.parseMarkdown(markdown, md4cFlags, isGFM, textLinkRegex, codeLinkRegex) ?: run { - mainHandler.post { if (renderId == currentRenderId && isAttachedToWindow) text = "" } - return@execute - } -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt -index 442567d5f006966204f48f37f061f304b39592df..5ad3d1fcc3819d4dda610f863757c1f2cdadfb77 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt -@@ -13,6 +13,7 @@ import com.facebook.react.uimanager.annotations.ReactProp - import com.facebook.react.viewmanagers.EnrichedMarkdownTextManagerDelegate - import com.facebook.react.viewmanagers.EnrichedMarkdownTextManagerInterface - import com.facebook.yoga.YogaMeasureMode -+import com.swmansion.enriched.markdown.parser.parseTextLinkRegex - import com.swmansion.enriched.markdown.spoiler.SpoilerOverlay - import com.swmansion.enriched.markdown.utils.common.applyReactBorderProps - import com.swmansion.enriched.markdown.utils.common.emitContextMenuItemPress -@@ -149,6 +150,22 @@ class EnrichedMarkdownTextManager : - view?.setSelectionHandleColor(value) - } - -+ @ReactProp(name = "linkRegex") -+ override fun setLinkRegex( -+ view: EnrichedMarkdownText?, -+ value: ReadableMap?, -+ ) { -+ view?.setLinkRegex(parseTextLinkRegex(value)) -+ } -+ -+ @ReactProp(name = "inlineCodeLinkRegex") -+ override fun setInlineCodeLinkRegex( -+ view: EnrichedMarkdownText?, -+ value: ReadableMap?, -+ ) { -+ view?.setInlineCodeLinkRegex(parseTextLinkRegex(value)) -+ } -+ - @ReactProp(name = "md4cFlags") - override fun setMd4cFlags( - view: EnrichedMarkdownText?, -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt b/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt -index 160cc710dd7857bc517249857f0b6f71b5ec70b8..20a29bde47280a4fa0cd1681140c045195d41b5a 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt -@@ -13,8 +13,16 @@ import com.facebook.react.bridge.ReadableMap - import com.facebook.react.uimanager.PixelUtil - import com.facebook.yoga.YogaMeasureMode - import com.facebook.yoga.YogaMeasureOutput -+import com.swmansion.enriched.markdown.input.autolink.LinkRegexConfig -+import com.swmansion.enriched.markdown.media.DocumentAssets -+import com.swmansion.enriched.markdown.media.MediaSlotView -+import com.swmansion.enriched.markdown.media.mediaSlotsForDocument -+import com.swmansion.enriched.markdown.media.parseImageSources -+import com.swmansion.enriched.markdown.media.parseMediaOverrides -+import com.swmansion.enriched.markdown.media.withImageSources - import com.swmansion.enriched.markdown.parser.Md4cFlags - import com.swmansion.enriched.markdown.parser.Parser -+import com.swmansion.enriched.markdown.parser.parseTextLinkRegex - import com.swmansion.enriched.markdown.renderer.Renderer - import com.swmansion.enriched.markdown.segments.BlockquoteContainerView - import com.swmansion.enriched.markdown.segments.CodeBlockContainerView -@@ -328,6 +336,8 @@ object MeasurementStore { - var result = markdown.hashCode() - result = 31 * result + (styleMap?.hashCode() ?: 0) - result = 31 * result + (md4cFlagsMap?.hashCode() ?: 0) -+ result = 31 * result + (parseTextLinkRegex(props.getMapOrNull("linkRegex"))?.hashCode() ?: 0) -+ result = 31 * result + (parseTextLinkRegex(props.getMapOrNull("inlineCodeLinkRegex"))?.hashCode() ?: 0) - result = 31 * result + fontScale.toBits() - result = 31 * result + allowFontScaling.hashCode() - result = 31 * result + maxFontSizeMultiplier.toBits() -@@ -335,6 +345,14 @@ object MeasurementStore { - result = 31 * result + imageRequestHeaders.hashCode() - result = 31 * result + props.getIntOrDefault("numberOfLines", 0) - result = 31 * result + props.getStringOrDefault("ellipsizeMode", EllipsizeUtils.DEFAULT_MODE).hashCode() -+ result = 31 * result + props.getBooleanOrDefault("enableImageSourceResolution", false).hashCode() -+ result = 31 * result + props.getIntOrDefault("imageSourcesRevision", -1) -+ result = 31 * result + props.getIntOrDefault("imageSourcesContinuityStart", 1) -+ result = 31 * result + parseImageSources(props.getArrayOrNull("imageSources")).hashCode() -+ result = 31 * result + props.getIntOrDefault("documentRevision", 0) -+ result = 31 * result + props.getIntOrDefault("mediaOverridesRevision", -1) -+ result = 31 * result + props.getBooleanOrDefault("enableMediaSlots", false).hashCode() -+ result = 31 * result + parseMediaOverrides(props.getArrayOrNull("mediaOverrides")).hashCode() - return result - } - -@@ -405,6 +423,8 @@ object MeasurementStore { - allowFontScaling, - maxFontSizeMultiplier, - imageRequestHeaders, -+ parseTextLinkRegex(props.getMapOrNull("linkRegex")), -+ parseTextLinkRegex(props.getMapOrNull("inlineCodeLinkRegex")), - ) - spannable?.replaceMathSpansWithPlaceholders(context) - val textToMeasure = spannable ?: markdown -@@ -497,12 +517,36 @@ object MeasurementStore { - - return try { - val ast = -- Parser.shared.parseMarkdown(markdown, md4cFlags, isGFM) -+ Parser.shared.parseMarkdown( -+ markdown, -+ md4cFlags, -+ isGFM, -+ parseTextLinkRegex(props.getMapOrNull("linkRegex")), -+ parseTextLinkRegex(props.getMapOrNull("inlineCodeLinkRegex")), -+ ) - ?: return YogaMeasureOutput.make(PixelUtil.toDIPFromPixel(width), 0f) - - val style = StyleConfig(styleMap, context, allowFontScaling, maxFontSizeMultiplier) - style.imageRequestHeaders = parseImageRequestHeaders(props.getArrayOrNull("imageRequestHeaders")) -- val segments = splitASTIntoSegments(ast) -+ val sourceAST = -+ withImageSources( -+ ast, -+ isGFM && props.getBooleanOrDefault("enableImageSourceResolution", false), -+ props.getIntOrDefault("documentRevision", 0), -+ props.getIntOrDefault("imageSourcesRevision", -1), -+ props.getIntOrDefault("imageSourcesContinuityStart", 1), -+ parseImageSources(props.getArrayOrNull("imageSources")), -+ ) -+ val assets = DocumentAssets.collect(sourceAST) -+ val mediaSlots = -+ mediaSlotsForDocument( -+ assets, -+ props.getBooleanOrDefault("enableMediaSlots", false), -+ props.getIntOrDefault("documentRevision", 0), -+ props.getIntOrDefault("mediaOverridesRevision", -1), -+ parseMediaOverrides(props.getArrayOrNull("mediaOverrides")), -+ ) -+ val segments = splitASTIntoSegments(sourceAST, mediaSlots, assets) - val renderedSegments = MarkdownSegmentRenderer.render(segments, style, context, null, null) - - val mathHeightByIndex = HashMap() -@@ -582,7 +626,15 @@ object MeasurementStore { - - is RenderedSegment.Blockquote -> { - totalHeightPx += style.blockquoteStyle.marginTop -- totalHeightPx += BlockquoteContainerView.measureBlockquoteNodeHeight(segment.node, style, context, width) -+ totalHeightPx += -+ BlockquoteContainerView.measureBlockquoteNodeHeight( -+ segment.node, -+ style, -+ context, -+ width, -+ segment.mediaSlots, -+ segment.assets, -+ ) - maxContentWidthPx = width - if (includeBottomMargin) { - totalHeightPx += style.blockquoteStyle.marginBottom -@@ -590,11 +642,12 @@ object MeasurementStore { - } - - is RenderedSegment.Video -> { -- totalHeightPx += style.videoStyle.marginTop -- totalHeightPx += width / style.videoStyle.resolvedAspectRatio -+ totalHeightPx += segment.mediaSlot?.let { MediaSlotView.marginTop(it, style) } ?: style.videoStyle.marginTop -+ totalHeightPx += -+ segment.mediaSlot?.let { MediaSlotView.heightPx(it, style, width) } ?: (width / style.videoStyle.resolvedAspectRatio) - maxContentWidthPx = width - if (includeBottomMargin) { -- totalHeightPx += style.videoStyle.marginBottom -+ totalHeightPx += segment.mediaSlot?.let { MediaSlotView.marginBottom(it, style) } ?: style.videoStyle.marginBottom - } - } - } -@@ -618,6 +671,8 @@ object MeasurementStore { - text: CharSequence?, - widthPx: Int, - ) { -+ com.swmansion.enriched.markdown.spans.LinkPillSpan -+ .prepareForMeasurement(text, widthPx) - // widthPx == 1 is the coerceAtLeast(1) fallback for a not-yet-measured view - if (widthPx <= 1) return - val spanned = text as? android.text.Spanned ?: return -@@ -658,11 +713,13 @@ object MeasurementStore { - allowFontScaling: Boolean, - maxFontSizeMultiplier: Float, - imageRequestHeaders: Map = emptyMap(), -+ linkRegex: LinkRegexConfig? = null, -+ inlineCodeLinkRegex: LinkRegexConfig? = null, - ): SpannableString? { - if (styleMap == null) return null - - return try { -- val ast = Parser.shared.parseMarkdown(markdown, md4cFlags, isGFM) ?: return null -+ val ast = Parser.shared.parseMarkdown(markdown, md4cFlags, isGFM, linkRegex, inlineCodeLinkRegex) ?: return null - val style = StyleConfig(styleMap, context, allowFontScaling, maxFontSizeMultiplier) - style.imageRequestHeaders = imageRequestHeaders - measureRenderer.configure(style, context) -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/accessibility/AccessibleMarkdownTextView.kt b/android/src/main/java/com/swmansion/enriched/markdown/accessibility/AccessibleMarkdownTextView.kt -index 9de3bedd2226f67127eacc690cf6d37e241e85f3..49dfb95b8e0e727b137d45b6e1fade9f761c519f 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/accessibility/AccessibleMarkdownTextView.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/accessibility/AccessibleMarkdownTextView.kt -@@ -17,6 +17,23 @@ abstract class AccessibleMarkdownTextView - ) : AppCompatTextView(context, attrs, defStyleAttr) { - val accessibilityHelper = MarkdownAccessibilityHelper(this) - -+ override fun onMeasure( -+ widthMeasureSpec: Int, -+ heightMeasureSpec: Int, -+ ) { -+ if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED) { -+ val width = (MeasureSpec.getSize(widthMeasureSpec) - compoundPaddingLeft - compoundPaddingRight).coerceAtLeast(1) -+ if (com.swmansion.enriched.markdown.spans.LinkPillSpan -+ .prepareForMeasurement(text, width) -+ ) { -+ // TextView can reuse a layout at the same width after a style or label change. -+ val current = text -+ text = current -+ } -+ } -+ super.onMeasure(widthMeasureSpec, heightMeasureSpec) -+ } -+ - override fun dispatchHoverEvent(event: MotionEvent): Boolean = - accessibilityHelper.dispatchHoverEvent(event) || super.dispatchHoverEvent(event) - -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/media/DocumentAssets.kt b/android/src/main/java/com/swmansion/enriched/markdown/media/DocumentAssets.kt -new file mode 100644 -index 0000000000000000000000000000000000000000..18eeaec07394b35df85aae90b459ac3e22c08373 ---- /dev/null -+++ b/android/src/main/java/com/swmansion/enriched/markdown/media/DocumentAssets.kt -@@ -0,0 +1,156 @@ -+package com.swmansion.enriched.markdown.media -+ -+import com.swmansion.enriched.markdown.parser.MarkdownASTNode -+import java.util.IdentityHashMap -+import kotlin.math.abs -+ -+/** Descriptors come from the accepted native AST, including occurrences we cannot override. */ -+data class DocumentAsset( -+ val id: String, -+ val kind: String, -+ val url: String, -+ val altText: String, -+ val title: String, -+ val placement: String, -+ val eligible: Boolean, -+ val anchor: String, -+) -+ -+class DocumentAssets private constructor( -+ val assets: List, -+ private val byNode: IdentityHashMap, -+) { -+ fun assetForNode(node: MarkdownASTNode): DocumentAsset? = byNode[node] -+ -+ companion object { -+ fun collect(root: MarkdownASTNode): DocumentAssets { -+ val assets = mutableListOf() -+ val byNode = IdentityHashMap() -+ -+ fun text(node: MarkdownASTNode): String = node.content + node.children.joinToString("") { text(it) } -+ -+ fun visit( -+ node: MarkdownASTNode, -+ parent: MarkdownASTNode?, -+ placement: String, -+ path: String, -+ parentPath: String, -+ parentIsSegmentContainer: Boolean, -+ parentIsSegmentParagraph: Boolean, -+ ) { -+ val nestedPlacement = -+ when (node.type) { -+ MarkdownASTNode.NodeType.Table -> "table" -+ -+ MarkdownASTNode.NodeType.UnorderedList, -+ MarkdownASTNode.NodeType.OrderedList, -+ -> "list" -+ -+ MarkdownASTNode.NodeType.Blockquote, -+ MarkdownASTNode.NodeType.Admonition, -+ -> "blockquote" -+ -+ else -> placement -+ } -+ val isSegmentContainer = -+ node === root || -+ ( -+ parentIsSegmentContainer && -+ (node.type == MarkdownASTNode.NodeType.Blockquote || node.type == MarkdownASTNode.NodeType.Admonition) -+ ) -+ val kind = -+ when (node.type) { -+ MarkdownASTNode.NodeType.Image -> "image" -+ MarkdownASTNode.NodeType.Video -> "video" -+ MarkdownASTNode.NodeType.Link -> "link" -+ else -> null -+ } -+ if (kind != null) { -+ val standaloneImage = -+ kind == "image" && parent?.type == MarkdownASTNode.NodeType.Paragraph && -+ parent.children.size == 1 && parentIsSegmentParagraph -+ val eligible = standaloneImage || (kind == "video" && parentIsSegmentContainer) -+ val asset = -+ DocumentAsset( -+ id = "asset-${assets.size}", -+ kind = kind, -+ url = node.getAttribute("url") ?: "", -+ altText = text(node).trim(), -+ title = node.getAttribute("title") ?: "", -+ placement = -+ if (eligible && nestedPlacement == "block") { -+ "block" -+ } else if (nestedPlacement == "block") { -+ "inline" -+ } else { -+ nestedPlacement -+ }, -+ eligible = eligible, -+ anchor = if (standaloneImage) parentPath else path, -+ ) -+ assets.add(asset) -+ byNode[node] = asset -+ } -+ node.children.forEachIndexed { index, child -> -+ visit( -+ child, -+ node, -+ nestedPlacement, -+ "$path.$index", -+ path, -+ isSegmentContainer, -+ node.type == MarkdownASTNode.NodeType.Paragraph && parentIsSegmentContainer, -+ ) -+ } -+ } -+ visit(root, null, "block", "0", "", false, false) -+ return DocumentAssets(assets, byNode) -+ } -+ } -+} -+ -+/** Values are DIP. A zero width denotes a provisional height, valid at any width. */ -+data class MediaOverride( -+ val id: String, -+ val height: Float, -+ val width: Float, -+ val url: String, -+ val kind: String, -+ val anchor: String, -+) { -+ fun matches(asset: DocumentAsset): Boolean = -+ asset.eligible && id == asset.id && url == asset.url && kind == asset.kind && anchor == asset.anchor -+} -+ -+data class MediaSlot( -+ val asset: DocumentAsset, -+ val measuredOverride: MediaOverride?, -+) { -+ fun heightForWidth( -+ width: Float, -+ fallback: Float, -+ ): Float { -+ val value = measuredOverride ?: return fallback -+ return if (value.height.isFinite() && value.height >= 0 && -+ (value.width == 0f || abs(value.width - width) < 0.5f) -+ ) { -+ value.height -+ } else { -+ fallback -+ } -+ } -+} -+ -+fun mediaSlotsForDocument( -+ assets: DocumentAssets, -+ enabled: Boolean, -+ revision: Int, -+ overridesRevision: Int, -+ overrides: List, -+): Map { -+ if (!enabled) return emptyMap() -+ val decisions = overrides.associateBy { it.id } -+ return assets.assets -+ .filter { it.eligible && (overridesRevision != revision || decisions.containsKey(it.id)) } -+ .associate { asset -> asset.id to MediaSlot(asset, decisions[asset.id]?.takeIf { it.matches(asset) }) } -+} -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/media/ImageSourceBridge.kt b/android/src/main/java/com/swmansion/enriched/markdown/media/ImageSourceBridge.kt -new file mode 100644 -index 0000000000000000000000000000000000000000..073c6f343df872ef2e20ad94964f7ba1e9b52718 ---- /dev/null -+++ b/android/src/main/java/com/swmansion/enriched/markdown/media/ImageSourceBridge.kt -@@ -0,0 +1,20 @@ -+package com.swmansion.enriched.markdown.media -+ -+import com.facebook.react.bridge.ReadableArray -+import com.swmansion.enriched.markdown.utils.common.parseImageRequestHeaders -+ -+fun parseImageSources(value: ReadableArray?): List = -+ (0 until (value?.size() ?: 0)).mapNotNull { index -> -+ val entry = value?.getMap(index) ?: return@mapNotNull null -+ val id = entry.getString("id") ?: return@mapNotNull null -+ val url = entry.getString("url") ?: return@mapNotNull null -+ val anchor = entry.getString("anchor") ?: return@mapNotNull null -+ ImageSourceDecision( -+ id, -+ url, -+ anchor, -+ entry.getString("uri") ?: "", -+ parseImageRequestHeaders(entry.getArray("headers")), -+ entry.getBoolean("useDefault"), -+ ) -+ } -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/media/ImageSources.kt b/android/src/main/java/com/swmansion/enriched/markdown/media/ImageSources.kt -new file mode 100644 -index 0000000000000000000000000000000000000000..0da0be7746c1af9ea07e04b2a2d5a09260cedfef ---- /dev/null -+++ b/android/src/main/java/com/swmansion/enriched/markdown/media/ImageSources.kt -@@ -0,0 +1,66 @@ -+package com.swmansion.enriched.markdown.media -+ -+import com.swmansion.enriched.markdown.parser.MarkdownASTNode -+import java.util.Locale -+ -+/** Download transport only. A null URI holds the normal native placeholder. */ -+data class ImageSourceTransport( -+ val uri: String?, -+ val headers: Map = emptyMap(), -+) -+ -+data class ImageSourceDecision( -+ val id: String, -+ val url: String, -+ val anchor: String, -+ val uri: String, -+ val headers: Map, -+ val useDefault: Boolean, -+) { -+ fun matches(asset: DocumentAsset): Boolean = asset.kind == "image" && id == asset.id && url == asset.url && anchor == asset.anchor -+} -+ -+/** Copies accepted AST nodes without changing any semantic attributes or cached parser trees. */ -+fun withImageSources( -+ root: MarkdownASTNode, -+ enabled: Boolean, -+ documentRevision: Int, -+ sourcesRevision: Int, -+ continuityStart: Int, -+ decisions: List, -+): MarkdownASTNode { -+ if (!enabled) return root -+ val assets = DocumentAssets.collect(root) -+ val acceptedDecisions = -+ if (sourcesRevision >= continuityStart && sourcesRevision <= documentRevision) { -+ decisions.associateBy { it.id } -+ } else { -+ emptyMap() -+ } -+ -+ fun visit(node: MarkdownASTNode): MarkdownASTNode { -+ val children = node.children.map { visit(it) } -+ if (node.type != MarkdownASTNode.NodeType.Image) return node.copy(children = children) -+ val asset = assets.assetForNode(node) -+ val decision = asset?.let { acceptedDecisions[it.id]?.takeIf { source -> source.matches(it) } } -+ val transport = -+ when { -+ decision == null -> ImageSourceTransport(null) -+ decision.useDefault -> null -+ decision.uri.isBlank() -> ImageSourceTransport(null) -+ else -> ImageSourceTransport(decision.uri, decision.headers) -+ } -+ return node.copy(children = children, imageSource = transport) -+ } -+ return visit(root) -+} -+ -+/** HTTP field names are case-insensitive. Per-source values replace document values. */ -+fun mergeImageRequestHeaders( -+ document: Map, -+ source: Map, -+): Map = -+ buildMap { -+ document.forEach { (name, value) -> put(name.lowercase(Locale.ROOT), value) } -+ source.forEach { (name, value) -> put(name.lowercase(Locale.ROOT), value) } -+ } -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotBridge.kt b/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotBridge.kt -new file mode 100644 -index 0000000000000000000000000000000000000000..682ae9341e8500fffc07d5f8a0651ad77859c030 ---- /dev/null -+++ b/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotBridge.kt -@@ -0,0 +1,70 @@ -+package com.swmansion.enriched.markdown.media -+ -+import android.view.View -+import com.facebook.react.bridge.Arguments -+import com.facebook.react.bridge.ReactContext -+import com.facebook.react.bridge.ReadableArray -+import com.facebook.react.bridge.WritableMap -+import com.facebook.react.uimanager.UIManagerHelper -+import com.facebook.react.uimanager.events.Event -+ -+fun parseMediaOverrides(value: ReadableArray?): List = -+ (0 until (value?.size() ?: 0)).mapNotNull { index -> -+ val entry = value?.getMap(index) ?: return@mapNotNull null -+ val id = entry.getString("id") ?: return@mapNotNull null -+ val url = entry.getString("url") ?: return@mapNotNull null -+ val kind = entry.getString("kind") ?: return@mapNotNull null -+ val anchor = entry.getString("anchor") ?: return@mapNotNull null -+ val height = entry.getDouble("height").toFloat() -+ val width = entry.getDouble("width").toFloat() -+ if (!height.isFinite() || height < 0 || !width.isFinite() || width < 0) null else MediaOverride(id, height, width, url, kind, anchor) -+ } -+ -+fun emitMediaEvent( -+ view: View, -+ name: String, -+ data: WritableMap, -+): Boolean { -+ val context = view.context as ReactContext -+ val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id) ?: return false -+ dispatcher.dispatchEvent(MediaEvent(UIManagerHelper.getSurfaceId(context), view.id, name, data)) -+ return true -+} -+ -+fun documentAssetsEventData( -+ revision: Int, -+ assets: List, -+): WritableMap { -+ val entries = Arguments.createArray() -+ assets.forEach { asset -> -+ entries.pushMap( -+ Arguments.createMap().apply { -+ putString("id", asset.id) -+ putString("kind", asset.kind) -+ putString("url", asset.url) -+ putString("altText", asset.altText) -+ putString("title", asset.title) -+ putString("placement", asset.placement) -+ putBoolean("eligible", asset.eligible) -+ putString("anchor", asset.anchor) -+ }, -+ ) -+ } -+ return Arguments.createMap().apply { -+ putInt("revision", revision) -+ putArray("assets", entries) -+ } -+} -+ -+private class MediaEvent( -+ surfaceId: Int, -+ viewId: Int, -+ private val name: String, -+ private val data: WritableMap, -+) : Event(surfaceId, viewId) { -+ override fun getEventName(): String = name -+ -+ override fun getEventData(): WritableMap = data -+ -+ override fun canCoalesce(): Boolean = false -+} -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotFrame.kt b/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotFrame.kt -new file mode 100644 -index 0000000000000000000000000000000000000000..3bd8794a92575c32e4d5698ab0b8049ad51d3637 ---- /dev/null -+++ b/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotFrame.kt -@@ -0,0 +1,15 @@ -+package com.swmansion.enriched.markdown.media -+ -+/** Native pixels; conversion to DIP happens once at the root event boundary. */ -+data class MediaSlotFrame( -+ val id: String, -+ val x: Int, -+ val y: Int, -+ val width: Int, -+ val height: Int, -+) { -+ fun translated( -+ offsetX: Int, -+ offsetY: Int, -+ ): MediaSlotFrame = copy(x = x + offsetX, y = y + offsetY) -+} -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotView.kt b/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotView.kt -new file mode 100644 -index 0000000000000000000000000000000000000000..6d0ffd950300cabc4204930a6b3b0b7db8aac8c2 ---- /dev/null -+++ b/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotView.kt -@@ -0,0 +1,71 @@ -+package com.swmansion.enriched.markdown.media -+ -+import android.content.Context -+import android.view.View -+import com.facebook.react.uimanager.PixelUtil -+import com.swmansion.enriched.markdown.segments.BlockSegmentView -+import com.swmansion.enriched.markdown.styles.StyleConfig -+import kotlin.math.ceil -+ -+/** A measured, inaccessible native box. React owns its visual and interactive content. */ -+class MediaSlotView( -+ context: Context, -+ private val style: StyleConfig, -+ slot: MediaSlot, -+) : View(context), -+ BlockSegmentView { -+ var slot: MediaSlot = slot -+ set(value) { -+ if (field == value) return -+ field = value -+ requestLayout() -+ } -+ -+ init { -+ importantForAccessibility = IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS -+ isFocusable = false -+ } -+ -+ override val segmentMarginTop: Int get() = ceil(marginTop(slot, style)).toInt() -+ override val segmentMarginBottom: Int get() = ceil(marginBottom(slot, style)).toInt() -+ -+ override fun onMeasure( -+ widthMeasureSpec: Int, -+ heightMeasureSpec: Int, -+ ) { -+ val width = MeasureSpec.getSize(widthMeasureSpec) -+ setMeasuredDimension(width, ceil(heightPx(slot, style, width.toFloat())).toInt()) -+ } -+ -+ companion object { -+ fun marginTop( -+ slot: MediaSlot, -+ style: StyleConfig, -+ ): Float = ceil(if (slot.asset.kind == "video") style.videoStyle.marginTop else style.imageStyle.marginTop) -+ -+ fun marginBottom( -+ slot: MediaSlot, -+ style: StyleConfig, -+ ): Float = ceil(if (slot.asset.kind == "video") style.videoStyle.marginBottom else style.imageStyle.marginBottom) -+ -+ fun heightPx( -+ slot: MediaSlot, -+ style: StyleConfig, -+ width: Float, -+ ): Float { -+ val fallback = -+ if (slot.asset.kind == "video") { -+ width / style.videoStyle.resolvedAspectRatio -+ } else { -+ val image = style.imageStyle -+ val value = if (image.aspectRatio > 0) width / image.aspectRatio else image.height -+ if (image.maxHeight > 0) value.coerceAtMost(image.maxHeight) else value -+ } -+ return ceil( -+ PixelUtil.toPixelFromDIP( -+ slot.heightForWidth(PixelUtil.toDIPFromPixel(width), PixelUtil.toDIPFromPixel(fallback)), -+ ), -+ ) -+ } -+ } -+} -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt b/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt -index 8b8bce9d71d5a07e659d587c3efd75ee50277f55..4ce6880723db777ff5eeb0300b7dafe9e0246610 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt -@@ -1,50 +1,55 @@ - package com.swmansion.enriched.markdown.parser - --data class MarkdownASTNode( -- val type: NodeType, -- val content: String = "", -- val attributes: Map = emptyMap(), -- val children: List = emptyList(), --) { -- enum class NodeType { -- Document, -- Paragraph, -- Text, -- Link, -- Heading, -- LineBreak, -- Strong, -- Emphasis, -- Strikethrough, -- Underline, -- Code, -- Image, -- Blockquote, -- UnorderedList, -- OrderedList, -- ListItem, -- CodeBlock, -- ThematicBreak, -- Table, -- TableHead, -- TableBody, -- TableRow, -- TableHeaderCell, -- TableCell, -- LatexMathInline, -- LatexMathDisplay, -- Spoiler, -- Superscript, -- Subscript, -- Highlight, -- SoftBreak, -- BlankLine, -- Admonition, -- Video, -- } -+import com.swmansion.enriched.markdown.media.ImageSourceTransport -+ -+data class MarkdownASTNode -+ @JvmOverloads -+ constructor( -+ val type: NodeType, -+ val content: String = "", -+ val attributes: Map = emptyMap(), -+ val children: List = emptyList(), -+ val imageSource: ImageSourceTransport? = null, -+ ) { -+ enum class NodeType { -+ Document, -+ Paragraph, -+ Text, -+ Link, -+ Heading, -+ LineBreak, -+ Strong, -+ Emphasis, -+ Strikethrough, -+ Underline, -+ Code, -+ Image, -+ Blockquote, -+ UnorderedList, -+ OrderedList, -+ ListItem, -+ CodeBlock, -+ ThematicBreak, -+ Table, -+ TableHead, -+ TableBody, -+ TableRow, -+ TableHeaderCell, -+ TableCell, -+ LatexMathInline, -+ LatexMathDisplay, -+ Spoiler, -+ Superscript, -+ Subscript, -+ Highlight, -+ SoftBreak, -+ BlankLine, -+ Admonition, -+ Video, -+ } - -- fun getAttribute(key: String): String? = attributes[key] --} -+ fun getAttribute(key: String): String? = attributes[key] -+ } - - // A node type that md4c emits as a standalone block stacked vertically, as opposed to an inline span. - internal fun MarkdownASTNode.NodeType.isTopLevelBlock(): Boolean = -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt b/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt -index 217d46473a8cf6f1f6c6439bf0b802c328531b83..1fd34d2a4675fc786a1b48349bfef967b6cb5c68 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt -@@ -1,6 +1,7 @@ - package com.swmansion.enriched.markdown.parser - - import android.util.Log -+import com.swmansion.enriched.markdown.input.autolink.LinkRegexConfig - import com.swmansion.enriched.markdown.utils.common.FeatureFlags - - data class Md4cFlags( -@@ -51,6 +52,8 @@ class Parser { - markdown: String, - flags: Md4cFlags = Md4cFlags.DEFAULT, - isGFM: Boolean = true, -+ linkRegex: LinkRegexConfig? = null, -+ inlineCodeLinkRegex: LinkRegexConfig? = null, - ): MarkdownASTNode? { - if (markdown.isBlank()) { - return null -@@ -60,7 +63,7 @@ class Parser { - val ast = nativeParseMarkdown(markdown, flags, isGFM) - - if (ast != null) { -- return ast -+ return TextLinkRecognizer.recognize(ast, linkRegex, inlineCodeLinkRegex) - } else { - Log.w("MarkdownParser", "Native parser returned null") - return null -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/parser/TextLinkRecognizer.kt b/android/src/main/java/com/swmansion/enriched/markdown/parser/TextLinkRecognizer.kt -new file mode 100644 -index 0000000000000000000000000000000000000000..6d8b5faa65bd315ec67911dbe0300a26b9cbcd81 ---- /dev/null -+++ b/android/src/main/java/com/swmansion/enriched/markdown/parser/TextLinkRecognizer.kt -@@ -0,0 +1,89 @@ -+package com.swmansion.enriched.markdown.parser -+ -+import com.swmansion.enriched.markdown.input.autolink.LinkRegexConfig -+import com.swmansion.enriched.markdown.parser.MarkdownASTNode.NodeType -+import java.util.regex.Pattern -+import java.util.regex.PatternSyntaxException -+ -+/** Native regex parity with iOS ENRMTextLinkRecognizer, applied before AST consumers. */ -+object TextLinkRecognizer { -+ fun recognize( -+ ast: MarkdownASTNode, -+ linkRegex: LinkRegexConfig? = null, -+ inlineCodeLinkRegex: LinkRegexConfig? = null, -+ ): MarkdownASTNode { -+ val textPattern = compile(linkRegex) -+ val codePattern = compile(inlineCodeLinkRegex, wholeSpan = true) -+ if (textPattern == null && codePattern == null) return ast -+ -+ fun link( -+ child: MarkdownASTNode, -+ url: String, -+ ): MarkdownASTNode = -+ MarkdownASTNode( -+ NodeType.Link, -+ attributes = mapOf("url" to url, "recognizedLink" to "true"), -+ children = listOf(child), -+ ) -+ -+ fun transform(node: MarkdownASTNode): List { -+ when (node.type) { -+ NodeType.Link, NodeType.CodeBlock, NodeType.Image, NodeType.Video, -+ NodeType.LatexMathInline, NodeType.LatexMathDisplay, -+ -> { -+ return listOf(node) -+ } -+ -+ NodeType.Code -> { -+ // Code renderers concatenate the parser's text children verbatim. -+ val content = node.children.joinToString("") { it.content } -+ val matcher = codePattern?.matcher(content) -+ if (content.isNotEmpty() && matcher != null && matcher.find() && matcher.start() == 0 && matcher.end() == content.length) { -+ return listOf(link(node, content)) -+ } -+ return listOf(node) -+ } -+ -+ NodeType.Text -> { -+ val matcher = textPattern?.matcher(node.content) ?: return listOf(node) -+ val result = mutableListOf() -+ var offset = 0 -+ while (matcher.find()) { -+ val start = matcher.start() -+ val end = matcher.end() -+ if (start == end) continue -+ if (start > offset) result.add(node.copy(content = node.content.substring(offset, start))) -+ val matched = node.content.substring(start, end) -+ result.add(link(node.copy(content = matched), matched)) -+ offset = end -+ } -+ if (offset == 0) return listOf(node) -+ if (offset < node.content.length) result.add(node.copy(content = node.content.substring(offset))) -+ return result -+ } -+ -+ else -> { -+ return listOf(node.copy(children = node.children.flatMap { transform(it) })) -+ } -+ } -+ } -+ -+ // Documents are containers, so recognition never changes their root type. -+ return ast.copy(children = ast.children.flatMap { transform(it) }) -+ } -+ -+ private fun compile( -+ config: LinkRegexConfig?, -+ wholeSpan: Boolean = false, -+ ): Pattern? { -+ if (config == null || config.isDisabled || config.isDefault || config.pattern.isEmpty()) return null -+ var flags = 0 -+ if (config.caseInsensitive) flags = flags or Pattern.CASE_INSENSITIVE -+ if (config.dotAll) flags = flags or Pattern.DOTALL -+ return try { -+ Pattern.compile(if (wholeSpan) "\\A(?:${config.pattern})\\z" else config.pattern, flags) -+ } catch (_: PatternSyntaxException) { -+ null -+ } -+ } -+} -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/parser/TextLinkRegexProps.kt b/android/src/main/java/com/swmansion/enriched/markdown/parser/TextLinkRegexProps.kt -new file mode 100644 -index 0000000000000000000000000000000000000000..32e1219561fbd9c741d8711c75a763cc19181521 ---- /dev/null -+++ b/android/src/main/java/com/swmansion/enriched/markdown/parser/TextLinkRegexProps.kt -@@ -0,0 +1,15 @@ -+package com.swmansion.enriched.markdown.parser -+ -+import com.facebook.react.bridge.ReadableMap -+import com.swmansion.enriched.markdown.input.autolink.LinkRegexConfig -+ -+internal fun parseTextLinkRegex(map: ReadableMap?): LinkRegexConfig? { -+ if (map == null) return null -+ return LinkRegexConfig( -+ pattern = if (map.hasKey("pattern")) map.getString("pattern") ?: "" else "", -+ caseInsensitive = map.hasKey("caseInsensitive") && map.getBoolean("caseInsensitive"), -+ dotAll = map.hasKey("dotAll") && map.getBoolean("dotAll"), -+ isDisabled = !map.hasKey("isDisabled") || map.getBoolean("isDisabled"), -+ isDefault = map.hasKey("isDefault") && map.getBoolean("isDefault"), -+ ) -+} -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/renderer/ImageRenderer.kt b/android/src/main/java/com/swmansion/enriched/markdown/renderer/ImageRenderer.kt -index 0047361a70d925ec1d5cf8f34aed814e036e277c..5cd48d60bd70f97eaa3de58bdbe853cf11b213ee 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/renderer/ImageRenderer.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/renderer/ImageRenderer.kt -@@ -29,6 +29,7 @@ class ImageRenderer : NodeRenderer { - imageUrl = imageUrl, - isInline = isInline, - altText = altText, -+ imageSource = node.imageSource, - ) - - builder.setSpan( -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt b/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt -index 7beb976e1daa8eeee864edca6da33cd2e358ba7f..e49a12080732653cfe7416294b3eb8fef21e0a79 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt -@@ -1,8 +1,11 @@ - package com.swmansion.enriched.markdown.renderer - - import android.text.SpannableStringBuilder -+import android.text.TextPaint - import com.swmansion.enriched.markdown.parser.MarkdownASTNode -+import com.swmansion.enriched.markdown.spans.LinkPillSpan - import com.swmansion.enriched.markdown.spans.LinkSpan -+import com.swmansion.enriched.markdown.utils.text.extensions.applyBlockStyleFont - import com.swmansion.enriched.markdown.utils.text.span.SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE - - class LinkRenderer( -@@ -16,10 +19,35 @@ class LinkRenderer( - factory: RendererFactory, - ) { - val url = node.getAttribute("url") ?: return -+ val recognizedLink = node.getAttribute("recognizedLink") == "true" - - factory.renderWithSpan(builder, { factory.renderChildren(node, builder, onLinkPress, onLinkLongPress) }) { start, end, blockStyle -> -+ val variant = factory.styleCache.resolvedVariantForUrl(url) -+ if (variant?.pill == true && builder.getSpans(start, end, android.text.style.ReplacementSpan::class.java).isEmpty()) { -+ val fontFamily = variant.fontFamily.ifEmpty { factory.styleCache.linkFontFamily }.ifEmpty { blockStyle.fontFamily } -+ val font = TextPaint().apply { applyBlockStyleFont(blockStyle.copy(fontFamily = fontFamily), factory.context) } -+ factory.registerDeferredSpan( -+ LinkPillSpan( -+ variant, -+ font.typeface, -+ blockStyle.fontSize, -+ builder.subSequence(start, end).toString(), -+ ), -+ start, -+ end, -+ ) -+ } - builder.setSpan( -- LinkSpan(url, onLinkPress, onLinkLongPress, factory.styleCache, blockStyle, factory.context), -+ LinkSpan( -+ url, -+ onLinkPress, -+ onLinkLongPress, -+ factory.styleCache, -+ blockStyle, -+ factory.context, -+ preserveCodeFont = recognizedLink && node.children.any { it.type == MarkdownASTNode.NodeType.Code }, -+ recognizedLink = recognizedLink, -+ ), - start, - end, - SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE, -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt b/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt -index a0f37cdafe25dcadb0dcbbc8a63494acbd148070..f3dd36f771e5d366f5880e823951dcc83fab71b1 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt -@@ -4,6 +4,7 @@ import android.content.Context - import android.text.SpannableStringBuilder - import android.text.style.MetricAffectingSpan - import com.swmansion.enriched.markdown.math.LatexErrorReporter -+import com.swmansion.enriched.markdown.media.ImageSourceTransport - import com.swmansion.enriched.markdown.parser.MarkdownASTNode - import com.swmansion.enriched.markdown.spans.ImageSpan - import com.swmansion.enriched.markdown.styles.StyleConfig -@@ -71,6 +72,7 @@ class RendererFactory( - imageUrl: String, - isInline: Boolean, - altText: String, -+ imageSource: ImageSourceTransport? = null, - ): ImageSpan = - ImageSpan( - context = context, -@@ -78,6 +80,7 @@ class RendererFactory( - styleConfig = config.style, - isInline = isInline, - altText = altText, -+ imageSource = imageSource, - ) - - private val textRenderer = TextRenderer() -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/BlockquoteContainerView.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/BlockquoteContainerView.kt -index 8027e6054946a9402a0db1711d7475a14b98c490..54c1eaec45701d1a31ecc1af9937852bb3ae34c7 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/segments/BlockquoteContainerView.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/BlockquoteContainerView.kt -@@ -14,6 +14,9 @@ import androidx.core.graphics.withSave - import com.facebook.react.common.ReactConstants - import com.facebook.react.views.text.ReactTypefaceUtils.applyStyles - import com.swmansion.enriched.markdown.EnrichedMarkdownInternalText -+import com.swmansion.enriched.markdown.media.DocumentAssets -+import com.swmansion.enriched.markdown.media.MediaSlot -+import com.swmansion.enriched.markdown.media.MediaSlotView - import com.swmansion.enriched.markdown.parser.MarkdownASTNode - import com.swmansion.enriched.markdown.styles.BlockquoteStyle - import com.swmansion.enriched.markdown.styles.StyleConfig -@@ -115,7 +118,11 @@ class BlockquoteContainerView( - setOnLongClickListener { view -> showContextMenu(view) } - } - -- fun applyBlockquoteNode(node: MarkdownASTNode) { -+ fun applyBlockquoteNode( -+ node: MarkdownASTNode, -+ mediaSlots: Map = emptyMap(), -+ assets: DocumentAssets? = null, -+ ) { - admonitionType = - if (node.type == MarkdownASTNode.NodeType.Admonition) { - node.getAttribute("admonitionType")?.takeIf { it.isNotEmpty() } ?: "note" -@@ -128,7 +135,7 @@ class BlockquoteContainerView( - cachedMarkdown = MarkdownASTSerializer.serializeBlockquote(node) - cachedPlainText = MarkdownASTSerializer.plainText(node) - -- val segments = splitASTIntoSegments(node) -+ val segments = splitASTIntoSegments(node, mediaSlots, assets) - val rendered = - MarkdownSegmentRenderer.render( - segments, -@@ -276,12 +283,35 @@ class BlockquoteContainerView( - segment: RenderedSegment, - ): Boolean = - when (segment) { -- is RenderedSegment.Text -> view is EnrichedMarkdownInternalText -- is RenderedSegment.Table -> view is TableContainerView -- is RenderedSegment.Math -> SegmentViewCreators.isMathContainerView(view) -- is RenderedSegment.CodeBlock -> view is CodeBlockContainerView -- is RenderedSegment.Blockquote -> view is BlockquoteContainerView -- is RenderedSegment.Video -> SegmentViewCreators.isVideoContainerView(view) -+ is RenderedSegment.Text -> { -+ view is EnrichedMarkdownInternalText -+ } -+ -+ is RenderedSegment.Table -> { -+ view is TableContainerView -+ } -+ -+ is RenderedSegment.Math -> { -+ SegmentViewCreators.isMathContainerView(view) -+ } -+ -+ is RenderedSegment.CodeBlock -> { -+ view is CodeBlockContainerView -+ } -+ -+ is RenderedSegment.Blockquote -> { -+ view is BlockquoteContainerView -+ } -+ -+ is RenderedSegment.Video -> { -+ if (segment.mediaSlot != -+ null -+ ) { -+ view is MediaSlotView -+ } else { -+ SegmentViewCreators.isVideoContainerView(view) -+ } -+ } - } - - override fun createView(segment: RenderedSegment): View = -@@ -316,12 +346,33 @@ class BlockquoteContainerView( - segment: RenderedSegment, - ) { - when (segment) { -- is RenderedSegment.Text -> SegmentViewCreators.updateTextView(view as EnrichedMarkdownInternalText, segment) -- is RenderedSegment.Table -> (view as TableContainerView).applyTableNode(segment.node) -- is RenderedSegment.Math -> SegmentViewCreators.updateMathView(view, segment) -- is RenderedSegment.CodeBlock -> (view as CodeBlockContainerView).applyCodeBlockNode(segment.node) -- is RenderedSegment.Blockquote -> (view as BlockquoteContainerView).applyBlockquoteNode(segment.node) -- is RenderedSegment.Video -> SegmentViewCreators.updateVideoView(view, segment) -+ is RenderedSegment.Text -> { -+ SegmentViewCreators.updateTextView(view as EnrichedMarkdownInternalText, segment) -+ } -+ -+ is RenderedSegment.Table -> { -+ (view as TableContainerView).applyTableNode(segment.node) -+ } -+ -+ is RenderedSegment.Math -> { -+ SegmentViewCreators.updateMathView(view, segment) -+ } -+ -+ is RenderedSegment.CodeBlock -> { -+ (view as CodeBlockContainerView).applyCodeBlockNode(segment.node) -+ } -+ -+ is RenderedSegment.Blockquote -> { -+ (view as BlockquoteContainerView).applyBlockquoteNode( -+ segment.node, -+ segment.mediaSlots, -+ segment.assets, -+ ) -+ } -+ -+ is RenderedSegment.Video -> { -+ SegmentViewCreators.updateVideoView(view, segment) -+ } - } - } - -@@ -359,6 +410,8 @@ class BlockquoteContainerView( - config: StyleConfig, - context: Context, - width: Float, -+ mediaSlots: Map = emptyMap(), -+ assets: DocumentAssets? = null, - ): Float { - val style = config.blockquoteStyle - val leftInset = ceil(style.borderWidth + style.gapWidth + style.padding).toInt() -@@ -370,9 +423,9 @@ class BlockquoteContainerView( - } else { - 0f - } -- val innerWidth = (width - leftInset - rightInset).coerceAtLeast(1f) -+ val innerWidth = (ceil(width) - leftInset - rightInset).coerceAtLeast(1f) - -- val segments = splitASTIntoSegments(node) -+ val segments = splitASTIntoSegments(node, mediaSlots, assets) - val rendered = MarkdownSegmentRenderer.render(segments, config, context, null, null, style) - - val fontSize = style.fontSize -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/ContainerNodeView.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/ContainerNodeView.kt -index 016d11dd349dcbc8bd2c14e6c67543612cc98def..859b7f0780fcfe5a71c82ab84bcd46ee8c93342c 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/segments/ContainerNodeView.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/ContainerNodeView.kt -@@ -3,6 +3,8 @@ package com.swmansion.enriched.markdown.segments - import android.content.Context - import android.view.View - import android.widget.FrameLayout -+import com.swmansion.enriched.markdown.media.MediaSlotFrame -+import com.swmansion.enriched.markdown.media.MediaSlotView - import kotlin.math.ceil - import kotlin.math.max - -@@ -80,6 +82,20 @@ open class ContainerNodeView( - return result.viewsToAttach.isNotEmpty() || result.viewsToRemove.isNotEmpty() - } - -+ /** Slot rectangles include every quote inset and header, in this container's coordinates. */ -+ fun mediaSlotFrames(): List { -+ // A zero-width nested quote leaves its descendants' prior frames intact. -+ // Stop at that ancestor rather than publishing stale positive-width slots. -+ if (width - paddingLeft - paddingRight <= 0) return emptyList() -+ return segmentViews.flatMap { view -> -+ when (view) { -+ is MediaSlotView -> listOf(MediaSlotFrame(view.slot.asset.id, view.left, view.top, view.width, view.height)) -+ is ContainerNodeView -> view.mediaSlotFrames().map { it.translated(view.left, view.top) } -+ else -> emptyList() -+ } -+ } -+ } -+ - protected fun layoutSegments() { - val containerWidth = width - if (containerWidth <= 0) return -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/MarkdownSegment.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/MarkdownSegment.kt -index c203527cc55c9293b9ecb7ff46f8eecead50ed1c..b4a8499cdf92f52c307d906ecb150420bbe3e95f 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/segments/MarkdownSegment.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/MarkdownSegment.kt -@@ -1,5 +1,7 @@ - package com.swmansion.enriched.markdown.segments - -+import com.swmansion.enriched.markdown.media.DocumentAssets -+import com.swmansion.enriched.markdown.media.MediaSlot - import com.swmansion.enriched.markdown.parser.MarkdownASTNode - - sealed interface MarkdownSegment { -@@ -22,14 +24,21 @@ sealed interface MarkdownSegment { - - data class Blockquote( - val node: MarkdownASTNode, -+ val mediaSlots: Map = emptyMap(), -+ val assets: DocumentAssets? = null, - ) : MarkdownSegment - - data class Video( - val node: MarkdownASTNode, -+ val mediaSlot: MediaSlot? = null, - ) : MarkdownSegment - } - --fun splitASTIntoSegments(root: MarkdownASTNode): List { -+fun splitASTIntoSegments( -+ root: MarkdownASTNode, -+ mediaSlots: Map = emptyMap(), -+ assets: DocumentAssets? = null, -+): List { - val segments = mutableListOf() - val currentTextNodes = mutableListOf() - -@@ -41,6 +50,14 @@ fun splitASTIntoSegments(root: MarkdownASTNode): List { - } - - for (child in root.children) { -+ val mediaNode = -+ if (child.type == MarkdownASTNode.NodeType.Paragraph && child.children.size == 1) child.children.first() else child -+ val slot = assets?.assetForNode(mediaNode)?.let { mediaSlots[it.id] } -+ if (slot != null) { -+ flushTextNodes() -+ segments.add(MarkdownSegment.Video(mediaNode, slot)) -+ continue -+ } - when (child.type) { - MarkdownASTNode.NodeType.Table -> { - flushTextNodes() -@@ -67,7 +84,7 @@ fun splitASTIntoSegments(root: MarkdownASTNode): List { - MarkdownASTNode.NodeType.Admonition, - -> { - flushTextNodes() -- segments.add(MarkdownSegment.Blockquote(child)) -+ segments.add(MarkdownSegment.Blockquote(child, mediaSlots, assets)) - } - - MarkdownASTNode.NodeType.Video -> { -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/RenderedSegment.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/RenderedSegment.kt -index 6377d91e80b6d236f0a1d94ab315986796274b20..aa72b8463f8f35d2a03a4b2ff57bcec00cdc7261 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/segments/RenderedSegment.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/RenderedSegment.kt -@@ -3,6 +3,8 @@ package com.swmansion.enriched.markdown.segments - import android.content.Context - import android.text.SpannableString - import com.swmansion.enriched.markdown.math.LatexErrorReporter -+import com.swmansion.enriched.markdown.media.DocumentAssets -+import com.swmansion.enriched.markdown.media.MediaSlot - import com.swmansion.enriched.markdown.parser.MarkdownASTNode - import com.swmansion.enriched.markdown.renderer.BlockquoteTextRenderer - import com.swmansion.enriched.markdown.renderer.Renderer -@@ -39,11 +41,14 @@ sealed interface RenderedSegment { - data class Blockquote( - val node: MarkdownASTNode, - override val signature: Long, -+ val mediaSlots: Map = emptyMap(), -+ val assets: DocumentAssets? = null, - ) : RenderedSegment - - data class Video( - val node: MarkdownASTNode, - override val signature: Long, -+ val mediaSlot: MediaSlot? = null, - ) : RenderedSegment - } - -@@ -80,13 +85,15 @@ object MarkdownSegmentRenderer { - } - - is MarkdownSegment.Blockquote -> { -- val signature = SegmentSignature.signatureForNode(segment.node) xor SegmentSignature.BLOCKQUOTE_KIND_SALT -- RenderedSegment.Blockquote(segment.node, signature) -+ val signature = -+ SegmentSignature.signatureForNode(segment.node) xor SegmentSignature.BLOCKQUOTE_KIND_SALT xor -+ segment.mediaSlots.hashCode().toLong() -+ RenderedSegment.Blockquote(segment.node, signature, segment.mediaSlots, segment.assets) - } - - is MarkdownSegment.Video -> { - val signature = SegmentSignature.signatureForNode(segment.node) xor SegmentSignature.VIDEO_KIND_SALT -- RenderedSegment.Video(segment.node, signature) -+ RenderedSegment.Video(segment.node, signature xor (segment.mediaSlot?.hashCode()?.toLong() ?: 0L), segment.mediaSlot) - } - } - } -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentHeightMeasurer.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentHeightMeasurer.kt -index 58f34e97d390b9277b81c14b8c7c2699cf854ff4..592e9321cec4017797241ba52dd7b4f13ed98ea8 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentHeightMeasurer.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentHeightMeasurer.kt -@@ -78,14 +78,40 @@ object SegmentHeightMeasurer { - // A quote encountered here is always nested inside another quote, so it - // carries no vertical margin (only the outermost quote does, added by - // MeasurementStore); this mirrors BlockquoteContainerView.nested. -- totalHeightPx += BlockquoteContainerView.measureBlockquoteNodeHeight(segment.node, style, context, contentWidthPx) -+ totalHeightPx += -+ BlockquoteContainerView.measureBlockquoteNodeHeight( -+ segment.node, -+ style, -+ context, -+ contentWidthPx, -+ segment.mediaSlots, -+ segment.assets, -+ ) - } - - is RenderedSegment.Video -> { -- totalHeightPx += style.videoStyle.marginTop -- totalHeightPx += contentWidthPx / style.videoStyle.resolvedAspectRatio -+ totalHeightPx += -+ segment.mediaSlot?.let { -+ com.swmansion.enriched.markdown.media.MediaSlotView -+ .marginTop(it, style) -+ .let { margin -> ceil(margin) } -+ } -+ ?: style.videoStyle.marginTop -+ totalHeightPx += -+ segment.mediaSlot?.let { -+ com.swmansion.enriched.markdown.media.MediaSlotView -+ .heightPx(it, style, widthPx.toFloat()) -+ .let { height -> ceil(height) } -+ } -+ ?: (contentWidthPx / style.videoStyle.resolvedAspectRatio) - if (includeBottomMargin) { -- totalHeightPx += style.videoStyle.marginBottom -+ totalHeightPx += -+ segment.mediaSlot?.let { -+ com.swmansion.enriched.markdown.media.MediaSlotView -+ .marginBottom(it, style) -+ .let { margin -> ceil(margin) } -+ } -+ ?: style.videoStyle.marginBottom - } - } - } -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentSignature.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentSignature.kt -index d1c9346326bab2dc3eb675bcdc2d3385866a992a..648dcbf62407c33422624ac6de4cd9707e488d9a 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentSignature.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentSignature.kt -@@ -1,5 +1,6 @@ - package com.swmansion.enriched.markdown.segments - -+import com.swmansion.enriched.markdown.media.mergeImageRequestHeaders - import com.swmansion.enriched.markdown.parser.MarkdownASTNode - - /** FNV-1a 64-bit hashing. Constants match the iOS implementation for cross-platform parity. */ -@@ -64,6 +65,16 @@ object SegmentSignature { - } - } - -+ node.imageSource?.let { source -> -+ hash = fnvMixString(hash, "image-source") -+ hash = fnvMixLong(hash, source.uri?.length?.toLong() ?: -1) -+ hash = fnvMixString(hash, source.uri) -+ for ((name, value) in mergeImageRequestHeaders(emptyMap(), source.headers).toSortedMap()) { -+ hash = fnvMixString(hash, name) -+ hash = fnvMixString(hash, value) -+ } -+ } -+ - for (child in node.children) { - hash = fnvMixLong(hash, signatureForNode(child)) - } -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentViewCreators.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentViewCreators.kt -index c9644d15d11cb32bce9ac370d6283ab66aa6dd57..4dcaf4d1c1812f6e4f3335659f5e557271ba34c1 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentViewCreators.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentViewCreators.kt -@@ -9,6 +9,7 @@ import android.view.View - import com.swmansion.enriched.markdown.EnrichedMarkdownInternalText - import com.swmansion.enriched.markdown.accessibility.AccessibilityLabels - import com.swmansion.enriched.markdown.math.LatexErrorReporter -+import com.swmansion.enriched.markdown.media.MediaSlotView - import com.swmansion.enriched.markdown.parser.MarkdownASTNode - import com.swmansion.enriched.markdown.styles.StyleConfig - import com.swmansion.enriched.markdown.utils.common.BreakStrategyUtils -@@ -208,7 +209,7 @@ object SegmentViewCreators { - segment: RenderedSegment.Blockquote, - config: SegmentViewConfig, - ) = BlockquoteContainerView(config.context, config).apply { -- applyBlockquoteNode(segment.node) -+ applyBlockquoteNode(segment.node, segment.mediaSlots, segment.assets) - } - - private val cachedVideoContainerClass: Class<*>? by lazy { -@@ -227,6 +228,7 @@ object SegmentViewCreators { - segment: RenderedSegment.Video, - config: SegmentViewConfig, - ): View { -+ segment.mediaSlot?.let { return MediaSlotView(config.context, config.style, it) } - val resolvedClass = videoContainerClass() - if (!FeatureFlags.IS_VIDEO_ENABLED || resolvedClass == null) return View(config.context) - return try { -@@ -251,6 +253,10 @@ object SegmentViewCreators { - view: View, - segment: RenderedSegment.Video, - ) { -+ if (view is MediaSlotView) { -+ segment.mediaSlot?.let { view.slot = it } -+ return -+ } - videoContainerClass() - ?.getMethod("applyVideoNode", MarkdownASTNode::class.java) - ?.invoke(view, segment.node) -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/TableContainerView.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/TableContainerView.kt -index 40c959ba4dc7fa85cf0648d75e797bcd5bdecc7a..dde664899bee811b213a6db13f1bfa49c810aa56 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/segments/TableContainerView.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/TableContainerView.kt -@@ -446,6 +446,8 @@ class TableContainerView( - text: CharSequence, - widthPx: Int, - ) { -+ com.swmansion.enriched.markdown.spans.LinkPillSpan -+ .prepareForMeasurement(text, widthPx) - if (widthPx <= 1) return - val spanned = text as? Spanned ?: return - spanned -@@ -476,6 +478,8 @@ class TableContainerView( - val columnWidths = FloatArray(texts.maxOfOrNull { it.size } ?: 0) - texts.forEach { row -> - row.forEachIndexed { colIndex, cellText -> -+ com.swmansion.enriched.markdown.spans.LinkPillSpan -+ .prepareForMeasurement(cellText, maxColumnWidth.toInt()) - val layout = - StaticLayout.Builder - .obtain(cellText, 0, cellText.length, paint, maxColumnWidth.toInt()) -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt b/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt -index cbda855f33ae7e7dd25fd7b36f9805be6a1ebd56..c5e209803f96e2d9e17de343e414752c8862751a 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt -@@ -53,24 +53,49 @@ class CodeBackgroundSpan( - val spanEnd = text.getSpanEnd(this) - if (spanStart !in 0 until spanEnd) return - -- // 1. Determine relative positioning -- val isFirst = spanStart >= start -- val isLast = spanEnd <= end -- -- // 2. Calculate coordinates -- val finalBottom = adjustBottomForMargin(text, end, bottom) -- val leadingMargin = leadingMarginAt(text, start) -- val startX = if (isFirst) getHorizontalOffset(text, start, end, spanStart, p, leadingMargin) + left else left.toFloat() + leadingMargin -- val endX = if (isLast) getHorizontalOffset(text, start, end, spanEnd, p, leadingMargin) + left else right.toFloat() -- -- rect.set(min(startX, endX), top.toFloat(), max(startX, endX), finalBottom.toFloat()) -- -- // 3. Apply Style -- val codeStyle = styleConfig.codeStyle -- sharedBackgroundPaint.color = codeStyle.backgroundColor -- sharedBorderPaint.color = codeStyle.borderColor -+ // Keep CodeSpan and this background span intact for semantic extraction. Draw only -+ // portions outside replacement pills, including code surrounding a partially covered run. -+ fun drawUncoveredRange( -+ rangeStart: Int, -+ rangeEnd: Int, -+ ) { -+ if (max(rangeStart, start) >= min(rangeEnd, end)) return -+ // 1. Determine relative positioning -+ val isFirst = rangeStart >= start -+ val isLast = rangeEnd <= end -+ -+ // 2. Calculate coordinates -+ val finalBottom = adjustBottomForMargin(text, end, bottom) -+ val leadingMargin = leadingMarginAt(text, start) -+ val startX = -+ if (isFirst) { -+ getHorizontalOffset(text, start, end, rangeStart, p, leadingMargin) + left -+ } else { -+ left.toFloat() + -+ leadingMargin -+ } -+ val endX = if (isLast) getHorizontalOffset(text, start, end, rangeEnd, p, leadingMargin) + left else right.toFloat() -+ -+ rect.set(min(startX, endX), top.toFloat(), max(startX, endX), finalBottom.toFloat()) -+ -+ // 3. Apply Style -+ val codeStyle = styleConfig.codeStyle -+ sharedBackgroundPaint.color = codeStyle.backgroundColor -+ sharedBorderPaint.color = codeStyle.borderColor -+ -+ drawShapes(canvas, isFirst, isLast) -+ } - -- drawShapes(canvas, isFirst, isLast) -+ var cursor = spanStart -+ val pills = text.getSpans(spanStart, spanEnd, LinkPillSpan::class.java).sortedBy { text.getSpanStart(it) } -+ for (pill in pills) { -+ val coveredStart = max(spanStart, text.getSpanStart(pill)) -+ val coveredEnd = min(spanEnd, text.getSpanEnd(pill)) -+ if (coveredStart >= coveredEnd) continue -+ if (cursor < coveredStart) drawUncoveredRange(cursor, coveredStart) -+ cursor = max(cursor, coveredEnd) -+ } -+ drawUncoveredRange(cursor, spanEnd) - } - - /** -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt b/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt -index 56951af974e5d29d2398c136701b0aec63953ff1..2cdabe149c754d18ec5dbf875f269e06a1aee8ae 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt -@@ -19,6 +19,8 @@ import androidx.core.graphics.drawable.toDrawable - import androidx.core.graphics.withClip - import androidx.core.graphics.withSave - import com.swmansion.enriched.markdown.EnrichedMarkdownText -+import com.swmansion.enriched.markdown.media.ImageSourceTransport -+import com.swmansion.enriched.markdown.media.mergeImageRequestHeaders - import com.swmansion.enriched.markdown.styles.StyleConfig - import com.swmansion.enriched.markdown.utils.common.findEnrichedMarkdownAncestor - import com.swmansion.enriched.markdown.utils.text.ImageCache -@@ -35,6 +37,7 @@ class ImageSpan( - styleConfig: StyleConfig, - val isInline: Boolean = false, - val altText: String = "", -+ imageSource: ImageSourceTransport? = null, - ) : AndroidImageSpan( - Color.TRANSPARENT.toDrawable(), - imageUrl, -@@ -61,8 +64,10 @@ class ImageSpan( - else -> height - } - -- private val requestHeaders: Map = styleConfig.imageRequestHeaders -- private val requestKey: String = ImageCache.requestKey(imageUrl, requestHeaders) -+ private val transportUri: String? = if (imageSource == null) imageUrl else imageSource.uri -+ private val requestHeaders: Map = -+ mergeImageRequestHeaders(styleConfig.imageRequestHeaders, imageSource?.headers.orEmpty()) -+ private val requestKey: String? = transportUri?.let { ImageCache.requestKey(it, requestHeaders) } - - private var cachedWidth: Int = 0 - private var viewRef: WeakReference? = null -@@ -71,7 +76,7 @@ class ImageSpan( - - private fun intrinsicImageSize(): Pair { - sourceDrawable?.let { return it.intrinsicWidth to it.intrinsicHeight } -- val cached = ImageCache.getOriginal(imageUrl) ?: return 0 to 0 -+ val cached = requestKey?.let { ImageCache.getOriginal(it) } ?: return 0 to 0 - return cached.width to cached.height - } - -@@ -107,19 +112,21 @@ class ImageSpan( - } - - private fun loadImage() { -- val scheme = Uri.parse(imageUrl).scheme?.lowercase() -+ val uri = transportUri ?: return -+ val key = requestKey ?: return -+ val scheme = Uri.parse(uri).scheme?.lowercase() - if (scheme == "http" || scheme == "https") { -- ImageDownloader.download(context, imageUrl, requestHeaders) { bitmap -> -+ ImageDownloader.download(context, uri, requestHeaders) { bitmap -> - if (bitmap != null) { - sourceDrawable = bitmap.toDrawable(context.resources) - wrapAndAssignDrawable() - } - } - } else { -- val cached = ImageCache.getOriginal(imageUrl) -- val bitmap = cached ?: LocalImageLoader.load(context, imageUrl) -+ val cached = ImageCache.getOriginal(key) -+ val bitmap = cached ?: LocalImageLoader.load(context, uri) - if (bitmap != null) { -- if (cached == null) ImageCache.putOriginal(imageUrl, bitmap) -+ if (cached == null) ImageCache.putOriginal(key, bitmap) - sourceDrawable = bitmap.toDrawable(context.resources) - wrapAndAssignDrawable() - } -@@ -138,7 +145,8 @@ class ImageSpan( - - boxHeight = resolveBoxHeight(targetWidth) - -- val cachedBitmap = ImageCache.getProcessed(requestKey, targetWidth, boxHeight, borderRadiusPx, resizeMode) -+ val key = requestKey ?: return -+ val cachedBitmap = ImageCache.getProcessed(key, targetWidth, boxHeight, borderRadiusPx, resizeMode) - - if (cachedBitmap != null) { - loadedDrawable = -@@ -155,7 +163,7 @@ class ImageSpan( - isBlockImage = !isInline, - resizeMode = resizeMode, - legacySizing = legacySizing, -- cacheKey = CacheKey(requestKey, targetWidth, boxHeight, borderRadiusPx, resizeMode), -+ cacheKey = CacheKey(key, targetWidth, boxHeight, borderRadiusPx, resizeMode), - ) - } - requestReflow() -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkPillIconCache.kt b/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkPillIconCache.kt -new file mode 100644 -index 0000000000000000000000000000000000000000..bddad2494e82d73f1e22e47cbd0012941e5de611 ---- /dev/null -+++ b/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkPillIconCache.kt -@@ -0,0 +1,53 @@ -+package com.swmansion.enriched.markdown.spans -+ -+import android.graphics.Bitmap -+import android.graphics.BitmapFactory -+import android.net.Uri -+import java.io.File -+import kotlin.math.max -+ -+/** Original-color local icons, shared by measurement and rendering across reparses. */ -+internal object LinkPillIconCache { -+ private const val MAX_ENTRIES = 64 -+ private const val MAX_BYTES = 8 * 1024 * 1024 -+ private const val MAX_DIMENSION = 512 -+ -+ private data class Key( -+ val path: String, -+ val modified: Long, -+ val size: Long, -+ ) -+ -+ private val images = LinkedHashMap(16, 0.75f, true) -+ private var bytes = 0 -+ -+ @Synchronized -+ fun load(iconUri: String): Bitmap? = -+ runCatching { -+ val uri = Uri.parse(iconUri) -+ if (uri.scheme != "file") return@runCatching null -+ val file = File(uri.path ?: return@runCatching null).canonicalFile -+ if (!file.isFile) return@runCatching null -+ val key = Key(file.path, file.lastModified(), file.length()) -+ images[key]?.let { return@runCatching it } -+ val bounds = BitmapFactory.Options().apply { inJustDecodeBounds = true } -+ BitmapFactory.decodeFile(file.path, bounds) -+ if (bounds.outWidth <= 0 || bounds.outHeight <= 0) return@runCatching null -+ val options = BitmapFactory.Options().apply { inSampleSize = 1 } -+ while (max(bounds.outWidth, bounds.outHeight) / options.inSampleSize > MAX_DIMENSION) { -+ options.inSampleSize *= 2 -+ } -+ val bitmap = BitmapFactory.decodeFile(file.path, options) ?: return@runCatching null -+ val cost = bitmap.allocationByteCount -+ if (cost > MAX_BYTES) return@runCatching bitmap -+ images[key] = bitmap -+ bytes += cost -+ while (images.size > MAX_ENTRIES || bytes > MAX_BYTES) { -+ val oldest = images.entries.iterator() -+ bytes -= oldest.next().value.allocationByteCount -+ oldest.remove() -+ // Do not recycle: existing spans can still own the evicted bitmap. -+ } -+ bitmap -+ }.getOrNull() -+} -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkPillSpan.kt b/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkPillSpan.kt -new file mode 100644 -index 0000000000000000000000000000000000000000..7dc8be3d3e9a0af60bff269617751db4bbd3dda0 ---- /dev/null -+++ b/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkPillSpan.kt -@@ -0,0 +1,142 @@ -+package com.swmansion.enriched.markdown.spans -+ -+import android.graphics.Canvas -+import android.graphics.Paint -+import android.graphics.PorterDuff -+import android.graphics.PorterDuffColorFilter -+import android.graphics.RectF -+import android.os.Build -+import android.text.Spanned -+import android.text.TextPaint -+import android.text.TextUtils -+import android.text.style.ReplacementSpan -+import com.swmansion.enriched.markdown.styles.LinkVariantEntry -+import kotlin.math.ceil -+import kotlin.math.max -+import kotlin.math.min -+ -+/** Draws an atomic visual over the original link text, without changing stored characters. */ -+class LinkPillSpan( -+ private val variant: LinkVariantEntry, -+ private val typeface: android.graphics.Typeface, -+ private val fontSize: Float, -+ originalLabel: String, -+) : ReplacementSpan() { -+ private val label = (variant.label.ifEmpty { originalLabel }).replace('\n', ' ').replace('\r', ' ') -+ private var availableWidth = Float.MAX_VALUE -+ private val icon = LinkPillIconCache.load(variant.iconUri) -+ private val iconPaint = -+ Paint(Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG).apply { -+ variant.iconTintColor?.let { colorFilter = PorterDuffColorFilter(it, PorterDuff.Mode.SRC_IN) } -+ } -+ -+ init { -+ // TalkBack reads original semantics even when the visual label differs. -+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) contentDescription = originalLabel -+ } -+ -+ fun prepareForMeasurement(width: Int): Boolean { -+ val next = width.coerceAtLeast(1).toFloat() -+ if (availableWidth == next) return false -+ availableWidth = next -+ return true -+ } -+ -+ private fun textPaint(paint: Paint) = -+ TextPaint(paint).apply { -+ typeface = this@LinkPillSpan.typeface -+ textSize = fontSize -+ color = variant.color -+ bgColor = 0 -+ isUnderlineText = variant.underline -+ isStrikeThruText = false -+ } -+ -+ private fun width(paint: Paint): Float { -+ val iconWidth = if (icon == null) 0f else fontSize + fontSize * 0.25f -+ val natural = paint.measureText(label) + iconWidth + 2 * (variant.paddingHorizontal + variant.borderWidth) -+ val limit = if (variant.maxWidth > 0) min(availableWidth, variant.maxWidth) else availableWidth -+ return min(ceil(natural), limit).coerceAtLeast(1f) -+ } -+ -+ override fun getSize( -+ paint: Paint, -+ text: CharSequence, -+ start: Int, -+ end: Int, -+ fm: Paint.FontMetricsInt?, -+ ): Int { -+ val labelPaint = textPaint(paint) -+ val metrics = labelPaint.fontMetricsInt -+ val inset = ceil(variant.paddingVertical + variant.borderWidth).toInt() -+ fm?.let { -+ it.ascent = min(it.ascent, metrics.ascent - inset) -+ it.descent = max(it.descent, metrics.descent + inset) -+ it.top = min(it.top, it.ascent) -+ it.bottom = max(it.bottom, it.descent) -+ } -+ return ceil(width(labelPaint)).toInt() -+ } -+ -+ override fun draw( -+ canvas: Canvas, -+ text: CharSequence, -+ start: Int, -+ end: Int, -+ x: Float, -+ top: Int, -+ y: Int, -+ bottom: Int, -+ paint: Paint, -+ ) { -+ val labelPaint = textPaint(paint) -+ val metrics = labelPaint.fontMetrics -+ val inset = variant.paddingVertical + variant.borderWidth -+ val rect = RectF(x, y + metrics.ascent - inset, x + width(labelPaint), y + metrics.descent + inset) -+ val fill = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = variant.backgroundColor } -+ canvas.drawRoundRect(rect, variant.borderRadius, variant.borderRadius, fill) -+ if (variant.borderWidth > 0) { -+ fill.color = variant.borderColor -+ fill.style = Paint.Style.STROKE -+ fill.strokeWidth = variant.borderWidth -+ val border = RectF(rect).apply { inset(variant.borderWidth / 2, variant.borderWidth / 2) } -+ canvas.drawRoundRect(border, variant.borderRadius, variant.borderRadius, fill) -+ } -+ val save = canvas.save() -+ canvas.clipRect(rect) -+ var left = x + variant.paddingHorizontal + variant.borderWidth -+ val right = rect.right - variant.paddingHorizontal - variant.borderWidth -+ if (icon != null && right - left >= fontSize) { -+ val iconTop = y + (metrics.ascent + metrics.descent - fontSize) / 2 -+ val scale = fontSize / max(icon.width, icon.height) -+ val destination = RectF(left, iconTop, left + icon.width * scale, iconTop + icon.height * scale) -+ destination.offset((fontSize - destination.width()) / 2, (fontSize - destination.height()) / 2) -+ canvas.drawBitmap(icon, null, destination, iconPaint) -+ left += fontSize + fontSize * 0.25f -+ } -+ val displayed = TextUtils.ellipsize(label, labelPaint, max(0f, right - left), TextUtils.TruncateAt.END) -+ canvas.drawText(displayed.toString(), left, y.toFloat(), labelPaint) -+ canvas.restoreToCount(save) -+ } -+ -+ companion object { -+ /** Called before both Fabric measurement and visible TextView layout, including table cells. */ -+ fun prepareForMeasurement( -+ text: CharSequence?, -+ width: Int, -+ ): Boolean { -+ val spanned = text as? Spanned ?: return false -+ var changed = false -+ spanned.getSpans(0, spanned.length, LinkPillSpan::class.java).forEach { pill -> -+ val start = spanned.getSpanStart(pill) -+ val end = spanned.getSpanEnd(pill) -+ val margin = -+ spanned -+ .getSpans(start, end, android.text.style.LeadingMarginSpan::class.java) -+ .sumOf { max(it.getLeadingMargin(true), it.getLeadingMargin(false)) } -+ changed = pill.prepareForMeasurement(width - margin) || changed -+ } -+ return changed -+ } -+ } -+} -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt b/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt -index 2cef891852a55b5050de339481e195e588c7393d..f699342b3cc0ff12405c6a0ca1f8d2e9d35c8ec7 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt -@@ -17,6 +17,8 @@ class LinkSpan( - private val styleCache: SpanStyleCache, - private val blockStyle: BlockStyle, - private val context: Context, -+ private val preserveCodeFont: Boolean = false, -+ val recognizedLink: Boolean = false, - ) : ClickableSpan() { - @Volatile - private var longPressTriggered = false -@@ -43,16 +45,18 @@ class LinkSpan( - override fun updateDrawState(textPaint: TextPaint) { - super.updateDrawState(textPaint) - -- textPaint.textSize = blockStyle.fontSize -+ if (!preserveCodeFont) textPaint.textSize = blockStyle.fontSize - - val variant = styleCache.resolvedVariantForUrl(url) - -- val fontFamily = styleCache.linkFontFamily -- if (fontFamily.isNotEmpty()) { -- val overriddenBlockStyle = blockStyle.copy(fontFamily = fontFamily) -- textPaint.applyBlockStyleFont(overriddenBlockStyle, context) -- } else { -- textPaint.applyBlockStyleFont(blockStyle, context) -+ val fontFamily = variant?.fontFamily?.takeIf { it.isNotEmpty() } ?: styleCache.linkFontFamily -+ if (!preserveCodeFont) { -+ if (fontFamily.isNotEmpty()) { -+ val overriddenBlockStyle = blockStyle.copy(fontFamily = fontFamily) -+ textPaint.applyBlockStyleFont(overriddenBlockStyle, context) -+ } else { -+ textPaint.applyBlockStyleFont(blockStyle, context) -+ } - } - - textPaint.color = variant?.color ?: styleCache.linkColor -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkVariantEntry.kt b/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkVariantEntry.kt -index e502ae1671c24c3fea1d2087412b8c48cd6cbc6e..c0f2ad3ab16ad03dfc8fd6c33384ca07a21013e1 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkVariantEntry.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkVariantEntry.kt -@@ -13,6 +13,17 @@ data class LinkVariantEntry( - val color: Int, - val underline: Boolean, - val backgroundColor: Int, -+ val fontFamily: String = "", -+ val pill: Boolean = false, -+ val label: String = "", -+ val iconUri: String = "", -+ val iconTintColor: Int? = null, -+ val borderRadius: Float = 8f, -+ val paddingHorizontal: Float = 6f, -+ val paddingVertical: Float = 2f, -+ val borderWidth: Float = 0f, -+ val borderColor: Int = android.graphics.Color.TRANSPARENT, -+ val maxWidth: Float = 0f, - ) { - companion object { - fun fromReadableMap( -@@ -24,6 +35,17 @@ data class LinkVariantEntry( - color = parser.parseColor(map, "color"), - underline = parser.parseBoolean(map, "underline"), - backgroundColor = parser.parseColor(map, "backgroundColor"), -+ fontFamily = parser.parseString(map, "fontFamily"), -+ pill = parser.parseBoolean(map, "pill"), -+ label = parser.parseString(map, "label"), -+ iconUri = parser.parseString(map, "iconUri"), -+ iconTintColor = parser.parseOptionalColor(map, "iconTintColor"), -+ borderRadius = parser.toPixelFromDIP(parser.parseOptionalDouble(map, "borderRadius", 8.0).toFloat()), -+ paddingHorizontal = parser.toPixelFromDIP(parser.parseOptionalDouble(map, "paddingHorizontal", 6.0).toFloat()), -+ paddingVertical = parser.toPixelFromDIP(parser.parseOptionalDouble(map, "paddingVertical", 2.0).toFloat()), -+ borderWidth = parser.toPixelFromDIP(parser.parseOptionalDouble(map, "borderWidth").toFloat()), -+ borderColor = parser.parseOptionalColor(map, "borderColor") ?: android.graphics.Color.TRANSPARENT, -+ maxWidth = parser.toPixelFromDIP(parser.parseOptionalDouble(map, "maxWidth").toFloat()), - ) - } - } -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt b/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt -index 705176702a715092c79cd3d2aaded6fc0513054f..7e156aa9b7644fb43fbc16b7c4d8efb92c4a0f5e 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt -@@ -298,6 +298,10 @@ object MarkdownASTSerializer { - } - - NodeType.Link -> { -+ if (node.getAttribute("recognizedLink") == "true") { -+ appendChildren(node, buffer) -+ return -+ } - val url = node.getAttribute("url") ?: "" - buffer.append("[") - appendChildren(node, buffer) -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt b/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt -index b96bac1b663db52f4c3ac766371b0fb0512f42a9..9702d30908f3585b4799afee2566278810f856d0 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt -@@ -3,6 +3,7 @@ package com.swmansion.enriched.markdown.utils.text - import android.graphics.Bitmap - import android.util.LruCache - import java.security.MessageDigest -+import java.util.Locale - - object ImageCache { - private const val ORIGINAL_CACHE_SIZE = 20 * 1024 * 1024 -@@ -23,7 +24,9 @@ object ImageCache { - ): String { - if (headers.isEmpty()) return url - val joined = -- headers.entries -+ headers -+ .mapKeys { it.key.lowercase(Locale.ROOT) } -+ .entries - .sortedBy { it.key } - .joinToString(separator = "\n") { "${it.key}:${it.value}" } - val digest = MessageDigest.getInstance("SHA-256").digest(joined.toByteArray()) -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt b/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt -index 7a2071e4d8aefe3e4106436d5affd48f197d88a6..582b70d22237ceebaf4d99ce0b8fe8a5fc0c2b47 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt -@@ -7,6 +7,7 @@ import android.os.Handler - import android.os.Looper - import android.util.Log - import okhttp3.Cache -+import okhttp3.CacheControl - import okhttp3.Call - import okhttp3.Callback - import okhttp3.OkHttpClient -@@ -69,12 +70,7 @@ object ImageDownloader { - inFlight[requestKey] = mutableListOf(callback) - } - -- val request = -- Request -- .Builder() -- .url(url) -- .apply { headers.forEach { (name, value) -> addHeader(name, value) } } -- .build() -+ val request = requestForImage(url, headers) - getClient(context).newCall(request).enqueue( - object : Callback { - override fun onResponse( -@@ -110,6 +106,27 @@ object ImageDownloader { - ) - } - -+ internal fun requestForImage( -+ url: String, -+ headers: Map, -+ ): Request = -+ Request -+ .Builder() -+ .url(url) -+ .apply { -+ headers.forEach { (name, value) -> addHeader(name, value) } -+ // The HTTP cache uses URL + server Vary, which may omit source header identity. -+ if (headers.isNotEmpty()) { -+ cacheControl( -+ CacheControl -+ .Builder() -+ .noCache() -+ .noStore() -+ .build(), -+ ) -+ } -+ }.build() -+ - private fun decodeDownsampled( - bytes: ByteArray, - targetWidth: Int, -diff --git a/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/MarkdownExtractor.kt b/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/MarkdownExtractor.kt -index 2957f98ceb399397359c14481d0d0a3e628258e8..ec5a0347a7c62f6c8d893b189c95d099173ea911 100644 ---- a/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/MarkdownExtractor.kt -+++ b/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/MarkdownExtractor.kt -@@ -300,7 +300,7 @@ object MarkdownExtractor { - val baselineShiftSpans = spannable.getSpans(start, end, BaselineShiftSpan::class.java) - val hasSuperscript = baselineShiftSpans.any { it.spanType == BaselineShiftSpan.SpanType.SUPERSCRIPT } - val hasSubscript = baselineShiftSpans.any { it.spanType == BaselineShiftSpan.SpanType.SUBSCRIPT } -- val linkSpans = spannable.getSpans(start, end, LinkSpan::class.java) -+ val linkSpans = spannable.getSpans(start, end, LinkSpan::class.java).filterNot { it.recognizedLink } - val hasHighlight = spannable.getSpans(start, end, HighlightSpan::class.java).isNotEmpty() - - var result = text -diff --git a/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h b/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h -index dea8bb2e79987d70aa8b01bffffcc5d079d077c4..43a423af43b267d84be94bdd005fde2a5983e9e3 100644 ---- a/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h -+++ b/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h -@@ -20,6 +20,17 @@ public: - MarkdownContainerShadowNode(ShadowNode const &sourceShadowNode, ShadowNodeFragment const &fragment) - : ConcreteViewShadowNode(sourceShadowNode, fragment) { - dirtyLayoutIfNeeded(); -+ const auto &previousProps = static_cast(sourceShadowNode).getConcreteProps(); -+ const auto &props = getConcreteProps(); -+ if (previousProps.enableImageSourceResolution != props.enableImageSourceResolution || -+ previousProps.imageSourcesRevision != props.imageSourcesRevision || -+ previousProps.imageSourcesContinuityStart != props.imageSourcesContinuityStart || -+ previousProps.imageSources != props.imageSources || previousProps.documentRevision != props.documentRevision || -+ previousProps.enableMediaSlots != props.enableMediaSlots || -+ previousProps.mediaOverridesRevision != props.mediaOverridesRevision || -+ previousProps.mediaOverrides != props.mediaOverrides) { -+ dirtyLayout(); -+ } - } - - static ShadowNodeTraits BaseTraits() { -diff --git a/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h b/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h -index 1c8ea11951050ff54f122728764c8ea5749dc2e3..d8fadfbdbb795e0753255e0e45681ddb6e76eb7e 100644 ---- a/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h -+++ b/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h -@@ -38,6 +38,29 @@ inline folly::dynamic toDynamic(const EnrichedMarkdownProps &props) { - serializedProps["allowTrailingMargin"] = props.allowTrailingMargin; - serializedProps["streamingAnimation"] = props.streamingAnimation; - -+ serializedProps["enableImageSourceResolution"] = props.enableImageSourceResolution; -+ serializedProps["imageSourcesRevision"] = props.imageSourcesRevision; -+ serializedProps["imageSourcesContinuityStart"] = props.imageSourcesContinuityStart; -+ folly::dynamic imageSources = folly::dynamic::array(); -+ for (const auto &source : props.imageSources) { -+ folly::dynamic headers = folly::dynamic::array(); -+ for (const auto &header : source.headers) { -+ headers.push_back(folly::dynamic::object("name", header.name)("value", header.value)); -+ } -+ imageSources.push_back(folly::dynamic::object("id", source.id)("url", source.url)("anchor", source.anchor)( -+ "uri", source.uri)("headers", std::move(headers))("useDefault", source.useDefault)); -+ } -+ serializedProps["imageSources"] = std::move(imageSources); -+ serializedProps["documentRevision"] = props.documentRevision; -+ serializedProps["mediaOverridesRevision"] = props.mediaOverridesRevision; -+ serializedProps["enableMediaSlots"] = props.enableMediaSlots; -+ folly::dynamic mediaOverrides = folly::dynamic::array(); -+ for (const auto &slot : props.mediaOverrides) { -+ mediaOverrides.push_back(folly::dynamic::object("id", slot.id)("height", slot.height)("width", slot.width)( -+ "url", slot.url)("kind", slot.kind)("anchor", slot.anchor)); -+ } -+ serializedProps["mediaOverrides"] = std::move(mediaOverrides); -+ - folly::dynamic imageRequestHeaders = folly::dynamic::array(); - for (const auto &header : props.imageRequestHeaders) { - imageRequestHeaders.push_back(toDynamic(header)); -diff --git a/cpp/md4c/md4c.h b/cpp/md4c/md4c.h -index cf965d8cc17cb2724c8d194f5cbd5784298f1e5c..d42080a9262b13a808b50c29794802c473fe1911 100644 ---- a/cpp/md4c/md4c.h -+++ b/cpp/md4c/md4c.h -@@ -26,6 +26,9 @@ - #ifndef MD4C_H - #define MD4C_H - -+/* Isolate the embedded parser from other libraries linking their own MD4C. */ -+#define md_parse enrm_md_parse -+ - #ifdef __cplusplus - extern "C" { - #endif -diff --git a/ios/EnrichedMarkdown.mm b/ios/EnrichedMarkdown.mm -index 5a22a30affaeda8431e439390962a9c5242f5608..c46857768d36ad107cc9660ffc1612103c5bcabf 100644 ---- a/ios/EnrichedMarkdown.mm -+++ b/ios/EnrichedMarkdown.mm -@@ -3,11 +3,14 @@ - #import "ENRMAccessibilityLabels.h" - #import "ENRMAsyncRenderCoordinator.h" - #import "ENRMAtomicSize.h" -+#import "ENRMDocumentAssets.h" - #import "ENRMImageAttachment.h" - #import "ENRMLatexErrorCoordinator.h" - #import "ENRMMarkdownParser.h" -+#import "ENRMMediaSlotView.h" - #import "ENRMTailFadeInAnimator.h" - #import "ENRMTextInteractionUtils.h" -+#import "ENRMTextLinkRecognizer.h" - #import "ENRMTextRenderer.h" - #import "ENRMTextViewSetup.h" - #import "ENRMUIKit.h" -@@ -78,6 +81,8 @@ static char kENRMSegmentFadeAnimatorKey; - - @interface EnrichedMarkdown () - + (ENRMMd4cFlags *)flagsFromProps:(const EnrichedMarkdownMd4cFlagsStruct &)props; -+- (void)emitDocumentAssets; -+- (void)emitMediaLayout:(NSArray *)frames; - - (void)emitLinkPress:(NSString *)url; - - (void)emitLinkLongPress:(NSString *)url; - - (void)emitImagePress:(NSString *)url altText:(NSString *)altText; -@@ -95,6 +100,8 @@ static char kENRMSegmentFadeAnimatorKey; - StyleConfig *_config; - ENRMMd4cFlags *_md4cFlags; - BOOL _isGFM; -+ ENRMLinkRegexConfig *_linkRegex; -+ ENRMLinkRegexConfig *_inlineCodeLinkRegex; - NSString *_cachedMarkdown; - NSString *_renderedMarkdown; - ENRMLatexErrorCoordinator *_latexErrorCoordinator; -@@ -141,6 +148,20 @@ static char kENRMSegmentFadeAnimatorKey; - NSWritingDirection _resolvedLayoutDirection; - - ENRMAtomicSize _lastCommittedSize; -+ NSInteger _documentRevision; -+ NSInteger _renderedDocumentRevision; -+ BOOL _enableDocumentAssets; -+ BOOL _enableMediaSlots; -+ BOOL _enableImageSourceResolution; -+ NSInteger _imageSourcesRevision; -+ NSInteger _imageSourcesContinuityStart; -+ NSDictionary *_imageSources; -+ NSInteger _mediaOverridesRevision; -+ NSDictionary *_mediaOverrides; -+ NSArray *_documentAssets; -+ NSArray *_lastMediaFrames; -+ NSArray *_lastEmittedAssets; -+ NSInteger _lastEmittedAssetsRevision; - } - - + (ComponentDescriptorProvider)componentDescriptorProvider -@@ -172,6 +193,15 @@ static char kENRMSegmentFadeAnimatorKey; - _parser = [[ENRMMarkdownParser alloc] init]; - _md4cFlags = [EnrichedMarkdown flagsFromProps:defaultProps->md4cFlags]; - _isGFM = defaultProps->isGFM; -+ _imageSourcesRevision = -1; -+ _imageSourcesContinuityStart = 1; -+ _imageSources = @{}; -+ _mediaOverridesRevision = -1; -+ _renderedDocumentRevision = -1; -+ _lastEmittedAssetsRevision = -1; -+ _mediaOverrides = @{}; -+ _linkRegex = ENRMTextLinkRegexConfigFromProps(defaultProps->linkRegex); -+ _inlineCodeLinkRegex = ENRMTextLinkRegexConfigFromProps(defaultProps->inlineCodeLinkRegex); - _segmentViews = [NSMutableArray array]; - _segmentSignatures = [NSMutableArray array]; - __weak __typeof(self) weakLatexSelf = self; -@@ -368,6 +398,18 @@ static char kENRMSegmentFadeAnimatorKey; - }]]; - #endif - -+ [handlers addObject:[ENRMSegmentViewHandler handlerWithKind:ENRMSegmentKindMediaSlot -+ matchesView:^BOOL(RCTUIView *view, ENRMRenderedSegment *segment) { -+ return [view isKindOfClass:[ENRMMediaSlotView class]]; -+ } -+ createView:^RCTUIView *(ENRMRenderedSegment *segment) { -+ ENRMMediaSlotView *view = [[ENRMMediaSlotView alloc] init]; -+ view.mediaNode = segment.mediaSlotNode; -+ return view; -+ } -+ updateView:^(RCTUIView *view, ENRMRenderedSegment *segment) { -+ ((ENRMMediaSlotView *)view).mediaNode = segment.mediaSlotNode; -+ }]]; - _segmentViewRegistry = [[ENRMSegmentViewRegistry alloc] initWithHandlers:handlers]; - } - -@@ -432,6 +474,7 @@ static char kENRMSegmentFadeAnimatorKey; - #endif - } - -+ NSMutableArray *mediaFrames = [NSMutableArray array]; - __block CGFloat yOffset = 0.0; - __block CGFloat maxContentWidth = 0.0; - const NSUInteger lastIndex = _segmentViews.count - 1; -@@ -443,7 +486,13 @@ static char kENRMSegmentFadeAnimatorKey; - CGFloat segmentHeight = 0; - const BOOL isTable = [segment isKindOfClass:[TableContainerView class]]; - -- if ([segment isKindOfClass:[EnrichedMarkdownInternalText class]]) { -+ if ([segment isKindOfClass:[ENRMMediaSlotView class]]) { -+ MarkdownASTNode *node = ((ENRMMediaSlotView *)segment).mediaNode; -+ BOOL video = [node.attributes[@"_enrmMediaKind"] isEqualToString:@"video"]; -+ yOffset += video ? _config.videoMarginTop : _config.imageMarginTop; -+ segmentHeight = ENRMMediaSlotHeight(node, width, _config); -+ maxContentWidth = width; -+ } else if ([segment isKindOfClass:[EnrichedMarkdownInternalText class]]) { - EnrichedMarkdownInternalText *textView = (EnrichedMarkdownInternalText *)segment; - textView.allowTrailingMargin = shouldAddBottomMargin; - CGSize textSize = [textView measureSize:width]; -@@ -504,7 +553,11 @@ static char kENRMSegmentFadeAnimatorKey; - - yOffset += segmentHeight; - -- if ([segment isKindOfClass:[TableContainerView class]] && shouldAddBottomMargin) { -+ if ([segment isKindOfClass:[ENRMMediaSlotView class]] && shouldAddBottomMargin) { -+ MarkdownASTNode *node = ((ENRMMediaSlotView *)segment).mediaNode; -+ yOffset += [node.attributes[@"_enrmMediaKind"] isEqualToString:@"video"] ? _config.videoMarginBottom -+ : _config.imageMarginBottom; -+ } else if ([segment isKindOfClass:[TableContainerView class]] && shouldAddBottomMargin) { - yOffset += _config.tableMarginBottom; - } - #if ENRICHED_MARKDOWN_MATH -@@ -524,6 +577,28 @@ static char kENRMSegmentFadeAnimatorKey; - #endif - }]; - -+ if (applyFrames && _enableMediaSlots && _renderedDocumentRevision == _documentRevision) { -+ for (RCTUIView *view in _segmentViews) { -+ if ([view isKindOfClass:[ENRMMediaSlotView class]]) { -+ MarkdownASTNode *node = ((ENRMMediaSlotView *)view).mediaNode; -+ CGRect rect = [self convertRect:view.bounds fromView:view]; -+ [mediaFrames addObject:@{ -+ @"id" : node.attributes[@"_enrmMediaSlot"], -+ @"x" : @(rect.origin.x), -+ @"y" : @(rect.origin.y), -+ @"width" : @(rect.size.width), -+ @"height" : @(rect.size.height) -+ }]; -+ } else if ([view isKindOfClass:[ENRMContainerNodeView class]]) { -+ [(ENRMContainerNodeView *)view appendMediaFrames:mediaFrames relativeToView:self]; -+ } -+ } -+ } -+ if (applyFrames && _enableMediaSlots && _renderedDocumentRevision == _documentRevision && -+ ![_lastMediaFrames isEqualToArray:mediaFrames]) { -+ _lastMediaFrames = [mediaFrames copy]; -+ [self emitMediaLayout:mediaFrames]; -+ } - return CGSizeMake(maxContentWidth, yOffset); - } - -@@ -669,6 +744,8 @@ static char kENRMSegmentFadeAnimatorKey; - ENRMMarkdownParser *parser = _parser; - ENRMMd4cFlags *md4cFlags = [_md4cFlags copy]; - BOOL isGFM = _isGFM; -+ ENRMLinkRegexConfig *linkRegex = _linkRegex; -+ ENRMLinkRegexConfig *inlineCodeLinkRegex = _inlineCodeLinkRegex; - - BOOL allowFontScaling = _fontScaleObserver.allowFontScaling; - CGFloat maxFontSizeMultiplier = _maxFontSizeMultiplier; -@@ -680,6 +757,16 @@ static char kENRMSegmentFadeAnimatorKey; - ENRMWritingDirectionMode writingDirectionMode = _writingDirectionMode; - NSWritingDirection resolvedLayoutDirection = _resolvedLayoutDirection; - -+ NSInteger revision = _documentRevision; -+ BOOL enableMediaSlots = _enableMediaSlots; -+ BOOL enableDocumentAssets = _enableDocumentAssets; -+ BOOL decisionsAccepted = _mediaOverridesRevision == revision; -+ NSDictionary *mediaOverrides = [_mediaOverrides copy]; -+ BOOL enableImageSourceResolution = _enableImageSourceResolution && isGFM; -+ BOOL imageSourcesAccepted = -+ _imageSourcesRevision >= _imageSourcesContinuityStart && _imageSourcesRevision <= revision; -+ NSDictionary *imageSources = [_imageSources copy]; -+ __block NSArray *documentAssets = @[]; - __block NSArray *renderedSegments = nil; - __block NSString *renderableMarkdown = nil; - __block BOOL endsInsideOpenCodeFence = NO; -@@ -696,10 +783,17 @@ static char kENRMSegmentFadeAnimatorKey; - return YES; - } - -- MarkdownASTNode *ast = [parser parseMarkdown:renderableMarkdown flags:md4cFlags isGFM:isGFM]; -+ MarkdownASTNode *ast = [parser parseMarkdown:renderableMarkdown -+ flags:md4cFlags -+ isGFM:isGFM -+ linkRegex:linkRegex -+ inlineCodeLinkRegex:inlineCodeLinkRegex]; - if (!ast) - return NO; - -+ if (enableDocumentAssets || enableMediaSlots || enableImageSourceResolution) -+ documentAssets = ENRMPrepareDocumentAssets(ast, enableMediaSlots, decisionsAccepted, mediaOverrides); -+ ENRMPrepareImageSources(ast, documentAssets, enableImageSourceResolution, imageSourcesAccepted, imageSources); - renderedSegments = ENRMRenderSegmentsFromAST(ast, config, allowTrailingMargin, allowFontScaling, - maxFontSizeMultiplier, lineBreakStrategy, - /*blockquoteContent*/ NO); -@@ -712,6 +806,12 @@ static char kENRMSegmentFadeAnimatorKey; - return YES; - } - apply:^{ -+ if (revision != self->_documentRevision) -+ return; -+ self->_renderedDocumentRevision = revision; -+ self->_documentAssets = documentAssets; -+ self->_lastMediaFrames = nil; -+ [self emitDocumentAssets]; - self->_renderedStyleFingerprint = self->_pendingStyleFingerprint; - [self applyRenderedSegments:renderedSegments - renderedMarkdown:renderableMarkdown -@@ -721,11 +821,23 @@ static char kENRMSegmentFadeAnimatorKey; - - - (NSArray *)parseAndRenderSegments:(NSString *)markdownString - { -- MarkdownASTNode *ast = [_parser parseMarkdown:markdownString flags:_md4cFlags isGFM:_isGFM]; -+ MarkdownASTNode *ast = [_parser parseMarkdown:markdownString -+ flags:_md4cFlags -+ isGFM:_isGFM -+ linkRegex:_linkRegex -+ inlineCodeLinkRegex:_inlineCodeLinkRegex]; - if (!ast) { - return nil; - } - -+ if (_enableDocumentAssets || _enableMediaSlots || (_enableImageSourceResolution && _isGFM)) -+ _documentAssets = ENRMPrepareDocumentAssets(ast, _enableMediaSlots, _mediaOverridesRevision == _documentRevision, -+ _mediaOverrides); -+ ENRMPrepareImageSources(ast, _documentAssets, _enableImageSourceResolution && _isGFM, -+ _imageSourcesRevision >= _imageSourcesContinuityStart && -+ _imageSourcesRevision <= _documentRevision, -+ _imageSources); -+ _renderedDocumentRevision = _documentRevision; - NSArray *segments = - ENRMRenderSegmentsFromAST(ast, _config, _allowTrailingMargin, _fontScaleObserver.allowFontScaling, - _maxFontSizeMultiplier, _lineBreakStrategy, /*blockquoteContent*/ NO); -@@ -1025,6 +1137,34 @@ static char kENRMSegmentFadeAnimatorKey; - _dirtyFlags |= ENRMDirtyRender; - } - -+ NSDictionary *mediaOverrides = ENRMMediaOverridesFromProps(newViewProps); -+ if (_documentRevision != newViewProps.documentRevision || _enableMediaSlots != newViewProps.enableMediaSlots || -+ _enableDocumentAssets != newViewProps.enableDocumentAssets || -+ _mediaOverridesRevision != newViewProps.mediaOverridesRevision || -+ ![_mediaOverrides isEqualToDictionary:mediaOverrides]) { -+ _documentRevision = newViewProps.documentRevision; -+ _enableMediaSlots = newViewProps.enableMediaSlots; -+ if (_enableDocumentAssets != newViewProps.enableDocumentAssets) -+ _lastEmittedAssets = nil; -+ _enableDocumentAssets = newViewProps.enableDocumentAssets; -+ _mediaOverridesRevision = newViewProps.mediaOverridesRevision; -+ _mediaOverrides = mediaOverrides; -+ _lastMediaFrames = nil; -+ _dirtyFlags |= ENRMDirtyForceHeight | ENRMDirtyRender; -+ } -+ -+ NSDictionary *imageSources = ENRMImageSourcesFromProps(newViewProps); -+ if (_enableImageSourceResolution != newViewProps.enableImageSourceResolution || -+ _imageSourcesRevision != newViewProps.imageSourcesRevision || -+ _imageSourcesContinuityStart != newViewProps.imageSourcesContinuityStart || -+ ![_imageSources isEqualToDictionary:imageSources]) { -+ _enableImageSourceResolution = newViewProps.enableImageSourceResolution; -+ _imageSourcesRevision = newViewProps.imageSourcesRevision; -+ _imageSourcesContinuityStart = newViewProps.imageSourcesContinuityStart; -+ _imageSources = imageSources; -+ _dirtyFlags |= ENRMDirtyRecreateSegments | ENRMDirtyForceHeight | ENRMDirtyRender; -+ } -+ - if (_config == nil) { - _config = [[StyleConfig alloc] init]; - [_config setFontScaleMultiplier:_fontScaleObserver.effectiveFontScale]; -@@ -1039,10 +1179,7 @@ static char kENRMSegmentFadeAnimatorKey; - - if (ENRMImageRequestHeadersChanged(oldViewProps.imageRequestHeaders, newViewProps.imageRequestHeaders)) { - [_config setImageRequestHeaders:ENRMImageRequestHeadersFromProps(newViewProps.imageRequestHeaders)]; -- _dirtyFlags |= ENRMDirtyRender; -- if (!markdownChanged) { -- _dirtyFlags |= ENRMDirtyRecreateSegments; -- } -+ _dirtyFlags |= ENRMDirtyRecreateSegments | ENRMDirtyForceHeight | ENRMDirtyRender; - } - - _selectable = newViewProps.selectable; -@@ -1077,6 +1214,19 @@ static char kENRMSegmentFadeAnimatorKey; - _dirtyFlags |= ENRMDirtyRecreateSegments | ENRMDirtyForceHeight | ENRMDirtyRender; - } - -+ ENRMLinkRegexConfig *linkRegex = ENRMTextLinkRegexConfigFromProps(newViewProps.linkRegex); -+ ENRMLinkRegexConfig *inlineCodeLinkRegex = ENRMTextLinkRegexConfigFromProps(newViewProps.inlineCodeLinkRegex); -+ if ((_linkRegex || linkRegex) && ![_linkRegex isEqualToConfig:linkRegex]) { -+ _linkRegex = linkRegex; -+ _dirtyFlags |= ENRMDirtyRender; -+ _dirtyFlags |= ENRMDirtyForceHeight; -+ } -+ if ((_inlineCodeLinkRegex || inlineCodeLinkRegex) && ![_inlineCodeLinkRegex isEqualToConfig:inlineCodeLinkRegex]) { -+ _inlineCodeLinkRegex = inlineCodeLinkRegex; -+ _dirtyFlags |= ENRMDirtyRender; -+ _dirtyFlags |= ENRMDirtyForceHeight; -+ } -+ - if (newViewProps.md4cFlags.underline != oldViewProps.md4cFlags.underline || - newViewProps.md4cFlags.superscript != oldViewProps.md4cFlags.superscript || - newViewProps.md4cFlags.subscript != oldViewProps.md4cFlags.subscript || -@@ -1258,9 +1408,25 @@ static char kENRMSegmentFadeAnimatorKey; - - _cachedMarkdown = nil; - _renderedMarkdown = nil; -+ _documentAssets = nil; -+ _lastEmittedAssets = nil; -+ _lastEmittedAssetsRevision = -1; -+ _lastMediaFrames = nil; -+ _mediaOverrides = nil; -+ _imageSources = nil; -+ _imageSourcesRevision = -1; -+ _imageSourcesContinuityStart = 1; -+ _enableImageSourceResolution = NO; -+ _documentRevision = 0; -+ _renderedDocumentRevision = -1; -+ _mediaOverridesRevision = -1; -+ _enableDocumentAssets = NO; -+ _enableMediaSlots = NO; - _config = nil; - _md4cFlags = [EnrichedMarkdown flagsFromProps:resetProps->md4cFlags]; - _isGFM = resetProps->isGFM; -+ _linkRegex = ENRMTextLinkRegexConfigFromProps(resetProps->linkRegex); -+ _inlineCodeLinkRegex = ENRMTextLinkRegexConfigFromProps(resetProps->inlineCodeLinkRegex); - _maxFontSizeMultiplier = 0; - _allowTrailingMargin = NO; - _streamingAnimation = NO; -@@ -1357,6 +1523,52 @@ Class EnrichedMarkdownCls(void) - } - #endif - -+- (void)emitDocumentAssets -+{ -+ if (!_enableDocumentAssets || _renderedDocumentRevision != _documentRevision || -+ (_lastEmittedAssetsRevision == _renderedDocumentRevision && [_lastEmittedAssets isEqualToArray:_documentAssets])) -+ return; -+ auto emitter = std::static_pointer_cast(_eventEmitter); -+ if (!emitter) -+ return; -+ EnrichedMarkdownEventEmitter::OnDocumentAssets event{}; -+ event.revision = (int)_renderedDocumentRevision; -+ for (NSDictionary *asset in _documentAssets) { -+ decltype(event.assets)::value_type item{}; -+ item.id = std::string([asset[@"id"] UTF8String]); -+ item.anchor = std::string([asset[@"anchor"] UTF8String]); -+ item.kind = std::string([asset[@"kind"] UTF8String]); -+ item.url = std::string([asset[@"url"] UTF8String]); -+ item.altText = std::string([asset[@"altText"] UTF8String]); -+ item.title = std::string([asset[@"title"] UTF8String]); -+ item.placement = std::string([asset[@"placement"] UTF8String]); -+ item.eligible = [asset[@"eligible"] boolValue]; -+ event.assets.push_back(item); -+ } -+ _lastEmittedAssetsRevision = _renderedDocumentRevision; -+ _lastEmittedAssets = [_documentAssets copy]; -+ emitter->onDocumentAssets(event); -+} -+ -+- (void)emitMediaLayout:(NSArray *)frames -+{ -+ auto emitter = std::static_pointer_cast(_eventEmitter); -+ if (!emitter) -+ return; -+ EnrichedMarkdownEventEmitter::OnMediaLayout event{}; -+ event.revision = (int)_renderedDocumentRevision; -+ for (NSDictionary *frame in frames) { -+ decltype(event.frames)::value_type item{}; -+ item.id = std::string([frame[@"id"] UTF8String]); -+ item.x = [frame[@"x"] floatValue]; -+ item.y = [frame[@"y"] floatValue]; -+ item.width = [frame[@"width"] floatValue]; -+ item.height = [frame[@"height"] floatValue]; -+ event.frames.push_back(item); -+ } -+ emitter->onMediaLayout(event); -+} -+ - - (void)emitLinkPress:(NSString *)url - { - auto emitter = std::static_pointer_cast(_eventEmitter); -@@ -1418,8 +1630,14 @@ Class EnrichedMarkdownCls(void) - - - (void)updateEventEmitter:(const facebook::react::EventEmitter::Shared &)eventEmitter - { -+ BOOL firstAttachment = !_eventEmitter && eventEmitter; - [super updateEventEmitter:eventEmitter]; - [_latexErrorCoordinator flushPending]; -+ [self emitDocumentAssets]; -+ if (firstAttachment) { -+ _lastMediaFrames = nil; -+ [self setNeedsLayout]; -+ } - } - - - (void)textTapped:(ENRMTapRecognizer *)recognizer -@@ -1510,7 +1728,12 @@ Class EnrichedMarkdownCls(void) - - - (NSArray *)accessibilityElements - { -- return _segmentViews; -+ NSMutableArray *elements = [NSMutableArray array]; -+ for (RCTUIView *segment in _segmentViews) { -+ if (![segment isKindOfClass:[ENRMMediaSlotView class]]) -+ [elements addObject:segment]; -+ } -+ return elements; - } - - - (NSInteger)accessibilityElementCount -diff --git a/ios/EnrichedMarkdownText.mm b/ios/EnrichedMarkdownText.mm -index 0bfa5d353bb1f99dc4d94277c0982f6fcd5046f2..20d3749ddf19742e3791efd1699c30f9f9a7b053 100644 ---- a/ios/EnrichedMarkdownText.mm -+++ b/ios/EnrichedMarkdownText.mm -@@ -12,6 +12,7 @@ - #import "ENRMSpoilerTapUtils.h" - #import "ENRMTailFadeInAnimator.h" - #import "ENRMTextInteractionUtils.h" -+#import "ENRMTextLinkRecognizer.h" - #import "ENRMTextRenderer.h" - #import "ENRMTextViewSetup.h" - #import "ENRMUIKit.h" -@@ -75,6 +76,8 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { - StyleConfig *_config; - ENRMMd4cFlags *_md4cFlags; - BOOL _isGFM; -+ ENRMLinkRegexConfig *_linkRegex; -+ ENRMLinkRegexConfig *_inlineCodeLinkRegex; - - ENRMAsyncRenderCoordinator *_renderCoordinator; - -@@ -243,6 +246,8 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { - _parser = [[ENRMMarkdownParser alloc] init]; - _md4cFlags = [EnrichedMarkdownText flagsFromProps:defaultProps->md4cFlags]; - _isGFM = defaultProps->isGFM; -+ _linkRegex = ENRMTextLinkRegexConfigFromProps(defaultProps->linkRegex); -+ _inlineCodeLinkRegex = ENRMTextLinkRegexConfigFromProps(defaultProps->inlineCodeLinkRegex); - - _renderCoordinator = - [[ENRMAsyncRenderCoordinator alloc] initWithQueueLabel:"com.swmansion.enriched.markdown.render"]; -@@ -303,7 +308,7 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { - - (void)setupTextView - { - #if !TARGET_OS_OSX -- _textView = [[ENRMPlatformTextView alloc] init]; -+ _textView = ENRMCreateMarkdownTextView(); - _textView.text = @""; - #else - _textView = [[ENRMContextMenuTextView alloc] init]; -@@ -375,6 +380,8 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { - ENRMMarkdownParser *parser = _parser; - ENRMMd4cFlags *md4cFlags = [_md4cFlags copy]; - BOOL isGFM = _isGFM; -+ ENRMLinkRegexConfig *linkRegex = _linkRegex; -+ ENRMLinkRegexConfig *inlineCodeLinkRegex = _inlineCodeLinkRegex; - - BOOL allowFontScaling = _fontScaleObserver.allowFontScaling; - CGFloat maxFontSizeMultiplier = _maxFontSizeMultiplier; -@@ -387,7 +394,11 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { - - [_renderCoordinator - scheduleRender:^BOOL { -- MarkdownASTNode *ast = [parser parseMarkdown:markdownString flags:md4cFlags isGFM:isGFM]; -+ MarkdownASTNode *ast = [parser parseMarkdown:markdownString -+ flags:md4cFlags -+ isGFM:isGFM -+ linkRegex:linkRegex -+ inlineCodeLinkRegex:inlineCodeLinkRegex]; - if (!ast) - return NO; - -@@ -407,7 +418,11 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { - - - (NSMutableAttributedString *)parseAndRenderMarkdown:(NSString *)markdownString - { -- MarkdownASTNode *ast = [_parser parseMarkdown:markdownString flags:_md4cFlags isGFM:_isGFM]; -+ MarkdownASTNode *ast = [_parser parseMarkdown:markdownString -+ flags:_md4cFlags -+ isGFM:_isGFM -+ linkRegex:_linkRegex -+ inlineCodeLinkRegex:_inlineCodeLinkRegex]; - if (!ast) { - return nil; - } -@@ -618,6 +633,19 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { - _dirtyFlags |= ENRMDirtyRender; - } - -+ ENRMLinkRegexConfig *linkRegex = ENRMTextLinkRegexConfigFromProps(newViewProps.linkRegex); -+ ENRMLinkRegexConfig *inlineCodeLinkRegex = ENRMTextLinkRegexConfigFromProps(newViewProps.inlineCodeLinkRegex); -+ if ((_linkRegex || linkRegex) && ![_linkRegex isEqualToConfig:linkRegex]) { -+ _linkRegex = linkRegex; -+ _dirtyFlags |= ENRMDirtyRender; -+ _forceHeightUpdateOnNextRender = YES; -+ } -+ if ((_inlineCodeLinkRegex || inlineCodeLinkRegex) && ![_inlineCodeLinkRegex isEqualToConfig:inlineCodeLinkRegex]) { -+ _inlineCodeLinkRegex = inlineCodeLinkRegex; -+ _dirtyFlags |= ENRMDirtyRender; -+ _forceHeightUpdateOnNextRender = YES; -+ } -+ - if (newViewProps.md4cFlags.underline != oldViewProps.md4cFlags.underline || - newViewProps.md4cFlags.superscript != oldViewProps.md4cFlags.superscript || - newViewProps.md4cFlags.subscript != oldViewProps.md4cFlags.subscript || -@@ -769,6 +797,8 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { - _config = nil; - _md4cFlags = [EnrichedMarkdownText flagsFromProps:resetProps->md4cFlags]; - _isGFM = resetProps->isGFM; -+ _linkRegex = ENRMTextLinkRegexConfigFromProps(resetProps->linkRegex); -+ _inlineCodeLinkRegex = ENRMTextLinkRegexConfigFromProps(resetProps->inlineCodeLinkRegex); - _maxFontSizeMultiplier = 0; - _lastElementMarginBottom = 0; - _allowTrailingMargin = NO; -diff --git a/ios/attachments/ENRMImageAttachment.h b/ios/attachments/ENRMImageAttachment.h -index b0247d7cb0c570b63b64f6cf969f2d9bdbee43d3..677295bdbf10e2666a3ce4763e0a1aa1154c750e 100644 ---- a/ios/attachments/ENRMImageAttachment.h -+++ b/ios/attachments/ENRMImageAttachment.h -@@ -43,6 +43,13 @@ NS_ASSUME_NONNULL_BEGIN - - + (instancetype)attachmentForURL:(NSString *)imageURL config:(StyleConfig *)config isInline:(BOOL)isInline; - -+// A nil transportURI holds the normal placeholder without starting a request. -++ (instancetype)attachmentForURL:(NSString *)imageURL -+ config:(StyleConfig *)config -+ isInline:(BOOL)isInline -+ transportURI:(nullable NSString *)transportURI -+ requestHeaders:(nullable NSDictionary *)requestHeaders; -+ - + (NSCache *)originalImageCache; - + (NSCache *)processedImageCache; - -diff --git a/ios/attachments/ENRMImageAttachment.m b/ios/attachments/ENRMImageAttachment.m -index f17cfb0274d9e5bdcbece40efcf5c4ca4629e445..37d5bb80481d4e639874a2f63607d989fd4ff049 100644 ---- a/ios/attachments/ENRMImageAttachment.m -+++ b/ios/attachments/ENRMImageAttachment.m -@@ -34,6 +34,7 @@ static NSCache *_processedImageCache; - @interface ENRMImageAttachment () - - @property (nonatomic, copy) NSString *imageURL; -+@property (nonatomic, copy, nullable) NSString *transportURI; - @property (nonatomic, copy, nullable) NSDictionary *requestHeaders; - @property (nonatomic, copy) NSString *cacheKey; - @property (nonatomic, assign) BOOL isInline; -@@ -81,16 +82,38 @@ static NSCache *_processedImageCache; - // the same image URL at a different width than a copy outside the table, and a shared - // NSTextAttachment would thrash its single last-processed width into a redraw loop. The - // image caches keep fresh instances cheap (no re-fetch or re-scale). -- return [[self alloc] initWithImageURL:imageURL config:config isInline:isInline]; -+ return [self attachmentForURL:imageURL -+ config:config -+ isInline:isInline -+ transportURI:imageURL -+ requestHeaders:config.imageRequestHeaders]; - } - --- (instancetype)initWithImageURL:(NSString *)imageURL config:(StyleConfig *)config isInline:(BOOL)isInline -++ (instancetype)attachmentForURL:(NSString *)imageURL -+ config:(StyleConfig *)config -+ isInline:(BOOL)isInline -+ transportURI:(NSString *)transportURI -+ requestHeaders:(NSDictionary *)requestHeaders -+{ -+ return [[self alloc] initWithImageURL:imageURL -+ config:config -+ isInline:isInline -+ transportURI:transportURI -+ requestHeaders:requestHeaders]; -+} -+ -+- (instancetype)initWithImageURL:(NSString *)imageURL -+ config:(StyleConfig *)config -+ isInline:(BOOL)isInline -+ transportURI:(NSString *)transportURI -+ requestHeaders:(NSDictionary *)requestHeaders - { - self = [super init]; - if (self) { - _imageURL = imageURL; -- _requestHeaders = [[config imageRequestHeaders] copy]; -- _cacheKey = ENRMImageCacheKey(imageURL, _requestHeaders); -+ _transportURI = [transportURI copy]; -+ _requestHeaders = [requestHeaders copy]; -+ _cacheKey = transportURI ? ENRMImageCacheKey(transportURI, _requestHeaders) : @""; - _isInline = isInline; - - _cachedHeight = isInline ? [config inlineImageSize] : [config imageHeight]; -@@ -320,11 +343,11 @@ static NSCache *_processedImageCache; - - - (void)startDownloadingImage - { -- if (self.imageURL.length == 0) -+ if (self.transportURI.length == 0) - return; - - __weak typeof(self) weakSelf = self; -- [[ENRMImageDownloader shared] downloadURL:self.imageURL -+ [[ENRMImageDownloader shared] downloadURL:self.transportURI - headers:self.requestHeaders - completion:^(RCTUIImage *image) { [weakSelf handleLoadedImage:image]; }]; - } -diff --git a/ios/attachments/ENRMLinkPillAttachment.h b/ios/attachments/ENRMLinkPillAttachment.h -new file mode 100644 -index 0000000000000000000000000000000000000000..344ee92b158abc55e2b3db6b70e34e20d161bb13 ---- /dev/null -+++ b/ios/attachments/ENRMLinkPillAttachment.h -@@ -0,0 +1,20 @@ -+#pragma once -+#import "ENRMUIKit.h" -+ -+#if !TARGET_OS_OSX -+@class LinkVariantConfig; -+ -+/// Presentation over the original link characters. Text storage never receives U+FFFC. -+@interface ENRMLinkPillAttachment : NSTextAttachment -+@property (nonatomic, readonly) CGFloat boxHeight; -+- (instancetype)initWithLabel:(NSString *)originalLabel variant:(LinkVariantConfig *)variant font:(UIFont *)font; -+@end -+ -+/// Stateless and shared by visible, table, and view-free TextKit stacks. -+@interface ENRMLinkPillLayoutDelegate : NSObject -++ (instancetype)shared; -+@end -+ -+FOUNDATION_EXPORT CGRect ENRMLinkPillTextBounds(NSAttributedString *text, CGFloat width); -+FOUNDATION_EXPORT void ENRMDrawLinkPillText(NSAttributedString *text, CGRect rect); -+#endif -diff --git a/ios/attachments/ENRMLinkPillAttachment.m b/ios/attachments/ENRMLinkPillAttachment.m -new file mode 100644 -index 0000000000000000000000000000000000000000..9314cebe1cf6415fd5105e24c4507b954e538c7e ---- /dev/null -+++ b/ios/attachments/ENRMLinkPillAttachment.m -@@ -0,0 +1,289 @@ -+#import "ENRMLinkPillAttachment.h" -+#import "ENRMLinkPillIconCache.h" -+#import "ENRMLinkPillTextStorage.h" -+#import "StyleConfig.h" -+#import -+ -+#if !TARGET_OS_OSX -+ -+@implementation ENRMLinkPillAttachment { -+ NSString *_label; -+ LinkVariantConfig *_variant; -+ UIFont *_font; -+ UIImage *_icon; -+} -+ -+- (instancetype)initWithLabel:(NSString *)originalLabel variant:(LinkVariantConfig *)variant font:(UIFont *)font -+{ -+ self = [super initWithData:nil ofType:nil]; -+ if (self) { -+ _variant = variant; -+ _font = font ?: [UIFont systemFontOfSize:16]; -+ NSString *label = variant.label.length > 0 ? variant.label : originalLabel; -+ _label = [[label stringByReplacingOccurrencesOfString:@"\n" -+ withString:@" "] stringByReplacingOccurrencesOfString:@"\r" -+ withString:@" "]; -+ _icon = ENRMLoadLinkPillIcon(variant.iconUri); -+ } -+ return self; -+} -+ -+- (CGFloat)boxHeight -+{ -+ return ceil(_font.ascender - _font.descender + 2 * (_variant.paddingVertical + _variant.borderWidth)); -+} -+ -+- (CGFloat)widthForLimit:(CGFloat)available -+{ -+ CGFloat iconWidth = _icon ? _font.pointSize * 1.25 : 0; -+ CGFloat natural = ceil([_label sizeWithAttributes:@{NSFontAttributeName : _font}].width + iconWidth + -+ 2 * (_variant.paddingHorizontal + _variant.borderWidth)); -+ CGFloat limit = _variant.maxWidth > 0 ? MIN(available, _variant.maxWidth) : available; -+ return MAX(1, MIN(natural, limit)); -+} -+ -+- (BOOL)startsAttachmentInTextContainer:(NSTextContainer *)container characterIndex:(NSUInteger)index -+{ -+ NSTextStorage *storage = container.layoutManager.textStorage; -+ if (!storage) -+ return YES; -+ if (index >= storage.length) -+ return NO; -+ NSRange range; -+ id attachment = [storage attribute:NSAttachmentAttributeName -+ atIndex:index -+ longestEffectiveRange:&range -+ inRange:NSMakeRange(0, storage.length)]; -+ return attachment == self && index == range.location; -+} -+ -+- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)container -+ proposedLineFragment:(CGRect)lineFragment -+ glyphPosition:(CGPoint)position -+ characterIndex:(NSUInteger)characterIndex -+{ -+ // TextKit can query attachments directly, bypassing the glyph delegate for -+ // attachment characters. Only the first source character owns the pill box. -+ if (![self startsAttachmentInTextContainer:container characterIndex:characterIndex]) -+ return CGRectZero; -+ // Use the full container width, not the remainder of the current line. TextKit then moves -+ // the whole attachment to the next line if it doesn't fit the remainder. -+ NSParagraphStyle *paragraph = [container.layoutManager.textStorage attribute:NSParagraphStyleAttributeName -+ atIndex:characterIndex -+ effectiveRange:NULL]; -+ CGFloat indent = MAX(paragraph.firstLineHeadIndent, paragraph.headIndent); -+ CGFloat tailInset = paragraph.tailIndent < 0 ? -paragraph.tailIndent : 0; -+ CGFloat available = MAX(1, container.size.width - 2 * container.lineFragmentPadding - indent - tailInset); -+ CGFloat inset = _variant.paddingVertical + _variant.borderWidth; -+ return CGRectMake(0, _font.descender - inset, [self widthForLimit:available], self.boxHeight); -+} -+ -+- (UIImage *)imageForBounds:(CGRect)bounds textContainer:(NSTextContainer *)container characterIndex:(NSUInteger)index -+{ -+ if (bounds.size.width <= 0 || bounds.size.height <= 0 || -+ ![self startsAttachmentInTextContainer:container characterIndex:index]) -+ return nil; -+ CGSize size = bounds.size; -+ UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat preferredFormat]; -+ format.opaque = NO; -+ UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size format:format]; -+ return [renderer imageWithActions:^(UIGraphicsImageRendererContext *context) { -+ CGRect rect = (CGRect){CGPointZero, size}; -+ UIBezierPath *background = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:_variant.borderRadius]; -+ [_variant.backgroundColor ?: UIColor.clearColor setFill]; -+ [background fill]; -+ if (_variant.borderWidth > 0) { -+ UIBezierPath *border = -+ [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, _variant.borderWidth / 2, _variant.borderWidth / 2) -+ cornerRadius:_variant.borderRadius]; -+ border.lineWidth = _variant.borderWidth; -+ [_variant.borderColor setStroke]; -+ [border stroke]; -+ } -+ [background addClip]; -+ CGFloat left = _variant.paddingHorizontal + _variant.borderWidth; -+ CGFloat right = size.width - left; -+ if (_icon && right - left >= _font.pointSize) { -+ CGFloat side = _font.pointSize; -+ CGFloat scale = side / MAX(_icon.size.width, _icon.size.height); -+ CGSize iconSize = CGSizeMake(_icon.size.width * scale, _icon.size.height * scale); -+ CGRect iconRect = CGRectMake(left + (side - iconSize.width) / 2, (size.height - iconSize.height) / 2, -+ iconSize.width, iconSize.height); -+ UIImage *presentedIcon = _variant.iconTintColor ? [_icon imageWithTintColor:_variant.iconTintColor -+ renderingMode:UIImageRenderingModeAlwaysOriginal] -+ : _icon; -+ [presentedIcon drawInRect:iconRect]; -+ left += side * 1.25; -+ } -+ NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init]; -+ paragraph.lineBreakMode = NSLineBreakByTruncatingTail; -+ NSDictionary *attributes = @{ -+ NSFontAttributeName : _font, -+ NSForegroundColorAttributeName : _variant.color, -+ NSUnderlineStyleAttributeName : @(_variant.underline ? NSUnderlineStyleSingle : NSUnderlineStyleNone), -+ NSParagraphStyleAttributeName : paragraph, -+ }; -+ [_label drawInRect:CGRectMake(left, _variant.paddingVertical + _variant.borderWidth, MAX(0, right - left), -+ size.height) -+ withAttributes:attributes]; -+ }]; -+} -+@end -+ -+@interface ENRMPillGlyphTail : NSObject -+@property (nonatomic) NSUInteger glyphEnd; -+@property (nonatomic) NSUInteger characterIndex; -+@end -+@implementation ENRMPillGlyphTail -+@end -+ -+static char ENRMPillGlyphTailKey; -+ -+@implementation ENRMLinkPillLayoutDelegate -++ (instancetype)shared -+{ -+ static ENRMLinkPillLayoutDelegate *delegate; -+ static dispatch_once_t once; -+ dispatch_once(&once, ^{ delegate = [[self alloc] init]; }); -+ return delegate; -+} -+ -+- (NSUInteger)layoutManager:(NSLayoutManager *)manager -+ shouldGenerateGlyphs:(const CGGlyph *)glyphs -+ properties:(const NSGlyphProperty *)properties -+ characterIndexes:(const NSUInteger *)indexes -+ font:(UIFont *)font -+ forGlyphRange:(NSRange)glyphRange -+{ -+ NSUInteger count = glyphRange.length; -+ if (count == 0) -+ return 0; -+ ENRMPillGlyphTail *tail = objc_getAssociatedObject(manager, &ENRMPillGlyphTailKey); -+ BOOL continuesFirstCharacter = tail && tail.glyphEnd == glyphRange.location && tail.characterIndex == indexes[0]; -+ if (!tail) { -+ tail = [ENRMPillGlyphTail new]; -+ objc_setAssociatedObject(manager, &ENRMPillGlyphTailKey, tail, OBJC_ASSOCIATION_RETAIN_NONATOMIC); -+ } -+ // Remember only the immediately preceding callback. Querying surrounding glyphs -+ // during generation can recurse into this delegate before those glyphs exist. -+ tail.glyphEnd = NSMaxRange(glyphRange); -+ tail.characterIndex = indexes[count - 1]; -+ NSMutableData *glyphData = nil; -+ NSMutableData *propertyData = nil; -+ CGGlyph *replacement = NULL; -+ NSGlyphProperty *replacementProperties = NULL; -+ for (NSUInteger i = 0; i < count; i++) { -+ id attachment = [manager.textStorage attribute:NSAttachmentAttributeName atIndex:indexes[i] effectiveRange:NULL]; -+ if (![attachment isKindOfClass:ENRMLinkPillAttachment.class]) -+ continue; -+ NSRange range; -+ // Attribute runs may split at every source character after UIKit fixes fonts/colors. -+ // The pill starts at the longest range of the attachment alone, not the current run. -+ [manager.textStorage attribute:NSAttachmentAttributeName -+ atIndex:indexes[i] -+ longestEffectiveRange:&range -+ inRange:NSMakeRange(0, manager.textStorage.length)]; -+ if (!glyphData) { -+ glyphData = [NSMutableData dataWithBytes:glyphs length:count * sizeof(CGGlyph)]; -+ propertyData = [NSMutableData dataWithBytes:properties length:count * sizeof(NSGlyphProperty)]; -+ replacement = glyphData.mutableBytes; -+ replacementProperties = propertyData.mutableBytes; -+ } -+ // A character can have multiple glyphs, even across font/callback boundaries. -+ BOOL startsAttachment = indexes[i] == range.location; -+ BOOL continuesCharacter = startsAttachment && (i > 0 ? indexes[i - 1] == indexes[i] : continuesFirstCharacter); -+ if (startsAttachment && !continuesCharacter) { -+ // TextKit's attachment glyph exists only in the glyph buffer, never in text storage. -+ replacement[i] = 0xFFFC; -+ replacementProperties[i] = 0; -+ } else { -+ replacement[i] = 0; -+ replacementProperties[i] = NSGlyphPropertyNull; -+ } -+ } -+ if (!glyphData) -+ return 0; -+ [manager setGlyphs:replacement -+ properties:replacementProperties -+ characterIndexes:indexes -+ font:font -+ forGlyphRange:glyphRange]; -+ return count; -+} -+ -+- (BOOL)layoutManager:(NSLayoutManager *)manager shouldBreakLineByWordBeforeCharacterAtIndex:(NSUInteger)index -+{ -+ if (index >= manager.textStorage.length) -+ return YES; -+ id attachment = [manager.textStorage attribute:NSAttachmentAttributeName atIndex:index effectiveRange:NULL]; -+ if (![attachment isKindOfClass:ENRMLinkPillAttachment.class]) -+ return YES; -+ NSRange range; -+ [manager.textStorage attribute:NSAttachmentAttributeName -+ atIndex:index -+ longestEffectiveRange:&range -+ inRange:NSMakeRange(0, manager.textStorage.length)]; -+ return index == range.location; -+} -+@end -+ -+static NSLayoutManager *ENRMPillLayout(NSAttributedString *text, CGSize size, NSTextStorage **storageOut, -+ NSTextContainer **containerOut) -+{ -+ NSTextStorage *storage = [[ENRMLinkPillTextStorage alloc] initWithAttributedString:text]; -+ NSLayoutManager *manager = [[NSLayoutManager alloc] init]; -+ manager.delegate = ENRMLinkPillLayoutDelegate.shared; -+ manager.allowsNonContiguousLayout = NO; -+ NSTextContainer *container = [[NSTextContainer alloc] initWithSize:size]; -+ container.lineFragmentPadding = 0; -+ [storage addLayoutManager:manager]; -+ [manager addTextContainer:container]; -+ [manager ensureLayoutForTextContainer:container]; -+ *storageOut = storage; -+ *containerOut = container; -+ return manager; -+} -+ -+static BOOL ENRMHasLinkPill(NSAttributedString *text) -+{ -+ __block BOOL found = NO; -+ [text enumerateAttribute:NSAttachmentAttributeName -+ inRange:NSMakeRange(0, text.length) -+ options:0 -+ usingBlock:^(id value, NSRange range, BOOL *stop) { -+ if ([value isKindOfClass:ENRMLinkPillAttachment.class]) { -+ found = YES; -+ *stop = YES; -+ } -+ }]; -+ return found; -+} -+ -+CGRect ENRMLinkPillTextBounds(NSAttributedString *text, CGFloat width) -+{ -+ if (!ENRMHasLinkPill(text)) -+ return [text boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) -+ options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading -+ context:nil]; -+ // NSLayoutManager does not own its storage. Keep it alive through measurement/drawing under ARC. -+ __attribute__((objc_precise_lifetime)) NSTextStorage *storage; -+ NSTextContainer *container; -+ NSLayoutManager *manager = ENRMPillLayout(text, CGSizeMake(width, CGFLOAT_MAX), &storage, &container); -+ return [manager usedRectForTextContainer:container]; -+} -+ -+void ENRMDrawLinkPillText(NSAttributedString *text, CGRect rect) -+{ -+ if (!ENRMHasLinkPill(text)) { -+ [text drawWithRect:rect options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil]; -+ return; -+ } -+ // NSLayoutManager does not own its storage. Keep it alive through measurement/drawing under ARC. -+ __attribute__((objc_precise_lifetime)) NSTextStorage *storage; -+ NSTextContainer *container; -+ NSLayoutManager *manager = ENRMPillLayout(text, rect.size, &storage, &container); -+ NSRange glyphs = [manager glyphRangeForTextContainer:container]; -+ [manager drawBackgroundForGlyphRange:glyphs atPoint:rect.origin]; -+ [manager drawGlyphsForGlyphRange:glyphs atPoint:rect.origin]; -+} -+#endif -diff --git a/ios/attachments/ENRMLinkPillIconCache.h b/ios/attachments/ENRMLinkPillIconCache.h -new file mode 100644 -index 0000000000000000000000000000000000000000..ab708fbe0a1882278c684849a759295e81704fb5 ---- /dev/null -+++ b/ios/attachments/ENRMLinkPillIconCache.h -@@ -0,0 +1,7 @@ -+#pragma once -+#import "ENRMUIKit.h" -+ -+#if !TARGET_OS_OSX -+/** Original-color local icons; bounded shared cache, tint remains presentation-specific. */ -+FOUNDATION_EXPORT UIImage *_Nullable ENRMLoadLinkPillIcon(NSString *_Nullable iconUri); -+#endif -diff --git a/ios/attachments/ENRMLinkPillIconCache.m b/ios/attachments/ENRMLinkPillIconCache.m -new file mode 100644 -index 0000000000000000000000000000000000000000..0bece83dac6608ff78e8458c40095d7279ef87bc ---- /dev/null -+++ b/ios/attachments/ENRMLinkPillIconCache.m -@@ -0,0 +1,63 @@ -+#import "ENRMLinkPillIconCache.h" -+#if !TARGET_OS_OSX -+#import -+ -+UIImage *ENRMLoadLinkPillIcon(NSString *iconUri) -+{ -+ NSURL *uri = iconUri.length > 0 ? [NSURL URLWithString:iconUri] : nil; -+ if (!uri.isFileURL) -+ return nil; -+ NSString *path = uri.URLByResolvingSymlinksInPath.path; -+ NSDictionary *attributes = [NSFileManager.defaultManager attributesOfItemAtPath:path error:nil]; -+ if (!attributes || ![attributes[NSFileType] isEqual:NSFileTypeRegular]) -+ return nil; -+ NSString *key = -+ [NSString stringWithFormat:@"%@|%.9f|%@", path, [attributes[NSFileModificationDate] timeIntervalSince1970], -+ attributes[NSFileSize]]; -+ static NSMutableDictionary *images; -+ static NSMutableArray *order; -+ static NSUInteger bytes; -+ static dispatch_once_t once; -+ dispatch_once(&once, ^{ -+ images = [NSMutableDictionary new]; -+ order = [NSMutableArray new]; -+ }); -+ @synchronized(images) { -+ UIImage *cached = images[key]; -+ if (cached) { -+ [order removeObject:key]; -+ [order addObject:key]; -+ return cached; -+ } -+ CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)[NSURL fileURLWithPath:path], NULL); -+ if (!source) -+ return nil; -+ NSDictionary *options = @{ -+ (__bridge NSString *)kCGImageSourceCreateThumbnailFromImageAlways : @YES, -+ (__bridge NSString *)kCGImageSourceCreateThumbnailWithTransform : @YES, -+ (__bridge NSString *)kCGImageSourceShouldCacheImmediately : @YES, -+ (__bridge NSString *)kCGImageSourceThumbnailMaxPixelSize : @512, -+ }; -+ CGImageRef decoded = CGImageSourceCreateThumbnailAtIndex(source, 0, (__bridge CFDictionaryRef)options); -+ CFRelease(source); -+ if (!decoded) -+ return nil; -+ NSUInteger cost = CGImageGetBytesPerRow(decoded) * CGImageGetHeight(decoded); -+ UIImage *image = [UIImage imageWithCGImage:decoded]; -+ CGImageRelease(decoded); -+ if (cost > 8 * 1024 * 1024) -+ return image; -+ images[key] = image; -+ [order addObject:key]; -+ bytes += cost; -+ while (order.count > 64 || bytes > 8 * 1024 * 1024) { -+ NSString *oldest = order.firstObject; -+ CGImageRef previous = images[oldest].CGImage; -+ bytes -= CGImageGetBytesPerRow(previous) * CGImageGetHeight(previous); -+ [images removeObjectForKey:oldest]; -+ [order removeObjectAtIndex:0]; -+ } -+ return image; -+ } -+} -+#endif -diff --git a/ios/attachments/ENRMLinkPillTextStorage.h b/ios/attachments/ENRMLinkPillTextStorage.h -new file mode 100644 -index 0000000000000000000000000000000000000000..a2479abd1dcf31de33d74a74d2396f8eeb0dd579 ---- /dev/null -+++ b/ios/attachments/ENRMLinkPillTextStorage.h -@@ -0,0 +1,11 @@ -+#pragma once -+#import "ENRMUIKit.h" -+ -+#if !TARGET_OS_OSX -+/// Keeps presentation attachments over original link characters through TextKit attribute fixing. -+@interface ENRMLinkPillTextStorage : NSTextStorage -+@end -+ -+/// An explicit TextKit 1 stack using the same storage as view-free and table layout. -+FOUNDATION_EXPORT UITextView *ENRMCreateMarkdownTextView(void); -+#endif -diff --git a/ios/attachments/ENRMLinkPillTextStorage.m b/ios/attachments/ENRMLinkPillTextStorage.m -new file mode 100644 -index 0000000000000000000000000000000000000000..a70cb6898e6c48bab54435bfb9470ef0a1073565 ---- /dev/null -+++ b/ios/attachments/ENRMLinkPillTextStorage.m -@@ -0,0 +1,80 @@ -+#import "ENRMLinkPillTextStorage.h" -+#import "ENRMLinkPillAttachment.h" -+ -+#if !TARGET_OS_OSX -+@implementation ENRMLinkPillTextStorage { -+ NSMutableAttributedString *_backing; -+} -+ -+- (instancetype)init -+{ -+ self = [super init]; -+ if (self) -+ _backing = [[NSMutableAttributedString alloc] init]; -+ return self; -+} -+ -+- (instancetype)initWithAttributedString:(NSAttributedString *)text -+{ -+ self = [self init]; -+ if (self) -+ [self setAttributedString:text]; -+ return self; -+} -+ -+- (NSString *)string -+{ -+ return _backing.string; -+} -+ -+- (NSDictionary *)attributesAtIndex:(NSUInteger)index effectiveRange:(NSRangePointer)range -+{ -+ return [_backing attributesAtIndex:index effectiveRange:range]; -+} -+ -+- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)text -+{ -+ [_backing replaceCharactersInRange:range withString:text]; -+ [self edited:NSTextStorageEditedCharacters -+ range:range -+ changeInLength:(NSInteger)text.length - (NSInteger)range.length]; -+} -+ -+- (void)setAttributes:(NSDictionary *)attributes range:(NSRange)range -+{ -+ [_backing setAttributes:attributes range:range]; -+ [self edited:NSTextStorageEditedAttributes range:range changeInLength:0]; -+} -+ -+- (void)fixAttributesInRange:(NSRange)range -+{ -+ // Foundation removes NSAttachmentAttributeName unless the source character is U+FFFC. -+ // A pill deliberately leaves source characters intact; preserve only these attachments. -+ // Standard fixing can extend to the complete paragraph, including pills outside the edit. -+ NSRange fixingRange = [_backing.string paragraphRangeForRange:range]; -+ NSMutableArray *pills = [NSMutableArray new]; -+ [_backing enumerateAttribute:NSAttachmentAttributeName -+ inRange:fixingRange -+ options:0 -+ usingBlock:^(id value, NSRange subrange, BOOL *stop) { -+ if ([value isKindOfClass:ENRMLinkPillAttachment.class]) -+ [pills addObject:@{@"attachment" : value, @"range" : [NSValue valueWithRange:subrange]}]; -+ }]; -+ [_backing fixAttributesInRange:range]; -+ for (NSDictionary *pill in pills) -+ [_backing addAttribute:NSAttachmentAttributeName value:pill[@"attachment"] range:[pill[@"range"] rangeValue]]; -+ // Fixing belongs to the existing edit notification. Direct backing restoration avoids recursive edits. -+} -+@end -+ -+UITextView *ENRMCreateMarkdownTextView(void) -+{ -+ ENRMLinkPillTextStorage *storage = [[ENRMLinkPillTextStorage alloc] init]; -+ NSLayoutManager *manager = [[NSLayoutManager alloc] init]; -+ manager.delegate = ENRMLinkPillLayoutDelegate.shared; -+ [storage addLayoutManager:manager]; -+ NSTextContainer *container = [[NSTextContainer alloc] initWithSize:CGSizeMake(0, CGFLOAT_MAX)]; -+ [manager addTextContainer:container]; -+ return [[UITextView alloc] initWithFrame:CGRectZero textContainer:container]; -+} -+#endif -diff --git a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp -index 1b1b96234e8313e1e1fb2f033a19df84434255f0..e854371ae92d15228fb65133108ce2f4bd4c234d 100644 ---- a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp -+++ b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp -@@ -13,6 +13,55 @@ - - namespace facebook::react { - -+void EnrichedMarkdownEventEmitter::onDocumentAssets(OnDocumentAssets event) const { -+ dispatchEvent("documentAssets", [event=std::move(event)](jsi::Runtime &runtime) { -+ auto payload = jsi::Object(runtime); -+ payload.setProperty(runtime, "revision", event.revision); -+ -+ auto assets = jsi::Array(runtime, event.assets.size()); -+ size_t assetsIndex = 0; -+ for (auto assetsValue : event.assets) { -+ auto assetsObject = jsi::Object(runtime); -+ assetsObject.setProperty(runtime, "anchor", assetsValue.anchor); -+assetsObject.setProperty(runtime, "id", assetsValue.id); -+assetsObject.setProperty(runtime, "kind", assetsValue.kind); -+assetsObject.setProperty(runtime, "url", assetsValue.url); -+assetsObject.setProperty(runtime, "altText", assetsValue.altText); -+assetsObject.setProperty(runtime, "title", assetsValue.title); -+assetsObject.setProperty(runtime, "placement", assetsValue.placement); -+assetsObject.setProperty(runtime, "eligible", assetsValue.eligible); -+ assets.setValueAtIndex(runtime, assetsIndex++, assetsObject); -+ } -+ payload.setProperty(runtime, "assets", assets); -+ -+ return payload; -+ }); -+} -+ -+ -+void EnrichedMarkdownEventEmitter::onMediaLayout(OnMediaLayout event) const { -+ dispatchEvent("mediaLayout", [event=std::move(event)](jsi::Runtime &runtime) { -+ auto payload = jsi::Object(runtime); -+ payload.setProperty(runtime, "revision", event.revision); -+ -+ auto frames = jsi::Array(runtime, event.frames.size()); -+ size_t framesIndex = 0; -+ for (auto framesValue : event.frames) { -+ auto framesObject = jsi::Object(runtime); -+ framesObject.setProperty(runtime, "id", framesValue.id); -+framesObject.setProperty(runtime, "x", framesValue.x); -+framesObject.setProperty(runtime, "y", framesValue.y); -+framesObject.setProperty(runtime, "width", framesValue.width); -+framesObject.setProperty(runtime, "height", framesValue.height); -+ frames.setValueAtIndex(runtime, framesIndex++, framesObject); -+ } -+ payload.setProperty(runtime, "frames", frames); -+ -+ return payload; -+ }); -+} -+ -+ - void EnrichedMarkdownEventEmitter::onLinkPress(OnLinkPress event) const { - dispatchEvent("linkPress", [event=std::move(event)](jsi::Runtime &runtime) { - auto payload = jsi::Object(runtime); -diff --git a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h -index 3fda20ba6e4d253545401f9a4d76fabdebe4126f..0aa908394302b7753305f324d8165aaea3b24d08 100644 ---- a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h -+++ b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h -@@ -17,6 +17,35 @@ class EnrichedMarkdownEventEmitter : public ViewEventEmitter { - public: - using ViewEventEmitter::ViewEventEmitter; - -+ struct OnDocumentAssetsAssets { -+ std::string anchor; -+ std::string id; -+ std::string kind; -+ std::string url; -+ std::string altText; -+ std::string title; -+ std::string placement; -+ bool eligible; -+ }; -+ -+ struct OnDocumentAssets { -+ int revision; -+ std::vector assets; -+ }; -+ -+ struct OnMediaLayoutFrames { -+ std::string id; -+ Float x; -+ Float y; -+ Float width; -+ Float height; -+ }; -+ -+ struct OnMediaLayout { -+ int revision; -+ std::vector frames; -+ }; -+ - struct OnLinkPress { - std::string url; - }; -@@ -58,6 +87,10 @@ class EnrichedMarkdownEventEmitter : public ViewEventEmitter { - int selectionStart; - int selectionEnd; - }; -+ void onDocumentAssets(OnDocumentAssets value) const; -+ -+ void onMediaLayout(OnMediaLayout value) const; -+ - void onLinkPress(OnLinkPress value) const; - - void onLinkLongPress(OnLinkLongPress value) const; -diff --git a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp -index fe3cfc5c95ceafbdbf32ea2fbbf1cba8989157e8..5bc5b43908ad3ce0b80f061d491a75058a59872f 100644 ---- a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp -+++ b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp -@@ -19,6 +19,17 @@ EnrichedMarkdownProps::EnrichedMarkdownProps( - const EnrichedMarkdownProps &sourceProps, - const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), - -+ enableImageSourceResolution(convertRawProp(context, rawProps, "enableImageSourceResolution", sourceProps.enableImageSourceResolution, {false})), -+ imageSourcesRevision(convertRawProp(context, rawProps, "imageSourcesRevision", sourceProps.imageSourcesRevision, {-1})), -+ imageSourcesContinuityStart(convertRawProp(context, rawProps, "imageSourcesContinuityStart", sourceProps.imageSourcesContinuityStart, {1})), -+ imageSources(convertRawProp(context, rawProps, "imageSources", sourceProps.imageSources, {})), -+ documentRevision(convertRawProp(context, rawProps, "documentRevision", sourceProps.documentRevision, {0})), -+ enableDocumentAssets(convertRawProp(context, rawProps, "enableDocumentAssets", sourceProps.enableDocumentAssets, {false})), -+ enableMediaSlots(convertRawProp(context, rawProps, "enableMediaSlots", sourceProps.enableMediaSlots, {false})), -+ mediaOverridesRevision(convertRawProp(context, rawProps, "mediaOverridesRevision", sourceProps.mediaOverridesRevision, {-1})), -+ mediaOverrides(convertRawProp(context, rawProps, "mediaOverrides", sourceProps.mediaOverrides, {})), -+ linkRegex(convertRawProp(context, rawProps, "linkRegex", sourceProps.linkRegex, {})), -+ inlineCodeLinkRegex(convertRawProp(context, rawProps, "inlineCodeLinkRegex", sourceProps.inlineCodeLinkRegex, {})), - markdown(convertRawProp(context, rawProps, "markdown", sourceProps.markdown, {})), - markdownStyle(convertRawProp(context, rawProps, "markdownStyle", sourceProps.markdownStyle, {})), - enableImagePress(convertRawProp(context, rawProps, "enableImagePress", sourceProps.enableImagePress, {false})), -@@ -63,6 +74,50 @@ folly::dynamic EnrichedMarkdownProps::getDiffProps( - } - folly::dynamic result = HostPlatformViewProps::getDiffProps(prevProps); - -+ if (enableImageSourceResolution != oldProps->enableImageSourceResolution) { -+ result["enableImageSourceResolution"] = enableImageSourceResolution; -+ } -+ -+ if (imageSourcesRevision != oldProps->imageSourcesRevision) { -+ result["imageSourcesRevision"] = imageSourcesRevision; -+ } -+ -+ if (imageSourcesContinuityStart != oldProps->imageSourcesContinuityStart) { -+ result["imageSourcesContinuityStart"] = imageSourcesContinuityStart; -+ } -+ -+ if (imageSources != oldProps->imageSources) { -+ result["imageSources"] = toDynamic(imageSources); -+ } -+ -+ if (documentRevision != oldProps->documentRevision) { -+ result["documentRevision"] = documentRevision; -+ } -+ -+ if (enableDocumentAssets != oldProps->enableDocumentAssets) { -+ result["enableDocumentAssets"] = enableDocumentAssets; -+ } -+ -+ if (enableMediaSlots != oldProps->enableMediaSlots) { -+ result["enableMediaSlots"] = enableMediaSlots; -+ } -+ -+ if (mediaOverridesRevision != oldProps->mediaOverridesRevision) { -+ result["mediaOverridesRevision"] = mediaOverridesRevision; -+ } -+ -+ if (mediaOverrides != oldProps->mediaOverrides) { -+ result["mediaOverrides"] = toDynamic(mediaOverrides); -+ } -+ -+ if (linkRegex != oldProps->linkRegex) { -+ result["linkRegex"] = toDynamic(linkRegex); -+ } -+ -+ if (inlineCodeLinkRegex != oldProps->inlineCodeLinkRegex) { -+ result["inlineCodeLinkRegex"] = toDynamic(inlineCodeLinkRegex); -+ } -+ - if (markdown != oldProps->markdown) { - result["markdown"] = markdown; - } -@@ -317,6 +372,8 @@ EnrichedMarkdownTextProps::EnrichedMarkdownTextProps( - const EnrichedMarkdownTextProps &sourceProps, - const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), - -+ linkRegex(convertRawProp(context, rawProps, "linkRegex", sourceProps.linkRegex, {})), -+ inlineCodeLinkRegex(convertRawProp(context, rawProps, "inlineCodeLinkRegex", sourceProps.inlineCodeLinkRegex, {})), - markdown(convertRawProp(context, rawProps, "markdown", sourceProps.markdown, {})), - markdownStyle(convertRawProp(context, rawProps, "markdownStyle", sourceProps.markdownStyle, {})), - enableImagePress(convertRawProp(context, rawProps, "enableImagePress", sourceProps.enableImagePress, {false})), -@@ -361,6 +418,14 @@ folly::dynamic EnrichedMarkdownTextProps::getDiffProps( - } - folly::dynamic result = HostPlatformViewProps::getDiffProps(prevProps); - -+ if (linkRegex != oldProps->linkRegex) { -+ result["linkRegex"] = toDynamic(linkRegex); -+ } -+ -+ if (inlineCodeLinkRegex != oldProps->inlineCodeLinkRegex) { -+ result["inlineCodeLinkRegex"] = toDynamic(inlineCodeLinkRegex); -+ } -+ - if (markdown != oldProps->markdown) { - result["markdown"] = markdown; - } -diff --git a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h -index ed3b4bf2507500ee012b6412e85b48f11214b364..9c8f8139bbbbff277c0b10eb541723e366fb6015 100644 ---- a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h -+++ b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h -@@ -18,6 +18,320 @@ - - namespace facebook::react { - -+struct EnrichedMarkdownImageSourcesHeadersStruct { -+ std::string name{}; -+ std::string value{}; -+ -+ -+#ifdef RN_SERIALIZABLE_STATE -+ bool operator==(const EnrichedMarkdownImageSourcesHeadersStruct&) const = default; -+ -+ folly::dynamic toDynamic() const { -+ folly::dynamic result = folly::dynamic::object(); -+ result["name"] = name; -+ result["value"] = value; -+ return result; -+ } -+#endif -+}; -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownImageSourcesHeadersStruct &result) { -+ auto map = (std::unordered_map)value; -+ -+ auto tmp_name = map.find("name"); -+ if (tmp_name != map.end()) { -+ fromRawValue(context, tmp_name->second, result.name); -+ } -+ auto tmp_value = map.find("value"); -+ if (tmp_value != map.end()) { -+ fromRawValue(context, tmp_value->second, result.value); -+ } -+} -+ -+static inline std::string toString(const EnrichedMarkdownImageSourcesHeadersStruct &value) { -+ return "[Object EnrichedMarkdownImageSourcesHeadersStruct]"; -+} -+ -+#ifdef RN_SERIALIZABLE_STATE -+static inline folly::dynamic toDynamic(const EnrichedMarkdownImageSourcesHeadersStruct &value) { -+ return value.toDynamic(); -+} -+#endif -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, std::vector &result) { -+ auto items = (std::vector)value; -+ for (const auto &item : items) { -+ EnrichedMarkdownImageSourcesHeadersStruct newItem; -+ fromRawValue(context, item, newItem); -+ result.emplace_back(newItem); -+ } -+} -+ -+ -+struct EnrichedMarkdownImageSourcesStruct { -+ std::string id{}; -+ std::string url{}; -+ std::string anchor{}; -+ std::string uri{}; -+ std::vector headers{}; -+ bool useDefault{false}; -+ -+ -+#ifdef RN_SERIALIZABLE_STATE -+ bool operator==(const EnrichedMarkdownImageSourcesStruct&) const = default; -+ -+ folly::dynamic toDynamic() const { -+ folly::dynamic result = folly::dynamic::object(); -+ result["id"] = id; -+ result["url"] = url; -+ result["anchor"] = anchor; -+ result["uri"] = uri; -+ result["headers"] = ::facebook::react::toDynamic(headers); -+ result["useDefault"] = useDefault; -+ return result; -+ } -+#endif -+}; -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownImageSourcesStruct &result) { -+ auto map = (std::unordered_map)value; -+ -+ auto tmp_id = map.find("id"); -+ if (tmp_id != map.end()) { -+ fromRawValue(context, tmp_id->second, result.id); -+ } -+ auto tmp_url = map.find("url"); -+ if (tmp_url != map.end()) { -+ fromRawValue(context, tmp_url->second, result.url); -+ } -+ auto tmp_anchor = map.find("anchor"); -+ if (tmp_anchor != map.end()) { -+ fromRawValue(context, tmp_anchor->second, result.anchor); -+ } -+ auto tmp_uri = map.find("uri"); -+ if (tmp_uri != map.end()) { -+ fromRawValue(context, tmp_uri->second, result.uri); -+ } -+ auto tmp_headers = map.find("headers"); -+ if (tmp_headers != map.end()) { -+ fromRawValue(context, tmp_headers->second, result.headers); -+ } -+ auto tmp_useDefault = map.find("useDefault"); -+ if (tmp_useDefault != map.end()) { -+ fromRawValue(context, tmp_useDefault->second, result.useDefault); -+ } -+} -+ -+static inline std::string toString(const EnrichedMarkdownImageSourcesStruct &value) { -+ return "[Object EnrichedMarkdownImageSourcesStruct]"; -+} -+ -+#ifdef RN_SERIALIZABLE_STATE -+static inline folly::dynamic toDynamic(const EnrichedMarkdownImageSourcesStruct &value) { -+ return value.toDynamic(); -+} -+#endif -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, std::vector &result) { -+ auto items = (std::vector)value; -+ for (const auto &item : items) { -+ EnrichedMarkdownImageSourcesStruct newItem; -+ fromRawValue(context, item, newItem); -+ result.emplace_back(newItem); -+ } -+} -+ -+ -+struct EnrichedMarkdownMediaOverridesStruct { -+ std::string url{}; -+ std::string kind{}; -+ std::string anchor{}; -+ std::string id{}; -+ Float height{0.0}; -+ Float width{0.0}; -+ -+ -+#ifdef RN_SERIALIZABLE_STATE -+ bool operator==(const EnrichedMarkdownMediaOverridesStruct&) const = default; -+ -+ folly::dynamic toDynamic() const { -+ folly::dynamic result = folly::dynamic::object(); -+ result["url"] = url; -+ result["kind"] = kind; -+ result["anchor"] = anchor; -+ result["id"] = id; -+ result["height"] = height; -+ result["width"] = width; -+ return result; -+ } -+#endif -+}; -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownMediaOverridesStruct &result) { -+ auto map = (std::unordered_map)value; -+ -+ auto tmp_url = map.find("url"); -+ if (tmp_url != map.end()) { -+ fromRawValue(context, tmp_url->second, result.url); -+ } -+ auto tmp_kind = map.find("kind"); -+ if (tmp_kind != map.end()) { -+ fromRawValue(context, tmp_kind->second, result.kind); -+ } -+ auto tmp_anchor = map.find("anchor"); -+ if (tmp_anchor != map.end()) { -+ fromRawValue(context, tmp_anchor->second, result.anchor); -+ } -+ auto tmp_id = map.find("id"); -+ if (tmp_id != map.end()) { -+ fromRawValue(context, tmp_id->second, result.id); -+ } -+ auto tmp_height = map.find("height"); -+ if (tmp_height != map.end()) { -+ fromRawValue(context, tmp_height->second, result.height); -+ } -+ auto tmp_width = map.find("width"); -+ if (tmp_width != map.end()) { -+ fromRawValue(context, tmp_width->second, result.width); -+ } -+} -+ -+static inline std::string toString(const EnrichedMarkdownMediaOverridesStruct &value) { -+ return "[Object EnrichedMarkdownMediaOverridesStruct]"; -+} -+ -+#ifdef RN_SERIALIZABLE_STATE -+static inline folly::dynamic toDynamic(const EnrichedMarkdownMediaOverridesStruct &value) { -+ return value.toDynamic(); -+} -+#endif -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, std::vector &result) { -+ auto items = (std::vector)value; -+ for (const auto &item : items) { -+ EnrichedMarkdownMediaOverridesStruct newItem; -+ fromRawValue(context, item, newItem); -+ result.emplace_back(newItem); -+ } -+} -+ -+ -+struct EnrichedMarkdownLinkRegexStruct { -+ std::string pattern{}; -+ bool caseInsensitive{false}; -+ bool dotAll{false}; -+ bool isDisabled{false}; -+ bool isDefault{false}; -+ -+ -+#ifdef RN_SERIALIZABLE_STATE -+ bool operator==(const EnrichedMarkdownLinkRegexStruct&) const = default; -+ -+ folly::dynamic toDynamic() const { -+ folly::dynamic result = folly::dynamic::object(); -+ result["pattern"] = pattern; -+ result["caseInsensitive"] = caseInsensitive; -+ result["dotAll"] = dotAll; -+ result["isDisabled"] = isDisabled; -+ result["isDefault"] = isDefault; -+ return result; -+ } -+#endif -+}; -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownLinkRegexStruct &result) { -+ auto map = (std::unordered_map)value; -+ -+ auto tmp_pattern = map.find("pattern"); -+ if (tmp_pattern != map.end()) { -+ fromRawValue(context, tmp_pattern->second, result.pattern); -+ } -+ auto tmp_caseInsensitive = map.find("caseInsensitive"); -+ if (tmp_caseInsensitive != map.end()) { -+ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); -+ } -+ auto tmp_dotAll = map.find("dotAll"); -+ if (tmp_dotAll != map.end()) { -+ fromRawValue(context, tmp_dotAll->second, result.dotAll); -+ } -+ auto tmp_isDisabled = map.find("isDisabled"); -+ if (tmp_isDisabled != map.end()) { -+ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); -+ } -+ auto tmp_isDefault = map.find("isDefault"); -+ if (tmp_isDefault != map.end()) { -+ fromRawValue(context, tmp_isDefault->second, result.isDefault); -+ } -+} -+ -+static inline std::string toString(const EnrichedMarkdownLinkRegexStruct &value) { -+ return "[Object EnrichedMarkdownLinkRegexStruct]"; -+} -+ -+#ifdef RN_SERIALIZABLE_STATE -+static inline folly::dynamic toDynamic(const EnrichedMarkdownLinkRegexStruct &value) { -+ return value.toDynamic(); -+} -+#endif -+ -+struct EnrichedMarkdownInlineCodeLinkRegexStruct { -+ std::string pattern{}; -+ bool caseInsensitive{false}; -+ bool dotAll{false}; -+ bool isDisabled{false}; -+ bool isDefault{false}; -+ -+ -+#ifdef RN_SERIALIZABLE_STATE -+ bool operator==(const EnrichedMarkdownInlineCodeLinkRegexStruct&) const = default; -+ -+ folly::dynamic toDynamic() const { -+ folly::dynamic result = folly::dynamic::object(); -+ result["pattern"] = pattern; -+ result["caseInsensitive"] = caseInsensitive; -+ result["dotAll"] = dotAll; -+ result["isDisabled"] = isDisabled; -+ result["isDefault"] = isDefault; -+ return result; -+ } -+#endif -+}; -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownInlineCodeLinkRegexStruct &result) { -+ auto map = (std::unordered_map)value; -+ -+ auto tmp_pattern = map.find("pattern"); -+ if (tmp_pattern != map.end()) { -+ fromRawValue(context, tmp_pattern->second, result.pattern); -+ } -+ auto tmp_caseInsensitive = map.find("caseInsensitive"); -+ if (tmp_caseInsensitive != map.end()) { -+ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); -+ } -+ auto tmp_dotAll = map.find("dotAll"); -+ if (tmp_dotAll != map.end()) { -+ fromRawValue(context, tmp_dotAll->second, result.dotAll); -+ } -+ auto tmp_isDisabled = map.find("isDisabled"); -+ if (tmp_isDisabled != map.end()) { -+ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); -+ } -+ auto tmp_isDefault = map.find("isDefault"); -+ if (tmp_isDefault != map.end()) { -+ fromRawValue(context, tmp_isDefault->second, result.isDefault); -+ } -+} -+ -+static inline std::string toString(const EnrichedMarkdownInlineCodeLinkRegexStruct &value) { -+ return "[Object EnrichedMarkdownInlineCodeLinkRegexStruct]"; -+} -+ -+#ifdef RN_SERIALIZABLE_STATE -+static inline folly::dynamic toDynamic(const EnrichedMarkdownInlineCodeLinkRegexStruct &value) { -+ return value.toDynamic(); -+} -+#endif -+ - struct EnrichedMarkdownMarkdownStyleParagraphStruct { - Float fontSize{0.0}; - std::string fontFamily{}; -@@ -1313,6 +1627,17 @@ struct EnrichedMarkdownMarkdownStyleLinkVariantsStruct { - SharedColor color{}; - bool underline{false}; - SharedColor backgroundColor{}; -+ std::string fontFamily{}; -+ bool pill{false}; -+ std::string label{}; -+ std::string iconUri{}; -+ SharedColor iconTintColor{}; -+ Float borderRadius{0.0}; -+ Float paddingHorizontal{0.0}; -+ Float paddingVertical{0.0}; -+ Float borderWidth{0.0}; -+ SharedColor borderColor{}; -+ Float maxWidth{0.0}; - - - #ifdef RN_SERIALIZABLE_STATE -@@ -1324,6 +1649,17 @@ struct EnrichedMarkdownMarkdownStyleLinkVariantsStruct { - result["color"] = ::facebook::react::toDynamic(color); - result["underline"] = underline; - result["backgroundColor"] = ::facebook::react::toDynamic(backgroundColor); -+ result["fontFamily"] = fontFamily; -+ result["pill"] = pill; -+ result["label"] = label; -+ result["iconUri"] = iconUri; -+ result["iconTintColor"] = ::facebook::react::toDynamic(iconTintColor); -+ result["borderRadius"] = borderRadius; -+ result["paddingHorizontal"] = paddingHorizontal; -+ result["paddingVertical"] = paddingVertical; -+ result["borderWidth"] = borderWidth; -+ result["borderColor"] = ::facebook::react::toDynamic(borderColor); -+ result["maxWidth"] = maxWidth; - return result; - } - #endif -@@ -1348,6 +1684,50 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu - if (tmp_backgroundColor != map.end()) { - fromRawValue(context, tmp_backgroundColor->second, result.backgroundColor); - } -+ auto tmp_fontFamily = map.find("fontFamily"); -+ if (tmp_fontFamily != map.end()) { -+ fromRawValue(context, tmp_fontFamily->second, result.fontFamily); -+ } -+ auto tmp_pill = map.find("pill"); -+ if (tmp_pill != map.end()) { -+ fromRawValue(context, tmp_pill->second, result.pill); -+ } -+ auto tmp_label = map.find("label"); -+ if (tmp_label != map.end()) { -+ fromRawValue(context, tmp_label->second, result.label); -+ } -+ auto tmp_iconUri = map.find("iconUri"); -+ if (tmp_iconUri != map.end()) { -+ fromRawValue(context, tmp_iconUri->second, result.iconUri); -+ } -+ auto tmp_iconTintColor = map.find("iconTintColor"); -+ if (tmp_iconTintColor != map.end()) { -+ fromRawValue(context, tmp_iconTintColor->second, result.iconTintColor); -+ } -+ auto tmp_borderRadius = map.find("borderRadius"); -+ if (tmp_borderRadius != map.end()) { -+ fromRawValue(context, tmp_borderRadius->second, result.borderRadius); -+ } -+ auto tmp_paddingHorizontal = map.find("paddingHorizontal"); -+ if (tmp_paddingHorizontal != map.end()) { -+ fromRawValue(context, tmp_paddingHorizontal->second, result.paddingHorizontal); -+ } -+ auto tmp_paddingVertical = map.find("paddingVertical"); -+ if (tmp_paddingVertical != map.end()) { -+ fromRawValue(context, tmp_paddingVertical->second, result.paddingVertical); -+ } -+ auto tmp_borderWidth = map.find("borderWidth"); -+ if (tmp_borderWidth != map.end()) { -+ fromRawValue(context, tmp_borderWidth->second, result.borderWidth); -+ } -+ auto tmp_borderColor = map.find("borderColor"); -+ if (tmp_borderColor != map.end()) { -+ fromRawValue(context, tmp_borderColor->second, result.borderColor); -+ } -+ auto tmp_maxWidth = map.find("maxWidth"); -+ if (tmp_maxWidth != map.end()) { -+ fromRawValue(context, tmp_maxWidth->second, result.maxWidth); -+ } - } - - static inline std::string toString(const EnrichedMarkdownMarkdownStyleLinkVariantsStruct &value) { -@@ -3116,6 +3496,17 @@ class EnrichedMarkdownProps final : public ViewProps { - - #pragma mark - Props - -+ bool enableImageSourceResolution{false}; -+ int imageSourcesRevision{-1}; -+ int imageSourcesContinuityStart{1}; -+ std::vector imageSources{}; -+ int documentRevision{0}; -+ bool enableDocumentAssets{false}; -+ bool enableMediaSlots{false}; -+ int mediaOverridesRevision{-1}; -+ std::vector mediaOverrides{}; -+ EnrichedMarkdownLinkRegexStruct linkRegex{}; -+ EnrichedMarkdownInlineCodeLinkRegexStruct inlineCodeLinkRegex{}; - std::string markdown{}; - EnrichedMarkdownMarkdownStyleStruct markdownStyle{}; - bool enableImagePress{false}; -@@ -4078,6 +4469,122 @@ class EnrichedMarkdownTextInputProps final : public ViewProps { - - }; - -+struct EnrichedMarkdownTextLinkRegexStruct { -+ std::string pattern{}; -+ bool caseInsensitive{false}; -+ bool dotAll{false}; -+ bool isDisabled{false}; -+ bool isDefault{false}; -+ -+ -+#ifdef RN_SERIALIZABLE_STATE -+ bool operator==(const EnrichedMarkdownTextLinkRegexStruct&) const = default; -+ -+ folly::dynamic toDynamic() const { -+ folly::dynamic result = folly::dynamic::object(); -+ result["pattern"] = pattern; -+ result["caseInsensitive"] = caseInsensitive; -+ result["dotAll"] = dotAll; -+ result["isDisabled"] = isDisabled; -+ result["isDefault"] = isDefault; -+ return result; -+ } -+#endif -+}; -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownTextLinkRegexStruct &result) { -+ auto map = (std::unordered_map)value; -+ -+ auto tmp_pattern = map.find("pattern"); -+ if (tmp_pattern != map.end()) { -+ fromRawValue(context, tmp_pattern->second, result.pattern); -+ } -+ auto tmp_caseInsensitive = map.find("caseInsensitive"); -+ if (tmp_caseInsensitive != map.end()) { -+ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); -+ } -+ auto tmp_dotAll = map.find("dotAll"); -+ if (tmp_dotAll != map.end()) { -+ fromRawValue(context, tmp_dotAll->second, result.dotAll); -+ } -+ auto tmp_isDisabled = map.find("isDisabled"); -+ if (tmp_isDisabled != map.end()) { -+ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); -+ } -+ auto tmp_isDefault = map.find("isDefault"); -+ if (tmp_isDefault != map.end()) { -+ fromRawValue(context, tmp_isDefault->second, result.isDefault); -+ } -+} -+ -+static inline std::string toString(const EnrichedMarkdownTextLinkRegexStruct &value) { -+ return "[Object EnrichedMarkdownTextLinkRegexStruct]"; -+} -+ -+#ifdef RN_SERIALIZABLE_STATE -+static inline folly::dynamic toDynamic(const EnrichedMarkdownTextLinkRegexStruct &value) { -+ return value.toDynamic(); -+} -+#endif -+ -+struct EnrichedMarkdownTextInlineCodeLinkRegexStruct { -+ std::string pattern{}; -+ bool caseInsensitive{false}; -+ bool dotAll{false}; -+ bool isDisabled{false}; -+ bool isDefault{false}; -+ -+ -+#ifdef RN_SERIALIZABLE_STATE -+ bool operator==(const EnrichedMarkdownTextInlineCodeLinkRegexStruct&) const = default; -+ -+ folly::dynamic toDynamic() const { -+ folly::dynamic result = folly::dynamic::object(); -+ result["pattern"] = pattern; -+ result["caseInsensitive"] = caseInsensitive; -+ result["dotAll"] = dotAll; -+ result["isDisabled"] = isDisabled; -+ result["isDefault"] = isDefault; -+ return result; -+ } -+#endif -+}; -+ -+static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownTextInlineCodeLinkRegexStruct &result) { -+ auto map = (std::unordered_map)value; -+ -+ auto tmp_pattern = map.find("pattern"); -+ if (tmp_pattern != map.end()) { -+ fromRawValue(context, tmp_pattern->second, result.pattern); -+ } -+ auto tmp_caseInsensitive = map.find("caseInsensitive"); -+ if (tmp_caseInsensitive != map.end()) { -+ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); -+ } -+ auto tmp_dotAll = map.find("dotAll"); -+ if (tmp_dotAll != map.end()) { -+ fromRawValue(context, tmp_dotAll->second, result.dotAll); -+ } -+ auto tmp_isDisabled = map.find("isDisabled"); -+ if (tmp_isDisabled != map.end()) { -+ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); -+ } -+ auto tmp_isDefault = map.find("isDefault"); -+ if (tmp_isDefault != map.end()) { -+ fromRawValue(context, tmp_isDefault->second, result.isDefault); -+ } -+} -+ -+static inline std::string toString(const EnrichedMarkdownTextInlineCodeLinkRegexStruct &value) { -+ return "[Object EnrichedMarkdownTextInlineCodeLinkRegexStruct]"; -+} -+ -+#ifdef RN_SERIALIZABLE_STATE -+static inline folly::dynamic toDynamic(const EnrichedMarkdownTextInlineCodeLinkRegexStruct &value) { -+ return value.toDynamic(); -+} -+#endif -+ - struct EnrichedMarkdownTextMarkdownStyleParagraphStruct { - Float fontSize{0.0}; - std::string fontFamily{}; -@@ -5373,6 +5880,17 @@ struct EnrichedMarkdownTextMarkdownStyleLinkVariantsStruct { - SharedColor color{}; - bool underline{false}; - SharedColor backgroundColor{}; -+ std::string fontFamily{}; -+ bool pill{false}; -+ std::string label{}; -+ std::string iconUri{}; -+ SharedColor iconTintColor{}; -+ Float borderRadius{0.0}; -+ Float paddingHorizontal{0.0}; -+ Float paddingVertical{0.0}; -+ Float borderWidth{0.0}; -+ SharedColor borderColor{}; -+ Float maxWidth{0.0}; - - - #ifdef RN_SERIALIZABLE_STATE -@@ -5384,6 +5902,17 @@ struct EnrichedMarkdownTextMarkdownStyleLinkVariantsStruct { - result["color"] = ::facebook::react::toDynamic(color); - result["underline"] = underline; - result["backgroundColor"] = ::facebook::react::toDynamic(backgroundColor); -+ result["fontFamily"] = fontFamily; -+ result["pill"] = pill; -+ result["label"] = label; -+ result["iconUri"] = iconUri; -+ result["iconTintColor"] = ::facebook::react::toDynamic(iconTintColor); -+ result["borderRadius"] = borderRadius; -+ result["paddingHorizontal"] = paddingHorizontal; -+ result["paddingVertical"] = paddingVertical; -+ result["borderWidth"] = borderWidth; -+ result["borderColor"] = ::facebook::react::toDynamic(borderColor); -+ result["maxWidth"] = maxWidth; - return result; - } - #endif -@@ -5408,6 +5937,50 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu - if (tmp_backgroundColor != map.end()) { - fromRawValue(context, tmp_backgroundColor->second, result.backgroundColor); - } -+ auto tmp_fontFamily = map.find("fontFamily"); -+ if (tmp_fontFamily != map.end()) { -+ fromRawValue(context, tmp_fontFamily->second, result.fontFamily); -+ } -+ auto tmp_pill = map.find("pill"); -+ if (tmp_pill != map.end()) { -+ fromRawValue(context, tmp_pill->second, result.pill); -+ } -+ auto tmp_label = map.find("label"); -+ if (tmp_label != map.end()) { -+ fromRawValue(context, tmp_label->second, result.label); -+ } -+ auto tmp_iconUri = map.find("iconUri"); -+ if (tmp_iconUri != map.end()) { -+ fromRawValue(context, tmp_iconUri->second, result.iconUri); -+ } -+ auto tmp_iconTintColor = map.find("iconTintColor"); -+ if (tmp_iconTintColor != map.end()) { -+ fromRawValue(context, tmp_iconTintColor->second, result.iconTintColor); -+ } -+ auto tmp_borderRadius = map.find("borderRadius"); -+ if (tmp_borderRadius != map.end()) { -+ fromRawValue(context, tmp_borderRadius->second, result.borderRadius); -+ } -+ auto tmp_paddingHorizontal = map.find("paddingHorizontal"); -+ if (tmp_paddingHorizontal != map.end()) { -+ fromRawValue(context, tmp_paddingHorizontal->second, result.paddingHorizontal); -+ } -+ auto tmp_paddingVertical = map.find("paddingVertical"); -+ if (tmp_paddingVertical != map.end()) { -+ fromRawValue(context, tmp_paddingVertical->second, result.paddingVertical); -+ } -+ auto tmp_borderWidth = map.find("borderWidth"); -+ if (tmp_borderWidth != map.end()) { -+ fromRawValue(context, tmp_borderWidth->second, result.borderWidth); -+ } -+ auto tmp_borderColor = map.find("borderColor"); -+ if (tmp_borderColor != map.end()) { -+ fromRawValue(context, tmp_borderColor->second, result.borderColor); -+ } -+ auto tmp_maxWidth = map.find("maxWidth"); -+ if (tmp_maxWidth != map.end()) { -+ fromRawValue(context, tmp_maxWidth->second, result.maxWidth); -+ } - } - - static inline std::string toString(const EnrichedMarkdownTextMarkdownStyleLinkVariantsStruct &value) { -@@ -7176,6 +7749,8 @@ class EnrichedMarkdownTextProps final : public ViewProps { - - #pragma mark - Props - -+ EnrichedMarkdownTextLinkRegexStruct linkRegex{}; -+ EnrichedMarkdownTextInlineCodeLinkRegexStruct inlineCodeLinkRegex{}; - std::string markdown{}; - EnrichedMarkdownTextMarkdownStyleStruct markdownStyle{}; - bool enableImagePress{false}; -diff --git a/ios/input/ENRMInputParser.mm b/ios/input/ENRMInputParser.mm -index f82e72b3b838e40d886cf1eb5037b0a406730afe..79c53c0eeea362902c5a62f1d6be3e730715ab6f 100644 ---- a/ios/input/ENRMInputParser.mm -+++ b/ios/input/ENRMInputParser.mm -@@ -1,7 +1,7 @@ - #import "ENRMInputParser.h" -+#include "../../cpp/md4c/md4c.h" - #import "ENRMFormattingRange.h" - #import "ENRMInputRemend.h" --#include "md4c.h" - #include - #include - #include -diff --git a/ios/internals/ENRMViewFreeMeasurement.h b/ios/internals/ENRMViewFreeMeasurement.h -index 8f7b44006ef080ff62976be02520c08c5b6463f2..c15350c28c65eb4386844612f69dfd9bd9e9a661 100644 ---- a/ios/internals/ENRMViewFreeMeasurement.h -+++ b/ios/internals/ENRMViewFreeMeasurement.h -@@ -2,8 +2,10 @@ - - #import "ENRMBlockquoteContainerView.h" - #import "ENRMCodeBlockContainerView.h" -+#import "ENRMDocumentAssets.h" - #import "ENRMFeatureFlags.h" - #import "ENRMMarkdownParser.h" -+#import "ENRMTextLinkRecognizer.h" - #import "ENRMTextRenderer.h" - #import "ENRMTextViewSetup.h" - #import "ImageRequestHeaderUtils.h" -@@ -147,10 +149,17 @@ static inline CGSize ENRMMeasureAttributedTextViewFree(NSAttributedString *text, - textContainer.lineBreakMode = lineBreakMode; - } - NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; -+#if !TARGET_OS_OSX -+ layoutManager.delegate = ENRMLinkPillLayoutDelegate.shared; -+#endif - layoutManager.allowsNonContiguousLayout = NO; - layoutManager.usesFontLeading = NO; - [layoutManager addTextContainer:textContainer]; -+#if !TARGET_OS_OSX -+ NSTextStorage *textStorage = [[ENRMLinkPillTextStorage alloc] initWithAttributedString:text]; -+#else - NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:text]; -+#endif - [textStorage addLayoutManager:layoutManager]; - - [layoutManager ensureLayoutForTextContainer:textContainer]; -@@ -184,7 +193,11 @@ static inline CGSize ENRMMeasureMarkdownViewFree(const PropsT &typedProps, CGFlo - - ENRMMd4cFlags *flags = ENRMMd4cFlagsFromProps(typedProps.md4cFlags); - ENRMMarkdownParser *parser = [[ENRMMarkdownParser alloc] init]; -- MarkdownASTNode *ast = [parser parseMarkdown:markdown flags:flags isGFM:typedProps.isGFM]; -+ MarkdownASTNode *ast = [parser parseMarkdown:markdown -+ flags:flags -+ isGFM:typedProps.isGFM -+ linkRegex:ENRMTextLinkRegexConfigFromProps(typedProps.linkRegex) -+ inlineCodeLinkRegex:ENRMTextLinkRegexConfigFromProps(typedProps.inlineCodeLinkRegex)]; - if (!ast) { - return fallback; - } -@@ -262,7 +275,11 @@ static inline CGSize ENRMMeasureSegmentedMarkdownViewFree(const PropsT &typedPro - - ENRMMd4cFlags *flags = ENRMMd4cFlagsFromProps(typedProps.md4cFlags); - ENRMMarkdownParser *parser = [[ENRMMarkdownParser alloc] init]; -- MarkdownASTNode *ast = [parser parseMarkdown:markdown flags:flags isGFM:typedProps.isGFM]; -+ MarkdownASTNode *ast = [parser parseMarkdown:markdown -+ flags:flags -+ isGFM:typedProps.isGFM -+ linkRegex:ENRMTextLinkRegexConfigFromProps(typedProps.linkRegex) -+ inlineCodeLinkRegex:ENRMTextLinkRegexConfigFromProps(typedProps.inlineCodeLinkRegex)]; - if (!ast) { - return fallback; - } -@@ -272,6 +289,15 @@ static inline CGSize ENRMMeasureSegmentedMarkdownViewFree(const PropsT &typedPro - ENRMWritingDirectionMode writingDirectionMode = - ENRMResolveWritingDirectionMode([[NSString alloc] initWithUTF8String:typedProps.writingDirection.c_str()]); - -+ BOOL resolveSources = typedProps.enableImageSourceResolution && typedProps.isGFM; -+ NSArray *assets = @[]; -+ if (typedProps.enableMediaSlots || resolveSources) { -+ assets = ENRMPrepareDocumentAssets(ast, typedProps.enableMediaSlots, -+ typedProps.mediaOverridesRevision == typedProps.documentRevision, -+ ENRMMediaOverridesFromProps(typedProps)); -+ } -+ ENRMPrepareImageSources(ast, assets, resolveSources, ENRMImageSourcesAccepted(typedProps), -+ ENRMImageSourcesFromProps(typedProps)); - NSArray *segments = - ENRMRenderSegmentsFromAST(ast, config, typedProps.allowTrailingMargin, typedProps.allowFontScaling, - typedProps.maxFontSizeMultiplier, lineBreakStrategy, /*blockquoteContent*/ NO); -@@ -294,7 +320,14 @@ static inline CGSize ENRMMeasureSegmentedMarkdownViewFree(const PropsT &typedPro - const BOOL isLast = (i == lastIndex); - const BOOL shouldAddBottomMargin = (!isLast || typedProps.allowTrailingMargin); - -- if (segment.kind == ENRMSegmentKindText && segment.textResult) { -+ if (segment.kind == ENRMSegmentKindMediaSlot && segment.mediaSlotNode) { -+ BOOL video = [segment.mediaSlotNode.attributes[@"_enrmMediaKind"] isEqualToString:@"video"]; -+ yOffset += video ? config.videoMarginTop : config.imageMarginTop; -+ yOffset += ENRMMediaSlotHeight(segment.mediaSlotNode, maxWidth, config); -+ maxContentWidth = maxWidth; -+ if (shouldAddBottomMargin) -+ yOffset += video ? config.videoMarginBottom : config.imageMarginBottom; -+ } else if (segment.kind == ENRMSegmentKindText && segment.textResult) { - CGSize textSize = ENRMMeasureAttributedTextViewFree( - segment.textResult.attributedText, maxWidth, config, shouldAddBottomMargin, - segment.textResult.lastElementMarginBottom, pointScaleFactor, 0, NSLineBreakByWordWrapping); -diff --git a/ios/internals/EnrichedMarkdownShadowNode.mm b/ios/internals/EnrichedMarkdownShadowNode.mm -index 056225f54a2ae249b6178c2e48c87685042389a1..2eab8469c16a5c50b90749505f00839d584e1f84 100644 ---- a/ios/internals/EnrichedMarkdownShadowNode.mm -+++ b/ios/internals/EnrichedMarkdownShadowNode.mm -@@ -31,6 +31,10 @@ EnrichedMarkdownShadowNode::EnrichedMarkdownShadowNode(const ShadowNode &sourceS - lastExactMeasurementCounter_ = -1; - } - -+ if (ENRMMediaPropsFingerprint(oldProps) != ENRMMediaPropsFingerprint(newProps)) { -+ lastExactMeasurementCounter_ = -1; -+ YGNodeMarkDirty(&yogaNode_); -+ } - dirtyLayoutIfNeeded(); - } - -diff --git a/ios/internals/MeasurementCache.h b/ios/internals/MeasurementCache.h -index 64604a3ac7e8788c06701ca6074badc3b852bcb9..12934e3c88dfbf940a954898ac41af4adfbe47e4 100644 ---- a/ios/internals/MeasurementCache.h -+++ b/ios/internals/MeasurementCache.h -@@ -1,5 +1,6 @@ - #pragma once - -+#import "ENRMDocumentAssets.h" - #include - #include - #include -@@ -50,6 +51,8 @@ struct MeasurementCacheKey { - std::string writingDirection; - int numberOfLines; - std::string ellipsizeMode; -+ std::string linkRegexKey; -+ std::string inlineCodeLinkRegexKey; - - bool operator==(const MeasurementCacheKey &other) const - { -@@ -57,13 +60,14 @@ struct MeasurementCacheKey { - md4cFlagsUnderline, md4cFlagsSuperscript, md4cFlagsSubscript, md4cFlagsHighlight, - md4cFlagsLatexMath, md4cFlagsHardSoftBreaks, md4cFlagsPreserveBlankLines, md4cFlagsAdmonitions, - styleFingerprint, fontScale, flavor, lineBreakStrategyIOS, writingDirection, numberOfLines, -- ellipsizeMode) == -+ ellipsizeMode, linkRegexKey, inlineCodeLinkRegexKey) == - std::tie(other.markdown, other.maxWidth, other.allowTrailingMargin, other.allowFontScaling, - other.maxFontSizeMultiplier, other.md4cFlagsUnderline, other.md4cFlagsSuperscript, - other.md4cFlagsSubscript, other.md4cFlagsHighlight, other.md4cFlagsLatexMath, - other.md4cFlagsHardSoftBreaks, other.md4cFlagsPreserveBlankLines, other.md4cFlagsAdmonitions, - other.styleFingerprint, other.fontScale, other.flavor, other.lineBreakStrategyIOS, -- other.writingDirection, other.numberOfLines, other.ellipsizeMode); -+ other.writingDirection, other.numberOfLines, other.ellipsizeMode, other.linkRegexKey, -+ other.inlineCodeLinkRegexKey); - } - }; - -@@ -91,6 +95,8 @@ struct MeasurementCacheKeyHash { - HashUtils::hash_one(h, key.writingDirection); - HashUtils::hash_one(h, key.numberOfLines); - HashUtils::hash_one(h, key.ellipsizeMode); -+ HashUtils::hash_one(h, key.linkRegexKey); -+ HashUtils::hash_one(h, key.inlineCodeLinkRegexKey); - return h; - } - }; -@@ -157,6 +163,17 @@ template inline size_t computeStyleFingerprint(const Styl - return h; - } - -+template inline std::string buildLinkRecognitionCacheKey(const RegexProps &props) -+{ -+ // Fixed-width flag prefix keeps key equality exact, including pattern changes. -+ std::string key; -+ key += props.caseInsensitive ? '1' : '0'; -+ key += props.dotAll ? '1' : '0'; -+ key += props.isDisabled ? '1' : '0'; -+ key += props.isDefault ? '1' : '0'; -+ return key + props.pattern; -+} -+ - template - inline MeasurementCacheKey buildMeasurementCacheKey(const PropsType &props, CGFloat maxWidth, CGFloat fontScale, - MarkdownFlavor flavor) -@@ -175,13 +192,15 @@ inline MeasurementCacheKey buildMeasurementCacheKey(const PropsType &props, CGFl - .md4cFlagsHardSoftBreaks = props.md4cFlags.hardSoftBreaks, - .md4cFlagsPreserveBlankLines = props.md4cFlags.preserveBlankLines, - .md4cFlagsAdmonitions = props.md4cFlags.admonitions, -- .styleFingerprint = computeStyleFingerprint(props.markdownStyle), -+ .styleFingerprint = computeStyleFingerprint(props.markdownStyle) ^ ENRMMediaPropsFingerprint(props), - .fontScale = fontScale, - .flavor = flavor, - .lineBreakStrategyIOS = props.lineBreakStrategyIOS, - .writingDirection = props.writingDirection, - .numberOfLines = props.numberOfLines, - .ellipsizeMode = props.ellipsizeMode, -+ .linkRegexKey = buildLinkRecognitionCacheKey(props.linkRegex), -+ .inlineCodeLinkRegexKey = buildLinkRecognitionCacheKey(props.inlineCodeLinkRegex), - }; - } - -diff --git a/ios/internals/ShadowMeasurementUtils.h b/ios/internals/ShadowMeasurementUtils.h -index 6cee54b0c814462aa3479d3c080537404775b1cb..3122de09d937a3bee13275911cabe1ed1a499f4d 100644 ---- a/ios/internals/ShadowMeasurementUtils.h -+++ b/ios/internals/ShadowMeasurementUtils.h -@@ -59,7 +59,8 @@ static inline Size ENRMClampMeasuredSize(CGSize size, const LayoutConstraints &l - template - static inline bool ENRMPropsNeedExactStreamingMeasurement(const PropsT &oldProps, const PropsT &newProps) - { -- return oldProps.streamingAnimation != newProps.streamingAnimation || -+ return ENRMMediaPropsFingerprint(oldProps) != ENRMMediaPropsFingerprint(newProps) || -+ oldProps.streamingAnimation != newProps.streamingAnimation || - oldProps.allowFontScaling != newProps.allowFontScaling || - oldProps.maxFontSizeMultiplier != newProps.maxFontSizeMultiplier || - oldProps.allowTrailingMargin != newProps.allowTrailingMargin || -@@ -70,8 +71,7 @@ static inline bool ENRMPropsNeedExactStreamingMeasurement(const PropsT &oldProps - oldProps.md4cFlags.highlight != newProps.md4cFlags.highlight || - oldProps.md4cFlags.hardSoftBreaks != newProps.md4cFlags.hardSoftBreaks || - oldProps.md4cFlags.preserveBlankLines != newProps.md4cFlags.preserveBlankLines || -- oldProps.isGFM != newProps.isGFM || -- oldProps.md4cFlags.admonitions != newProps.md4cFlags.admonitions || -+ oldProps.isGFM != newProps.isGFM || oldProps.md4cFlags.admonitions != newProps.md4cFlags.admonitions || - computeStyleFingerprint(oldProps.markdownStyle) != computeStyleFingerprint(newProps.markdownStyle); - } - -@@ -104,7 +104,8 @@ ENRMMeasureMarkdownContent(const PropsT &typedProps, const std::shared_ptr - // bumps lastExactMeasurementCounter, the rest land here. Return the freshly - // measured size, not the view's mailbox — mid-pass the frame isn't committed, - // so the mailbox is a generation stale and would freeze the height. -- if (typedProps.streamingAnimation && view && receivedCounter <= lastExactMeasurementCounter) { -+ if (typedProps.streamingAnimation && !ENRMMediaSlotsEnabled(typedProps) && view && -+ receivedCounter <= lastExactMeasurementCounter) { - if (lastExactMeasurementSize.width > 0 && lastExactMeasurementSize.height > 0) { - return ENRMClampMeasuredSize(lastExactMeasurementSize, layoutConstraints); - } -diff --git a/ios/parser/ENRMMarkdownParser.h b/ios/parser/ENRMMarkdownParser.h -index 7bcba9f8c131e3ec81e1ed94ea851f00ef9a324d..0c792b53b3a63b67f3839174cec4bcb61149bdd9 100644 ---- a/ios/parser/ENRMMarkdownParser.h -+++ b/ios/parser/ENRMMarkdownParser.h -@@ -16,10 +16,18 @@ - - @end - -+@class ENRMLinkRegexConfig; -+ - @interface ENRMMarkdownParser : NSObject - - - (MarkdownASTNode *)parseMarkdown:(NSString *)markdown; - - (MarkdownASTNode *)parseMarkdown:(NSString *)markdown flags:(ENRMMd4cFlags *)flags; - - (MarkdownASTNode *)parseMarkdown:(NSString *)markdown flags:(ENRMMd4cFlags *)flags isGFM:(BOOL)isGFM; -+// Recognition runs before returning the AST to rendering or document assets. -+- (MarkdownASTNode *)parseMarkdown:(NSString *)markdown -+ flags:(ENRMMd4cFlags *)flags -+ isGFM:(BOOL)isGFM -+ linkRegex:(ENRMLinkRegexConfig *)linkRegex -+ inlineCodeLinkRegex:(ENRMLinkRegexConfig *)inlineCodeLinkRegex; - - @end -diff --git a/ios/parser/ENRMMarkdownParser.mm b/ios/parser/ENRMMarkdownParser.mm -index a4a0022b73edeb53924a4ca067f68c5e6d2bd58a..2515b424dd51a3c6631e5ae697f86200e1b4e6df 100644 ---- a/ios/parser/ENRMMarkdownParser.mm -+++ b/ios/parser/ENRMMarkdownParser.mm -@@ -1,4 +1,5 @@ - #import "ENRMMarkdownParser.h" -+#import "ENRMTextLinkRecognizer.h" - #import "MarkdownASTNode.h" - - extern MarkdownASTNode *parseMarkdownWithCppParser(NSString *markdown, ENRMMd4cFlags *flags, BOOL isGFM); -@@ -58,4 +59,15 @@ extern MarkdownASTNode *parseMarkdownWithCppParser(NSString *markdown, ENRMMd4cF - return parseMarkdownWithCppParser(markdown, flags, isGFM); - } - -+- (MarkdownASTNode *)parseMarkdown:(NSString *)markdown -+ flags:(ENRMMd4cFlags *)flags -+ isGFM:(BOOL)isGFM -+ linkRegex:(ENRMLinkRegexConfig *)linkRegex -+ inlineCodeLinkRegex:(ENRMLinkRegexConfig *)inlineCodeLinkRegex -+{ -+ MarkdownASTNode *ast = [self parseMarkdown:markdown flags:flags isGFM:isGFM]; -+ ENRMRecognizeTextLinks(ast, linkRegex, inlineCodeLinkRegex); -+ return ast; -+} -+ - @end -diff --git a/ios/parser/ENRMTextLinkAttributes.h b/ios/parser/ENRMTextLinkAttributes.h -new file mode 100644 -index 0000000000000000000000000000000000000000..9d36943d00d9ef57c7f7405a279b25c48a77e04c ---- /dev/null -+++ b/ios/parser/ENRMTextLinkAttributes.h -@@ -0,0 +1,7 @@ -+#pragma once -+ -+#import -+ -+// Rendering metadata only. Copy reconstruction retains the source semantics. -+static NSString *const ENRMRecognizedLinkAttributeName = @"ENRMRecognizedLink"; -+static NSString *const ENRMRecognizedLinkOriginalUnderlineAttributeName = @"ENRMRecognizedLinkOriginalUnderline"; -diff --git a/ios/parser/ENRMTextLinkRecognizer.h b/ios/parser/ENRMTextLinkRecognizer.h -new file mode 100644 -index 0000000000000000000000000000000000000000..b83648d603bf9cd03eacf07deadafde6ffccfab9 ---- /dev/null -+++ b/ios/parser/ENRMTextLinkRecognizer.h -@@ -0,0 +1,31 @@ -+#pragma once -+ -+#import "ENRMLinkRegexConfig.h" -+#import "MarkdownASTNode.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+// Mutates only the freshly parsed AST. Existing links and block code are opaque. -+void ENRMRecognizeTextLinks(MarkdownASTNode *ast, ENRMLinkRegexConfig *linkRegex, -+ ENRMLinkRegexConfig *inlineCodeLinkRegex); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#ifdef __cplusplus -+// Props share EnrichedMarkdownTextInput's native regex transport. -+template -+static inline ENRMLinkRegexConfig *ENRMTextLinkRegexConfigFromProps(const RegexProps &props) -+{ -+ if (props.isDisabled || props.isDefault || props.pattern.empty()) -+ return nil; -+ return [[ENRMLinkRegexConfig alloc] initWithPattern:[NSString stringWithUTF8String:props.pattern.c_str()] -+ caseInsensitive:props.caseInsensitive -+ dotAll:props.dotAll -+ isDisabled:props.isDisabled -+ isDefault:props.isDefault]; -+} -+#endif -diff --git a/ios/parser/ENRMTextLinkRecognizer.m b/ios/parser/ENRMTextLinkRecognizer.m -new file mode 100644 -index 0000000000000000000000000000000000000000..797354e5dc05a5b7a7baa5a9dc4dcee0aca404d3 ---- /dev/null -+++ b/ios/parser/ENRMTextLinkRecognizer.m -@@ -0,0 +1,98 @@ -+#import "ENRMTextLinkRecognizer.h" -+ -+static MarkdownASTNode *ENRMRecognizedLink(MarkdownASTNode *child, NSString *url) -+{ -+ MarkdownASTNode *link = [[MarkdownASTNode alloc] initWithType:MarkdownNodeTypeLink]; -+ [link setAttribute:@"url" value:url]; -+ [link setAttribute:@"recognizedLink" value:@"true"]; -+ [link addChild:child]; -+ return link; -+} -+ -+static MarkdownASTNode *ENRMTextSlice(MarkdownASTNode *node, NSString *content) -+{ -+ MarkdownASTNode *text = [[MarkdownASTNode alloc] initWithType:MarkdownNodeTypeText]; -+ text.content = content; -+ text.attributes = [node.attributes mutableCopy]; -+ return text; -+} -+ -+static NSArray *ENRMRecognizeNode(MarkdownASTNode *node, NSRegularExpression *textRegex, -+ NSRegularExpression *codeRegex) -+{ -+ switch (node.type) { -+ case MarkdownNodeTypeLink: -+ case MarkdownNodeTypeCodeBlock: -+ case MarkdownNodeTypeImage: -+ case MarkdownNodeTypeVideo: -+ case MarkdownNodeTypeLatexMathInline: -+ case MarkdownNodeTypeLatexMathDisplay: -+ return @[ node ]; -+ -+ case MarkdownNodeTypeCode: { -+ NSMutableString *content = [NSMutableString string]; -+ for (MarkdownASTNode *child in node.children) { -+ [content appendString:child.content ?: @""]; -+ } -+ NSRange range = NSMakeRange(0, content.length); -+ NSTextCheckingResult *match = [codeRegex firstMatchInString:content options:0 range:range]; -+ if (content.length > 0 && match && NSEqualRanges(match.range, range)) { -+ return @[ ENRMRecognizedLink(node, content) ]; -+ } -+ return @[ node ]; -+ } -+ -+ case MarkdownNodeTypeText: { -+ if (!textRegex) -+ return @[ node ]; -+ NSString *content = node.content ?: @""; -+ NSMutableArray *result = [NSMutableArray array]; -+ NSUInteger offset = 0; -+ for (NSTextCheckingResult *match in [textRegex matchesInString:content -+ options:0 -+ range:NSMakeRange(0, content.length)]) { -+ if (match.range.length == 0) -+ continue; -+ if (match.range.location > offset) { -+ [result addObject:ENRMTextSlice( -+ node, [content substringWithRange:NSMakeRange(offset, match.range.location - offset)])]; -+ } -+ NSString *matched = [content substringWithRange:match.range]; -+ [result addObject:ENRMRecognizedLink(ENRMTextSlice(node, matched), matched)]; -+ offset = NSMaxRange(match.range); -+ } -+ if (offset == 0) -+ return @[ node ]; -+ if (offset < content.length) { -+ [result addObject:ENRMTextSlice(node, [content substringFromIndex:offset])]; -+ } -+ return result; -+ } -+ -+ default: { -+ NSMutableArray *children = [NSMutableArray array]; -+ for (MarkdownASTNode *child in node.children) { -+ [children addObjectsFromArray:ENRMRecognizeNode(child, textRegex, codeRegex)]; -+ } -+ node.children = children; -+ return @[ node ]; -+ } -+ } -+} -+ -+void ENRMRecognizeTextLinks(MarkdownASTNode *ast, ENRMLinkRegexConfig *linkRegex, -+ ENRMLinkRegexConfig *inlineCodeLinkRegex) -+{ -+ NSRegularExpression *textRegex = (!linkRegex.isDefault && !linkRegex.isDisabled) ? linkRegex.parsedRegex : nil; -+ NSRegularExpression *codeRegex = nil; -+ if (!inlineCodeLinkRegex.isDefault && !inlineCodeLinkRegex.isDisabled && inlineCodeLinkRegex.parsedRegex) { -+ // Full-span matching, including alternatives that first match a shorter prefix. -+ codeRegex = [NSRegularExpression -+ regularExpressionWithPattern:[NSString stringWithFormat:@"\\A(?:%@)\\z", inlineCodeLinkRegex.pattern] -+ options:inlineCodeLinkRegex.parsedRegex.options -+ error:nil]; -+ } -+ if (ast && (textRegex || codeRegex)) { -+ ENRMRecognizeNode(ast, textRegex, codeRegex); -+ } -+} -diff --git a/ios/parser/MarkdownParserBridge.mm b/ios/parser/MarkdownParserBridge.mm -index e700fcee063a5def59cf0a966f69221d627e24fe..07d862c5dc253b7f4302162b8bb3946f0430647b 100644 ---- a/ios/parser/MarkdownParserBridge.mm -+++ b/ios/parser/MarkdownParserBridge.mm -@@ -1,7 +1,7 @@ -+#include "../../cpp/parser/MD4CParser.hpp" -+#include "../../cpp/parser/MarkdownASTNode.hpp" - #import "ENRMMarkdownParser.h" --#include "MD4CParser.hpp" - #import "MarkdownASTNode.h" --#include "MarkdownASTNode.hpp" - #import - - // Convert C++ AST node to Objective-C AST node -diff --git a/ios/renderer/BaselineShiftTextAttributes.h b/ios/renderer/BaselineShiftTextAttributes.h -index e862a564c4af827fa4ec85ee09a3657e7496d568..b56208c4311e57b3ec7fb1e7a4eda2fe196906cb 100644 ---- a/ios/renderer/BaselineShiftTextAttributes.h -+++ b/ios/renderer/BaselineShiftTextAttributes.h -@@ -2,5 +2,7 @@ - #import "ENRMUIKit.h" - #import - -+extern NSString *const ENRMScriptAttributeName; -+ - void ENRMApplyBaselineShift(NSMutableAttributedString *output, NSRange range, CGFloat fontScale, - CGFloat baselineOffsetScale); -diff --git a/ios/renderer/BaselineShiftTextAttributes.m b/ios/renderer/BaselineShiftTextAttributes.m -index da1d4b40332e83a1f88935632eb835be8876702b..c9d44b48fbd544c963bd7168d4e627a8755063d7 100644 ---- a/ios/renderer/BaselineShiftTextAttributes.m -+++ b/ios/renderer/BaselineShiftTextAttributes.m -@@ -1,5 +1,7 @@ - #import "BaselineShiftTextAttributes.h" - -+NSString *const ENRMScriptAttributeName = @"ENRMScript"; -+ - void ENRMApplyBaselineShift(NSMutableAttributedString *output, NSRange range, CGFloat fontScale, - CGFloat baselineOffsetScale) - { -diff --git a/ios/renderer/ENRMImageRenderer.m b/ios/renderer/ENRMImageRenderer.m -index 32edfcce882d4a9cb6133f938b7354c26e259f03..4253d82229fd34691ca204b9bc9bed6a54e10636 100644 ---- a/ios/renderer/ENRMImageRenderer.m -+++ b/ios/renderer/ENRMImageRenderer.m -@@ -1,5 +1,6 @@ - #import "ENRMImageRenderer.h" - #import "ENRMImageAttachment.h" -+#import "ENRMImageSources.h" - #import "MarkdownASTNode.h" - #import "RenderContext.h" - #import "RendererFactory.h" -@@ -20,7 +21,15 @@ static const unichar kZeroWidthSpace = 0x200B; - } - - BOOL isInline = [self isInlineImageInOutput:output]; -- ENRMImageAttachment *attachment = [ENRMImageAttachment attachmentForURL:imageURL config:_config isInline:isInline]; -+ NSDictionary *source = ENRMImageSourceDecisionForNode(node); -+ NSString *transportURI = [source[@"pending"] boolValue] ? nil : (source[@"uri"] ?: imageURL); -+ NSDictionary *headers = source ? ENRMMergeImageRequestHeaders(_config.imageRequestHeaders, source[@"headers"]) -+ : _config.imageRequestHeaders; -+ ENRMImageAttachment *attachment = [ENRMImageAttachment attachmentForURL:imageURL -+ config:_config -+ isInline:isInline -+ transportURI:transportURI -+ requestHeaders:headers]; - - NSUInteger startIndex = output.length; - -diff --git a/ios/renderer/LinkRenderer.m b/ios/renderer/LinkRenderer.m -index 5fdc4a78b464e58f36ecb8d5b7728eca125dff49..c9b54328b88b2765254acbd91d3a2e331c46862d 100644 ---- a/ios/renderer/LinkRenderer.m -+++ b/ios/renderer/LinkRenderer.m -@@ -1,4 +1,7 @@ - #import "LinkRenderer.h" -+#import "ENRMLinkPillAttachment.h" -+#import "CodeBackground.h" -+#import "ENRMTextLinkAttributes.h" - #import "FontUtils.h" - #import "RenderContext.h" - #import "RendererFactory.h" -@@ -13,6 +16,7 @@ - into:(NSMutableAttributedString *)output - context:(RenderContext *)context - { -+ BOOL recognizedLink = [node.attributes[@"recognizedLink"] isEqualToString:@"true"]; - NSUInteger start = output.length; - - // 1. Render children first to establish base attributes -@@ -28,7 +32,7 @@ - - RCTUIColor *linkColor = variant.color ?: [_config linkColor]; - BOOL linkUnderline = variant ? variant.underline : [_config linkUnderline]; -- NSString *linkFontFamily = [_config linkFontFamily]; -+ NSString *linkFontFamily = variant.fontFamily.length > 0 ? variant.fontFamily : [_config linkFontFamily]; - RCTUIColor *backgroundColor = variant ? variant.backgroundColor : [_config linkBackgroundColor]; - - NSNumber *underlineStyle = @(linkUnderline ? NSUnderlineStyleSingle : NSUnderlineStyleNone); -@@ -41,6 +45,11 @@ - options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired - usingBlock:^(NSDictionary *attrs, NSRange subrange, BOOL *stop) { - NSMutableDictionary *newAttributes = [NSMutableDictionary dictionary]; -+ if (recognizedLink) { -+ newAttributes[ENRMRecognizedLinkAttributeName] = @YES; -+ newAttributes[ENRMRecognizedLinkOriginalUnderlineAttributeName] = -+ attrs[NSUnderlineStyleAttributeName] ?: @0; -+ } - - // Only apply link color if the subrange isn't already colored by the link style - if (linkColor && ![attrs[NSForegroundColorAttributeName] isEqual:linkColor]) { -@@ -53,7 +62,7 @@ - newAttributes[NSUnderlineStyleAttributeName] = underlineStyle; - } - -- if (linkFontFamily.length > 0) { -+ if (linkFontFamily.length > 0 && (!recognizedLink || !attrs[CodeAttributeName])) { - UIFont *currentFont = attrs[NSFontAttributeName]; - if (currentFont) { - UIFont *linkFont = [RCTFont updateFont:currentFont -@@ -78,6 +87,29 @@ - [output addAttribute:NSBackgroundColorAttributeName value:backgroundColor range:range]; - } - -+#if !TARGET_OS_OSX -+ if (variant.pill) { -+ __block BOOL hasAttachment = NO; -+ [output enumerateAttribute:NSAttachmentAttributeName -+ inRange:range -+ options:0 -+ usingBlock:^(id value, NSRange subrange, BOOL *stop) { -+ if (value) { -+ hasAttachment = YES; -+ *stop = YES; -+ } -+ }]; -+ if (!hasAttachment) { -+ UIFont *font = [output attribute:NSFontAttributeName atIndex:range.location effectiveRange:NULL]; -+ ENRMLinkPillAttachment *pill = -+ [[ENRMLinkPillAttachment alloc] initWithLabel:[output.string substringWithRange:range] -+ variant:variant -+ font:font ?: [context getBlockStyle].cachedFont]; -+ [output removeAttribute:NSBackgroundColorAttributeName range:range]; -+ [output addAttribute:NSAttachmentAttributeName value:pill range:range]; -+ } -+ } -+#endif - [context registerLinkRange:range url:url]; - } - -diff --git a/ios/renderer/SubscriptRenderer.m b/ios/renderer/SubscriptRenderer.m -index f697216589db39e72cef5ed5f3f85ad2d5e009a1..d88f5e15ed79440ace831efe531f47e00d0cbfb2 100644 ---- a/ios/renderer/SubscriptRenderer.m -+++ b/ios/renderer/SubscriptRenderer.m -@@ -18,6 +18,7 @@ - if (range.length == 0) - return; - -+ [output addAttribute:ENRMScriptAttributeName value:@"subscript" range:range]; - ENRMApplyBaselineShift(output, range, _config.subscriptFontScale, -_config.subscriptBaselineOffsetScale); - } - -diff --git a/ios/renderer/SuperscriptRenderer.m b/ios/renderer/SuperscriptRenderer.m -index edba7364733ea7bb312176893387b7906c34353c..308b8de0ecfec3ce5a0b5961bbeafc3bf2f99b56 100644 ---- a/ios/renderer/SuperscriptRenderer.m -+++ b/ios/renderer/SuperscriptRenderer.m -@@ -18,6 +18,7 @@ - if (range.length == 0) - return; - -+ [output addAttribute:ENRMScriptAttributeName value:@"superscript" range:range]; - ENRMApplyBaselineShift(output, range, _config.superscriptFontScale, _config.superscriptBaselineOffsetScale); - } - -diff --git a/ios/renderer/UnderlineRenderer.m b/ios/renderer/UnderlineRenderer.m -index e772e4ba509a05163dfd19bf4315d1fe543b56d2..007fe7bb76e41cdaf17f493dab0e7f7234be5496 100644 ---- a/ios/renderer/UnderlineRenderer.m -+++ b/ios/renderer/UnderlineRenderer.m -@@ -1,4 +1,5 @@ - #import "UnderlineRenderer.h" -+#import "ENRMTextLinkAttributes.h" - #import "MarkdownASTNode.h" - #import "RenderContext.h" - #import "RendererFactory.h" -@@ -20,6 +21,7 @@ - return; - - [output addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:range]; -+ [output addAttribute:ENRMRecognizedLinkOriginalUnderlineAttributeName value:@(NSUnderlineStyleSingle) range:range]; - - RCTUIColor *underlineColor = [_config underlineColor]; - -diff --git a/ios/segments/ENRMBlockquoteContainerView.mm b/ios/segments/ENRMBlockquoteContainerView.mm -index b2f2eb57aa12963b88255150d505977c33464aa8..42fe66e2fefb60b1297a948413df156000e06d3b 100644 ---- a/ios/segments/ENRMBlockquoteContainerView.mm -+++ b/ios/segments/ENRMBlockquoteContainerView.mm -@@ -2,6 +2,7 @@ - #import "ENRMAdmonitionIcons.h" - #import "ENRMCodeBlockContainerView.h" - #import "ENRMFeatureFlags.h" -+#import "ENRMMediaSlotView.h" - #import "ENRMSegmentHeightMeasurer.h" - #import "ENRMTextInteractionUtils.h" - #import "ENRMTextRenderer.h" -@@ -312,6 +313,18 @@ static UIEdgeInsets ENRMBlockquoteContentInsets(StyleConfig *config) - }]]; - #endif - -+ [handlers addObject:[ENRMSegmentViewHandler handlerWithKind:ENRMSegmentKindMediaSlot -+ matchesView:^BOOL(RCTUIView *view, ENRMRenderedSegment *segment) { -+ return [view isKindOfClass:[ENRMMediaSlotView class]]; -+ } -+ createView:^RCTUIView *(ENRMRenderedSegment *segment) { -+ ENRMMediaSlotView *view = [[ENRMMediaSlotView alloc] init]; -+ view.mediaNode = segment.mediaSlotNode; -+ return view; -+ } -+ updateView:^(RCTUIView *view, ENRMRenderedSegment *segment) { -+ ((ENRMMediaSlotView *)view).mediaNode = segment.mediaSlotNode; -+ }]]; - return [[ENRMSegmentViewRegistry alloc] initWithHandlers:handlers]; - } - -diff --git a/ios/segments/ENRMContainerNodeView.h b/ios/segments/ENRMContainerNodeView.h -index 41e522d05e47f398c989389be1afc74419458053..849a4eaafcbb42988873a65cce740641bae1e137 100644 ---- a/ios/segments/ENRMContainerNodeView.h -+++ b/ios/segments/ENRMContainerNodeView.h -@@ -47,6 +47,9 @@ NS_ASSUME_NONNULL_BEGIN - // i.e. bounds width minus horizontal insets), including the vertical insets. - - (CGFloat)computeContentHeightForWidth:(CGFloat)contentWidth; - -+// Lays out nested children and appends accepted slot rectangles in root space. -+- (void)appendMediaFrames:(NSMutableArray *)frames relativeToView:(RCTUIView *)rootView; -+ - @end - - NS_ASSUME_NONNULL_END -diff --git a/ios/segments/ENRMContainerNodeView.mm b/ios/segments/ENRMContainerNodeView.mm -index 448840013e73e2abd483cfec94441831082ff889..d26f3b390d564d73062e20bf0f15f12239e7d417 100644 ---- a/ios/segments/ENRMContainerNodeView.mm -+++ b/ios/segments/ENRMContainerNodeView.mm -@@ -1,7 +1,9 @@ - #import "ENRMContainerNodeView.h" - #import "ENRMBlockquoteContainerView.h" - #import "ENRMCodeBlockContainerView.h" -+#import "ENRMDocumentAssets.h" - #import "ENRMFeatureFlags.h" -+#import "ENRMMediaSlotView.h" - #import "EnrichedMarkdownInternalText.h" - #import "SegmentReconciler.h" - #import "TableContainerView.h" -@@ -66,6 +68,11 @@ - - - (CGFloat)marginTopForView:(RCTUIView *)view - { -+ if ([view isKindOfClass:[ENRMMediaSlotView class]]) { -+ MarkdownASTNode *node = ((ENRMMediaSlotView *)view).mediaNode; -+ return [node.attributes[@"_enrmMediaKind"] isEqualToString:@"video"] ? _config.videoMarginTop -+ : _config.imageMarginTop; -+ } - if ([view isKindOfClass:[TableContainerView class]]) { - return _config.tableMarginTop; - } -@@ -92,6 +99,11 @@ - - - (CGFloat)marginBottomForView:(RCTUIView *)view - { -+ if ([view isKindOfClass:[ENRMMediaSlotView class]]) { -+ MarkdownASTNode *node = ((ENRMMediaSlotView *)view).mediaNode; -+ return [node.attributes[@"_enrmMediaKind"] isEqualToString:@"video"] ? _config.videoMarginBottom -+ : _config.imageMarginBottom; -+ } - if ([view isKindOfClass:[TableContainerView class]]) { - return _config.tableMarginBottom; - } -@@ -116,6 +128,8 @@ - - - (CGFloat)heightForView:(RCTUIView *)view atWidth:(CGFloat)width shouldAddBottomMargin:(BOOL)shouldAddBottomMargin - { -+ if ([view isKindOfClass:[ENRMMediaSlotView class]]) -+ return ENRMMediaSlotHeight(((ENRMMediaSlotView *)view).mediaNode, width, _config); - if ([view isKindOfClass:[EnrichedMarkdownInternalText class]]) { - EnrichedMarkdownInternalText *textView = (EnrichedMarkdownInternalText *)view; - textView.allowTrailingMargin = shouldAddBottomMargin; -@@ -178,6 +192,32 @@ - return CGSizeMake(outerWidth, yOffset); - } - -+- (void)appendMediaFrames:(NSMutableArray *)frames relativeToView:(RCTUIView *)rootView -+{ -+ // The layout helper leaves child frames untouched when no inner width exists. -+ // Never publish those rectangles from the previous positive-width layout. -+ if (self.bounds.size.width - _contentInsets.left - _contentInsets.right <= 0) -+ return; -+ // Apply nested frames now rather than relying on UIKit's later subview pass: -+ // the root publishes this batch immediately after its own segment layout. -+ [self layoutChildrenForOuterWidth:self.bounds.size.width applyFrames:YES]; -+ for (RCTUIView *view in _segmentViews) { -+ if ([view isKindOfClass:[ENRMMediaSlotView class]]) { -+ MarkdownASTNode *node = ((ENRMMediaSlotView *)view).mediaNode; -+ CGRect rect = [rootView convertRect:view.bounds fromView:view]; -+ [frames addObject:@{ -+ @"id" : node.attributes[@"_enrmMediaSlot"], -+ @"x" : @(rect.origin.x), -+ @"y" : @(rect.origin.y), -+ @"width" : @(rect.size.width), -+ @"height" : @(rect.size.height) -+ }]; -+ } else if ([view isKindOfClass:[ENRMContainerNodeView class]]) { -+ [(ENRMContainerNodeView *)view appendMediaFrames:frames relativeToView:rootView]; -+ } -+ } -+} -+ - - (CGFloat)computeContentHeightForWidth:(CGFloat)contentWidth - { - return [self layoutChildrenForOuterWidth:contentWidth + _contentInsets.left + _contentInsets.right applyFrames:NO] -diff --git a/ios/segments/ENRMMediaSlotView.h b/ios/segments/ENRMMediaSlotView.h -new file mode 100644 -index 0000000000000000000000000000000000000000..b89cde54e2365d6e20567d4922115f71ccc6c13e ---- /dev/null -+++ b/ios/segments/ENRMMediaSlotView.h -@@ -0,0 +1,6 @@ -+#pragma once -+#import "ENRMUIKit.h" -+@class MarkdownASTNode; -+@interface ENRMMediaSlotView : RCTUIView -+@property (nonatomic, strong) MarkdownASTNode *mediaNode; -+@end -diff --git a/ios/segments/ENRMMediaSlotView.m b/ios/segments/ENRMMediaSlotView.m -new file mode 100644 -index 0000000000000000000000000000000000000000..ef5a16547e58f15074599142962737f84efbdff4 ---- /dev/null -+++ b/ios/segments/ENRMMediaSlotView.m -@@ -0,0 +1,14 @@ -+#import "ENRMMediaSlotView.h" -+@implementation ENRMMediaSlotView -+- (instancetype)initWithFrame:(CGRect)frame -+{ -+ if ((self = [super initWithFrame:frame])) { -+#if !TARGET_OS_OSX -+ self.isAccessibilityElement = NO; -+ self.accessibilityElementsHidden = YES; -+ self.userInteractionEnabled = NO; -+#endif -+ } -+ return self; -+} -+@end -diff --git a/ios/segments/ENRMSegmentHeightMeasurer.mm b/ios/segments/ENRMSegmentHeightMeasurer.mm -index 0f4eeb1e6adf3ab21c6713846b972ffce425a329..30a3a5598a2610273259bc0be4f9bc1de6d3653e 100644 ---- a/ios/segments/ENRMSegmentHeightMeasurer.mm -+++ b/ios/segments/ENRMSegmentHeightMeasurer.mm -@@ -1,6 +1,7 @@ - #import "ENRMSegmentHeightMeasurer.h" - #import "ENRMBlockquoteContainerView.h" - #import "ENRMCodeBlockContainerView.h" -+#import "ENRMDocumentAssets.h" - #import "ENRMFeatureFlags.h" - #import "ENRMTextRenderer.h" - #import "ENRMViewFreeMeasurement.h" -@@ -30,7 +31,13 @@ CGFloat ENRMMeasureSegmentsHeightViewFree(NSArray *segmen - const BOOL isLast = (i == lastIndex); - const BOOL shouldAddBottomMargin = (!isLast || allowTrailingMargin); - -- if (segment.kind == ENRMSegmentKindText && segment.textResult) { -+ if (segment.kind == ENRMSegmentKindMediaSlot && segment.mediaSlotNode) { -+ BOOL video = [segment.mediaSlotNode.attributes[@"_enrmMediaKind"] isEqualToString:@"video"]; -+ totalHeight += video ? config.videoMarginTop : config.imageMarginTop; -+ totalHeight += ENRMMediaSlotHeight(segment.mediaSlotNode, contentWidth, config); -+ if (shouldAddBottomMargin) -+ totalHeight += video ? config.videoMarginBottom : config.imageMarginBottom; -+ } else if (segment.kind == ENRMSegmentKindText && segment.textResult) { - // GFM segments are never line-clamped (numberOfLines is a no-op for GFM). - CGSize textSize = ENRMMeasureAttributedTextViewFree( - segment.textResult.attributedText, contentWidth, config, shouldAddBottomMargin, -diff --git a/ios/segments/ENRMTableIOSGridView.m b/ios/segments/ENRMTableIOSGridView.m -index 138435033005771ce0bb194f273316a5328e3057..b4cdf7a13292366c21951749e7a496dbea7a097d 100644 ---- a/ios/segments/ENRMTableIOSGridView.m -+++ b/ios/segments/ENRMTableIOSGridView.m -@@ -1,4 +1,6 @@ - #import "ENRMTableIOSGridView.h" -+#import "ENRMLinkPillAttachment.h" -+#import "ENRMLinkPillTextStorage.h" - - #if !TARGET_OS_OSX - -@@ -97,9 +99,7 @@ - if (text.length > 0) { - CGRect textRect = CGRectMake(xOffset + _horizontalCellPadding, yOffset + _verticalCellPadding, - columnWidth - _horizontalCellPadding * 2, rowHeight - _verticalCellPadding * 2); -- [text drawWithRect:textRect -- options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading -- context:nil]; -+ ENRMDrawLinkPillText(text, textRect); - } - - xOffset += columnWidth; -@@ -149,8 +149,9 @@ static NSString *linkInAttributedString(NSAttributedString *text, CGRect textRec - if (text.length == 0) - return nil; - -- NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:text]; -+ NSTextStorage *textStorage = [[ENRMLinkPillTextStorage alloc] initWithAttributedString:text]; - NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; -+ layoutManager.delegate = ENRMLinkPillLayoutDelegate.shared; - NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:textRect.size]; - textContainer.lineFragmentPadding = 0; - [layoutManager addTextContainer:textContainer]; -diff --git a/ios/segments/RenderedMarkdownSegment.h b/ios/segments/RenderedMarkdownSegment.h -index 4a0e3c797d789536cfcacd8899714e50074be9bf..1e548df87da6cb8205ba5da08604245d00a5698a 100644 ---- a/ios/segments/RenderedMarkdownSegment.h -+++ b/ios/segments/RenderedMarkdownSegment.h -@@ -13,7 +13,8 @@ typedef NS_ENUM(NSInteger, ENRMSegmentKind) { - ENRMSegmentKindMath, - ENRMSegmentKindCodeBlock, - ENRMSegmentKindBlockquote, -- ENRMSegmentKindVideo -+ ENRMSegmentKindVideo, -+ ENRMSegmentKindMediaSlot - }; - - @interface ENRMTextSegment : NSObject -@@ -49,6 +50,7 @@ typedef NS_ENUM(NSInteger, ENRMSegmentKind) { - @interface ENRMRenderedSegment : NSObject - @property (nonatomic, assign) ENRMSegmentKind kind; - @property (nonatomic, assign) uint64_t signature; -+@property (nonatomic, strong, nullable) MarkdownASTNode *mediaSlotNode; - @property (nonatomic, strong, nullable) ENRMRenderResult *textResult; - @property (nonatomic, strong, nullable) ENRMTableSegment *tableSegment; - @property (nonatomic, strong, nullable) ENRMMathSegment *mathSegment; -diff --git a/ios/segments/SegmentRenderer.m b/ios/segments/SegmentRenderer.m -index 1cbe7fd0a50e5302f08a299cad468eab736a012d..b5e225ddab2c4fe829d3673b0956404d8532673d 100644 ---- a/ios/segments/SegmentRenderer.m -+++ b/ios/segments/SegmentRenderer.m -@@ -1,5 +1,6 @@ - #import "SegmentRenderer.h" - #import "ENRMFeatureFlags.h" -+#import "ENRMImageSources.h" - #import "ENRMTextRenderer.h" - #import "MarkdownASTNode.h" - #import "ParagraphStyleUtils.h" -@@ -11,7 +12,13 @@ static NSArray *ENRMSplitASTIntoSegments(MarkdownASTNode *root) - NSMutableArray *currentTextNodes = [NSMutableArray array]; - - for (MarkdownASTNode *child in root.children) { -- if (child.type == MarkdownNodeTypeTable) { -+ if (child.attributes[@"_enrmMediaSlot"]) { -+ if (currentTextNodes.count > 0) { -+ [segments addObject:[ENRMTextSegment segmentWithNodes:[currentTextNodes copy]]]; -+ [currentTextNodes removeAllObjects]; -+ } -+ [segments addObject:child]; -+ } else if (child.type == MarkdownNodeTypeTable) { - if (currentTextNodes.count > 0) { - [segments addObject:[ENRMTextSegment segmentWithNodes:[currentTextNodes copy]]]; - [currentTextNodes removeAllObjects]; -@@ -83,18 +90,26 @@ NSArray *ENRMRenderSegmentsFromAST(MarkdownASTNode *ast, - static const uint64_t kVideoKindSalt = 0x7669646F00000000ULL; // "vido" - - for (id segment in segments) { -- if ([segment isKindOfClass:[ENRMTextSegment class]]) { -+ if ([segment isKindOfClass:[MarkdownASTNode class]]) { -+ ENRMRenderedSegment *rendered = [[ENRMRenderedSegment alloc] init]; -+ rendered.kind = ENRMSegmentKindMediaSlot; -+ rendered.mediaSlotNode = segment; -+ rendered.signature = ENRMSignatureForNode(segment); -+ [renderedSegments addObject:rendered]; -+ } else if ([segment isKindOfClass:[ENRMTextSegment class]]) { - ENRMTextSegment *textSegment = (ENRMTextSegment *)segment; - ENRMRenderResult *rendered = blockquoteContent - ? ENRMRenderBlockquoteContentNodes(textSegment.nodes, config, allowFontScaling, - maxFontSizeMultiplier, lineBreakStrategy) - : ENRMRenderASTNodes(textSegment.nodes, config, allowTrailingMargin, - allowFontScaling, maxFontSizeMultiplier, lineBreakStrategy); -- uint64_t signature = ENRMSignatureForNodes(textSegment.nodes) ^ kTextKindSalt; -+ uint64_t signature = ENRMSignatureForNodes(textSegment.nodes) ^ -+ ENRMImageSourceSignatureForNodes(textSegment.nodes) ^ kTextKindSalt; - [renderedSegments addObject:[ENRMRenderedSegment textSegmentWithResult:rendered signature:signature]]; - } else if ([segment isKindOfClass:[ENRMTableSegment class]]) { - ENRMTableSegment *tableSegment = (ENRMTableSegment *)segment; -- uint64_t signature = ENRMSignatureForNode(tableSegment.tableNode) ^ kTableKindSalt; -+ uint64_t signature = ENRMSignatureForNode(tableSegment.tableNode) ^ -+ ENRMImageSourceSignatureForNode(tableSegment.tableNode) ^ kTableKindSalt; - [renderedSegments addObject:[ENRMRenderedSegment tableSegmentWithSegment:tableSegment signature:signature]]; - } - #if ENRICHED_MARKDOWN_MATH -@@ -117,7 +132,8 @@ NSArray *ENRMRenderSegmentsFromAST(MarkdownASTNode *ast, - signature:signature]]; - } else if ([segment isKindOfClass:[ENRMBlockquoteSegment class]]) { - ENRMBlockquoteSegment *blockquoteSegment = (ENRMBlockquoteSegment *)segment; -- uint64_t signature = ENRMSignatureForNode(blockquoteSegment.blockquoteNode) ^ kBlockquoteKindSalt; -+ uint64_t signature = ENRMSignatureForNode(blockquoteSegment.blockquoteNode) ^ -+ ENRMImageSourceSignatureForNode(blockquoteSegment.blockquoteNode) ^ kBlockquoteKindSalt; - [renderedSegments addObject:[ENRMRenderedSegment blockquoteSegmentWithSegment:blockquoteSegment - signature:signature]]; - } -diff --git a/ios/segments/TableContainerView.m b/ios/segments/TableContainerView.m -index 0423787367f9cae1acf3ebf6d0139c4fc24e984e..47ba558a1caf42684bae8ccf1d35ff59091cbad6 100644 ---- a/ios/segments/TableContainerView.m -+++ b/ios/segments/TableContainerView.m -@@ -2,6 +2,7 @@ - #import "AttributedRenderer.h" - #import "ENRMAccessibilityLabels.h" - #import "ENRMImageAttachment.h" -+#import "ENRMLinkPillAttachment.h" - #import "HTMLGenerator.h" - #import "LinkTapUtils.h" - #import "MarkdownASTNode.h" -@@ -190,10 +191,14 @@ static void ENRMTableComputeLayout(NSArray *> *rows, NS - - for (NSArray *row in rows) { - for (NSUInteger column = 0; column < row.count; column++) { -+#if !TARGET_OS_OSX -+ CGRect boundingRect = ENRMLinkPillTextBounds(row[column].attributedText, maximumColumnWidth); -+#else - CGRect boundingRect = [row[column].attributedText - boundingRectWithSize:CGSizeMake(maximumColumnWidth, CGFLOAT_MAX) - options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading - context:nil]; -+#endif - CGFloat width = MIN(MAX(ceil(boundingRect.size.width) + horizontalPadding, minimumColumnWidth), - maximumColumnWidth + horizontalPadding); - if (width > [colWidths[column] doubleValue]) -@@ -206,10 +211,14 @@ static void ENRMTableComputeLayout(NSArray *> *rows, NS - CGFloat maxHeight = 0; - for (NSUInteger column = 0; column < row.count; column++) { - CGFloat availableWidth = [colWidths[column] doubleValue] - horizontalPadding; -+#if !TARGET_OS_OSX -+ CGRect boundingRect = ENRMLinkPillTextBounds(row[column].attributedText, availableWidth); -+#else - CGRect boundingRect = [row[column].attributedText - boundingRectWithSize:CGSizeMake(availableWidth, CGFLOAT_MAX) - options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading - context:nil]; -+#endif - maxHeight = MAX(maxHeight, ceil(boundingRect.size.height) + verticalPadding); - } - [rowHeights addObject:@(maxHeight)]; -diff --git a/ios/styles/StyleConfig.h b/ios/styles/StyleConfig.h -index d4491f69aded5b7368ae915aef5cc88a1aa706a1..04869dce2cf958d1543d96f4f70edf92b4ca7232 100644 ---- a/ios/styles/StyleConfig.h -+++ b/ios/styles/StyleConfig.h -@@ -9,6 +9,17 @@ NS_ASSUME_NONNULL_BEGIN - * Populated from the JS `linkVariants` map by StylePropsUtils and consumed by LinkRenderer. - */ - @interface LinkVariantConfig : NSObject -+@property (nonatomic, copy) NSString *fontFamily; -+@property (nonatomic, assign) BOOL pill; -+@property (nonatomic, copy) NSString *label; -+@property (nonatomic, copy) NSString *iconUri; -+@property (nonatomic, strong, nullable) RCTUIColor *iconTintColor; -+@property (nonatomic, assign) CGFloat borderRadius; -+@property (nonatomic, assign) CGFloat paddingHorizontal; -+@property (nonatomic, assign) CGFloat paddingVertical; -+@property (nonatomic, assign) CGFloat borderWidth; -+@property (nonatomic, strong) RCTUIColor *borderColor; -+@property (nonatomic, assign) CGFloat maxWidth; - @property (nonatomic, copy) NSString *pattern; - @property (nonatomic, strong) RCTUIColor *color; - @property (nonatomic, assign) BOOL underline; -diff --git a/ios/utils/CodeBackground.m b/ios/utils/CodeBackground.m -index 5e5d5bf06370c9a94ed5645ccba4436894fe2bdb..fa30eb3812cf76681778415215da3e0c0319a148 100644 ---- a/ios/utils/CodeBackground.m -+++ b/ios/utils/CodeBackground.m -@@ -1,4 +1,5 @@ - #import "CodeBackground.h" -+#import "ENRMLinkPillAttachment.h" - #import "ENRMUIKit.h" - #import "RenderContext.h" - -@@ -43,12 +44,31 @@ static const CGFloat kCodeBackgroundBorderWidth = 0.5; - if (NSIntersectionRange(range, charRange).length == 0) - return; - -- [self drawCodeBackgroundForRange:range -- layoutManager:layoutManager -- textContainer:textContainer -- atPoint:origin -- backgroundColor:backgroundColor -- borderColor:self->_config.codeBorderColor]; -+#if !TARGET_OS_OSX -+ // Keep CodeAttributeName for extraction; attachments own their visual background. -+ [textStorage enumerateAttribute:NSAttachmentAttributeName -+ inRange:range -+ options:0 -+ usingBlock:^(id attachment, NSRange uncoveredRange, BOOL *innerStop) { -+ if ([attachment isKindOfClass:ENRMLinkPillAttachment.class]) -+ return; -+ if (NSIntersectionRange(uncoveredRange, charRange).length == 0) -+ return; -+ [self drawCodeBackgroundForRange:uncoveredRange -+ layoutManager:layoutManager -+ textContainer:textContainer -+ atPoint:origin -+ backgroundColor:backgroundColor -+ borderColor:self->_config.codeBorderColor]; -+ }]; -+#else -+ [self drawCodeBackgroundForRange:range -+ layoutManager:layoutManager -+ textContainer:textContainer -+ atPoint:origin -+ backgroundColor:backgroundColor -+ borderColor:self->_config.codeBorderColor]; -+#endif - }]; - } - -diff --git a/ios/utils/ENRMDocumentAssets.h b/ios/utils/ENRMDocumentAssets.h -new file mode 100644 -index 0000000000000000000000000000000000000000..c0709eb7376a4ada87a32d5cb5da08db5ecb4fb7 ---- /dev/null -+++ b/ios/utils/ENRMDocumentAssets.h -@@ -0,0 +1,68 @@ -+#pragma once -+#import "ENRMImageSources.h" -+#import "MarkdownASTNode.h" -+#import "StyleConfig.h" -+ -+// Traverses the accepted native AST in source order. IDs identify occurrences, -+// including links, so duplicate URLs remain independent. -+FOUNDATION_EXPORT NSArray *ENRMPrepareDocumentAssets(MarkdownASTNode *ast, BOOL enableMediaSlots, -+ BOOL decisionsAccepted, NSDictionary *overrides); -+FOUNDATION_EXPORT CGFloat ENRMMediaSlotHeight(MarkdownASTNode *node, CGFloat width, StyleConfig *config); -+ -+#ifdef __cplusplus -+#include -+#include -+#include -+#include -+#include -+template struct ENRMHasMediaSlots : std::false_type {}; -+template -+struct ENRMHasMediaSlots().mediaOverrides)>> : std::true_type {}; -+ -+template static inline NSDictionary *ENRMMediaOverridesFromProps(const PropsT &props) -+{ -+ NSMutableDictionary *overrides = [NSMutableDictionary dictionary]; -+ for (const auto &item : props.mediaOverrides) { -+ if (!std::isfinite(item.height) || item.height < 0 || !std::isfinite(item.width) || item.width < 0) -+ continue; -+ NSString *identifier = [[NSString alloc] initWithUTF8String:item.id.c_str()]; -+ overrides[identifier] = @{ -+ @"height" : @(item.height), -+ @"width" : @(item.width), -+ @"url" : [[NSString alloc] initWithUTF8String:item.url.c_str()], -+ @"kind" : [[NSString alloc] initWithUTF8String:item.kind.c_str()], -+ @"anchor" : [[NSString alloc] initWithUTF8String:item.anchor.c_str()] -+ }; -+ } -+ return overrides; -+} -+ -+template static inline size_t ENRMMediaPropsFingerprint(const PropsT &props) -+{ -+ size_t hash = 0; -+ if constexpr (ENRMHasMediaSlots::value) { -+ auto mix = [&](size_t value) { hash ^= value + 0x9e3779b9 + (hash << 6) + (hash >> 2); }; -+ mix(std::hash{}(props.enableMediaSlots)); -+ mix(std::hash{}(props.documentRevision)); -+ mix(std::hash{}(props.mediaOverridesRevision)); -+ for (const auto &item : props.mediaOverrides) { -+ mix(std::hash{}(item.id)); -+ mix(std::hash{}(item.url)); -+ mix(std::hash{}(item.kind)); -+ mix(std::hash{}(item.anchor)); -+ mix(std::hash{}(item.height)); -+ mix(std::hash{}(item.width)); -+ } -+ } -+ return hash ^ ENRMImageSourcesFingerprint(props); -+} -+#endif -+ -+#ifdef __cplusplus -+template static inline bool ENRMMediaSlotsEnabled(const PropsT &props) -+{ -+ if constexpr (ENRMHasMediaSlots::value) -+ return props.enableMediaSlots; -+ return false; -+} -+#endif -diff --git a/ios/utils/ENRMDocumentAssets.m b/ios/utils/ENRMDocumentAssets.m -new file mode 100644 -index 0000000000000000000000000000000000000000..3e643ad0dc76d650aaee75afed741de80fe686d6 ---- /dev/null -+++ b/ios/utils/ENRMDocumentAssets.m -@@ -0,0 +1,94 @@ -+#import "ENRMDocumentAssets.h" -+#import -+ -+static NSString *ENRMAssetText(MarkdownASTNode *node) -+{ -+ NSMutableString *text = [NSMutableString stringWithString:node.content ?: @""]; -+ for (MarkdownASTNode *child in node.children) -+ [text appendString:ENRMAssetText(child)]; -+ return text; -+} -+ -+static void ENRMVisitAssets(MarkdownASTNode *node, MarkdownASTNode *parent, MarkdownASTNode *root, NSString *placement, -+ NSString *anchor, BOOL segmentChild, BOOL parentIsSegmentChild, NSMutableArray *assets, -+ BOOL enableSlots, BOOL decisionsAccepted, NSDictionary *overrides) -+{ -+ if (node.type == MarkdownNodeTypeTable) -+ placement = @"table"; -+ else if (node.type == MarkdownNodeTypeOrderedList || node.type == MarkdownNodeTypeUnorderedList) -+ placement = @"list"; -+ else if (node.type == MarkdownNodeTypeBlockquote || node.type == MarkdownNodeTypeAdmonition) -+ placement = @"blockquote"; -+ -+ BOOL isImage = node.type == MarkdownNodeTypeImage; -+ BOOL isVideo = node.type == MarkdownNodeTypeVideo; -+ if (isImage || isVideo || node.type == MarkdownNodeTypeLink) { -+ BOOL blockImage = -+ isImage && parent.type == MarkdownNodeTypeParagraph && parent.children.count == 1 && parentIsSegmentChild; -+ BOOL eligible = blockImage || (isVideo && segmentChild); -+ NSString *identifier = [NSString stringWithFormat:@"asset-%lu", (unsigned long)assets.count]; -+ NSString *assetPlacement = eligible && ![placement isEqualToString:@"blockquote"] ? @"block" : placement; -+ NSString *assetAnchor = -+ blockImage ? [anchor substringToIndex:[anchor rangeOfString:@"." options:NSBackwardsSearch].location] : anchor; -+ NSString *kind = isImage ? @"image" : (isVideo ? @"video" : @"link"); -+ NSString *url = node.attributes[@"url"] ?: @""; -+ [assets addObject:@{ -+ @"id" : identifier, -+ @"kind" : kind, -+ @"url" : url, -+ @"anchor" : assetAnchor, -+ @"altText" : -+ [ENRMAssetText(node) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]], -+ @"title" : node.attributes[@"title"] ?: @"", -+ @"placement" : assetPlacement, -+ @"eligible" : @(eligible) -+ }]; -+ NSDictionary *override = overrides[identifier]; -+ if (eligible && enableSlots && (!decisionsAccepted || override)) { -+ MarkdownASTNode *slot = blockImage ? parent : node; -+ slot.attributes[@"_enrmMediaSlot"] = identifier; -+ slot.attributes[@"_enrmMediaKind"] = isVideo ? @"video" : @"image"; -+ BOOL matchesIdentity = override && [override[@"url"] isEqualToString:url] && -+ [override[@"kind"] isEqualToString:kind] && -+ [override[@"anchor"] isEqualToString:assetAnchor]; -+ // JS carries overrides only across safe trailing appends. The accepted -+ // native parse still verifies occurrence identity before using its height. -+ if (matchesIdentity) { -+ slot.attributes[@"_enrmMediaHeight"] = [override[@"height"] stringValue]; -+ slot.attributes[@"_enrmMediaWidth"] = [override[@"width"] stringValue]; -+ } -+ } -+ } -+ // Only document/quote segment containers can host slots. Once traversal enters -+ // a list, table, paragraph, or link, descendant quotes stay in the text path. -+ BOOL childrenAreSegmentChildren = -+ node == root || -+ (segmentChild && (node.type == MarkdownNodeTypeBlockquote || node.type == MarkdownNodeTypeAdmonition)); -+ [node.children enumerateObjectsUsingBlock:^(MarkdownASTNode *child, NSUInteger index, BOOL *stop) { -+ NSString *childAnchor = anchor.length > 0 ? [anchor stringByAppendingFormat:@".%lu", (unsigned long)index] -+ : [NSString stringWithFormat:@"%lu", (unsigned long)index]; -+ ENRMVisitAssets(child, node, root, placement, childAnchor, childrenAreSegmentChildren, segmentChild, assets, -+ enableSlots, decisionsAccepted, overrides); -+ }]; -+} -+ -+NSArray *ENRMPrepareDocumentAssets(MarkdownASTNode *ast, BOOL enableMediaSlots, BOOL decisionsAccepted, -+ NSDictionary *overrides) -+{ -+ NSMutableArray *assets = [NSMutableArray array]; -+ ENRMVisitAssets(ast, nil, ast, @"inline", @"0", NO, NO, assets, enableMediaSlots, decisionsAccepted, overrides); -+ return assets; -+} -+ -+CGFloat ENRMMediaSlotHeight(MarkdownASTNode *node, CGFloat width, StyleConfig *config) -+{ -+ NSString *height = node.attributes[@"_enrmMediaHeight"]; -+ CGFloat measuredWidth = [node.attributes[@"_enrmMediaWidth"] doubleValue]; -+ if (height && (measuredWidth == 0 || fabs(measuredWidth - width) < 0.5)) -+ return MAX(0, height.doubleValue); -+ if ([node.attributes[@"_enrmMediaKind"] isEqualToString:@"video"]) -+ return width / MAX(config.videoAspectRatio, 0.01); -+ if (config.imageAspectRatio > 0) -+ return width / config.imageAspectRatio; -+ return config.imageMaxHeight > 0 ? config.imageMaxHeight : MAX(config.imageHeight, 1); -+} -diff --git a/ios/utils/ENRMImageDownloader.h b/ios/utils/ENRMImageDownloader.h -index af39f58ac2ee4cbd0431b07f2851fefe580a982b..434cca4d3b275ab954a05033406b4d776a687e59 100644 ---- a/ios/utils/ENRMImageDownloader.h -+++ b/ios/utils/ENRMImageDownloader.h -@@ -11,7 +11,7 @@ typedef void (^ENRMImageDownloadCompletion)(RCTUIImage *_Nullable image); - * pairs, so the same URL fetched with different headers is cached and - * deduplicated separately without embedding header values in the key. - */ --NSString *ENRMImageCacheKey(NSString *url, NSDictionary *_Nullable headers); -+FOUNDATION_EXPORT NSString *ENRMImageCacheKey(NSString *url, NSDictionary *_Nullable headers); - - @interface ENRMImageDownloader : NSObject - -diff --git a/ios/utils/ENRMImageDownloader.m b/ios/utils/ENRMImageDownloader.m -index 974154201f4d923f61b19c8814b17a02fc335f9d..d9b85049972861afde530b5e766c3ee908383063 100644 ---- a/ios/utils/ENRMImageDownloader.m -+++ b/ios/utils/ENRMImageDownloader.m -@@ -38,6 +38,7 @@ NSString *ENRMImageCacheKey(NSString *url, NSDictionary - - @implementation ENRMImageDownloader { - NSURLSession *_session; -+ NSURLSession *_headerSession; - NSMutableDictionary *> *_inFlightRequests; - } - -@@ -61,6 +62,12 @@ NSString *ENRMImageCacheKey(NSString *url, NSDictionary - config.timeoutIntervalForRequest = 15; - config.timeoutIntervalForResource = 30; - _session = [NSURLSession sessionWithConfiguration:config]; -+ // URLCache does not provide our effective URI/header identity. Header-bearing -+ // requests use only the decoded cache above, which includes every header. -+ NSURLSessionConfiguration *headerConfig = [config copy]; -+ headerConfig.URLCache = nil; -+ headerConfig.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData; -+ _headerSession = [NSURLSession sessionWithConfiguration:headerConfig]; - _inFlightRequests = [NSMutableDictionary dictionary]; - } - return self; -@@ -76,7 +83,7 @@ NSString *ENRMImageCacheKey(NSString *url, NSDictionary - } - - BOOL isLocal = ENRMIsLocalImageURL(url); -- NSString *cacheKey = isLocal ? url : ENRMImageCacheKey(url, headers); -+ NSString *cacheKey = ENRMImageCacheKey(url, headers); - - RCTUIImage *cached = [[ENRMImageAttachment originalImageCache] objectForKey:cacheKey]; - if (cached) { -@@ -113,22 +120,25 @@ NSString *ENRMImageCacheKey(NSString *url, NSDictionary - [request setValue:value forHTTPHeaderField:name]; - }]; - -- [[_session dataTaskWithRequest:request -- completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { -+ NSURLSession *session = headers.count > 0 ? _headerSession : _session; -+ if (headers.count > 0) -+ request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData; -+ [[session dataTaskWithRequest:request -+ completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { - #if !TARGET_OS_OSX -- RCTUIImage *image = (data && !error) ? [RCTUIImage imageWithData:data] : nil; -+ RCTUIImage *image = (data && !error) ? [RCTUIImage imageWithData:data] : nil; - #else - RCTUIImage *image = (data && !error) ? [[RCTUIImage alloc] initWithData:data] : nil; - #endif - -- if (image) { -- [[ENRMImageAttachment originalImageCache] setObject:image -- forKey:cacheKey -- cost:ENRMImageByteCost(image)]; -- } -+ if (image) { -+ [[ENRMImageAttachment originalImageCache] setObject:image -+ forKey:cacheKey -+ cost:ENRMImageByteCost(image)]; -+ } - -- [self dispatchCallbacksForKey:cacheKey image:image]; -- }] resume]; -+ [self dispatchCallbacksForKey:cacheKey image:image]; -+ }] resume]; - } - - - (void)dispatchCallbacksForKey:(NSString *)cacheKey image:(RCTUIImage *_Nullable)image -diff --git a/ios/utils/ENRMImageSources.h b/ios/utils/ENRMImageSources.h -new file mode 100644 -index 0000000000000000000000000000000000000000..5ceba7b78d29ca90f1024ff487fa5239d5e85227 ---- /dev/null -+++ b/ios/utils/ENRMImageSources.h -@@ -0,0 +1,72 @@ -+#pragma once -+#import "ImageRequestHeaderUtils.h" -+#import "MarkdownASTNode.h" -+ -+// Annotates only transport on the accepted AST. The manifest owns occurrence identity. -+FOUNDATION_EXPORT void ENRMPrepareImageSources(MarkdownASTNode *ast, NSArray *assets, BOOL enabled, -+ BOOL decisionsAccepted, NSDictionary *sources); -+FOUNDATION_EXPORT NSDictionary *ENRMImageSourceDecisionForNode(MarkdownASTNode *node); -+// Render signatures include transport state without changing semantic AST signatures. -+FOUNDATION_EXPORT uint64_t ENRMImageSourceSignatureForNode(MarkdownASTNode *node); -+FOUNDATION_EXPORT uint64_t ENRMImageSourceSignatureForNodes(NSArray *nodes); -+FOUNDATION_EXPORT NSDictionary *ENRMMergeImageRequestHeaders(NSDictionary *documentHeaders, -+ NSDictionary *sourceHeaders); -+ -+#ifdef __cplusplus -+#include -+#include -+#include -+#include -+template struct ENRMHasImageSources : std::false_type {}; -+template -+struct ENRMHasImageSources().imageSources)>> : std::true_type {}; -+ -+template static inline NSDictionary *ENRMImageSourcesFromProps(const PropsT &props) -+{ -+ NSMutableDictionary *sources = [NSMutableDictionary dictionary]; -+ for (const auto &item : props.imageSources) { -+ sources[@(item.id.c_str())] = @{ -+ @"id" : @(item.id.c_str()), -+ @"url" : @(item.url.c_str()), -+ @"anchor" : @(item.anchor.c_str()), -+ @"uri" : @(item.uri.c_str()), -+ @"useDefault" : @(item.useDefault), -+ @"headers" : ENRMImageRequestHeadersFromProps(item.headers) ?: @{} -+ }; -+ } -+ return sources; -+} -+ -+template static inline BOOL ENRMImageSourcesAccepted(const PropsT &props) -+{ -+ return props.imageSourcesRevision >= props.imageSourcesContinuityStart && -+ props.imageSourcesRevision <= props.documentRevision; -+} -+ -+template static inline size_t ENRMImageSourcesFingerprint(const PropsT &props) -+{ -+ size_t hash = 0; -+ if constexpr (ENRMHasImageSources::value) { -+ auto mix = [&](size_t value) { hash ^= value + 0x9e3779b9 + (hash << 6) + (hash >> 2); }; -+ mix(std::hash{}(props.enableImageSourceResolution)); -+ for (const auto &header : props.imageRequestHeaders) { -+ mix(std::hash{}(header.name)); -+ mix(std::hash{}(header.value)); -+ } -+ mix(std::hash{}(props.imageSourcesRevision)); -+ mix(std::hash{}(props.imageSourcesContinuityStart)); -+ for (const auto &item : props.imageSources) { -+ mix(std::hash{}(item.id)); -+ mix(std::hash{}(item.url)); -+ mix(std::hash{}(item.anchor)); -+ mix(std::hash{}(item.uri)); -+ mix(std::hash{}(item.useDefault)); -+ for (const auto &header : item.headers) { -+ mix(std::hash{}(header.name)); -+ mix(std::hash{}(header.value)); -+ } -+ } -+ } -+ return hash; -+} -+#endif -diff --git a/ios/utils/ENRMImageSources.m b/ios/utils/ENRMImageSources.m -new file mode 100644 -index 0000000000000000000000000000000000000000..fb8faac1698315f8624eccd41d673dbde5373aca ---- /dev/null -+++ b/ios/utils/ENRMImageSources.m -@@ -0,0 +1,120 @@ -+#import "ENRMImageSources.h" -+#import -+ -+static char ENRMImageSourceDecisionKey; -+ -+NSDictionary *ENRMImageSourceDecisionForNode(MarkdownASTNode *node) -+{ -+ return objc_getAssociatedObject(node, &ENRMImageSourceDecisionKey); -+} -+ -+NSDictionary *ENRMMergeImageRequestHeaders(NSDictionary *documentHeaders, -+ NSDictionary *sourceHeaders) -+{ -+ NSMutableDictionary *merged = [NSMutableDictionary dictionary]; -+ // Lowercase keys make overrides and cache identity independent of HTTP header casing. -+ for (NSString *name in documentHeaders) -+ merged[name.lowercaseString] = documentHeaders[name]; -+ for (NSString *name in sourceHeaders) -+ merged[name.lowercaseString] = sourceHeaders[name]; -+ return merged; -+} -+ -+static void ENRMVisitImageSources(MarkdownASTNode *node, NSArray *assets, NSDictionary *sources, -+ BOOL decisionsAccepted, NSUInteger *occurrence) -+{ -+ // Match the accepted collector's image/video/link occurrence order. No source parse. -+ if (node.type == MarkdownNodeTypeImage || node.type == MarkdownNodeTypeVideo || node.type == MarkdownNodeTypeLink) { -+ NSUInteger index = (*occurrence)++; -+ if (node.type == MarkdownNodeTypeImage) { -+ NSDictionary *decision = @{@"pending" : @YES}; -+ NSDictionary *asset = index < assets.count ? assets[index] : nil; -+ NSDictionary *source = asset ? sources[asset[@"id"]] : nil; -+ BOOL matches = -+ decisionsAccepted && [asset[@"kind"] isEqualToString:@"image"] && -+ [source[@"id"] isEqualToString:asset[@"id"]] && [asset[@"url"] isEqualToString:node.attributes[@"url"]] && -+ [source[@"url"] isEqualToString:asset[@"url"]] && [source[@"anchor"] isEqualToString:asset[@"anchor"]]; -+ if (matches && ([source[@"useDefault"] boolValue] || [source[@"uri"] length] > 0)) { -+ decision = [source[@"useDefault"] boolValue] -+ ? @{@"pending" : @NO} -+ : @{@"pending" : @NO, -+ @"uri" : source[@"uri"], -+ @"headers" : source[@"headers"] ?: @{}}; -+ } -+ objc_setAssociatedObject(node, &ENRMImageSourceDecisionKey, decision, OBJC_ASSOCIATION_RETAIN_NONATOMIC); -+ } -+ } -+ for (MarkdownASTNode *child in node.children) -+ ENRMVisitImageSources(child, assets, sources, decisionsAccepted, occurrence); -+} -+ -+static void ENRMClearImageSources(MarkdownASTNode *node) -+{ -+ objc_setAssociatedObject(node, &ENRMImageSourceDecisionKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); -+ for (MarkdownASTNode *child in node.children) -+ ENRMClearImageSources(child); -+} -+ -+void ENRMPrepareImageSources(MarkdownASTNode *ast, NSArray *assets, BOOL enabled, -+ BOOL decisionsAccepted, NSDictionary *sources) -+{ -+ if (!enabled) { -+ ENRMClearImageSources(ast); -+ return; -+ } -+ NSUInteger occurrence = 0; -+ ENRMVisitImageSources(ast, assets, sources, decisionsAccepted, &occurrence); -+} -+ -+static uint64_t ENRMSourceMixUInt64(uint64_t hash, uint64_t value) -+{ -+ for (NSUInteger i = 0; i < 8; i++) { -+ hash ^= (uint8_t)(value & 0xFF); -+ hash *= 1099511628211ULL; -+ value >>= 8; -+ } -+ return hash; -+} -+ -+static uint64_t ENRMSourceMixString(uint64_t hash, NSString *value) -+{ -+ NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding]; -+ hash = ENRMSourceMixUInt64(hash, data.length); -+ const uint8_t *bytes = data.bytes; -+ for (NSUInteger i = 0; i < data.length; i++) { -+ hash ^= bytes[i]; -+ hash *= 1099511628211ULL; -+ } -+ return hash; -+} -+ -+uint64_t ENRMImageSourceSignatureForNode(MarkdownASTNode *node) -+{ -+ NSDictionary *source = ENRMImageSourceDecisionForNode(node); -+ uint64_t hash = 0; -+ if (source) { -+ hash = ENRMSourceMixUInt64(14695981039346656037ULL, [source[@"pending"] boolValue] ? 1 : 2); -+ hash = ENRMSourceMixString(hash, source[@"uri"] ?: @""); -+ NSDictionary *headers = ENRMMergeImageRequestHeaders(nil, source[@"headers"]); -+ for (NSString *name in [headers.allKeys sortedArrayUsingSelector:@selector(compare:)]) { -+ hash = ENRMSourceMixString(hash, name); -+ hash = ENRMSourceMixString(hash, headers[name]); -+ } -+ } -+ uint64_t children = ENRMImageSourceSignatureForNodes(node.children); -+ if (children) -+ hash = ENRMSourceMixUInt64(hash ?: 14695981039346656037ULL, children); -+ return hash; -+} -+ -+uint64_t ENRMImageSourceSignatureForNodes(NSArray *nodes) -+{ -+ uint64_t hash = 14695981039346656037ULL; -+ BOOL hasSources = NO; -+ for (MarkdownASTNode *node in nodes) { -+ uint64_t source = ENRMImageSourceSignatureForNode(node); -+ hasSources |= source != 0; -+ hash = ENRMSourceMixUInt64(hash, source); -+ } -+ return hasSources ? hash : 0; -+} -diff --git a/ios/utils/ENRMTextViewSetup.h b/ios/utils/ENRMTextViewSetup.h -index 0151d0fc54691c34348be6e77febd693a725c3fa..9e74e78e20958cc393988b85a668babe6be0ce58 100644 ---- a/ios/utils/ENRMTextViewSetup.h -+++ b/ios/utils/ENRMTextViewSetup.h -@@ -1,4 +1,6 @@ - #pragma once -+#import "ENRMLinkPillAttachment.h" -+#import "ENRMLinkPillTextStorage.h" - #import "ENRMUIKit.h" - #import "LastElementUtils.h" - #import "StyleConfig.h" -@@ -15,6 +17,9 @@ static inline void ENRMAttachLayoutManager(ENRMPlatformTextView *textView, Style - return; - } - layoutManager.allowsNonContiguousLayout = NO; -+#if !TARGET_OS_OSX -+ layoutManager.delegate = ENRMLinkPillLayoutDelegate.shared; -+#endif - object_setClass(layoutManager, [TextViewLayoutManager class]); - if (config != nil) { - [layoutManager setValue:config forKey:@"config"]; -@@ -26,6 +31,9 @@ static inline void ENRMDetachLayoutManager(ENRMPlatformTextView *textView) - NSLayoutManager *layoutManager = textView.layoutManager; - if (layoutManager != nil && [object_getClass(layoutManager) isEqual:[TextViewLayoutManager class]]) { - [layoutManager setValue:nil forKey:@"config"]; -+#if !TARGET_OS_OSX -+ layoutManager.delegate = nil; -+#endif - object_setClass(layoutManager, [NSLayoutManager class]); - } - } -diff --git a/ios/utils/MarkdownASTSerializer.m b/ios/utils/MarkdownASTSerializer.m -index 01b9054bc29b0608594c08248acc0206d0f5d1c2..c6ce7efb444190450b9430fa31e2ea93f6500fc4 100644 ---- a/ios/utils/MarkdownASTSerializer.m -+++ b/ios/utils/MarkdownASTSerializer.m -@@ -81,6 +81,10 @@ static void serializeNode(MarkdownASTNode *node, NSMutableString *buffer) - break; - - case MarkdownNodeTypeLink: { -+ if ([node.attributes[@"recognizedLink"] isEqualToString:@"true"]) { -+ serializeChildren(node, buffer); -+ break; -+ } - NSString *url = node.attributes[@"url"] ?: @""; - [buffer appendString:@"["]; - serializeChildren(node, buffer); -diff --git a/ios/utils/MarkdownExtractor.m b/ios/utils/MarkdownExtractor.m -index eb4482c6cdf842dfbd952b8c6cdb9ce836579b53..ff3426ea7e13a9503f3fe309df84d45521a73ac4 100644 ---- a/ios/utils/MarkdownExtractor.m -+++ b/ios/utils/MarkdownExtractor.m -@@ -1,7 +1,11 @@ - #import "MarkdownExtractor.h" -+#import "BaselineShiftTextAttributes.h" - #import "BlockquoteBorder.h" -+#import "CodeBackground.h" - #import "ENRMFeatureFlags.h" - #import "ENRMImageAttachment.h" -+#import "ENRMLinkPillAttachment.h" -+#import "ENRMTextLinkAttributes.h" - #import "ENRMUIKit.h" - #import "HighlightRenderer.h" - #include -@@ -126,6 +130,17 @@ NSString *_Nullable extractMarkdownFromAttributedString(NSAttributedString *attr - } - - range.length = MIN(range.length, attributedText.length - range.location); -+#if !TARGET_OS_OSX -+ NSMutableAttributedString *semanticText = [attributedText mutableCopy]; -+ [attributedText enumerateAttribute:NSAttachmentAttributeName -+ inRange:range -+ options:0 -+ usingBlock:^(id value, NSRange attachmentRange, BOOL *stop) { -+ if ([value isKindOfClass:ENRMLinkPillAttachment.class]) -+ [semanticText removeAttribute:NSAttachmentAttributeName range:attachmentRange]; -+ }]; -+ attributedText = semanticText; -+#endif - - NSMutableString *result = [NSMutableString string]; - -@@ -294,18 +309,25 @@ NSString *_Nullable extractMarkdownFromAttributedString(NSAttributedString *attr - - // Inline formatting - BOOL isBold, isItalic, isMonospace; -+ BOOL recognizedLink = [attrs[ENRMRecognizedLinkAttributeName] boolValue]; - extractFontTraits(attrs, &isBold, &isItalic, &isMonospace); -+ if (recognizedLink) -+ isMonospace = [attrs[CodeAttributeName] boolValue]; - - NSNumber *strikethroughStyle = attrs[NSStrikethroughStyleAttributeName]; - BOOL isStrikethrough = (strikethroughStyle != nil && [strikethroughStyle integerValue] != 0); -- NSNumber *underlineStyle = attrs[NSUnderlineStyleAttributeName]; -+ NSNumber *underlineStyle = recognizedLink -+ ? attrs[ENRMRecognizedLinkOriginalUnderlineAttributeName] -+ : attrs[NSUnderlineStyleAttributeName]; - BOOL isUnderline = (underlineStyle != nil && [underlineStyle integerValue] != 0); -- NSNumber *baselineOffset = attrs[NSBaselineOffsetAttributeName]; -- BOOL isSuperscript = baselineOffset != nil && [baselineOffset doubleValue] > 0; -- BOOL isSubscript = baselineOffset != nil && [baselineOffset doubleValue] < 0; -+ // Line-height alignment also shifts baselines. Only semantic script spans -+ // should produce superscript/subscript Markdown on the clipboard. -+ NSString *script = attrs[ENRMScriptAttributeName]; -+ BOOL isSuperscript = [script isEqualToString:@"superscript"]; -+ BOOL isSubscript = [script isEqualToString:@"subscript"]; - - BOOL isHighlight = [attrs[HighlightAttributeName] boolValue]; -- NSString *linkURL = attrs[NSLinkAttributeName]; -+ NSString *linkURL = recognizedLink ? nil : attrs[NSLinkAttributeName]; - NSString *segment = - applyInlineFormatting(text, isBold, isItalic, isMonospace, isStrikethrough, isUnderline, - isSuperscript, isSubscript, isHighlight, linkURL); -diff --git a/ios/utils/ParagraphStyleUtils.m b/ios/utils/ParagraphStyleUtils.m -index c625941ed8e0e0bf2fea05c87fb121cdb71b83b1..85e5223d6b66993df784efd49b5964cc542cd043 100644 ---- a/ios/utils/ParagraphStyleUtils.m -+++ b/ios/utils/ParagraphStyleUtils.m -@@ -1,6 +1,7 @@ - #import "ParagraphStyleUtils.h" - #import "ENRMFeatureFlags.h" - #import "ENRMImageAttachment.h" -+#import "ENRMLinkPillAttachment.h" - #import "LastElementUtils.h" - #import - -@@ -299,12 +300,24 @@ void applyLineHeight(NSMutableAttributedString *output, NSRange range, CGFloat l - }]; - #endif - -+ __block BOOL hasPill = NO; -+#if !TARGET_OS_OSX -+ [output enumerateAttribute:NSAttachmentAttributeName -+ inRange:range -+ options:0 -+ usingBlock:^(id value, NSRange subrange, BOOL *stop) { -+ if ([value isKindOfClass:ENRMLinkPillAttachment.class]) { -+ hasPill = YES; -+ *stop = YES; -+ } -+ }]; -+#endif - BOOL hasBlockImage = ENRMRangeContainsBlockImage(output, range); - - NSMutableParagraphStyle *style = getOrCreateParagraphStyle(output, range.location); - - style.minimumLineHeight = lineHeight; -- style.maximumLineHeight = (hasMath || hasBlockImage) ? 0 : lineHeight; -+ style.maximumLineHeight = (hasMath || hasBlockImage || hasPill) ? 0 : lineHeight; - - [output addAttribute:NSParagraphStyleAttributeName value:style range:range]; - } -@@ -358,6 +371,17 @@ void applyBaselineOffset(NSMutableAttributedString *output, NSRange range) - }]; - - CGFloat contentLineHeight = textLineHeight; -+#if !TARGET_OS_OSX -+ __block CGFloat pillBoxHeight = 0; -+ [output enumerateAttribute:NSAttachmentAttributeName -+ inRange:range -+ options:0 -+ usingBlock:^(id value, NSRange subrange, BOOL *stop) { -+ if ([value isKindOfClass:ENRMLinkPillAttachment.class]) -+ pillBoxHeight = MAX(pillBoxHeight, ((ENRMLinkPillAttachment *)value).boxHeight); -+ }]; -+ contentLineHeight = MAX(contentLineHeight, pillBoxHeight); -+#endif - - #if ENRICHED_MARKDOWN_MATH - // Math only grows the content height, so measure it (parsing LaTeX) only when text -@@ -372,7 +396,7 @@ void applyBaselineOffset(NSMutableAttributedString *output, NSRange range) - mathBoxHeight = MAX(((ENRMMathInlineAttachment *)value).boxHeight, mathBoxHeight); - } - }]; -- contentLineHeight = MAX(textLineHeight, mathBoxHeight); -+ contentLineHeight = MAX(contentLineHeight, mathBoxHeight); - } - #endif - -diff --git a/ios/utils/RTFExportUtils.m b/ios/utils/RTFExportUtils.m -index cf64c1a8080b922aabbd0f2628990204d96ac282..b00ead9106b36542e2ae3e1b267b26601392c68a 100644 ---- a/ios/utils/RTFExportUtils.m -+++ b/ios/utils/RTFExportUtils.m -@@ -1,6 +1,7 @@ - #import "RTFExportUtils.h" - #import "BlockquoteBorder.h" - #import "CodeBackground.h" -+#import "ENRMLinkPillAttachment.h" - #import "LastElementUtils.h" - #import "ListItemRenderer.h" - #import "RenderContext.h" -@@ -282,6 +283,15 @@ NSAttributedString *prepareAttributedStringForRTFExport(NSAttributedString *attr - return attributedString; - - NSMutableAttributedString *prepared = [attributedString mutableCopy]; -+#if !TARGET_OS_OSX -+ [attributedString enumerateAttribute:NSAttachmentAttributeName -+ inRange:NSMakeRange(0, attributedString.length) -+ options:0 -+ usingBlock:^(id value, NSRange range, BOOL *stop) { -+ if ([value isKindOfClass:ENRMLinkPillAttachment.class]) -+ [prepared removeAttribute:NSAttachmentAttributeName range:range]; -+ }]; -+#endif - - RCTUIColor *codeBgColor = [styleConfig codeBackgroundColor]; - RCTUIColor *codeBlockBgColor = [styleConfig codeBlockBackgroundColor]; -diff --git a/ios/utils/StylePropsUtils.h b/ios/utils/StylePropsUtils.h -index 1c34ada6dd16daa253e2b00054fe60a4d38f8ca4..8926a0aef6fe59cbbf81a5ed1c4537cbfc228bd2 100644 ---- a/ios/utils/StylePropsUtils.h -+++ b/ios/utils/StylePropsUtils.h -@@ -560,7 +560,15 @@ BOOL applyMarkdownStyleToConfig(StyleConfig *config, const MarkdownStyle &newSty - const auto &newVariant = newStyle.linkVariants[i]; - const auto &oldVariant = oldStyle.linkVariants[i]; - if (newVariant.pattern != oldVariant.pattern || newVariant.color != oldVariant.color || -- newVariant.underline != oldVariant.underline || newVariant.backgroundColor != oldVariant.backgroundColor) { -+ newVariant.underline != oldVariant.underline || newVariant.backgroundColor != oldVariant.backgroundColor || -+ newVariant.fontFamily != oldVariant.fontFamily || newVariant.pill != oldVariant.pill || -+ newVariant.label != oldVariant.label || newVariant.iconUri != oldVariant.iconUri || -+ newVariant.iconTintColor != oldVariant.iconTintColor || -+ newVariant.borderRadius != oldVariant.borderRadius || -+ newVariant.paddingHorizontal != oldVariant.paddingHorizontal || -+ newVariant.paddingVertical != oldVariant.paddingVertical || -+ newVariant.borderWidth != oldVariant.borderWidth || newVariant.borderColor != oldVariant.borderColor || -+ newVariant.maxWidth != oldVariant.maxWidth) { - linkVariantsChanged = YES; - break; - } -@@ -573,6 +581,17 @@ BOOL applyMarkdownStyleToConfig(StyleConfig *config, const MarkdownStyle &newSty - variant.pattern = [[NSString alloc] initWithUTF8String:entry.pattern.c_str()]; - variant.color = RCTUIColorFromSharedColor(entry.color); - variant.underline = entry.underline; -+ variant.fontFamily = [[NSString alloc] initWithUTF8String:entry.fontFamily.c_str()]; -+ variant.pill = entry.pill; -+ variant.label = [[NSString alloc] initWithUTF8String:entry.label.c_str()]; -+ variant.iconUri = [[NSString alloc] initWithUTF8String:entry.iconUri.c_str()]; -+ variant.iconTintColor = entry.iconTintColor ? RCTUIColorFromSharedColor(entry.iconTintColor) : nil; -+ variant.borderRadius = entry.borderRadius; -+ variant.paddingHorizontal = entry.paddingHorizontal; -+ variant.paddingVertical = entry.paddingVertical; -+ variant.borderWidth = entry.borderWidth; -+ variant.borderColor = RCTUIColorFromSharedColor(entry.borderColor); -+ variant.maxWidth = entry.maxWidth; - RCTUIColor *backgroundColor = RCTUIColorFromSharedColor(entry.backgroundColor); - variant.backgroundColor = CGColorGetAlpha(backgroundColor.CGColor) > 0 ? backgroundColor : nil; - [variants addObject:variant]; -diff --git a/ios/views/EnrichedMarkdownInternalText.m b/ios/views/EnrichedMarkdownInternalText.m -index 93eef7ac4edf45f001a93ebb230588817e3e921b..0696e112f693e93e6674472ae734272ce9e8bbee 100644 ---- a/ios/views/EnrichedMarkdownInternalText.m -+++ b/ios/views/EnrichedMarkdownInternalText.m -@@ -35,7 +35,7 @@ - - (void)setupTextView - { - #if !TARGET_OS_OSX -- _textView = [[ENRMPlatformTextView alloc] init]; -+ _textView = ENRMCreateMarkdownTextView(); - _textView.text = @""; - #else - _textView = [[ENRMContextMenuTextView alloc] init]; -diff --git a/lib/module/EnrichedMarkdownNativeComponent.ts b/lib/module/EnrichedMarkdownNativeComponent.ts -index 66d200af977b0c9a4086f4e621bb26f8400eb68b..db8e832e498ffa1fa1482f68e40d387421761a34 100644 ---- a/lib/module/EnrichedMarkdownNativeComponent.ts -+++ b/lib/module/EnrichedMarkdownNativeComponent.ts -@@ -97,6 +97,17 @@ interface LinkVariantEntryInternal { - color: ColorValue; - underline: boolean; - backgroundColor: ColorValue; -+ fontFamily: string; -+ pill: boolean; -+ label: string; -+ iconUri: string; -+ iconTintColor?: ColorValue; -+ borderRadius: CodegenTypes.Float; -+ paddingHorizontal: CodegenTypes.Float; -+ paddingVertical: CodegenTypes.Float; -+ borderWidth: CodegenTypes.Float; -+ borderColor: ColorValue; -+ maxWidth: CodegenTypes.Float; - } - - interface StrongStyleInternal { -@@ -406,7 +417,92 @@ interface StreamingConfigInternal { - codeBlockMode: string; - } - -+// Same transport as EnrichedMarkdownTextInput.linkRegex. Kept local for codegen. -+interface TextLinkNativeRegex { -+ pattern: string; -+ caseInsensitive: boolean; -+ dotAll: boolean; -+ isDisabled: boolean; -+ isDefault: boolean; -+} -+ -+export interface DocumentAssetInternal { -+ anchor: string; -+ id: string; -+ kind: string; -+ url: string; -+ altText: string; -+ title: string; -+ placement: string; -+ eligible: boolean; -+} -+ -+export interface DocumentAssetsEventInternal { -+ revision: CodegenTypes.Int32; -+ assets: { -+ anchor: string; -+ id: string; -+ kind: string; -+ url: string; -+ altText: string; -+ title: string; -+ placement: string; -+ eligible: boolean; -+ }[]; -+} -+ -+export interface MediaFrameInternal { -+ id: string; -+ x: CodegenTypes.Float; -+ y: CodegenTypes.Float; -+ width: CodegenTypes.Float; -+ height: CodegenTypes.Float; -+} -+ -+export interface MediaLayoutEventInternal { -+ revision: CodegenTypes.Int32; -+ frames: { -+ id: string; -+ x: CodegenTypes.Float; -+ y: CodegenTypes.Float; -+ width: CodegenTypes.Float; -+ height: CodegenTypes.Float; -+ }[]; -+} -+ -+export interface MediaOverrideInternal { -+ url: string; -+ kind: string; -+ anchor: string; -+ id: string; -+ height: CodegenTypes.Float; -+ width: CodegenTypes.Float; -+} -+ -+export interface ImageSourceInternal { -+ id: string; -+ url: string; -+ anchor: string; -+ uri: string; -+ headers: ReadonlyArray>; -+ useDefault: boolean; -+} -+ - export interface NativeProps extends ViewProps { -+ enableImageSourceResolution?: CodegenTypes.WithDefault; -+ imageSourcesRevision?: CodegenTypes.WithDefault; -+ imageSourcesContinuityStart?: CodegenTypes.WithDefault; -+ imageSources?: ReadonlyArray>; -+ documentRevision?: CodegenTypes.WithDefault; -+ enableDocumentAssets?: CodegenTypes.WithDefault; -+ enableMediaSlots?: CodegenTypes.WithDefault; -+ mediaOverridesRevision?: CodegenTypes.WithDefault; -+ mediaOverrides?: ReadonlyArray>; -+ onDocumentAssets?: CodegenTypes.DirectEventHandler; -+ onMediaLayout?: CodegenTypes.DirectEventHandler; -+ -+ linkRegex?: Readonly; -+ inlineCodeLinkRegex?: Readonly; - /** - * Markdown content to render. - */ -diff --git a/lib/module/EnrichedMarkdownTextNativeComponent.ts b/lib/module/EnrichedMarkdownTextNativeComponent.ts -index c034dd109ce151f9d6163a989f8f5ad651029a25..fcf45a04d1984bcdc210445beca44513a1fbb7b4 100644 ---- a/lib/module/EnrichedMarkdownTextNativeComponent.ts -+++ b/lib/module/EnrichedMarkdownTextNativeComponent.ts -@@ -97,6 +97,17 @@ interface LinkVariantEntryInternal { - color: ColorValue; - underline: boolean; - backgroundColor: ColorValue; -+ fontFamily: string; -+ pill: boolean; -+ label: string; -+ iconUri: string; -+ iconTintColor?: ColorValue; -+ borderRadius: CodegenTypes.Float; -+ paddingHorizontal: CodegenTypes.Float; -+ paddingVertical: CodegenTypes.Float; -+ borderWidth: CodegenTypes.Float; -+ borderColor: ColorValue; -+ maxWidth: CodegenTypes.Float; - } - - interface StrongStyleInternal { -@@ -407,7 +418,18 @@ interface StreamingConfigInternal { - codeBlockMode: string; - } - -+// Same transport as EnrichedMarkdownTextInput.linkRegex. Kept local for codegen. -+interface TextLinkNativeRegex { -+ pattern: string; -+ caseInsensitive: boolean; -+ dotAll: boolean; -+ isDisabled: boolean; -+ isDefault: boolean; -+} -+ - export interface NativeProps extends ViewProps { -+ linkRegex?: Readonly; -+ inlineCodeLinkRegex?: Readonly; - /** - * Markdown content to render. - */ -diff --git a/lib/module/imageSourceState.js b/lib/module/imageSourceState.js -new file mode 100644 -index 0000000000000000000000000000000000000000..fe20f71679a82362c263b2f148f402737099feb3 ---- /dev/null -+++ b/lib/module/imageSourceState.js -@@ -0,0 +1,86 @@ -+"use strict"; -+ -+const identity = asset => JSON.stringify(asset); -+const stripAnchor = ({ -+ anchor: _anchor, -+ ...asset -+}) => asset; -+ -+/** Per-occurrence decisions; superseded promises still count against the bound. */ -+export class ImageSourceState { -+ lineage = -1; -+ entries = new Map(); -+ active = 0; -+ running = false; -+ configure(resolver, lineage, assets) { -+ if (resolver !== this.resolver || lineage !== this.lineage) { -+ this.entries.clear(); -+ this.resolver = resolver; -+ this.lineage = lineage; -+ } -+ const next = new Map(); -+ if (resolver) { -+ for (const asset of assets) { -+ const key = identity(asset); -+ const previous = this.entries.get(asset.id); -+ next.set(asset.id, previous?.identity === key ? previous : { -+ asset, -+ identity: key, -+ status: 'queued' -+ }); -+ } -+ } -+ this.entries = next; -+ } -+ sources() { -+ return [...this.entries.values()].flatMap(entry => entry.source ? [entry.source] : []); -+ } -+ start(changed) { -+ this.running = true; -+ this.changed = changed; -+ this.pump(); -+ } -+ stop() { -+ this.running = false; -+ this.changed = undefined; -+ this.entries.clear(); -+ } -+ pump() { -+ if (!this.running || !this.resolver) return; -+ for (const entry of this.entries.values()) { -+ if (this.active >= 4) break; -+ if (entry.status !== 'queued') continue; -+ const resolve = this.resolver; -+ entry.status = 'active'; -+ this.active++; -+ // Always execute outside render. Synchronous throws follow rejection policy. -+ Promise.resolve().then(() => { -+ if (this.entries.get(entry.asset.id) !== entry || !this.running) return undefined; -+ return resolve(stripAnchor(entry.asset)); -+ }).then(result => { -+ if (this.entries.get(entry.asset.id) !== entry) return; -+ if (result === null || result && typeof result.uri === 'string' && result.uri.length > 0) { -+ entry.source = { -+ id: entry.asset.id, -+ url: entry.asset.url, -+ anchor: entry.asset.anchor, -+ uri: result?.uri ?? '', -+ headers: Object.entries(result?.headers ?? {}).map(([name, value]) => ({ -+ name, -+ value -+ })), -+ useDefault: result === null -+ }; -+ } -+ }).catch(() => { -+ // A rejected source remains a placeholder until its identity changes. -+ }).finally(() => { -+ entry.status = 'done'; -+ this.active--; -+ if (this.entries.get(entry.asset.id) === entry) this.changed?.(); -+ this.pump(); -+ }); -+ } -+ } -+} -+//# sourceMappingURL=imageSourceState.js.map -\ No newline at end of file -diff --git a/lib/module/imageSourceState.js.map b/lib/module/imageSourceState.js.map -new file mode 100644 -index 0000000000000000000000000000000000000000..54dae207fb8d9b6472de70c0bc6e7effe911518e ---- /dev/null -+++ b/lib/module/imageSourceState.js.map -@@ -0,0 +1 @@ -+{"version":3,"names":["identity","asset","JSON","stringify","stripAnchor","anchor","_anchor","ImageSourceState","lineage","entries","Map","active","running","configure","resolver","assets","clear","next","key","previous","get","id","set","status","sources","values","flatMap","entry","source","start","changed","pump","stop","undefined","resolve","Promise","then","result","uri","length","url","headers","Object","map","name","value","useDefault","catch","finally"],"sourceRoot":"../../src","sources":["imageSourceState.ts"],"mappings":"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","ignoreList":[]} -diff --git a/lib/module/index.js.map b/lib/module/index.js.map -index e76dd1e98e27d72f25bd51287eb1865ea4fe8bf8..5c6af988714ded6e343237bb5deee86562c27099 100644 ---- a/lib/module/index.js.map -+++ b/lib/module/index.js.map -@@ -1 +1 @@ --{"version":3,"names":["default","EnrichedMarkdownText","DEFAULT_ACCESSIBILITY_LABELS","resolveAccessibilityLabels","EnrichedMarkdownTextInput"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,OAAO,IAAIC,oBAAoB,QAAQ,kCAA+B;AAuB/E,SACEC,4BAA4B,EAC5BC,0BAA0B,QACrB,iCAA8B;AAErC,SAASC,yBAAyB,QAAQ,gCAA6B","ignoreList":[]} -+{"version":3,"names":["default","EnrichedMarkdownText","DEFAULT_ACCESSIBILITY_LABELS","resolveAccessibilityLabels","EnrichedMarkdownTextInput"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AACA,SAASA,OAAO,IAAIC,oBAAoB,QAAQ,kCAA+B;AAuB/E,SACEC,4BAA4B,EAC5BC,0BAA0B,QACrB,iCAA8B;AAErC,SAASC,yBAAyB,QAAQ,gCAA6B","ignoreList":[]} -diff --git a/lib/module/jest/index.js b/lib/module/jest/index.js -index 98c0792354014f64a5a93b194dea0e0e23a492e3..0a6a6faaae108f5cd469a6002c860d659cd7f5ef 100644 ---- a/lib/module/jest/index.js -+++ b/lib/module/jest/index.js -@@ -237,6 +237,7 @@ export const EnrichedMarkdownText = ({ - spoilerOverlay: _spoilerOverlay, - contextMenuItems: _contextMenuItems, - imageRequestHeaders: _imageRequestHeaders, -+ resolveImageSource: _resolveImageSource, - selectionMenuConfig: _selectionMenuConfig, - accessibilityLabels: _accessibilityLabels, - selectionColor: _selectionColor, -diff --git a/lib/module/jest/index.js.map b/lib/module/jest/index.js.map -index 443a10290ab432eb59038f1bf71a03cfd4b7879d..4e2027ea41745c447beea3d6ea9eab4897e17d7d 100644 ---- a/lib/module/jest/index.js.map -+++ b/lib/module/jest/index.js.map -@@ -1 +1 @@ --{"version":3,"names":["useImperativeHandle","useRef","useState","Text","TextInput","jsx","_jsx","DEFAULT_ACCESSIBILITY_LABELS","resolveAccessibilityLabels","spy","impl","jest","fn","EMPTY_CARET_RECT","x","y","width","height","EnrichedMarkdownTextInput","ref","defaultValue","onChangeText","onChangeMarkdown","onFocus","onBlur","editable","placeholder","placeholderTextColor","autoFocus","multiline","scrollEnabled","style","testID","accessible","accessibilityLabel","accessibilityHint","accessibilityRole","accessibilityState","nativeID","markdownStyle","_markdownStyle","cursorColor","_cursorColor","selectionColor","_selectionColor","autoCapitalize","_autoCapitalize","onChangeSelection","_onChangeSelection","onChangeState","_onChangeState","onKeyPress","_onKeyPress","onCaretRectChange","_onCaretRectChange","onLinkDetected","_onLinkDetected","mentionIndicators","_mentionIndicators","onStartMention","_onStartMention","onChangeMention","_onChangeMention","onEndMention","_onEndMention","contextMenuItems","_contextMenuItems","selectionMenuConfig","_selectionMenuConfig","formatMenuConfig","_formatMenuConfig","linkRegex","_linkRegex","writingDirection","_writingDirection","text","setText","textRef","inputRef","applyText","next","current","handleChangeText","instanceRef","focus","blur","measure","callback","measureInWindow","measureLayout","_relativeToNativeNode","onSuccess","setValue","markdown","setSelection","_start","_end","toggleBold","toggleItalic","toggleUnderline","toggleStrikethrough","toggleSpoiler","toggleHeading","_level","toggleUnorderedList","toggleOrderedList","indentList","outdentList","setLink","_url","insertLink","_text","insertText","insertMention","_displayText","startMention","_indicator","removeLink","copyToClipboard","getMarkdown","Promise","resolve","getCaretRect","value","INLINE_FMT_RE","LINK_RE","TASK_ITEM_RE","stripInlineFormatting","replace","splitByPattern","segment","regex","renderMatch","parts","lastIndex","match","exec","index","push","slice","length","applyTransform","children","transformFn","flatMap","child","createLinkTransform","onLinkPress","onLinkLongPress","keyCounter","linkText","url","onPress","onLongPress","undefined","createTaskListTransform","onTaskListItemPress","itemIndex","checked","currentIndex","buildChildren","opts","String","transforms","filter","t","transform","EnrichedMarkdownText","containerStyle","enableLinkPreview","_enableLinkPreview","selectable","_selectable","md4cFlags","_md4cFlags","allowFontScaling","_allowFontScaling","maxFontSizeMultiplier","_maxFontSizeMultiplier","allowTrailingMargin","_allowTrailingMargin","flavor","_flavor","streamingAnimation","_streamingAnimation","streamingConfig","_streamingConfig","spoilerOverlay","_spoilerOverlay","imageRequestHeaders","_imageRequestHeaders","accessibilityLabels","_accessibilityLabels","selectionHandleColor","_selectionHandleColor","textBreakStrategy","_textBreakStrategy","lineBreakStrategyIOS","_lineBreakStrategyIOS"],"sourceRoot":"../../../src","sources":["jest/index.tsx"],"mappings":"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","ignoreList":[]} -+{"version":3,"names":["useImperativeHandle","useRef","useState","Text","TextInput","jsx","_jsx","DEFAULT_ACCESSIBILITY_LABELS","resolveAccessibilityLabels","spy","impl","jest","fn","EMPTY_CARET_RECT","x","y","width","height","EnrichedMarkdownTextInput","ref","defaultValue","onChangeText","onChangeMarkdown","onFocus","onBlur","editable","placeholder","placeholderTextColor","autoFocus","multiline","scrollEnabled","style","testID","accessible","accessibilityLabel","accessibilityHint","accessibilityRole","accessibilityState","nativeID","markdownStyle","_markdownStyle","cursorColor","_cursorColor","selectionColor","_selectionColor","autoCapitalize","_autoCapitalize","onChangeSelection","_onChangeSelection","onChangeState","_onChangeState","onKeyPress","_onKeyPress","onCaretRectChange","_onCaretRectChange","onLinkDetected","_onLinkDetected","mentionIndicators","_mentionIndicators","onStartMention","_onStartMention","onChangeMention","_onChangeMention","onEndMention","_onEndMention","contextMenuItems","_contextMenuItems","selectionMenuConfig","_selectionMenuConfig","formatMenuConfig","_formatMenuConfig","linkRegex","_linkRegex","writingDirection","_writingDirection","text","setText","textRef","inputRef","applyText","next","current","handleChangeText","instanceRef","focus","blur","measure","callback","measureInWindow","measureLayout","_relativeToNativeNode","onSuccess","setValue","markdown","setSelection","_start","_end","toggleBold","toggleItalic","toggleUnderline","toggleStrikethrough","toggleSpoiler","toggleHeading","_level","toggleUnorderedList","toggleOrderedList","indentList","outdentList","setLink","_url","insertLink","_text","insertText","insertMention","_displayText","startMention","_indicator","removeLink","copyToClipboard","getMarkdown","Promise","resolve","getCaretRect","value","INLINE_FMT_RE","LINK_RE","TASK_ITEM_RE","stripInlineFormatting","replace","splitByPattern","segment","regex","renderMatch","parts","lastIndex","match","exec","index","push","slice","length","applyTransform","children","transformFn","flatMap","child","createLinkTransform","onLinkPress","onLinkLongPress","keyCounter","linkText","url","onPress","onLongPress","undefined","createTaskListTransform","onTaskListItemPress","itemIndex","checked","currentIndex","buildChildren","opts","String","transforms","filter","t","transform","EnrichedMarkdownText","containerStyle","enableLinkPreview","_enableLinkPreview","selectable","_selectable","md4cFlags","_md4cFlags","allowFontScaling","_allowFontScaling","maxFontSizeMultiplier","_maxFontSizeMultiplier","allowTrailingMargin","_allowTrailingMargin","flavor","_flavor","streamingAnimation","_streamingAnimation","streamingConfig","_streamingConfig","spoilerOverlay","_spoilerOverlay","imageRequestHeaders","_imageRequestHeaders","resolveImageSource","_resolveImageSource","accessibilityLabels","_accessibilityLabels","selectionHandleColor","_selectionHandleColor","textBreakStrategy","_textBreakStrategy","lineBreakStrategyIOS","_lineBreakStrategyIOS"],"sourceRoot":"../../../src","sources":["jest/index.tsx"],"mappings":"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","ignoreList":[]} -diff --git a/lib/module/linkVariantUtils.js b/lib/module/linkVariantUtils.js -index 8e758d18d34ea308c180bfa822ea8eed3ca450f6..2f3c050db6e974b42087d264ad408325af73fa71 100644 ---- a/lib/module/linkVariantUtils.js -+++ b/lib/module/linkVariantUtils.js -@@ -25,4 +25,19 @@ export function normalizeLinkVariantEntries(linkVariants) { - return true; - }); - } -+ -+/** Native pill geometry is finite and nonnegative before crossing codegen. */ -+export function normalizeLinkPillStyle(style) { -+ const dimension = (value, fallback) => value === undefined || !Number.isFinite(value) ? fallback : Math.max(0, value); -+ return { -+ pill: style.pill ?? false, -+ label: style.label ?? '', -+ iconUri: style.iconUri ?? '', -+ borderRadius: dimension(style.borderRadius, 8), -+ paddingHorizontal: dimension(style.paddingHorizontal, 6), -+ paddingVertical: dimension(style.paddingVertical, 2), -+ borderWidth: dimension(style.borderWidth, 0), -+ maxWidth: dimension(style.maxWidth, 0) -+ }; -+} - //# sourceMappingURL=linkVariantUtils.js.map -\ No newline at end of file -diff --git a/lib/module/linkVariantUtils.js.map b/lib/module/linkVariantUtils.js.map -index 05d599bd7d2e3e6f9917dab29f2c35b8acc58b0b..dd6409335c09860ac08e9c5759d08554aba2dc60 100644 ---- a/lib/module/linkVariantUtils.js.map -+++ b/lib/module/linkVariantUtils.js.map -@@ -1 +1 @@ --{"version":3,"names":["UNSAFE_LOOKBEHIND_RE","warnAboutUnsafePattern","pattern","test","console","warn","normalizeLinkVariantEntries","linkVariants","Object","entries","sort","a","b","length","filter","RegExp","__DEV__"],"sourceRoot":"../../src","sources":["linkVariantUtils.ts"],"mappings":";;AAIA;AACA;AACA;AACA,MAAMA,oBAAoB,GAAG,WAAW;AAExC,SAASC,sBAAsBA,CAACC,OAAe,EAAQ;EACrD,IAAIF,oBAAoB,CAACG,IAAI,CAACD,OAAO,CAAC,EAAE;IACtCE,OAAO,CAACC,IAAI,CACV,yCAAyCH,OAAO,kDAAkD,GAChG,oFAAoF,GACpF,2DACJ,CAAC;EACH;AACF;AAEA,OAAO,SAASI,2BAA2BA,CACzCC,YAA+C,EAC3B;EACpB,OAAOC,MAAM,CAACC,OAAO,CAACF,YAAY,IAAI,CAAC,CAAC,CAAC,CACtCG,IAAI,CAAC,CAAC,CAACC,CAAC,CAAC,EAAE,CAACC,CAAC,CAAC,KAAKA,CAAC,CAACC,MAAM,GAAGF,CAAC,CAACE,MAAM,CAAC,CACvCC,MAAM,CAAC,CAAC,CAACZ,OAAO,CAAC,KAAK;IACrB,IAAI;MACFa,MAAM,CAACb,OAAO,CAAC;IACjB,CAAC,CAAC,MAAM;MACN,IAAIc,OAAO,EAAE;QACXZ,OAAO,CAACC,IAAI,CACV,yCAAyCH,OAAO,6CAClD,CAAC;MACH;MACA,OAAO,KAAK;IACd;IAEA,IAAIc,OAAO,EAAE;MACXf,sBAAsB,CAACC,OAAO,CAAC;IACjC;IACA,OAAO,IAAI;EACb,CAAC,CAAC;AACN","ignoreList":[]} -+{"version":3,"names":["UNSAFE_LOOKBEHIND_RE","warnAboutUnsafePattern","pattern","test","console","warn","normalizeLinkVariantEntries","linkVariants","Object","entries","sort","a","b","length","filter","RegExp","__DEV__","normalizeLinkPillStyle","style","dimension","value","fallback","undefined","Number","isFinite","Math","max","pill","label","iconUri","borderRadius","paddingHorizontal","paddingVertical","borderWidth","maxWidth"],"sourceRoot":"../../src","sources":["linkVariantUtils.ts"],"mappings":";;AAIA;AACA;AACA;AACA,MAAMA,oBAAoB,GAAG,WAAW;AAExC,SAASC,sBAAsBA,CAACC,OAAe,EAAQ;EACrD,IAAIF,oBAAoB,CAACG,IAAI,CAACD,OAAO,CAAC,EAAE;IACtCE,OAAO,CAACC,IAAI,CACV,yCAAyCH,OAAO,kDAAkD,GAChG,oFAAoF,GACpF,2DACJ,CAAC;EACH;AACF;AAEA,OAAO,SAASI,2BAA2BA,CACzCC,YAA+C,EAC3B;EACpB,OAAOC,MAAM,CAACC,OAAO,CAACF,YAAY,IAAI,CAAC,CAAC,CAAC,CACtCG,IAAI,CAAC,CAAC,CAACC,CAAC,CAAC,EAAE,CAACC,CAAC,CAAC,KAAKA,CAAC,CAACC,MAAM,GAAGF,CAAC,CAACE,MAAM,CAAC,CACvCC,MAAM,CAAC,CAAC,CAACZ,OAAO,CAAC,KAAK;IACrB,IAAI;MACFa,MAAM,CAACb,OAAO,CAAC;IACjB,CAAC,CAAC,MAAM;MACN,IAAIc,OAAO,EAAE;QACXZ,OAAO,CAACC,IAAI,CACV,yCAAyCH,OAAO,6CAClD,CAAC;MACH;MACA,OAAO,KAAK;IACd;IAEA,IAAIc,OAAO,EAAE;MACXf,sBAAsB,CAACC,OAAO,CAAC;IACjC;IACA,OAAO,IAAI;EACb,CAAC,CAAC;AACN;;AAEA;AACA,OAAO,SAASe,sBAAsBA,CAACC,KAAuB,EAAE;EAC9D,MAAMC,SAAS,GAAGA,CAACC,KAAyB,EAAEC,QAAgB,KAC5DD,KAAK,KAAKE,SAAS,IAAI,CAACC,MAAM,CAACC,QAAQ,CAACJ,KAAK,CAAC,GAC1CC,QAAQ,GACRI,IAAI,CAACC,GAAG,CAAC,CAAC,EAAEN,KAAK,CAAC;EACxB,OAAO;IACLO,IAAI,EAAET,KAAK,CAACS,IAAI,IAAI,KAAK;IACzBC,KAAK,EAAEV,KAAK,CAACU,KAAK,IAAI,EAAE;IACxBC,OAAO,EAAEX,KAAK,CAACW,OAAO,IAAI,EAAE;IAC5BC,YAAY,EAAEX,SAAS,CAACD,KAAK,CAACY,YAAY,EAAE,CAAC,CAAC;IAC9CC,iBAAiB,EAAEZ,SAAS,CAACD,KAAK,CAACa,iBAAiB,EAAE,CAAC,CAAC;IACxDC,eAAe,EAAEb,SAAS,CAACD,KAAK,CAACc,eAAe,EAAE,CAAC,CAAC;IACpDC,WAAW,EAAEd,SAAS,CAACD,KAAK,CAACe,WAAW,EAAE,CAAC,CAAC;IAC5CC,QAAQ,EAAEf,SAAS,CAACD,KAAK,CAACgB,QAAQ,EAAE,CAAC;EACvC,CAAC;AACH","ignoreList":[]} -diff --git a/lib/module/mediaSlotState.js b/lib/module/mediaSlotState.js -new file mode 100644 -index 0000000000000000000000000000000000000000..6b4693fb44451c0a0c8efc7bcc2a6e30b6521a1d ---- /dev/null -+++ b/lib/module/mediaSlotState.js -@@ -0,0 +1,22 @@ -+"use strict"; -+ -+export const sameMediaSize = (a, b) => Math.abs(a - b) < 0.5; -+ -+/** Accept only finite native frames with usable widths. */ -+export const validMediaFrames = frames => frames.filter(({ -+ x, -+ y, -+ width, -+ height -+}) => [x, y, width, height].every(Number.isFinite) && width > 0 && height >= 0); -+ -+/** A width change requires React to measure again before native uses the height. */ -+export const mediaOverrideForFrame = (id, frame, measurement) => frame && measurement && sameMediaSize(frame.width, measurement.width) ? measurement : { -+ id, -+ width: 0, -+ height: 1 -+}; -+ -+/** Reject stale onLayout callbacks and suppress subpixel feedback loops. */ -+export const acceptMediaMeasurement = (eventRevision, revision, frame, next, previous) => eventRevision === revision && !!frame && Number.isFinite(next.width) && Number.isFinite(next.height) && next.width > 0 && next.height >= 0 && sameMediaSize(frame.width, next.width) && (!previous || !sameMediaSize(previous.width, next.width) || !sameMediaSize(previous.height, next.height)); -+//# sourceMappingURL=mediaSlotState.js.map -\ No newline at end of file -diff --git a/lib/module/mediaSlotState.js.map b/lib/module/mediaSlotState.js.map -new file mode 100644 -index 0000000000000000000000000000000000000000..1a7a4bacc98f8e187a3259408fe628f2121118cc ---- /dev/null -+++ b/lib/module/mediaSlotState.js.map -@@ -0,0 +1 @@ -+{"version":3,"names":["sameMediaSize","a","b","Math","abs","validMediaFrames","frames","filter","x","y","width","height","every","Number","isFinite","mediaOverrideForFrame","id","frame","measurement","acceptMediaMeasurement","eventRevision","revision","next","previous"],"sourceRoot":"../../src","sources":["mediaSlotState.ts"],"mappings":";;AAQA,OAAO,MAAMA,aAAa,GAAGA,CAACC,CAAS,EAAEC,CAAS,KAAKC,IAAI,CAACC,GAAG,CAACH,CAAC,GAAGC,CAAC,CAAC,GAAG,GAAG;;AAE5E;AACA,OAAO,MAAMG,gBAAgB,GAC3BC,MAAqC,IAErCA,MAAM,CAACC,MAAM,CACX,CAAC;EAAEC,CAAC;EAAEC,CAAC;EAAEC,KAAK;EAAEC;AAAO,CAAC,KACtB,CAACH,CAAC,EAAEC,CAAC,EAAEC,KAAK,EAAEC,MAAM,CAAC,CAACC,KAAK,CAACC,MAAM,CAACC,QAAQ,CAAC,IAAIJ,KAAK,GAAG,CAAC,IAAIC,MAAM,IAAI,CAC3E,CAAC;;AAEH;AACA,OAAO,MAAMI,qBAAqB,GAAGA,CACnCC,EAAU,EACVC,KAAqC,EACrCC,WAAyC,KAEzCD,KAAK,IAAIC,WAAW,IAAIlB,aAAa,CAACiB,KAAK,CAACP,KAAK,EAAEQ,WAAW,CAACR,KAAK,CAAC,GACjEQ,WAAW,GACX;EAAEF,EAAE;EAAEN,KAAK,EAAE,CAAC;EAAEC,MAAM,EAAE;AAAE,CAAC;;AAEjC;AACA,OAAO,MAAMQ,sBAAsB,GAAGA,CACpCC,aAAqB,EACrBC,QAAgB,EAChBJ,KAAqC,EACrCK,IAAsB,EACtBC,QAAsC,KAEtCH,aAAa,KAAKC,QAAQ,IAC1B,CAAC,CAACJ,KAAK,IACPJ,MAAM,CAACC,QAAQ,CAACQ,IAAI,CAACZ,KAAK,CAAC,IAC3BG,MAAM,CAACC,QAAQ,CAACQ,IAAI,CAACX,MAAM,CAAC,IAC5BW,IAAI,CAACZ,KAAK,GAAG,CAAC,IACdY,IAAI,CAACX,MAAM,IAAI,CAAC,IAChBX,aAAa,CAACiB,KAAK,CAACP,KAAK,EAAEY,IAAI,CAACZ,KAAK,CAAC,KACrC,CAACa,QAAQ,IACR,CAACvB,aAAa,CAACuB,QAAQ,CAACb,KAAK,EAAEY,IAAI,CAACZ,KAAK,CAAC,IAC1C,CAACV,aAAa,CAACuB,QAAQ,CAACZ,MAAM,EAAEW,IAAI,CAACX,MAAM,CAAC,CAAC","ignoreList":[]} -diff --git a/lib/module/native/EnrichedMarkdownText.js b/lib/module/native/EnrichedMarkdownText.js -index ab5f4a794bac16e8e8a6ca9fba753cadf17e0532..c37db5a374fed3de6b661c6fd5f2dd4ca5e7594c 100644 ---- a/lib/module/native/EnrichedMarkdownText.js -+++ b/lib/module/native/EnrichedMarkdownText.js -@@ -1,12 +1,15 @@ - "use strict"; - -+import { StyleSheet, View } from 'react-native'; -+import { useMediaSlots } from "./useMediaSlots.js"; - import { useMemo, useCallback, useRef, useEffect } from 'react'; - import EnrichedMarkdownTextNativeComponent from '../EnrichedMarkdownTextNativeComponent'; - import EnrichedMarkdownNativeComponent from '../EnrichedMarkdownNativeComponent'; -+import { toNativeTextLinkRegexConfig } from "../utils/regexParser.js"; - import { normalizeMarkdownStyle } from '../normalizeMarkdownStyle'; - import { resolveAccessibilityLabels } from "../accessibilityLabelDefaults.js"; - import { normalizeMenuItem, normalizeLegacyBooleanMenuItem } from "../normalizeMenuItem.js"; --import { jsx as _jsx } from "react/jsx-runtime"; -+import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; - // Default English labels for the built-in selection menu actions. Defaults are - // resolved here (JS-side) so the native code always receives a concrete string. - const DEFAULT_COPY_LABEL = 'Copy'; -@@ -68,11 +71,16 @@ const defaultMd4cFlags = { - }; - export const EnrichedMarkdownText = ({ - markdown, -+ linkRegex: _linkRegex, -+ inlineCodeLinkRegex: _inlineCodeLinkRegex, - markdownStyle = {}, - containerStyle, - onLinkPress, - onLinkLongPress, - onImagePress, -+ renderMedia, -+ resolveImageSource, -+ onDocumentAssets, - onTaskListItemPress, - enableTaskListItemToggle = true, - onCopyPress, -@@ -102,6 +110,8 @@ export const EnrichedMarkdownText = ({ - ellipsizeMode, - ...rest - }) => { -+ const linkRegex = useMemo(() => toNativeTextLinkRegexConfig(_linkRegex), [_linkRegex]); -+ const inlineCodeLinkRegex = useMemo(() => toNativeTextLinkRegexConfig(_inlineCodeLinkRegex), [_inlineCodeLinkRegex]); - const normalizedStyleRef = useRef(null); - const normalized = normalizeMarkdownStyle(markdownStyle); - // normalizeMarkdownStyle returns cached objects for structurally equal inputs, -@@ -253,6 +263,8 @@ export const EnrichedMarkdownText = ({ - const resolvedAccessibilityLabels = useMemo(() => resolveAccessibilityLabels(accessibilityLabels), [accessibilityLabels]); - const sharedProps = { - markdown, -+ linkRegex, -+ inlineCodeLinkRegex, - markdownStyle: normalizedStyle, - onLinkPress: handleLinkPress, - onLinkLongPress: handleLinkLongPress, -@@ -290,9 +302,27 @@ export const EnrichedMarkdownText = ({ - ellipsizeMode, - ...rest - }; -+ -+ // Include native recognition configs when composed with the optional text -+ // recognition API. Asset revisions must follow all parser inputs. -+ const nativeParserProps = sharedProps; -+ const media = useMediaSlots(markdown, JSON.stringify([normalizedMd4cFlags, streamingAnimation, normalizedStreamingConfig, flavor, !!renderMedia, !!onDocumentAssets, !!resolveImageSource, nativeParserProps.linkRegex, nativeParserProps.inlineCodeLinkRegex]), flavor === 'github' ? renderMedia : undefined, flavor === 'github' ? onDocumentAssets : undefined, flavor === 'github' ? resolveImageSource : undefined); - if (flavor === 'github') { -+ if (renderMedia) { -+ return /*#__PURE__*/_jsxs(View, { -+ style: containerStyle, -+ onLayout: rest.onLayout, -+ children: [/*#__PURE__*/_jsx(EnrichedMarkdownNativeComponent, { -+ ...sharedProps, -+ ...media.nativeProps, -+ style: mediaStyles.native, -+ onLayout: media.onNativeLayout -+ }), media.slots] -+ }); -+ } - return /*#__PURE__*/_jsx(EnrichedMarkdownNativeComponent, { -- ...sharedProps -+ ...sharedProps, -+ ...media.nativeProps - }); - } - return /*#__PURE__*/_jsx(EnrichedMarkdownTextNativeComponent, { -@@ -300,4 +330,9 @@ export const EnrichedMarkdownText = ({ - }); - }; - export default EnrichedMarkdownText; -+const mediaStyles = StyleSheet.create({ -+ native: { -+ alignSelf: 'stretch' -+ } -+}); - //# sourceMappingURL=EnrichedMarkdownText.js.map -\ No newline at end of file -diff --git a/lib/module/native/EnrichedMarkdownText.js.map b/lib/module/native/EnrichedMarkdownText.js.map -index 5f02ffeff3e46cb58659f2ddaa5d6580af1c3367..5b66c8eb5068fa32edca4a10cef9686e3889216a 100644 ---- a/lib/module/native/EnrichedMarkdownText.js.map -+++ b/lib/module/native/EnrichedMarkdownText.js.map -@@ -1 +1 @@ --{"version":3,"names":["useMemo","useCallback","useRef","useEffect","EnrichedMarkdownTextNativeComponent","EnrichedMarkdownNativeComponent","normalizeMarkdownStyle","resolveAccessibilityLabels","normalizeMenuItem","normalizeLegacyBooleanMenuItem","jsx","_jsx","DEFAULT_COPY_LABEL","DEFAULT_COPY_AS_MARKDOWN_LABEL","DEFAULT_COPY_IMAGE_URL_LABEL","DEFAULT_COPY_IMAGE_URLS_LABEL","buildPluralTemplates","pluralLabels","singularLabel","IntlRef","Intl","PluralRules","pluralRules","other","byCategory","zero","one","two","few","many","templates","n","push","select","defaultMd4cFlags","underline","superscript","subscript","latexMath","highlight","hardSoftBreaks","preserveBlankLines","admonitions","EnrichedMarkdownText","markdown","markdownStyle","containerStyle","onLinkPress","onLinkLongPress","onImagePress","onTaskListItemPress","enableTaskListItemToggle","onCopyPress","onLatexError","onCodeBlockPress","enableBlockContextMenu","enableLinkPreview","selectable","md4cFlags","allowFontScaling","maxFontSizeMultiplier","allowTrailingMargin","flavor","streamingAnimation","streamingConfig","spoilerOverlay","contextMenuItems","imageRequestHeaders","selectionMenuConfig","accessibilityLabels","selectionColor","selectionHandleColor","textBreakStrategy","lineBreakStrategyIOS","writingDirection","numberOfLines","ellipsizeMode","rest","normalizedStyleRef","normalized","current","normalizedStyle","normalizedMd4cFlags","contextMenuCallbacksRef","Map","callbacksMap","item","set","text","onPress","nativeContextMenuItems","filter","visible","map","icon","nativeImageRequestHeaders","Object","entries","name","value","sort","a","b","undefined","handleContextMenuItemPress","e","itemText","selectedText","selectionStart","selectionEnd","nativeEvent","callback","get","selection","start","end","handleLinkPress","url","handleLinkLongPress","handleImagePress","altText","handleTaskListItemPress","index","checked","handleCopyPress","code","language","handleLatexError","source","message","displayMode","handleCodeBlockPress","tableMode","codeBlockMode","normalizedStreamingConfig","normalizedSelectionMenuConfig","config","copy","copyAsMarkdown","copyImageUrl","enabled","copyLabel","label","copyAsMarkdownLabel","copyImageUrlLabel","copyImageUrlsLabel","copyImageUrlPluralTemplates","resolvedAccessibilityLabels","sharedProps","enableImagePress","enableCodeBlockPress","isGFM","style","onContextMenuItemPress"],"sourceRoot":"../../../src","sources":["native/EnrichedMarkdownText.tsx"],"mappings":"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","ignoreList":[]} -+{"version":3,"names":["StyleSheet","View","useMediaSlots","useMemo","useCallback","useRef","useEffect","EnrichedMarkdownTextNativeComponent","EnrichedMarkdownNativeComponent","toNativeTextLinkRegexConfig","normalizeMarkdownStyle","resolveAccessibilityLabels","normalizeMenuItem","normalizeLegacyBooleanMenuItem","jsx","_jsx","jsxs","_jsxs","DEFAULT_COPY_LABEL","DEFAULT_COPY_AS_MARKDOWN_LABEL","DEFAULT_COPY_IMAGE_URL_LABEL","DEFAULT_COPY_IMAGE_URLS_LABEL","buildPluralTemplates","pluralLabels","singularLabel","IntlRef","Intl","PluralRules","pluralRules","other","byCategory","zero","one","two","few","many","templates","n","push","select","defaultMd4cFlags","underline","superscript","subscript","latexMath","highlight","hardSoftBreaks","preserveBlankLines","admonitions","EnrichedMarkdownText","markdown","linkRegex","_linkRegex","inlineCodeLinkRegex","_inlineCodeLinkRegex","markdownStyle","containerStyle","onLinkPress","onLinkLongPress","onImagePress","renderMedia","resolveImageSource","onDocumentAssets","onTaskListItemPress","enableTaskListItemToggle","onCopyPress","onLatexError","onCodeBlockPress","enableBlockContextMenu","enableLinkPreview","selectable","md4cFlags","allowFontScaling","maxFontSizeMultiplier","allowTrailingMargin","flavor","streamingAnimation","streamingConfig","spoilerOverlay","contextMenuItems","imageRequestHeaders","selectionMenuConfig","accessibilityLabels","selectionColor","selectionHandleColor","textBreakStrategy","lineBreakStrategyIOS","writingDirection","numberOfLines","ellipsizeMode","rest","normalizedStyleRef","normalized","current","normalizedStyle","normalizedMd4cFlags","contextMenuCallbacksRef","Map","callbacksMap","item","set","text","onPress","nativeContextMenuItems","filter","visible","map","icon","nativeImageRequestHeaders","Object","entries","name","value","sort","a","b","undefined","handleContextMenuItemPress","e","itemText","selectedText","selectionStart","selectionEnd","nativeEvent","callback","get","selection","start","end","handleLinkPress","url","handleLinkLongPress","handleImagePress","altText","handleTaskListItemPress","index","checked","handleCopyPress","code","language","handleLatexError","source","message","displayMode","handleCodeBlockPress","tableMode","codeBlockMode","normalizedStreamingConfig","normalizedSelectionMenuConfig","config","copy","copyAsMarkdown","copyImageUrl","enabled","copyLabel","label","copyAsMarkdownLabel","copyImageUrlLabel","copyImageUrlsLabel","copyImageUrlPluralTemplates","resolvedAccessibilityLabels","sharedProps","enableImagePress","enableCodeBlockPress","isGFM","style","onContextMenuItemPress","nativeParserProps","media","JSON","stringify","onLayout","children","nativeProps","mediaStyles","native","onNativeLayout","slots","create","alignSelf"],"sourceRoot":"../../../src","sources":["native/EnrichedMarkdownText.tsx"],"mappings":"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","ignoreList":[]} -diff --git a/lib/module/native/useImageSources.js b/lib/module/native/useImageSources.js -new file mode 100644 -index 0000000000000000000000000000000000000000..d1a3999db1e1b4c089326f6d0f186f7a91055b82 ---- /dev/null -+++ b/lib/module/native/useImageSources.js -@@ -0,0 +1,24 @@ -+"use strict"; -+ -+import { useEffect, useRef, useState } from 'react'; -+import { ImageSourceState } from "../imageSourceState.js"; -+export function useImageSources(resolver, continuityStart, assetsRevision, assets) { -+ const state = useRef(undefined); -+ if (!state.current) state.current = new ImageSourceState(); -+ const current = state.current; -+ const [, refresh] = useState(0); -+ current.configure(resolver, continuityStart, assets); -+ // Reconcile after every commit. Configure deduplicates layout-only renders. -+ useEffect(() => { -+ current.configure(resolver, continuityStart, assets); -+ current.start(() => refresh(value => value + 1)); -+ }); -+ useEffect(() => () => current.stop(), [current]); -+ return { -+ enableImageSourceResolution: !!resolver, -+ imageSourcesContinuityStart: resolver ? continuityStart : 1, -+ imageSourcesRevision: resolver ? assetsRevision : -1, -+ imageSources: current.sources() -+ }; -+} -+//# sourceMappingURL=useImageSources.js.map -\ No newline at end of file -diff --git a/lib/module/native/useImageSources.js.map b/lib/module/native/useImageSources.js.map -new file mode 100644 -index 0000000000000000000000000000000000000000..79366ad6f065cbaac348f00d8c66cd677820ccef ---- /dev/null -+++ b/lib/module/native/useImageSources.js.map -@@ -0,0 +1 @@ -+{"version":3,"names":["useEffect","useRef","useState","ImageSourceState","useImageSources","resolver","continuityStart","assetsRevision","assets","state","undefined","current","refresh","configure","start","value","stop","enableImageSourceResolution","imageSourcesContinuityStart","imageSourcesRevision","imageSources","sources"],"sourceRoot":"../../../src","sources":["native/useImageSources.ts"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AACnD,SAASC,gBAAgB,QAAQ,wBAAqB;AAItD,OAAO,SAASC,eAAeA,CAC7BC,QAAyD,EACzDC,eAAuB,EACvBC,cAAsB,EACtBC,MAA0B,EAC1B;EACA,MAAMC,KAAK,GAAGR,MAAM,CAA+BS,SAAS,CAAC;EAC7D,IAAI,CAACD,KAAK,CAACE,OAAO,EAAEF,KAAK,CAACE,OAAO,GAAG,IAAIR,gBAAgB,CAAC,CAAC;EAC1D,MAAMQ,OAAO,GAAGF,KAAK,CAACE,OAAO;EAC7B,MAAM,GAAGC,OAAO,CAAC,GAAGV,QAAQ,CAAC,CAAC,CAAC;EAC/BS,OAAO,CAACE,SAAS,CAACR,QAAQ,EAAEC,eAAe,EAAEE,MAAM,CAAC;EACpD;EACAR,SAAS,CAAC,MAAM;IACdW,OAAO,CAACE,SAAS,CAACR,QAAQ,EAAEC,eAAe,EAAEE,MAAM,CAAC;IACpDG,OAAO,CAACG,KAAK,CAAC,MAAMF,OAAO,CAAEG,KAAK,IAAKA,KAAK,GAAG,CAAC,CAAC,CAAC;EACpD,CAAC,CAAC;EACFf,SAAS,CAAC,MAAM,MAAMW,OAAO,CAACK,IAAI,CAAC,CAAC,EAAE,CAACL,OAAO,CAAC,CAAC;EAChD,OAAO;IACLM,2BAA2B,EAAE,CAAC,CAACZ,QAAQ;IACvCa,2BAA2B,EAAEb,QAAQ,GAAGC,eAAe,GAAG,CAAC;IAC3Da,oBAAoB,EAAEd,QAAQ,GAAGE,cAAc,GAAG,CAAC,CAAC;IACpDa,YAAY,EAAET,OAAO,CAACU,OAAO,CAAC;EAChC,CAAC;AACH","ignoreList":[]} -diff --git a/lib/module/native/useMediaSlots.js b/lib/module/native/useMediaSlots.js -new file mode 100644 -index 0000000000000000000000000000000000000000..f149720cf0d0aea874ea2c8e1eb341dc07377e93 ---- /dev/null -+++ b/lib/module/native/useMediaSlots.js -@@ -0,0 +1,203 @@ -+"use strict"; -+ -+import { useRef, useState } from 'react'; -+import { useImageSources } from "./useImageSources.js"; -+import { StyleSheet, View } from 'react-native'; -+import { acceptMediaMeasurement, mediaOverrideForFrame, sameMediaSize, validMediaFrames } from "../mediaSlotState.js"; -+import { jsx as _jsx } from "react/jsx-runtime"; -+const stripAnchor = ({ -+ anchor: _anchor, -+ ...asset -+}) => asset; -+const identity = asset => JSON.stringify([asset.id, asset.kind, asset.url, asset.anchor, asset.eligible]); -+const identities = assets => Object.fromEntries(assets.map(asset => [asset.id, identity(asset)])); -+export function useMediaSlots(markdown, parserKey, renderMedia, onDocumentAssets, resolveImageSource) { -+ const document = useRef({ -+ markdown, -+ parserKey, -+ revision: 1, -+ continuityStart: 1, -+ generation: 0 -+ }); -+ if (document.current.markdown !== markdown || document.current.parserKey !== parserKey) { -+ const previous = document.current; -+ const append = previous.parserKey === parserKey && previous.markdown.length > 0 && markdown.length > previous.markdown.length && markdown.startsWith(previous.markdown); -+ document.current = { -+ markdown, -+ parserKey, -+ revision: previous.revision + 1, -+ continuityStart: append ? previous.continuityStart : previous.revision + 1, -+ generation: previous.generation + (append ? 0 : 1) -+ }; -+ } -+ const { -+ revision, -+ continuityStart, -+ generation -+ } = document.current; -+ const [manifest, setManifest] = useState(); -+ const acceptedManifest = useRef(undefined); -+ const [layout, setLayout] = useState(); -+ const latestLayout = useRef(undefined); -+ const pendingLayout = useRef(undefined); -+ const [origin, setOrigin] = useState({ -+ x: 0, -+ y: 0 -+ }); -+ const [measurements, setMeasurements] = useState({}); -+ const reported = useRef(-1); -+ // Only uninterrupted appends with identical parser inputs retain prior data. -+ // Native revalidates each carried decision against the newly accepted AST. -+ const assets = manifest && manifest.revision >= continuityStart ? manifest.assets : []; -+ const frames = layout && layout.revision >= continuityStart ? layout.frames : []; -+ const frameForAsset = asset => layout?.identities[asset.id] === identity(asset) ? frames.find(entry => entry.id === asset.id) : undefined; -+ const rendered = assets.flatMap(asset => { -+ if (asset.kind === 'link' || !asset.eligible || !renderMedia) return []; -+ const content = renderMedia(stripAnchor(asset)); -+ if (content == null || typeof content === 'boolean') return []; -+ return [{ -+ asset, -+ content -+ }]; -+ }); -+ const imageSources = useImageSources(resolveImageSource, continuityStart, manifest && manifest.revision >= continuityStart ? manifest.revision : -1, assets.filter(asset => asset.kind === 'image' && !rendered.some(entry => entry.asset.id === asset.id))); -+ const overrides = rendered.map(({ -+ asset -+ }) => { -+ const measurement = measurements[asset.id]; -+ const box = mediaOverrideForFrame(asset.id, frameForAsset(asset), measurement?.identity === identity(asset) && measurement.generation === generation ? measurement : undefined); -+ return { -+ id: box.id, -+ height: box.height, -+ width: box.width, -+ url: asset.url, -+ kind: asset.kind, -+ anchor: asset.anchor -+ }; -+ }); -+ const onNativeDocumentAssets = event => { -+ if (event.nativeEvent.revision !== document.current.revision) return; -+ const next = event.nativeEvent; -+ acceptedManifest.current = next; -+ setManifest(previous => previous?.revision === next.revision && JSON.stringify(previous.assets) === JSON.stringify(next.assets) ? previous : next); -+ // A frame can arrive before its manifest. Stamp only frames of this exact -+ // revision; older frames keep their original occurrence identities. -+ const received = pendingLayout.current?.revision === next.revision ? pendingLayout.current : latestLayout.current?.revision === next.revision ? latestLayout.current : undefined; -+ if (received) { -+ const updated = { -+ ...received, -+ identities: identities(next.assets) -+ }; -+ latestLayout.current = updated; -+ pendingLayout.current = undefined; -+ setLayout(updated); -+ } -+ if (reported.current !== next.revision) { -+ reported.current = next.revision; -+ onDocumentAssets?.({ -+ revision: next.revision, -+ assets: next.assets.map(stripAnchor) -+ }); -+ } -+ }; -+ const onNativeMediaLayout = event => { -+ const next = event.nativeEvent; -+ if (next.revision !== document.current.revision) return; -+ const valid = validMediaFrames(next.frames); -+ const current = acceptedManifest.current; -+ if (current?.revision !== next.revision) { -+ // Keep mounted slots until the accepted manifest can identify new frames. -+ pendingLayout.current = { -+ revision: next.revision, -+ frames: valid -+ }; -+ return; -+ } -+ const nextLayout = { -+ revision: next.revision, -+ frames: valid, -+ identities: current?.revision === next.revision ? identities(current.assets) : {} -+ }; -+ latestLayout.current = nextLayout; -+ setLayout(previous => { -+ if (previous?.revision === next.revision && JSON.stringify(previous.identities) === JSON.stringify(nextLayout.identities) && previous.frames.length === valid.length && previous.frames.every((frame, index) => { -+ const other = valid[index]; -+ return frame.id === other.id && sameMediaSize(frame.x, other.x) && sameMediaSize(frame.y, other.y) && sameMediaSize(frame.width, other.width) && sameMediaSize(frame.height, other.height); -+ })) return previous; -+ return nextLayout; -+ }); -+ }; -+ const onNativeLayout = ({ -+ nativeEvent -+ }) => { -+ const { -+ x, -+ y -+ } = nativeEvent.layout; -+ setOrigin(previous => sameMediaSize(previous.x, x) && sameMediaSize(previous.y, y) ? previous : { -+ x, -+ y -+ }); -+ }; -+ const onSlotLayout = (asset, frame, event) => { -+ const { -+ width, -+ height -+ } = event.nativeEvent.layout; -+ const next = { -+ id: asset.id, -+ width, -+ height -+ }; -+ setMeasurements(previous => { -+ const current = acceptedManifest.current; -+ const currentAsset = current?.assets.find(entry => entry.id === asset.id); -+ if (!current || current.revision < document.current.continuityStart || !currentAsset || identity(currentAsset) !== identity(asset) || !acceptMediaMeasurement(revision, document.current.revision, pendingLayout.current?.revision === revision ? pendingLayout.current.frames.find(entry => entry.id === frame.id) : latestLayout.current?.identities[asset.id] === identity(asset) && latestLayout.current.revision >= document.current.continuityStart ? latestLayout.current.frames.find(entry => entry.id === frame.id) : undefined, next, previous[asset.id]?.identity === identity(asset) && previous[asset.id]?.generation === generation ? previous[asset.id] : undefined)) return previous; -+ return { -+ ...previous, -+ [asset.id]: { -+ ...next, -+ identity: identity(asset), -+ generation -+ } -+ }; -+ }); -+ }; -+ const slots = rendered.map(({ -+ asset, -+ content -+ }) => { -+ const frame = frameForAsset(asset); -+ if (!frame) return null; -+ return /*#__PURE__*/_jsx(View, { -+ collapsable: false, -+ style: [styles.slot, { -+ left: origin.x + frame.x, -+ top: origin.y + frame.y, -+ width: frame.width -+ }], -+ onLayout: event => onSlotLayout(asset, frame, event), -+ children: content -+ }, `${generation}:${identity(asset)}`); -+ }); -+ return { -+ slots, -+ onNativeLayout, -+ nativeProps: { -+ ...imageSources, -+ documentRevision: revision, -+ enableDocumentAssets: !!renderMedia || !!onDocumentAssets || !!resolveImageSource, -+ enableMediaSlots: !!renderMedia, -+ mediaOverridesRevision: manifest && manifest.revision >= continuityStart ? manifest.revision : -1, -+ mediaOverrides: overrides, -+ onDocumentAssets: onNativeDocumentAssets, -+ onMediaLayout: onNativeMediaLayout -+ } -+ }; -+} -+const styles = StyleSheet.create({ -+ slot: { -+ position: 'absolute' -+ } -+}); -+//# sourceMappingURL=useMediaSlots.js.map -\ No newline at end of file -diff --git a/lib/module/native/useMediaSlots.js.map b/lib/module/native/useMediaSlots.js.map -new file mode 100644 -index 0000000000000000000000000000000000000000..c20941a5e09cbaccb6a0a601b77d38c13f4c59cc ---- /dev/null -+++ b/lib/module/native/useMediaSlots.js.map -@@ -0,0 +1 @@ -+{"version":3,"names":["useRef","useState","useImageSources","StyleSheet","View","acceptMediaMeasurement","mediaOverrideForFrame","sameMediaSize","validMediaFrames","jsx","_jsx","stripAnchor","anchor","_anchor","asset","identity","JSON","stringify","id","kind","url","eligible","identities","assets","Object","fromEntries","map","useMediaSlots","markdown","parserKey","renderMedia","onDocumentAssets","resolveImageSource","document","revision","continuityStart","generation","current","previous","append","length","startsWith","manifest","setManifest","acceptedManifest","undefined","layout","setLayout","latestLayout","pendingLayout","origin","setOrigin","x","y","measurements","setMeasurements","reported","frames","frameForAsset","find","entry","rendered","flatMap","content","imageSources","filter","some","overrides","measurement","box","height","width","onNativeDocumentAssets","event","nativeEvent","next","received","updated","onNativeMediaLayout","valid","nextLayout","every","frame","index","other","onNativeLayout","onSlotLayout","currentAsset","slots","collapsable","style","styles","slot","left","top","onLayout","children","nativeProps","documentRevision","enableDocumentAssets","enableMediaSlots","mediaOverridesRevision","mediaOverrides","onMediaLayout","create","position"],"sourceRoot":"../../../src","sources":["native/useMediaSlots.tsx"],"mappings":"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","ignoreList":[]} -diff --git a/lib/module/normalizeMarkdownStyle.js b/lib/module/normalizeMarkdownStyle.js -index cc43227ba04341f1d1ba7bf0540840ec09fdfe90..5727f6b53d9d89aef7ef8f2f574238fc4970e25d 100644 ---- a/lib/module/normalizeMarkdownStyle.js -+++ b/lib/module/normalizeMarkdownStyle.js -@@ -2,7 +2,7 @@ - - import { Platform } from 'react-native'; - import { isStyleEqual, normalizeColor, mergeSubStyle } from "./styleUtils.js"; --import { normalizeLinkVariantEntries } from "./linkVariantUtils.js"; -+import { normalizeLinkVariantEntries, normalizeLinkPillStyle } from "./linkVariantUtils.js"; - import { resolveAdmonitionColors } from "./admonitionDefaults.js"; - import { DEFAULT_HEADING_FONT_WEIGHT, HEADING_DEFAULTS } from "./headingDefaults.js"; - const getSystemFont = () => Platform.select({ -@@ -362,6 +362,10 @@ export const normalizeMarkdownStyle = style => { - result.linkVariants = normalizeLinkVariantEntries(style.linkVariants).map(([pattern, override]) => { - return { - pattern, -+ ...normalizeLinkPillStyle(override), -+ iconTintColor: normalizeColor(override.iconTintColor), -+ fontFamily: override.fontFamily ?? linkBase.fontFamily, -+ borderColor: normalizeColor(override.borderColor ?? 'transparent') ?? transparent, - color: (override.color ? normalizeColor(override.color) : null) ?? linkBase.color, - underline: override.underline ?? linkBase.underline, - backgroundColor: override.backgroundColor ? normalizeColor(override.backgroundColor) ?? transparent : transparent -diff --git a/lib/module/normalizeMarkdownStyle.js.map b/lib/module/normalizeMarkdownStyle.js.map -index c3114c52abfa69c5ebfca1c4769d055fefd71c92..c016713a564fc9099436d5b9c0f45c99d58f6c5c 100644 ---- a/lib/module/normalizeMarkdownStyle.js.map -+++ b/lib/module/normalizeMarkdownStyle.js.map -@@ -1 +1 @@ --{"version":3,"names":["Platform","isStyleEqual","normalizeColor","mergeSubStyle","normalizeLinkVariantEntries","resolveAdmonitionColors","DEFAULT_HEADING_FONT_WEIGHT","HEADING_DEFAULTS","getSystemFont","select","ios","android","web","default","getMonospaceFont","defaultTextColor","codeBlockTextColor","DEFAULT_CODE_BLOCK_SYNTAX_COLORS","keyword","operatorColor","punctuation","string","number","constant","comment","function","type","variable","property","tag","attribute","embedded","INHERIT_SYNTAX_TOKENS","Set","PUBLIC_SYNTAX_TOKEN_KEYS","baseHeader","fontFamily","fontWeight","marginTop","marginBottom","textAlign","DEFAULT_NORMALIZED_STYLE","Object","freeze","paragraph","fontSize","color","lineHeight","h1","h2","h3","h4","h5","h6","blockquote","borderColor","borderWidth","gapWidth","backgroundColor","borderRadius","padding","admonitions","undefined","list","bulletColor","bulletSize","markerMinWidth","markerColor","markerFontWeight","marginLeft","itemSpacing","codeBlock","syntaxColors","link","underline","linkVariants","strong","em","fontStyle","strikethrough","code","image","height","maxHeight","aspectRatio","resizeMode","video","inlineImage","size","thematicBreak","table","headerFontFamily","headerBackgroundColor","headerTextColor","rowEvenBackgroundColor","rowOddBackgroundColor","cellPaddingHorizontal","cellPaddingVertical","horizontalOverflow","align","math","inlineMath","taskList","checkedColor","checkboxSize","checkboxBorderRadius","checkmarkColor","checkedTextColor","checkedStrikethrough","spoiler","particles","density","speed","solid","superscript","fontScale","baselineOffsetScale","subscript","highlight","refCache","WeakMap","structuralCache","LRU_MAX","styleReferenceKeys","keys","normalizeMarkdownStyle","style","length","refHit","get","structIdx","findIndex","e","entry","splice","unshift","set","result","forEach","key","Array","isArray","userValue","transparent","linkBase","map","pattern","override","listSize","Math","round","paragraphColor","userSyntaxColors","resolvedSyntaxColors","token","publicKey","has","finalResult","pop"],"sourceRoot":"../../src","sources":["normalizeMarkdownStyle.ts"],"mappings":"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","ignoreList":[]} -+{"version":3,"names":["Platform","isStyleEqual","normalizeColor","mergeSubStyle","normalizeLinkVariantEntries","normalizeLinkPillStyle","resolveAdmonitionColors","DEFAULT_HEADING_FONT_WEIGHT","HEADING_DEFAULTS","getSystemFont","select","ios","android","web","default","getMonospaceFont","defaultTextColor","codeBlockTextColor","DEFAULT_CODE_BLOCK_SYNTAX_COLORS","keyword","operatorColor","punctuation","string","number","constant","comment","function","type","variable","property","tag","attribute","embedded","INHERIT_SYNTAX_TOKENS","Set","PUBLIC_SYNTAX_TOKEN_KEYS","baseHeader","fontFamily","fontWeight","marginTop","marginBottom","textAlign","DEFAULT_NORMALIZED_STYLE","Object","freeze","paragraph","fontSize","color","lineHeight","h1","h2","h3","h4","h5","h6","blockquote","borderColor","borderWidth","gapWidth","backgroundColor","borderRadius","padding","admonitions","undefined","list","bulletColor","bulletSize","markerMinWidth","markerColor","markerFontWeight","marginLeft","itemSpacing","codeBlock","syntaxColors","link","underline","linkVariants","strong","em","fontStyle","strikethrough","code","image","height","maxHeight","aspectRatio","resizeMode","video","inlineImage","size","thematicBreak","table","headerFontFamily","headerBackgroundColor","headerTextColor","rowEvenBackgroundColor","rowOddBackgroundColor","cellPaddingHorizontal","cellPaddingVertical","horizontalOverflow","align","math","inlineMath","taskList","checkedColor","checkboxSize","checkboxBorderRadius","checkmarkColor","checkedTextColor","checkedStrikethrough","spoiler","particles","density","speed","solid","superscript","fontScale","baselineOffsetScale","subscript","highlight","refCache","WeakMap","structuralCache","LRU_MAX","styleReferenceKeys","keys","normalizeMarkdownStyle","style","length","refHit","get","structIdx","findIndex","e","entry","splice","unshift","set","result","forEach","key","Array","isArray","userValue","transparent","linkBase","map","pattern","override","iconTintColor","listSize","Math","round","paragraphColor","userSyntaxColors","resolvedSyntaxColors","token","publicKey","has","finalResult","pop"],"sourceRoot":"../../src","sources":["normalizeMarkdownStyle.ts"],"mappings":"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","ignoreList":[]} -diff --git a/lib/module/normalizeMarkdownStyle.web.js b/lib/module/normalizeMarkdownStyle.web.js -index 6d21cbb6caacac946dc65fdce6bc4114b67ad6c1..b06258ab32a008b0cf5d0c43ff9ad7052098ad89 100644 ---- a/lib/module/normalizeMarkdownStyle.web.js -+++ b/lib/module/normalizeMarkdownStyle.web.js -@@ -1,7 +1,7 @@ - "use strict"; - - import { isStyleEqual, mergeSubStyle } from "./styleUtils.js"; --import { normalizeLinkVariantEntries } from "./linkVariantUtils.js"; -+import { normalizeLinkVariantEntries, normalizeLinkPillStyle } from "./linkVariantUtils.js"; - import { resolveAdmonitionColors } from "./admonitionDefaults.js"; - import { DEFAULT_HEADING_FONT_WEIGHT, HEADING_DEFAULTS } from "./headingDefaults.js"; - const SYSTEM_FONT = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'; -@@ -272,6 +272,10 @@ export const normalizeMarkdownStyle = style => { - result.linkVariants = normalizeLinkVariantEntries(style.linkVariants).map(([pattern, override]) => { - return { - pattern, -+ ...normalizeLinkPillStyle(override), -+ iconTintColor: override.iconTintColor, -+ fontFamily: override.fontFamily ?? linkBase.fontFamily, -+ borderColor: override.borderColor ?? 'transparent', - color: override.color ?? linkBase.color, - underline: override.underline ?? linkBase.underline, - backgroundColor: override.backgroundColor ?? 'transparent' -diff --git a/lib/module/normalizeMarkdownStyle.web.js.map b/lib/module/normalizeMarkdownStyle.web.js.map -index 2ea4122d84d61e392aa679d828f4bc2b458d3d23..f3b1bb07fc4ec11790c54f84531421458340ffb7 100644 ---- a/lib/module/normalizeMarkdownStyle.web.js.map -+++ b/lib/module/normalizeMarkdownStyle.web.js.map -@@ -1 +1 @@ --{"version":3,"names":["isStyleEqual","mergeSubStyle","normalizeLinkVariantEntries","resolveAdmonitionColors","DEFAULT_HEADING_FONT_WEIGHT","HEADING_DEFAULTS","SYSTEM_FONT","MONOSPACE_FONT","defaultTextColor","baseHeader","fontFamily","fontWeight","marginTop","marginBottom","textAlign","DEFAULT_NORMALIZED_STYLE","Object","freeze","paragraph","fontSize","color","lineHeight","h1","h2","h3","h4","h5","h6","blockquote","borderColor","borderWidth","gapWidth","backgroundColor","borderRadius","padding","admonitions","undefined","list","bulletColor","bulletSize","markerMinWidth","markerColor","markerFontWeight","marginLeft","itemSpacing","codeBlock","syntaxColors","keyword","operatorColor","punctuation","string","number","constant","comment","function","type","variable","property","tag","attribute","embedded","link","underline","linkVariants","strong","em","fontStyle","strikethrough","code","image","height","maxHeight","aspectRatio","resizeMode","video","inlineImage","size","thematicBreak","table","headerFontFamily","headerBackgroundColor","headerTextColor","rowEvenBackgroundColor","rowOddBackgroundColor","cellPaddingHorizontal","cellPaddingVertical","horizontalOverflow","align","math","inlineMath","taskList","checkedColor","checkboxSize","checkboxBorderRadius","checkmarkColor","checkedTextColor","checkedStrikethrough","spoiler","particles","density","speed","solid","superscript","fontScale","baselineOffsetScale","subscript","highlight","refCache","WeakMap","structuralCache","LRU_MAX","styleReferenceKeys","keys","normalizeMarkdownStyle","style","length","refHit","get","structIdx","findIndex","e","entry","splice","unshift","set","result","forEach","key","Array","isArray","userValue","linkBase","map","pattern","override","listSize","Math","round","paragraphColor","operator","finalResult","pop"],"sourceRoot":"../../src","sources":["normalizeMarkdownStyle.web.ts"],"mappings":"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","ignoreList":[]} -+{"version":3,"names":["isStyleEqual","mergeSubStyle","normalizeLinkVariantEntries","normalizeLinkPillStyle","resolveAdmonitionColors","DEFAULT_HEADING_FONT_WEIGHT","HEADING_DEFAULTS","SYSTEM_FONT","MONOSPACE_FONT","defaultTextColor","baseHeader","fontFamily","fontWeight","marginTop","marginBottom","textAlign","DEFAULT_NORMALIZED_STYLE","Object","freeze","paragraph","fontSize","color","lineHeight","h1","h2","h3","h4","h5","h6","blockquote","borderColor","borderWidth","gapWidth","backgroundColor","borderRadius","padding","admonitions","undefined","list","bulletColor","bulletSize","markerMinWidth","markerColor","markerFontWeight","marginLeft","itemSpacing","codeBlock","syntaxColors","keyword","operatorColor","punctuation","string","number","constant","comment","function","type","variable","property","tag","attribute","embedded","link","underline","linkVariants","strong","em","fontStyle","strikethrough","code","image","height","maxHeight","aspectRatio","resizeMode","video","inlineImage","size","thematicBreak","table","headerFontFamily","headerBackgroundColor","headerTextColor","rowEvenBackgroundColor","rowOddBackgroundColor","cellPaddingHorizontal","cellPaddingVertical","horizontalOverflow","align","math","inlineMath","taskList","checkedColor","checkboxSize","checkboxBorderRadius","checkmarkColor","checkedTextColor","checkedStrikethrough","spoiler","particles","density","speed","solid","superscript","fontScale","baselineOffsetScale","subscript","highlight","refCache","WeakMap","structuralCache","LRU_MAX","styleReferenceKeys","keys","normalizeMarkdownStyle","style","length","refHit","get","structIdx","findIndex","e","entry","splice","unshift","set","result","forEach","key","Array","isArray","userValue","linkBase","map","pattern","override","iconTintColor","listSize","Math","round","paragraphColor","operator","finalResult","pop"],"sourceRoot":"../../src","sources":["normalizeMarkdownStyle.web.ts"],"mappings":"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","ignoreList":[]} -diff --git a/lib/module/types/media.js b/lib/module/types/media.js -new file mode 100644 -index 0000000000000000000000000000000000000000..dab2d1653ce3da767a7baa02bf41cd7f298b05b6 ---- /dev/null -+++ b/lib/module/types/media.js -@@ -0,0 +1,2 @@ -+"use strict"; -+//# sourceMappingURL=media.js.map -\ No newline at end of file -diff --git a/lib/module/types/media.js.map b/lib/module/types/media.js.map -new file mode 100644 -index 0000000000000000000000000000000000000000..005523763c066c72185889ea1013c941e82f911b ---- /dev/null -+++ b/lib/module/types/media.js.map -@@ -0,0 +1 @@ -+{"version":3,"names":[],"sourceRoot":"../../../src","sources":["types/media.ts"],"mappings":"","ignoreList":[]} -diff --git a/lib/module/utils/regexParser.js b/lib/module/utils/regexParser.js -index 6aa8f78d7f4fc0635a0272ee5adf70054950c835..45d748fcfbf75d07c3340e06bd36ad64d3f18d5f 100644 ---- a/lib/module/utils/regexParser.js -+++ b/lib/module/utils/regexParser.js -@@ -40,4 +40,10 @@ export const toNativeRegexConfig = regex => { - isDefault: false - }; - }; -+ -+/** Renderer recognition is opt-in, including when input normalization falls back. */ -+export const toNativeTextLinkRegexConfig = regex => { -+ const config = toNativeRegexConfig(regex ?? null); -+ return config.isDefault ? DISABLED_REGEX : config; -+}; - //# sourceMappingURL=regexParser.js.map -\ No newline at end of file -diff --git a/lib/module/utils/regexParser.js.map b/lib/module/utils/regexParser.js.map -index 4f280570d1deced993a29fd572c36bab9c30f49e..38e490b0258cf3e2e1168b6493b5415f38a89909 100644 ---- a/lib/module/utils/regexParser.js.map -+++ b/lib/module/utils/regexParser.js.map -@@ -1 +1 @@ --{"version":3,"names":["DISABLED_REGEX","pattern","caseInsensitive","dotAll","isDisabled","isDefault","DEFAULT_REGEX","toNativeRegexConfig","regex","undefined","source","hasLookbehind","includes","lookbehindContent","match","test","__DEV__","console","error","ignoreCase"],"sourceRoot":"../../../src","sources":["utils/regexParser.ts"],"mappings":";;AAEA,MAAMA,cAA+B,GAAG;EACtCC,OAAO,EAAE,EAAE;EACXC,eAAe,EAAE,KAAK;EACtBC,MAAM,EAAE,KAAK;EACbC,UAAU,EAAE,IAAI;EAChBC,SAAS,EAAE;AACb,CAAC;AAED,MAAMC,aAA8B,GAAG;EACrCL,OAAO,EAAE,EAAE;EACXC,eAAe,EAAE,KAAK;EACtBC,MAAM,EAAE,KAAK;EACbC,UAAU,EAAE,KAAK;EACjBC,SAAS,EAAE;AACb,CAAC;AAED,OAAO,MAAME,mBAAmB,GAC9BC,KAAgC,IACZ;EACpB,IAAIA,KAAK,KAAK,IAAI,EAAE;IAClB,OAAOR,cAAc;EACvB;EAEA,IAAIQ,KAAK,KAAKC,SAAS,EAAE;IACvB,OAAOH,aAAa;EACtB;EAEA,MAAMI,MAAM,GAAGF,KAAK,CAACE,MAAM;EAE3B,MAAMC,aAAa,GAAGD,MAAM,CAACE,QAAQ,CAAC,MAAM,CAAC,IAAIF,MAAM,CAACE,QAAQ,CAAC,MAAM,CAAC;EAExE,IAAID,aAAa,EAAE;IACjB,MAAME,iBAAiB,GAAGH,MAAM,CAACI,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE;IACrE,IAAI,OAAO,CAACC,IAAI,CAACF,iBAAiB,CAAC,EAAE;MACnC,IAAIG,OAAO,EAAE;QACXC,OAAO,CAACC,KAAK,CACX,yEACF,CAAC;MACH;MAEA,OAAOZ,aAAa;IACtB;EACF;EAEA,OAAO;IACLL,OAAO,EAAES,MAAM;IACfR,eAAe,EAAEM,KAAK,CAACW,UAAU;IACjChB,MAAM,EAAEK,KAAK,CAACL,MAAM;IACpBC,UAAU,EAAE,KAAK;IACjBC,SAAS,EAAE;EACb,CAAC;AACH,CAAC","ignoreList":[]} -+{"version":3,"names":["DISABLED_REGEX","pattern","caseInsensitive","dotAll","isDisabled","isDefault","DEFAULT_REGEX","toNativeRegexConfig","regex","undefined","source","hasLookbehind","includes","lookbehindContent","match","test","__DEV__","console","error","ignoreCase","toNativeTextLinkRegexConfig","config"],"sourceRoot":"../../../src","sources":["utils/regexParser.ts"],"mappings":";;AAEA,MAAMA,cAA+B,GAAG;EACtCC,OAAO,EAAE,EAAE;EACXC,eAAe,EAAE,KAAK;EACtBC,MAAM,EAAE,KAAK;EACbC,UAAU,EAAE,IAAI;EAChBC,SAAS,EAAE;AACb,CAAC;AAED,MAAMC,aAA8B,GAAG;EACrCL,OAAO,EAAE,EAAE;EACXC,eAAe,EAAE,KAAK;EACtBC,MAAM,EAAE,KAAK;EACbC,UAAU,EAAE,KAAK;EACjBC,SAAS,EAAE;AACb,CAAC;AAED,OAAO,MAAME,mBAAmB,GAC9BC,KAAgC,IACZ;EACpB,IAAIA,KAAK,KAAK,IAAI,EAAE;IAClB,OAAOR,cAAc;EACvB;EAEA,IAAIQ,KAAK,KAAKC,SAAS,EAAE;IACvB,OAAOH,aAAa;EACtB;EAEA,MAAMI,MAAM,GAAGF,KAAK,CAACE,MAAM;EAE3B,MAAMC,aAAa,GAAGD,MAAM,CAACE,QAAQ,CAAC,MAAM,CAAC,IAAIF,MAAM,CAACE,QAAQ,CAAC,MAAM,CAAC;EAExE,IAAID,aAAa,EAAE;IACjB,MAAME,iBAAiB,GAAGH,MAAM,CAACI,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE;IACrE,IAAI,OAAO,CAACC,IAAI,CAACF,iBAAiB,CAAC,EAAE;MACnC,IAAIG,OAAO,EAAE;QACXC,OAAO,CAACC,KAAK,CACX,yEACF,CAAC;MACH;MAEA,OAAOZ,aAAa;IACtB;EACF;EAEA,OAAO;IACLL,OAAO,EAAES,MAAM;IACfR,eAAe,EAAEM,KAAK,CAACW,UAAU;IACjChB,MAAM,EAAEK,KAAK,CAACL,MAAM;IACpBC,UAAU,EAAE,KAAK;IACjBC,SAAS,EAAE;EACb,CAAC;AACH,CAAC;;AAED;AACA,OAAO,MAAMe,2BAA2B,GACtCZ,KAAgC,IACZ;EACpB,MAAMa,MAAM,GAAGd,mBAAmB,CAACC,KAAK,IAAI,IAAI,CAAC;EACjD,OAAOa,MAAM,CAAChB,SAAS,GAAGL,cAAc,GAAGqB,MAAM;AACnD,CAAC","ignoreList":[]} -diff --git a/lib/module/web/styles.js b/lib/module/web/styles.js -index dde8f0093080dd4612f49f157830cf8f1111e238..4d745c0fdcdee23b1108aa412d5e752c527cb41a 100644 ---- a/lib/module/web/styles.js -+++ b/lib/module/web/styles.js -@@ -314,7 +314,7 @@ export function linkStyleForUrl(style, url) { - const backgroundColor = resolved.backgroundColor; - return { - color: resolved.color, -- fontFamily: normalizeFontFamily(base.fontFamily), -+ fontFamily: normalizeFontFamily(resolved.fontFamily), - textDecoration: resolved.underline ? 'underline' : 'none', - ...(backgroundColor && backgroundColor !== 'transparent' ? { - backgroundColor -diff --git a/lib/module/web/styles.js.map b/lib/module/web/styles.js.map -index 01776d3f34bb046542243700bb61aaa6c60d64f1..a4d85f687dd0ad27fb9604ec967a9f9fe84f6c62 100644 ---- a/lib/module/web/styles.js.map -+++ b/lib/module/web/styles.js.map -@@ -1 +1 @@ --{"version":3,"names":["normalizeFontFamily","value","undefined","VALID_FONT_WEIGHTS","Set","normalizeFontWeight","has","normalizeTextAlign","resolveColumnAlign","align","zeroTrailingMargins","style","paragraph","marginBottom","h1","h2","h3","h4","h5","h6","blockquote","list","codeBlock","thematicBreak","image","video","math","table","toHeadingLevel","level","clamped","Math","max","min","parseInt","baseBlock","block","fontSize","fontFamily","fontWeight","color","lineHeight","marginTop","textAlign","paragraphStyle","paragraphInBlockquoteStyle","headingStyle","blockquoteStyle","marginInlineStart","marginInlineEnd","paddingInlineStart","gapWidth","padding","paddingInlineEnd","paddingTop","paddingBottom","borderInlineStart","borderWidth","borderColor","borderRadius","backgroundColor","listStyle","isTaskList","listStylePosition","marginLeft","codeBlockStyle","border","margin","overflowX","direction","thematicBreakStyle","borderTop","height","width","RESIZE_MODE_TO_OBJECT_FIT","contain","cover","stretch","center","none","imageStyle","base","maxWidth","display","resizeMode","objectFit","aspectRatio","maxHeight","videoStyle","inlineImageStyle","size","inlineImage","verticalAlign","strongStyle","strong","emphasisStyle","emphasis","em","fontStyle","codeStyle","code","unicodeBidi","linkStyle","link","textDecoration","underline","_variantRegexCache","WeakMap","getCompiledVariantRegexes","variants","compiled","get","map","variant","RegExp","pattern","set","linkStyleForUrl","url","compiledVariantRegexes","linkVariants","variantIndex","findIndex","regex","test","resolved","strikethroughStyle","textDecorationLine","textDecorationColor","strikethrough","underlineStyle","superscriptStyle","fontScale","baselineOffsetScale","superscript","subscriptStyle","subscript","highlightStyle","highlight","mathInlineStyle","inlineMath","mathDisplayStyle","tableStyle","borderCollapse","listItemStyle","isTask","isFirstChild","itemSpacing","checkedTaskTextStyle","taskList","checkedTextColor","checkedStrikethrough","taskCheckboxDisabledStyle","taskCheckboxStyle","pointerEvents","cursor","checkboxSize","checkboxBorderRadius","accentColor","checkedColor","tableBodyRowStyle","rowIndex","rowEvenBackgroundColor","rowOddBackgroundColor","tableWrapperStyle","alignment","marginRight","overflowY","tableHeaderCellStyle","headerBackgroundColor","headerTextColor","headerFontFamily","cellPaddingVertical","cellPaddingHorizontal","tableCellStyle","parseErrorFallbackStyle","whiteSpace","stylesStore","buildStyles","cached","result","paragraphInBlockquote","listNested","listTask","codeBlockFont","mathInline","mathDisplay","tableWrapper","tableHeaderCell","left","right","default","tableCell","taskCheckbox","taskCheckboxDisabled"],"sourceRoot":"../../../src","sources":["web/styles.ts"],"mappings":"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","ignoreList":[]} -+{"version":3,"names":["normalizeFontFamily","value","undefined","VALID_FONT_WEIGHTS","Set","normalizeFontWeight","has","normalizeTextAlign","resolveColumnAlign","align","zeroTrailingMargins","style","paragraph","marginBottom","h1","h2","h3","h4","h5","h6","blockquote","list","codeBlock","thematicBreak","image","video","math","table","toHeadingLevel","level","clamped","Math","max","min","parseInt","baseBlock","block","fontSize","fontFamily","fontWeight","color","lineHeight","marginTop","textAlign","paragraphStyle","paragraphInBlockquoteStyle","headingStyle","blockquoteStyle","marginInlineStart","marginInlineEnd","paddingInlineStart","gapWidth","padding","paddingInlineEnd","paddingTop","paddingBottom","borderInlineStart","borderWidth","borderColor","borderRadius","backgroundColor","listStyle","isTaskList","listStylePosition","marginLeft","codeBlockStyle","border","margin","overflowX","direction","thematicBreakStyle","borderTop","height","width","RESIZE_MODE_TO_OBJECT_FIT","contain","cover","stretch","center","none","imageStyle","base","maxWidth","display","resizeMode","objectFit","aspectRatio","maxHeight","videoStyle","inlineImageStyle","size","inlineImage","verticalAlign","strongStyle","strong","emphasisStyle","emphasis","em","fontStyle","codeStyle","code","unicodeBidi","linkStyle","link","textDecoration","underline","_variantRegexCache","WeakMap","getCompiledVariantRegexes","variants","compiled","get","map","variant","RegExp","pattern","set","linkStyleForUrl","url","compiledVariantRegexes","linkVariants","variantIndex","findIndex","regex","test","resolved","strikethroughStyle","textDecorationLine","textDecorationColor","strikethrough","underlineStyle","superscriptStyle","fontScale","baselineOffsetScale","superscript","subscriptStyle","subscript","highlightStyle","highlight","mathInlineStyle","inlineMath","mathDisplayStyle","tableStyle","borderCollapse","listItemStyle","isTask","isFirstChild","itemSpacing","checkedTaskTextStyle","taskList","checkedTextColor","checkedStrikethrough","taskCheckboxDisabledStyle","taskCheckboxStyle","pointerEvents","cursor","checkboxSize","checkboxBorderRadius","accentColor","checkedColor","tableBodyRowStyle","rowIndex","rowEvenBackgroundColor","rowOddBackgroundColor","tableWrapperStyle","alignment","marginRight","overflowY","tableHeaderCellStyle","headerBackgroundColor","headerTextColor","headerFontFamily","cellPaddingVertical","cellPaddingHorizontal","tableCellStyle","parseErrorFallbackStyle","whiteSpace","stylesStore","buildStyles","cached","result","paragraphInBlockquote","listNested","listTask","codeBlockFont","mathInline","mathDisplay","tableWrapper","tableHeaderCell","left","right","default","tableCell","taskCheckbox","taskCheckboxDisabled"],"sourceRoot":"../../../src","sources":["web/styles.ts"],"mappings":"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","ignoreList":[]} -diff --git a/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts b/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts -index 2fd15eea6cf92b99549507f8d7c9d3ddb3473ead..8b995d4aa7c95362e04e8dc00a91d8c69c3506aa 100644 ---- a/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts -+++ b/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts -@@ -79,6 +79,17 @@ interface LinkVariantEntryInternal { - color: ColorValue; - underline: boolean; - backgroundColor: ColorValue; -+ fontFamily: string; -+ pill: boolean; -+ label: string; -+ iconUri: string; -+ iconTintColor?: ColorValue; -+ borderRadius: CodegenTypes.Float; -+ paddingHorizontal: CodegenTypes.Float; -+ paddingVertical: CodegenTypes.Float; -+ borderWidth: CodegenTypes.Float; -+ borderColor: ColorValue; -+ maxWidth: CodegenTypes.Float; - } - interface StrongStyleInternal { - fontFamily: string; -@@ -351,7 +362,86 @@ interface StreamingConfigInternal { - tableMode: string; - codeBlockMode: string; - } -+interface TextLinkNativeRegex { -+ pattern: string; -+ caseInsensitive: boolean; -+ dotAll: boolean; -+ isDisabled: boolean; -+ isDefault: boolean; -+} -+export interface DocumentAssetInternal { -+ anchor: string; -+ id: string; -+ kind: string; -+ url: string; -+ altText: string; -+ title: string; -+ placement: string; -+ eligible: boolean; -+} -+export interface DocumentAssetsEventInternal { -+ revision: CodegenTypes.Int32; -+ assets: { -+ anchor: string; -+ id: string; -+ kind: string; -+ url: string; -+ altText: string; -+ title: string; -+ placement: string; -+ eligible: boolean; -+ }[]; -+} -+export interface MediaFrameInternal { -+ id: string; -+ x: CodegenTypes.Float; -+ y: CodegenTypes.Float; -+ width: CodegenTypes.Float; -+ height: CodegenTypes.Float; -+} -+export interface MediaLayoutEventInternal { -+ revision: CodegenTypes.Int32; -+ frames: { -+ id: string; -+ x: CodegenTypes.Float; -+ y: CodegenTypes.Float; -+ width: CodegenTypes.Float; -+ height: CodegenTypes.Float; -+ }[]; -+} -+export interface MediaOverrideInternal { -+ url: string; -+ kind: string; -+ anchor: string; -+ id: string; -+ height: CodegenTypes.Float; -+ width: CodegenTypes.Float; -+} -+export interface ImageSourceInternal { -+ id: string; -+ url: string; -+ anchor: string; -+ uri: string; -+ headers: ReadonlyArray>; -+ useDefault: boolean; -+} - export interface NativeProps extends ViewProps { -+ enableImageSourceResolution?: CodegenTypes.WithDefault; -+ imageSourcesRevision?: CodegenTypes.WithDefault; -+ imageSourcesContinuityStart?: CodegenTypes.WithDefault; -+ imageSources?: ReadonlyArray>; -+ documentRevision?: CodegenTypes.WithDefault; -+ enableDocumentAssets?: CodegenTypes.WithDefault; -+ enableMediaSlots?: CodegenTypes.WithDefault; -+ mediaOverridesRevision?: CodegenTypes.WithDefault; -+ mediaOverrides?: ReadonlyArray>; -+ onDocumentAssets?: CodegenTypes.DirectEventHandler; -+ onMediaLayout?: CodegenTypes.DirectEventHandler; -+ linkRegex?: Readonly; -+ inlineCodeLinkRegex?: Readonly; - /** - * Markdown content to render. - */ -diff --git a/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map b/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map -index 48e42b9ac1cb79b3aee796a2c55ddf9dcfc4174c..dddaecfab08a143eccf89955a840f34e0752ca87 100644 ---- a/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map -+++ b/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map -@@ -1 +1 @@ --{"version":3,"file":"EnrichedMarkdownNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/EnrichedMarkdownNativeComponent.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -+{"version":3,"file":"EnrichedMarkdownNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/EnrichedMarkdownNativeComponent.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts b/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts -index 11572f06f21502dfab016495ad7ec3dad1874876..28379bf3f53eb02db71fa49069bcf1b9a9423d16 100644 ---- a/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts -+++ b/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts -@@ -79,6 +79,17 @@ interface LinkVariantEntryInternal { - color: ColorValue; - underline: boolean; - backgroundColor: ColorValue; -+ fontFamily: string; -+ pill: boolean; -+ label: string; -+ iconUri: string; -+ iconTintColor?: ColorValue; -+ borderRadius: CodegenTypes.Float; -+ paddingHorizontal: CodegenTypes.Float; -+ paddingVertical: CodegenTypes.Float; -+ borderWidth: CodegenTypes.Float; -+ borderColor: ColorValue; -+ maxWidth: CodegenTypes.Float; - } - interface StrongStyleInternal { - fontFamily: string; -@@ -351,7 +362,16 @@ interface StreamingConfigInternal { - tableMode: string; - codeBlockMode: string; - } -+interface TextLinkNativeRegex { -+ pattern: string; -+ caseInsensitive: boolean; -+ dotAll: boolean; -+ isDisabled: boolean; -+ isDefault: boolean; -+} - export interface NativeProps extends ViewProps { -+ linkRegex?: Readonly; -+ inlineCodeLinkRegex?: Readonly; - /** - * Markdown content to render. - */ -diff --git a/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map b/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map -index 3fca5357839d5a384796ad528d623a9646a8b4f3..91b2e26b14100d6232e0ed22b655cac8cf09074e 100644 ---- a/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map -+++ b/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map -@@ -1 +1 @@ --{"version":3,"file":"EnrichedMarkdownTextNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/EnrichedMarkdownTextNativeComponent.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -+{"version":3,"file":"EnrichedMarkdownTextNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/EnrichedMarkdownTextNativeComponent.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/lib/typescript/src/imageSourceState.d.ts b/lib/typescript/src/imageSourceState.d.ts -new file mode 100644 -index 0000000000000000000000000000000000000000..97a0831ddf6feefb8ea0f844d58a761badecfca3 ---- /dev/null -+++ b/lib/typescript/src/imageSourceState.d.ts -@@ -0,0 +1,23 @@ -+import type { ImageSourceInternal } from './EnrichedMarkdownNativeComponent'; -+import type { EnrichedMarkdownTextProps } from './types/MarkdownTextProps'; -+import type { MarkdownMediaAsset } from './types/media'; -+export type NativeImageAsset = MarkdownMediaAsset & { -+ anchor: string; -+}; -+type Resolver = NonNullable; -+/** Per-occurrence decisions; superseded promises still count against the bound. */ -+export declare class ImageSourceState { -+ private resolver?; -+ private lineage; -+ private entries; -+ private active; -+ private running; -+ private changed?; -+ configure(resolver: Resolver | undefined, lineage: number, assets: NativeImageAsset[]): void; -+ sources(): ImageSourceInternal[]; -+ start(changed: () => void): void; -+ stop(): void; -+ private pump; -+} -+export {}; -+//# sourceMappingURL=imageSourceState.d.ts.map -\ No newline at end of file -diff --git a/lib/typescript/src/imageSourceState.d.ts.map b/lib/typescript/src/imageSourceState.d.ts.map -new file mode 100644 -index 0000000000000000000000000000000000000000..844f7b3cd918c8abecdf367b5b2cd48f941de926 ---- /dev/null -+++ b/lib/typescript/src/imageSourceState.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"imageSourceState.d.ts","sourceRoot":"","sources":["../../../src/imageSourceState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AACvE,KAAK,QAAQ,GAAG,WAAW,CAAC,yBAAyB,CAAC,oBAAoB,CAAC,CAAC,CAAC;AAW7E,mFAAmF;AACnF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,CAAW;IAC5B,OAAO,CAAC,OAAO,CAAM;IACrB,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAC,CAAa;IAE7B,SAAS,CACP,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,gBAAgB,EAAE;IAuB5B,OAAO,IAAI,mBAAmB,EAAE;IAMhC,KAAK,CAAC,OAAO,EAAE,MAAM,IAAI;IAMzB,IAAI;IAMJ,OAAO,CAAC,IAAI;CA4Cb"} -\ No newline at end of file -diff --git a/lib/typescript/src/index.d.ts b/lib/typescript/src/index.d.ts -index 46496a5325e79c553d83cf8128016ce1d7a874cc..b0290881c5043de1060731a76812c055fb219ec0 100644 ---- a/lib/typescript/src/index.d.ts -+++ b/lib/typescript/src/index.d.ts -@@ -1,3 +1,4 @@ -+export type { LinkVariantStyle } from './types/MarkdownStyle'; - export { default as EnrichedMarkdownText } from './native/EnrichedMarkdownText'; - export type { EnrichedMarkdownTextProps, StreamingConfig, MarkdownStyle, Md4cFlags, ContextMenuItem as TextContextMenuItem, SelectionMenuConfig as TextSelectionMenuConfig, SelectionMenuPluralLabels as TextSelectionMenuPluralLabels, } from './native/EnrichedMarkdownText'; - export type { LinkPressEvent, LinkLongPressEvent, ImagePressEvent, TaskListItemPressEvent, CopyPressEvent, LatexErrorEvent, CodeBlockPressEvent, } from './types/events'; -@@ -5,4 +6,5 @@ export type { AccessibilityLabels, ResolvedAccessibilityLabels, } from './types/ - export { DEFAULT_ACCESSIBILITY_LABELS, resolveAccessibilityLabels, } from './accessibilityLabelDefaults'; - export { EnrichedMarkdownTextInput } from './EnrichedMarkdownTextInput'; - export type { EnrichedMarkdownTextInputProps, EnrichedMarkdownTextInputInstance, MarkdownTextInputStyle, StyleState, ContextMenuItem, InputSelectionMenuConfig, FormatMenuConfig, OnKeyPressEvent, OnLinkDetected, OnStartMentionEvent, OnChangeMentionEvent, OnEndMentionEvent, CaretRect, HeadingLevel, HeadingStyle, } from './EnrichedMarkdownTextInput'; -+export type { MarkdownAssetPlacement, MarkdownMediaAsset, MarkdownImageSource, MarkdownLinkAsset, MarkdownDocumentAsset, DocumentAssetsEvent, } from './types/media'; - //# sourceMappingURL=index.d.ts.map -\ No newline at end of file -diff --git a/lib/typescript/src/index.d.ts.map b/lib/typescript/src/index.d.ts.map -index c2863d1b435aed9117cf65de4ca4bd8a345cde26..423f68150a88f61a45c110299c4faf135f05e20c 100644 ---- a/lib/typescript/src/index.d.ts.map -+++ b/lib/typescript/src/index.d.ts.map -@@ -1 +1 @@ --{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAChF,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,aAAa,EACb,SAAS,EACT,eAAe,IAAI,mBAAmB,EACtC,mBAAmB,IAAI,uBAAuB,EAC9C,yBAAyB,IAAI,6BAA6B,GAC3D,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EACV,8BAA8B,EAC9B,iCAAiC,EACjC,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,wBAAwB,EACxB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,YAAY,GACb,MAAM,6BAA6B,CAAC"} -\ No newline at end of file -+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAChF,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,aAAa,EACb,SAAS,EACT,eAAe,IAAI,mBAAmB,EACtC,mBAAmB,IAAI,uBAAuB,EAC9C,yBAAyB,IAAI,6BAA6B,GAC3D,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EACV,8BAA8B,EAC9B,iCAAiC,EACjC,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,wBAAwB,EACxB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,YAAY,GACb,MAAM,6BAA6B,CAAC;AAErC,YAAY,EACV,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,eAAe,CAAC"} -\ No newline at end of file -diff --git a/lib/typescript/src/jest/index.d.ts b/lib/typescript/src/jest/index.d.ts -index 1640dcc465e7320663a13e340824a0ba3007233c..d0061c29b488605d1d6df6d40795735d05dd7248 100644 ---- a/lib/typescript/src/jest/index.d.ts -+++ b/lib/typescript/src/jest/index.d.ts -@@ -2,5 +2,5 @@ import type { EnrichedMarkdownTextInputProps } from '../EnrichedMarkdownTextInpu - import type { EnrichedMarkdownTextProps } from '../native/EnrichedMarkdownText'; - export { DEFAULT_ACCESSIBILITY_LABELS, resolveAccessibilityLabels, } from '../accessibilityLabelDefaults'; - export declare const EnrichedMarkdownTextInput: ({ ref, defaultValue, onChangeText, onChangeMarkdown, onFocus, onBlur, editable, placeholder, placeholderTextColor, autoFocus, multiline, scrollEnabled, style, testID, accessible, accessibilityLabel, accessibilityHint, accessibilityRole, accessibilityState, nativeID, markdownStyle: _markdownStyle, cursorColor: _cursorColor, selectionColor: _selectionColor, autoCapitalize: _autoCapitalize, onChangeSelection: _onChangeSelection, onChangeState: _onChangeState, onKeyPress: _onKeyPress, onCaretRectChange: _onCaretRectChange, onLinkDetected: _onLinkDetected, mentionIndicators: _mentionIndicators, onStartMention: _onStartMention, onChangeMention: _onChangeMention, onEndMention: _onEndMention, contextMenuItems: _contextMenuItems, selectionMenuConfig: _selectionMenuConfig, formatMenuConfig: _formatMenuConfig, linkRegex: _linkRegex, writingDirection: _writingDirection, }: EnrichedMarkdownTextInputProps) => import("react/jsx-runtime").JSX.Element; --export declare const EnrichedMarkdownText: ({ markdown, containerStyle, testID, accessible, accessibilityLabel, accessibilityHint, accessibilityRole, accessibilityState, nativeID, markdownStyle: _markdownStyle, onLinkPress, onLinkLongPress, onTaskListItemPress, enableLinkPreview: _enableLinkPreview, selectable: _selectable, md4cFlags: _md4cFlags, allowFontScaling: _allowFontScaling, maxFontSizeMultiplier: _maxFontSizeMultiplier, allowTrailingMargin: _allowTrailingMargin, flavor: _flavor, streamingAnimation: _streamingAnimation, streamingConfig: _streamingConfig, spoilerOverlay: _spoilerOverlay, contextMenuItems: _contextMenuItems, imageRequestHeaders: _imageRequestHeaders, selectionMenuConfig: _selectionMenuConfig, accessibilityLabels: _accessibilityLabels, selectionColor: _selectionColor, selectionHandleColor: _selectionHandleColor, textBreakStrategy: _textBreakStrategy, lineBreakStrategyIOS: _lineBreakStrategyIOS, writingDirection: _writingDirection, }: EnrichedMarkdownTextProps) => import("react/jsx-runtime").JSX.Element; -+export declare const EnrichedMarkdownText: ({ markdown, containerStyle, testID, accessible, accessibilityLabel, accessibilityHint, accessibilityRole, accessibilityState, nativeID, markdownStyle: _markdownStyle, onLinkPress, onLinkLongPress, onTaskListItemPress, enableLinkPreview: _enableLinkPreview, selectable: _selectable, md4cFlags: _md4cFlags, allowFontScaling: _allowFontScaling, maxFontSizeMultiplier: _maxFontSizeMultiplier, allowTrailingMargin: _allowTrailingMargin, flavor: _flavor, streamingAnimation: _streamingAnimation, streamingConfig: _streamingConfig, spoilerOverlay: _spoilerOverlay, contextMenuItems: _contextMenuItems, imageRequestHeaders: _imageRequestHeaders, resolveImageSource: _resolveImageSource, selectionMenuConfig: _selectionMenuConfig, accessibilityLabels: _accessibilityLabels, selectionColor: _selectionColor, selectionHandleColor: _selectionHandleColor, textBreakStrategy: _textBreakStrategy, lineBreakStrategyIOS: _lineBreakStrategyIOS, writingDirection: _writingDirection, }: EnrichedMarkdownTextProps) => import("react/jsx-runtime").JSX.Element; - //# sourceMappingURL=index.d.ts.map -\ No newline at end of file -diff --git a/lib/typescript/src/jest/index.d.ts.map b/lib/typescript/src/jest/index.d.ts.map -index e5a7a11601241d44583b9f00c1a1bf4e088cd7ac..570efcf12b442a8b595cd12a895c3b9ad7cac1ce 100644 ---- a/lib/typescript/src/jest/index.d.ts.map -+++ b/lib/typescript/src/jest/index.d.ts.map -@@ -1 +1 @@ --{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/jest/index.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAGV,8BAA8B,EAC/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAOhF,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,+BAA+B,CAAC;AASvC,eAAO,MAAM,yBAAyB,GAAI,02BAuCvC,8BAA8B,4CA2EhC,CAAC;AA6HF,eAAO,MAAM,oBAAoB,GAAI,85BAiClC,yBAAyB,4CAmB3B,CAAC"} -\ No newline at end of file -+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/jest/index.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAGV,8BAA8B,EAC/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAOhF,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,+BAA+B,CAAC;AASvC,eAAO,MAAM,yBAAyB,GAAI,02BAuCvC,8BAA8B,4CA2EhC,CAAC;AA6HF,eAAO,MAAM,oBAAoB,GAAI,u8BAkClC,yBAAyB,4CAmB3B,CAAC"} -\ No newline at end of file -diff --git a/lib/typescript/src/linkVariantUtils.d.ts b/lib/typescript/src/linkVariantUtils.d.ts -index 17139662039594be8780398f8dd5de4e774478f9..7003bc7c09ab814c4087c353431a5f3f65231c94 100644 ---- a/lib/typescript/src/linkVariantUtils.d.ts -+++ b/lib/typescript/src/linkVariantUtils.d.ts -@@ -1,5 +1,16 @@ - import type { LinkVariantStyle } from './types/MarkdownStyle'; - type LinkVariantEntry = [pattern: string, style: LinkVariantStyle]; - export declare function normalizeLinkVariantEntries(linkVariants?: Record): LinkVariantEntry[]; -+/** Native pill geometry is finite and nonnegative before crossing codegen. */ -+export declare function normalizeLinkPillStyle(style: LinkVariantStyle): { -+ pill: boolean; -+ label: string; -+ iconUri: string; -+ borderRadius: number; -+ paddingHorizontal: number; -+ paddingVertical: number; -+ borderWidth: number; -+ maxWidth: number; -+}; - export {}; - //# sourceMappingURL=linkVariantUtils.d.ts.map -\ No newline at end of file -diff --git a/lib/typescript/src/linkVariantUtils.d.ts.map b/lib/typescript/src/linkVariantUtils.d.ts.map -index 7a2a032f991fa0a5361700973afbd988207e09b7..da46e5b0ef0602a9bbdc6506e2112f7a7525cc1b 100644 ---- a/lib/typescript/src/linkVariantUtils.d.ts.map -+++ b/lib/typescript/src/linkVariantUtils.d.ts.map -@@ -1 +1 @@ --{"version":3,"file":"linkVariantUtils.d.ts","sourceRoot":"","sources":["../../../src/linkVariantUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,KAAK,gBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;AAiBnE,wBAAgB,2BAA2B,CACzC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAC9C,gBAAgB,EAAE,CAoBpB"} -\ No newline at end of file -+{"version":3,"file":"linkVariantUtils.d.ts","sourceRoot":"","sources":["../../../src/linkVariantUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,KAAK,gBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;AAiBnE,wBAAgB,2BAA2B,CACzC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAC9C,gBAAgB,EAAE,CAoBpB;AAED,8EAA8E;AAC9E,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,gBAAgB;;;;;;;;;EAe7D"} -\ No newline at end of file -diff --git a/lib/typescript/src/mediaSlotState.d.ts b/lib/typescript/src/mediaSlotState.d.ts -new file mode 100644 -index 0000000000000000000000000000000000000000..4ac70c5459463b25c0db4af6dab704af5372a55b ---- /dev/null -+++ b/lib/typescript/src/mediaSlotState.d.ts -@@ -0,0 +1,14 @@ -+import type { MediaFrameInternal } from './EnrichedMarkdownNativeComponent'; -+export interface MediaMeasurement { -+ id: string; -+ width: number; -+ height: number; -+} -+export declare const sameMediaSize: (a: number, b: number) => boolean; -+/** Accept only finite native frames with usable widths. */ -+export declare const validMediaFrames: (frames: readonly MediaFrameInternal[]) => MediaFrameInternal[]; -+/** A width change requires React to measure again before native uses the height. */ -+export declare const mediaOverrideForFrame: (id: string, frame: MediaFrameInternal | undefined, measurement: MediaMeasurement | undefined) => MediaMeasurement; -+/** Reject stale onLayout callbacks and suppress subpixel feedback loops. */ -+export declare const acceptMediaMeasurement: (eventRevision: number, revision: number, frame: MediaFrameInternal | undefined, next: MediaMeasurement, previous: MediaMeasurement | undefined) => boolean; -+//# sourceMappingURL=mediaSlotState.d.ts.map -\ No newline at end of file -diff --git a/lib/typescript/src/mediaSlotState.d.ts.map b/lib/typescript/src/mediaSlotState.d.ts.map -new file mode 100644 -index 0000000000000000000000000000000000000000..a8c18129cd717121decfd68b5b5e814066fb69c1 ---- /dev/null -+++ b/lib/typescript/src/mediaSlotState.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"mediaSlotState.d.ts","sourceRoot":"","sources":["../../../src/mediaSlotState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAE5E,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,aAAa,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,YAA0B,CAAC;AAE7E,2DAA2D;AAC3D,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,SAAS,kBAAkB,EAAE,KACpC,kBAAkB,EAIlB,CAAC;AAEJ,oFAAoF;AACpF,eAAO,MAAM,qBAAqB,GAChC,IAAI,MAAM,EACV,OAAO,kBAAkB,GAAG,SAAS,EACrC,aAAa,gBAAgB,GAAG,SAAS,KACxC,gBAG8B,CAAC;AAElC,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,GACjC,eAAe,MAAM,EACrB,UAAU,MAAM,EAChB,OAAO,kBAAkB,GAAG,SAAS,EACrC,MAAM,gBAAgB,EACtB,UAAU,gBAAgB,GAAG,SAAS,KACrC,OAU8C,CAAC"} -\ No newline at end of file -diff --git a/lib/typescript/src/native/EnrichedMarkdownText.d.ts b/lib/typescript/src/native/EnrichedMarkdownText.d.ts -index 6a1c672c2ac8ac257eb94b116583a8b584709046..985ea633b05acff479d0aff48dc6db20a1361d88 100644 ---- a/lib/typescript/src/native/EnrichedMarkdownText.d.ts -+++ b/lib/typescript/src/native/EnrichedMarkdownText.d.ts -@@ -4,6 +4,6 @@ import type { LinkPressEvent, LinkLongPressEvent, ImagePressEvent, TaskListItemP - export type { MarkdownStyle, Md4cFlags }; - export type { EnrichedMarkdownTextProps, StreamingConfig, ContextMenuItem, SelectionMenuConfig, SelectionMenuPluralLabels, }; - export type { LinkPressEvent, LinkLongPressEvent, ImagePressEvent, TaskListItemPressEvent, CopyPressEvent, LatexErrorEvent, CodeBlockPressEvent, }; --export declare const EnrichedMarkdownText: ({ markdown, markdownStyle, containerStyle, onLinkPress, onLinkLongPress, onImagePress, onTaskListItemPress, enableTaskListItemToggle, onCopyPress, onLatexError, onCodeBlockPress, enableBlockContextMenu, enableLinkPreview, selectable, md4cFlags, allowFontScaling, maxFontSizeMultiplier, allowTrailingMargin, flavor, streamingAnimation, streamingConfig, spoilerOverlay, contextMenuItems, imageRequestHeaders, selectionMenuConfig, accessibilityLabels, selectionColor, selectionHandleColor, textBreakStrategy, lineBreakStrategyIOS, writingDirection, numberOfLines, ellipsizeMode, ...rest }: EnrichedMarkdownTextProps) => import("react/jsx-runtime").JSX.Element; -+export declare const EnrichedMarkdownText: ({ markdown, linkRegex: _linkRegex, inlineCodeLinkRegex: _inlineCodeLinkRegex, markdownStyle, containerStyle, onLinkPress, onLinkLongPress, onImagePress, renderMedia, resolveImageSource, onDocumentAssets, onTaskListItemPress, enableTaskListItemToggle, onCopyPress, onLatexError, onCodeBlockPress, enableBlockContextMenu, enableLinkPreview, selectable, md4cFlags, allowFontScaling, maxFontSizeMultiplier, allowTrailingMargin, flavor, streamingAnimation, streamingConfig, spoilerOverlay, contextMenuItems, imageRequestHeaders, selectionMenuConfig, accessibilityLabels, selectionColor, selectionHandleColor, textBreakStrategy, lineBreakStrategyIOS, writingDirection, numberOfLines, ellipsizeMode, ...rest }: EnrichedMarkdownTextProps) => import("react/jsx-runtime").JSX.Element; - export default EnrichedMarkdownText; - //# sourceMappingURL=EnrichedMarkdownText.d.ts.map -\ No newline at end of file -diff --git a/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map b/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map -index d99c4224b331b298175e9d32e24d6f8cc572d01a..7325ad7b010f50d5617ceea4486cef128494a7cc 100644 ---- a/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map -+++ b/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map -@@ -1 +1 @@ --{"version":3,"file":"EnrichedMarkdownText.d.ts","sourceRoot":"","sources":["../../../../src/native/EnrichedMarkdownText.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,KAAK,EACV,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,mBAAmB,EAEpB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AACzC,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,yBAAyB,GAC1B,CAAC;AACF,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,mBAAmB,GACpB,CAAC;AA0EF,eAAO,MAAM,oBAAoB,GAAI,2kBAmClC,yBAAyB,4CAuO3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"} -\ No newline at end of file -+{"version":3,"file":"EnrichedMarkdownText.d.ts","sourceRoot":"","sources":["../../../../src/native/EnrichedMarkdownText.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,KAAK,EACV,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,mBAAmB,EAEpB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AACzC,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,yBAAyB,GAC1B,CAAC;AACF,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,mBAAmB,GACpB,CAAC;AA0EF,eAAO,MAAM,oBAAoB,GAAI,gsBAwClC,yBAAyB,4CAwR3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"} -\ No newline at end of file -diff --git a/lib/typescript/src/native/useImageSources.d.ts b/lib/typescript/src/native/useImageSources.d.ts -new file mode 100644 -index 0000000000000000000000000000000000000000..90480fa0f74c772e267c6cab2d94f28feab3fd6b ---- /dev/null -+++ b/lib/typescript/src/native/useImageSources.d.ts -@@ -0,0 +1,9 @@ -+import type { NativeImageAsset } from '../imageSourceState'; -+import type { EnrichedMarkdownTextProps } from '../types/MarkdownTextProps'; -+export declare function useImageSources(resolver: EnrichedMarkdownTextProps['resolveImageSource'], continuityStart: number, assetsRevision: number, assets: NativeImageAsset[]): { -+ enableImageSourceResolution: boolean; -+ imageSourcesContinuityStart: number; -+ imageSourcesRevision: number; -+ imageSources: import("../EnrichedMarkdownNativeComponent").ImageSourceInternal[]; -+}; -+//# sourceMappingURL=useImageSources.d.ts.map -\ No newline at end of file -diff --git a/lib/typescript/src/native/useImageSources.d.ts.map b/lib/typescript/src/native/useImageSources.d.ts.map -new file mode 100644 -index 0000000000000000000000000000000000000000..441a78598ecf861f68dfefacab3784e923301ea4 ---- /dev/null -+++ b/lib/typescript/src/native/useImageSources.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"useImageSources.d.ts","sourceRoot":"","sources":["../../../../src/native/useImageSources.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAE5E,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,yBAAyB,CAAC,oBAAoB,CAAC,EACzD,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,gBAAgB,EAAE;;;;;EAmB3B"} -\ No newline at end of file -diff --git a/lib/typescript/src/native/useMediaSlots.d.ts b/lib/typescript/src/native/useMediaSlots.d.ts -new file mode 100644 -index 0000000000000000000000000000000000000000..5b9265f5f2365e1fa810e320be9f982ca9f69ff6 ---- /dev/null -+++ b/lib/typescript/src/native/useMediaSlots.d.ts -@@ -0,0 +1,28 @@ -+import type { LayoutChangeEvent, NativeSyntheticEvent } from 'react-native'; -+import type { DocumentAssetsEventInternal, MediaLayoutEventInternal } from '../EnrichedMarkdownNativeComponent'; -+import type { EnrichedMarkdownTextProps } from '../types/MarkdownTextProps'; -+export declare function useMediaSlots(markdown: string, parserKey: string, renderMedia: EnrichedMarkdownTextProps['renderMedia'], onDocumentAssets: EnrichedMarkdownTextProps['onDocumentAssets'], resolveImageSource: EnrichedMarkdownTextProps['resolveImageSource']): { -+ slots: (import("react/jsx-runtime").JSX.Element | null)[]; -+ onNativeLayout: ({ nativeEvent }: LayoutChangeEvent) => void; -+ nativeProps: { -+ documentRevision: number; -+ enableDocumentAssets: boolean; -+ enableMediaSlots: boolean; -+ mediaOverridesRevision: number; -+ mediaOverrides: { -+ id: string; -+ height: number; -+ width: number; -+ url: string; -+ kind: "video" | "image"; -+ anchor: string; -+ }[]; -+ onDocumentAssets: (event: NativeSyntheticEvent) => void; -+ onMediaLayout: (event: NativeSyntheticEvent) => void; -+ enableImageSourceResolution: boolean; -+ imageSourcesContinuityStart: number; -+ imageSourcesRevision: number; -+ imageSources: import("../EnrichedMarkdownNativeComponent").ImageSourceInternal[]; -+ }; -+}; -+//# sourceMappingURL=useMediaSlots.d.ts.map -\ No newline at end of file -diff --git a/lib/typescript/src/native/useMediaSlots.d.ts.map b/lib/typescript/src/native/useMediaSlots.d.ts.map -new file mode 100644 -index 0000000000000000000000000000000000000000..1d0ea5399f2d38532398cbca02cc7febd1e44457 ---- /dev/null -+++ b/lib/typescript/src/native/useMediaSlots.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"useMediaSlots.d.ts","sourceRoot":"","sources":["../../../../src/native/useMediaSlots.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,KAAK,EACV,2BAA2B,EAC3B,wBAAwB,EAEzB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AA4B5E,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,yBAAyB,CAAC,aAAa,CAAC,EACrD,gBAAgB,EAAE,yBAAyB,CAAC,kBAAkB,CAAC,EAC/D,kBAAkB,EAAE,yBAAyB,CAAC,oBAAoB,CAAC;;sCAgK1B,iBAAiB;;;;;;;;;;;;;;kCAzEjD,oBAAoB,CAAC,2BAA2B,CAAC;+BAkCjD,oBAAoB,CAAC,wBAAwB,CAAC;;;;;;EAoIxD"} -\ No newline at end of file -diff --git a/lib/typescript/src/normalizeMarkdownStyle.d.ts.map b/lib/typescript/src/normalizeMarkdownStyle.d.ts.map -index 9a11306c12c94675cf05a157abc971c54e1db8bc..d8507b4a8f51ea3fdd8067e515975be109ebfbd0 100644 ---- a/lib/typescript/src/normalizeMarkdownStyle.d.ts.map -+++ b/lib/typescript/src/normalizeMarkdownStyle.d.ts.map -@@ -1 +1 @@ --{"version":3,"file":"normalizeMarkdownStyle.d.ts","sourceRoot":"","sources":["../../../src/normalizeMarkdownStyle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAIV,qBAAqB,EACtB,MAAM,+BAA+B,CAAC;AAsSvC,eAAO,MAAM,sBAAsB,GACjC,OAAO,aAAa,KACnB,qBA4GF,CAAC"} -\ No newline at end of file -+{"version":3,"file":"normalizeMarkdownStyle.d.ts","sourceRoot":"","sources":["../../../src/normalizeMarkdownStyle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAIV,qBAAqB,EACtB,MAAM,+BAA+B,CAAC;AAySvC,eAAO,MAAM,sBAAsB,GACjC,OAAO,aAAa,KACnB,qBAmHF,CAAC"} -\ No newline at end of file -diff --git a/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map b/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map -index b964e9e107bc0b9ddfdb141d5c22f00497f9b133..c92cc24d9393436a4405fc1ba89988615f6c94f5 100644 ---- a/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map -+++ b/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map -@@ -1 +1 @@ --{"version":3,"file":"normalizeMarkdownStyle.web.d.ts","sourceRoot":"","sources":["../../../src/normalizeMarkdownStyle.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAIV,qBAAqB,EACtB,MAAM,+BAA+B,CAAC;AAwPvC,eAAO,MAAM,sBAAsB,GACjC,OAAO,aAAa,KACnB,qBAwFF,CAAC"} -\ No newline at end of file -+{"version":3,"file":"normalizeMarkdownStyle.web.d.ts","sourceRoot":"","sources":["../../../src/normalizeMarkdownStyle.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAIV,qBAAqB,EACtB,MAAM,+BAA+B,CAAC;AA2PvC,eAAO,MAAM,sBAAsB,GACjC,OAAO,aAAa,KACnB,qBA4FF,CAAC"} -\ No newline at end of file -diff --git a/lib/typescript/src/types/MarkdownStyle.d.ts b/lib/typescript/src/types/MarkdownStyle.d.ts -index 34f22f3eb614338da146f6c93a378832e11f7046..a275469457d857b50abe6a1305b6f4ffdf238676 100644 ---- a/lib/typescript/src/types/MarkdownStyle.d.ts -+++ b/lib/typescript/src/types/MarkdownStyle.d.ts -@@ -114,6 +114,22 @@ export interface LinkVariantStyle { - color?: string; - underline?: boolean; - backgroundColor?: string; -+ fontFamily?: string; -+ /** Render the link as one native pill. Original text and URL remain selectable. */ -+ pill?: boolean; -+ /** Presentation label only. Missing or empty uses the original link text. */ -+ label?: string; -+ /** Local file:// image URI. Unreadable files are ignored. Native pills only. */ -+ iconUri?: string; -+ /** Optional source-in icon tint. Omitted preserves original image colors and alpha. */ -+ iconTintColor?: string; -+ borderRadius?: number; -+ paddingHorizontal?: number; -+ paddingVertical?: number; -+ borderWidth?: number; -+ borderColor?: string; -+ /** Maximum pill width in points/DIP. 0 uses the available text width. */ -+ maxWidth?: number; - } - interface StrongStyle { - fontFamily?: string; -@@ -326,7 +342,8 @@ export interface MarkdownStyle { - * - * `color` and `underline` inherit from the base `link` style when omitted. - * `backgroundColor` defaults to `transparent`. -- * `fontFamily` always follows the base `link` style and cannot be overridden per-variant. -+ * `fontFamily` inherits the base `link` family and can be overridden per variant. -+ * `pill: true` enables atomic native presentation with optional label, icon, and geometry. - * - * @example - * linkVariants: { -diff --git a/lib/typescript/src/types/MarkdownStyle.d.ts.map b/lib/typescript/src/types/MarkdownStyle.d.ts.map -index de80055783d57781bcb2dd860ecaf933fa28c086..d5168a7ef595e8087d1103d4019439150bae1351 100644 ---- a/lib/typescript/src/types/MarkdownStyle.d.ts.map -+++ b/lib/typescript/src/types/MarkdownStyle.d.ts.map -@@ -1 +1 @@ --{"version":3,"file":"MarkdownStyle.d.ts","sourceRoot":"","sources":["../../../../src/types/MarkdownStyle.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -+{"version":3,"file":"MarkdownStyle.d.ts","sourceRoot":"","sources":["../../../../src/types/MarkdownStyle.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/lib/typescript/src/types/MarkdownStyleInternal.d.ts b/lib/typescript/src/types/MarkdownStyleInternal.d.ts -index 45eef337364aa7e5806e4769ab794c5c77737f33..993d6daf572ca7958d5811e21563c47ae8fffd57 100644 ---- a/lib/typescript/src/types/MarkdownStyleInternal.d.ts -+++ b/lib/typescript/src/types/MarkdownStyleInternal.d.ts -@@ -82,6 +82,17 @@ export interface LinkVariantEntryInternal { - color: string; - underline: boolean; - backgroundColor: string; -+ fontFamily: string; -+ pill: boolean; -+ label: string; -+ iconUri: string; -+ iconTintColor?: string; -+ borderRadius: number; -+ paddingHorizontal: number; -+ paddingVertical: number; -+ borderWidth: number; -+ borderColor: string; -+ maxWidth: number; - } - interface StrongStyleInternal { - fontFamily: string; -diff --git a/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map b/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map -index e37cd26e931d112b3e99a3c7b415e3c5589266bf..0b5a8d4f4a0af51c1e3eab6462fba23a07475dc7 100644 ---- a/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map -+++ b/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map -@@ -1 +1 @@ --{"version":3,"file":"MarkdownStyleInternal.d.ts","sourceRoot":"","sources":["../../../../src/types/MarkdownStyleInternal.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -+{"version":3,"file":"MarkdownStyleInternal.d.ts","sourceRoot":"","sources":["../../../../src/types/MarkdownStyleInternal.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/lib/typescript/src/types/MarkdownTextProps.d.ts b/lib/typescript/src/types/MarkdownTextProps.d.ts -index 379af3df3b1d0084efc20bef202889feaa7c0902..cc93ad5e559e12d89fbafe15bbae80ce09b12265 100644 ---- a/lib/typescript/src/types/MarkdownTextProps.d.ts -+++ b/lib/typescript/src/types/MarkdownTextProps.d.ts -@@ -1,3 +1,5 @@ -+import type { ReactNode } from 'react'; -+import type { MarkdownMediaAsset, MarkdownImageSource, DocumentAssetsEvent } from './media'; - import type { ColorValue, ViewProps, ViewStyle, TextStyle } from 'react-native'; - import type { MarkdownStyle, Md4cFlags } from './MarkdownStyle'; - import type { AccessibilityLabels } from './AccessibilityLabels'; -@@ -117,6 +119,44 @@ export interface EnrichedMarkdownTextProps extends Omit { - * @platform ios, android, web - */ - markdown: string; -+ /** -+ * Render an eligible native media occurrence as a React sibling. Returning -+ * null keeps native rendering. Supports standalone image paragraphs and direct -+ * videos at the document root or in recursive quote/admonition containers in -+ * GitHub flavor on iOS and Android. React content owns interaction -+ * and accessibility; its intrinsic height reserves native layout space. -+ */ -+ renderMedia?: (asset: MarkdownMediaAsset) => ReactNode | null; -+ /** -+ * Resolve image download URI and headers from the accepted native AST. -+ * Null selects native fallback. Pending or rejected resolutions keep a -+ * placeholder. React renderMedia overrides take precedence. Supported only -+ * for GitHub flavor on iOS and Android, including nested/linked images. -+ * Keep the callback identity stable to retain decisions across renders. -+ */ -+ resolveImageSource?: (asset: MarkdownMediaAsset) => MarkdownImageSource | null | Promise; -+ /** Native parsed media and link occurrences, including unsupported placements. -+ * Supported in GitHub flavor on iOS and Android. -+ */ -+ onDocumentAssets?: (event: DocumentAssetsEvent) => void; -+ /** -+ * Recognize nonempty matches within parsed plain-text nodes as native links. -+ * The exact matched text is the URL. Existing links and code are excluded. -+ * Uses the input linkRegex conventions: native regex source plus i/s flags. -+ * Other JS flags are not transported; all non-overlapping matches are found. -+ * Patterns must work in NSRegularExpression and java.util.regex.Pattern. -+ * Undefined, null, rejected lookbehinds and invalid native patterns disable it. -+ * @default null -+ * @platform ios, android -+ */ -+ linkRegex?: RegExp | null; -+ /** -+ * Recognize an entire inline-code span as a native link, preserving its code -+ * node and text. Partial matches are ignored. Uses linkRegex conventions. -+ * @default null -+ * @platform ios, android -+ */ -+ inlineCodeLinkRegex?: RegExp | null; - /** - * Style configuration for markdown elements. - * @platform ios, android, web -diff --git a/lib/typescript/src/types/MarkdownTextProps.d.ts.map b/lib/typescript/src/types/MarkdownTextProps.d.ts.map -index c6f5e2a37e81174d7562a9012a2d714b8fb3ec4f..acb5cbcfa685c7f2285f6db91f8a42a7c24e5efa 100644 ---- a/lib/typescript/src/types/MarkdownTextProps.d.ts.map -+++ b/lib/typescript/src/types/MarkdownTextProps.d.ts.map -@@ -1 +1 @@ --{"version":3,"file":"MarkdownTextProps.d.ts","sourceRoot":"","sources":["../../../../src/types/MarkdownTextProps.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -+{"version":3,"file":"MarkdownTextProps.d.ts","sourceRoot":"","sources":["../../../../src/types/MarkdownTextProps.ts"],"names":[],"mappings":"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"} -\ No newline at end of file -diff --git a/lib/typescript/src/types/media.d.ts b/lib/typescript/src/types/media.d.ts -new file mode 100644 -index 0000000000000000000000000000000000000000..28a342625a9ead85fb1e07742f38153e55c556ca ---- /dev/null -+++ b/lib/typescript/src/types/media.d.ts -@@ -0,0 +1,31 @@ -+/** Placement in the native parsed document. */ -+export type MarkdownAssetPlacement = 'block' | 'inline' | 'list' | 'table' | 'blockquote'; -+interface MarkdownAssetDescriptor { -+ /** Occurrence ID, scoped to the component and document lineage. */ -+ id: string; -+ url: string; -+ altText: string; -+ title: string; -+ placement: MarkdownAssetPlacement; -+} -+export interface MarkdownMediaAsset extends MarkdownAssetDescriptor { -+ kind: 'image' | 'video'; -+ /** Whether this placement supports renderMedia. */ -+ eligible: boolean; -+} -+export interface MarkdownLinkAsset extends MarkdownAssetDescriptor { -+ kind: 'link'; -+ eligible: false; -+} -+export type MarkdownDocumentAsset = MarkdownMediaAsset | MarkdownLinkAsset; -+export interface DocumentAssetsEvent { -+ revision: number; -+ assets: MarkdownDocumentAsset[]; -+} -+/** Download transport only; semantic image metadata retains the original URL. */ -+export interface MarkdownImageSource { -+ uri: string; -+ headers?: Record; -+} -+export {}; -+//# sourceMappingURL=media.d.ts.map -\ No newline at end of file -diff --git a/lib/typescript/src/types/media.d.ts.map b/lib/typescript/src/types/media.d.ts.map -new file mode 100644 -index 0000000000000000000000000000000000000000..dbefdb4cb5caf6377006ee1ad26b3e93ae8dfa5b ---- /dev/null -+++ b/lib/typescript/src/types/media.d.ts.map -@@ -0,0 +1 @@ -+{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../../../src/types/media.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,MAAM,MAAM,sBAAsB,GAC9B,OAAO,GACP,QAAQ,GACR,MAAM,GACN,OAAO,GACP,YAAY,CAAC;AAEjB,UAAU,uBAAuB;IAC/B,mEAAmE;IACnE,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,sBAAsB,CAAC;CACnC;AAED,MAAM,WAAW,kBAAmB,SAAQ,uBAAuB;IACjE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,mDAAmD;IACnD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAkB,SAAQ,uBAAuB;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC;CACjB;AAED,MAAM,MAAM,qBAAqB,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;AAE3E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,qBAAqB,EAAE,CAAC;CACjC;AAED,iFAAiF;AACjF,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC"} -\ No newline at end of file -diff --git a/lib/typescript/src/utils/regexParser.d.ts b/lib/typescript/src/utils/regexParser.d.ts -index 972dc6cfb39b54a181abf758663d61f13304642a..b69a29e3b65f7e5e0132c78fe4bb0b94ae548c14 100644 ---- a/lib/typescript/src/utils/regexParser.d.ts -+++ b/lib/typescript/src/utils/regexParser.d.ts -@@ -1,3 +1,5 @@ - import type { LinkNativeRegex } from '../EnrichedMarkdownTextInputNativeComponent'; - export declare const toNativeRegexConfig: (regex: RegExp | undefined | null) => LinkNativeRegex; -+/** Renderer recognition is opt-in, including when input normalization falls back. */ -+export declare const toNativeTextLinkRegexConfig: (regex: RegExp | undefined | null) => LinkNativeRegex; - //# sourceMappingURL=regexParser.d.ts.map -\ No newline at end of file -diff --git a/lib/typescript/src/utils/regexParser.d.ts.map b/lib/typescript/src/utils/regexParser.d.ts.map -index 1e918889d77f96c40c305f2d0568f5311b6c0b9f..0b601754665fcff671c37fbf864e8614f2cfefb3 100644 ---- a/lib/typescript/src/utils/regexParser.d.ts.map -+++ b/lib/typescript/src/utils/regexParser.d.ts.map -@@ -1 +1 @@ --{"version":3,"file":"regexParser.d.ts","sourceRoot":"","sources":["../../../../src/utils/regexParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAkBnF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,MAAM,GAAG,SAAS,GAAG,IAAI,KAC/B,eAiCF,CAAC"} -\ No newline at end of file -+{"version":3,"file":"regexParser.d.ts","sourceRoot":"","sources":["../../../../src/utils/regexParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAkBnF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,MAAM,GAAG,SAAS,GAAG,IAAI,KAC/B,eAiCF,CAAC;AAEF,qFAAqF;AACrF,eAAO,MAAM,2BAA2B,GACtC,OAAO,MAAM,GAAG,SAAS,GAAG,IAAI,KAC/B,eAGF,CAAC"} -\ No newline at end of file -diff --git a/src/EnrichedMarkdownNativeComponent.ts b/src/EnrichedMarkdownNativeComponent.ts -index 66d200af977b0c9a4086f4e621bb26f8400eb68b..db8e832e498ffa1fa1482f68e40d387421761a34 100644 ---- a/src/EnrichedMarkdownNativeComponent.ts -+++ b/src/EnrichedMarkdownNativeComponent.ts -@@ -97,6 +97,17 @@ interface LinkVariantEntryInternal { - color: ColorValue; - underline: boolean; - backgroundColor: ColorValue; -+ fontFamily: string; -+ pill: boolean; -+ label: string; -+ iconUri: string; -+ iconTintColor?: ColorValue; -+ borderRadius: CodegenTypes.Float; -+ paddingHorizontal: CodegenTypes.Float; -+ paddingVertical: CodegenTypes.Float; -+ borderWidth: CodegenTypes.Float; -+ borderColor: ColorValue; -+ maxWidth: CodegenTypes.Float; - } - - interface StrongStyleInternal { -@@ -406,7 +417,92 @@ interface StreamingConfigInternal { - codeBlockMode: string; - } - -+// Same transport as EnrichedMarkdownTextInput.linkRegex. Kept local for codegen. -+interface TextLinkNativeRegex { -+ pattern: string; -+ caseInsensitive: boolean; -+ dotAll: boolean; -+ isDisabled: boolean; -+ isDefault: boolean; -+} -+ -+export interface DocumentAssetInternal { -+ anchor: string; -+ id: string; -+ kind: string; -+ url: string; -+ altText: string; -+ title: string; -+ placement: string; -+ eligible: boolean; -+} -+ -+export interface DocumentAssetsEventInternal { -+ revision: CodegenTypes.Int32; -+ assets: { -+ anchor: string; -+ id: string; -+ kind: string; -+ url: string; -+ altText: string; -+ title: string; -+ placement: string; -+ eligible: boolean; -+ }[]; -+} -+ -+export interface MediaFrameInternal { -+ id: string; -+ x: CodegenTypes.Float; -+ y: CodegenTypes.Float; -+ width: CodegenTypes.Float; -+ height: CodegenTypes.Float; -+} -+ -+export interface MediaLayoutEventInternal { -+ revision: CodegenTypes.Int32; -+ frames: { -+ id: string; -+ x: CodegenTypes.Float; -+ y: CodegenTypes.Float; -+ width: CodegenTypes.Float; -+ height: CodegenTypes.Float; -+ }[]; -+} -+ -+export interface MediaOverrideInternal { -+ url: string; -+ kind: string; -+ anchor: string; -+ id: string; -+ height: CodegenTypes.Float; -+ width: CodegenTypes.Float; -+} -+ -+export interface ImageSourceInternal { -+ id: string; -+ url: string; -+ anchor: string; -+ uri: string; -+ headers: ReadonlyArray>; -+ useDefault: boolean; -+} -+ - export interface NativeProps extends ViewProps { -+ enableImageSourceResolution?: CodegenTypes.WithDefault; -+ imageSourcesRevision?: CodegenTypes.WithDefault; -+ imageSourcesContinuityStart?: CodegenTypes.WithDefault; -+ imageSources?: ReadonlyArray>; -+ documentRevision?: CodegenTypes.WithDefault; -+ enableDocumentAssets?: CodegenTypes.WithDefault; -+ enableMediaSlots?: CodegenTypes.WithDefault; -+ mediaOverridesRevision?: CodegenTypes.WithDefault; -+ mediaOverrides?: ReadonlyArray>; -+ onDocumentAssets?: CodegenTypes.DirectEventHandler; -+ onMediaLayout?: CodegenTypes.DirectEventHandler; -+ -+ linkRegex?: Readonly; -+ inlineCodeLinkRegex?: Readonly; - /** - * Markdown content to render. - */ -diff --git a/src/EnrichedMarkdownTextNativeComponent.ts b/src/EnrichedMarkdownTextNativeComponent.ts -index c034dd109ce151f9d6163a989f8f5ad651029a25..fcf45a04d1984bcdc210445beca44513a1fbb7b4 100644 ---- a/src/EnrichedMarkdownTextNativeComponent.ts -+++ b/src/EnrichedMarkdownTextNativeComponent.ts -@@ -97,6 +97,17 @@ interface LinkVariantEntryInternal { - color: ColorValue; - underline: boolean; - backgroundColor: ColorValue; -+ fontFamily: string; -+ pill: boolean; -+ label: string; -+ iconUri: string; -+ iconTintColor?: ColorValue; -+ borderRadius: CodegenTypes.Float; -+ paddingHorizontal: CodegenTypes.Float; -+ paddingVertical: CodegenTypes.Float; -+ borderWidth: CodegenTypes.Float; -+ borderColor: ColorValue; -+ maxWidth: CodegenTypes.Float; - } - - interface StrongStyleInternal { -@@ -407,7 +418,18 @@ interface StreamingConfigInternal { - codeBlockMode: string; - } - -+// Same transport as EnrichedMarkdownTextInput.linkRegex. Kept local for codegen. -+interface TextLinkNativeRegex { -+ pattern: string; -+ caseInsensitive: boolean; -+ dotAll: boolean; -+ isDisabled: boolean; -+ isDefault: boolean; -+} -+ - export interface NativeProps extends ViewProps { -+ linkRegex?: Readonly; -+ inlineCodeLinkRegex?: Readonly; - /** - * Markdown content to render. - */ -diff --git a/src/imageSourceState.ts b/src/imageSourceState.ts -new file mode 100644 -index 0000000000000000000000000000000000000000..3754fa6d159f221964b7ebe8b33ef0843141c5c1 ---- /dev/null -+++ b/src/imageSourceState.ts -@@ -0,0 +1,114 @@ -+import type { ImageSourceInternal } from './EnrichedMarkdownNativeComponent'; -+import type { EnrichedMarkdownTextProps } from './types/MarkdownTextProps'; -+import type { MarkdownMediaAsset } from './types/media'; -+ -+export type NativeImageAsset = MarkdownMediaAsset & { anchor: string }; -+type Resolver = NonNullable; -+type Entry = { -+ asset: NativeImageAsset; -+ identity: string; -+ status: 'queued' | 'active' | 'done'; -+ source?: ImageSourceInternal; -+}; -+ -+const identity = (asset: NativeImageAsset) => JSON.stringify(asset); -+const stripAnchor = ({ anchor: _anchor, ...asset }: NativeImageAsset) => asset; -+ -+/** Per-occurrence decisions; superseded promises still count against the bound. */ -+export class ImageSourceState { -+ private resolver?: Resolver; -+ private lineage = -1; -+ private entries = new Map(); -+ private active = 0; -+ private running = false; -+ private changed?: () => void; -+ -+ configure( -+ resolver: Resolver | undefined, -+ lineage: number, -+ assets: NativeImageAsset[] -+ ) { -+ if (resolver !== this.resolver || lineage !== this.lineage) { -+ this.entries.clear(); -+ this.resolver = resolver; -+ this.lineage = lineage; -+ } -+ const next = new Map(); -+ if (resolver) { -+ for (const asset of assets) { -+ const key = identity(asset); -+ const previous = this.entries.get(asset.id); -+ next.set( -+ asset.id, -+ previous?.identity === key -+ ? previous -+ : { asset, identity: key, status: 'queued' } -+ ); -+ } -+ } -+ this.entries = next; -+ } -+ -+ sources(): ImageSourceInternal[] { -+ return [...this.entries.values()].flatMap((entry) => -+ entry.source ? [entry.source] : [] -+ ); -+ } -+ -+ start(changed: () => void) { -+ this.running = true; -+ this.changed = changed; -+ this.pump(); -+ } -+ -+ stop() { -+ this.running = false; -+ this.changed = undefined; -+ this.entries.clear(); -+ } -+ -+ private pump() { -+ if (!this.running || !this.resolver) return; -+ for (const entry of this.entries.values()) { -+ if (this.active >= 4) break; -+ if (entry.status !== 'queued') continue; -+ const resolve = this.resolver; -+ entry.status = 'active'; -+ this.active++; -+ // Always execute outside render. Synchronous throws follow rejection policy. -+ Promise.resolve() -+ .then(() => { -+ if (this.entries.get(entry.asset.id) !== entry || !this.running) -+ return undefined; -+ return resolve(stripAnchor(entry.asset)); -+ }) -+ .then((result) => { -+ if (this.entries.get(entry.asset.id) !== entry) return; -+ if ( -+ result === null || -+ (result && typeof result.uri === 'string' && result.uri.length > 0) -+ ) { -+ entry.source = { -+ id: entry.asset.id, -+ url: entry.asset.url, -+ anchor: entry.asset.anchor, -+ uri: result?.uri ?? '', -+ headers: Object.entries(result?.headers ?? {}).map( -+ ([name, value]) => ({ name, value }) -+ ), -+ useDefault: result === null, -+ }; -+ } -+ }) -+ .catch(() => { -+ // A rejected source remains a placeholder until its identity changes. -+ }) -+ .finally(() => { -+ entry.status = 'done'; -+ this.active--; -+ if (this.entries.get(entry.asset.id) === entry) this.changed?.(); -+ this.pump(); -+ }); -+ } -+ } -+} -diff --git a/src/index.tsx b/src/index.tsx -index 7ef02af9aaf268a2173901e4c06caaca6c777ce8..6f34160af71a99360eb307d0dbff2d8692a632e1 100644 ---- a/src/index.tsx -+++ b/src/index.tsx -@@ -1,3 +1,4 @@ -+export type { LinkVariantStyle } from './types/MarkdownStyle'; - export { default as EnrichedMarkdownText } from './native/EnrichedMarkdownText'; - export type { - EnrichedMarkdownTextProps, -@@ -44,3 +45,12 @@ export type { - HeadingLevel, - HeadingStyle, - } from './EnrichedMarkdownTextInput'; -+ -+export type { -+ MarkdownAssetPlacement, -+ MarkdownMediaAsset, -+ MarkdownImageSource, -+ MarkdownLinkAsset, -+ MarkdownDocumentAsset, -+ DocumentAssetsEvent, -+} from './types/media'; -diff --git a/src/jest/index.tsx b/src/jest/index.tsx -index f51c03152d64d6f3bb12941e86ac8f92464b3bde..28fece29049dbbbcb6824979314792aa6e44b423 100644 ---- a/src/jest/index.tsx -+++ b/src/jest/index.tsx -@@ -309,6 +309,7 @@ export const EnrichedMarkdownText = ({ - spoilerOverlay: _spoilerOverlay, - contextMenuItems: _contextMenuItems, - imageRequestHeaders: _imageRequestHeaders, -+ resolveImageSource: _resolveImageSource, - selectionMenuConfig: _selectionMenuConfig, - accessibilityLabels: _accessibilityLabels, - selectionColor: _selectionColor, -diff --git a/src/linkVariantUtils.ts b/src/linkVariantUtils.ts -index fe705dbe7dbbf4b7144d7c90b3e9d3ee0690b119..6cc83545811a63acaa08dee46a7bace5b2c1bfa7 100644 ---- a/src/linkVariantUtils.ts -+++ b/src/linkVariantUtils.ts -@@ -40,3 +40,21 @@ export function normalizeLinkVariantEntries( - return true; - }); - } -+ -+/** Native pill geometry is finite and nonnegative before crossing codegen. */ -+export function normalizeLinkPillStyle(style: LinkVariantStyle) { -+ const dimension = (value: number | undefined, fallback: number) => -+ value === undefined || !Number.isFinite(value) -+ ? fallback -+ : Math.max(0, value); -+ return { -+ pill: style.pill ?? false, -+ label: style.label ?? '', -+ iconUri: style.iconUri ?? '', -+ borderRadius: dimension(style.borderRadius, 8), -+ paddingHorizontal: dimension(style.paddingHorizontal, 6), -+ paddingVertical: dimension(style.paddingVertical, 2), -+ borderWidth: dimension(style.borderWidth, 0), -+ maxWidth: dimension(style.maxWidth, 0), -+ }; -+} -diff --git a/src/mediaSlotState.ts b/src/mediaSlotState.ts -new file mode 100644 -index 0000000000000000000000000000000000000000..f34b4f80cb38facc19046d04e2be31244e480479 ---- /dev/null -+++ b/src/mediaSlotState.ts -@@ -0,0 +1,47 @@ -+import type { MediaFrameInternal } from './EnrichedMarkdownNativeComponent'; -+ -+export interface MediaMeasurement { -+ id: string; -+ width: number; -+ height: number; -+} -+ -+export const sameMediaSize = (a: number, b: number) => Math.abs(a - b) < 0.5; -+ -+/** Accept only finite native frames with usable widths. */ -+export const validMediaFrames = ( -+ frames: readonly MediaFrameInternal[] -+): MediaFrameInternal[] => -+ frames.filter( -+ ({ x, y, width, height }) => -+ [x, y, width, height].every(Number.isFinite) && width > 0 && height >= 0 -+ ); -+ -+/** A width change requires React to measure again before native uses the height. */ -+export const mediaOverrideForFrame = ( -+ id: string, -+ frame: MediaFrameInternal | undefined, -+ measurement: MediaMeasurement | undefined -+): MediaMeasurement => -+ frame && measurement && sameMediaSize(frame.width, measurement.width) -+ ? measurement -+ : { id, width: 0, height: 1 }; -+ -+/** Reject stale onLayout callbacks and suppress subpixel feedback loops. */ -+export const acceptMediaMeasurement = ( -+ eventRevision: number, -+ revision: number, -+ frame: MediaFrameInternal | undefined, -+ next: MediaMeasurement, -+ previous: MediaMeasurement | undefined -+): boolean => -+ eventRevision === revision && -+ !!frame && -+ Number.isFinite(next.width) && -+ Number.isFinite(next.height) && -+ next.width > 0 && -+ next.height >= 0 && -+ sameMediaSize(frame.width, next.width) && -+ (!previous || -+ !sameMediaSize(previous.width, next.width) || -+ !sameMediaSize(previous.height, next.height)); -diff --git a/src/native/EnrichedMarkdownText.tsx b/src/native/EnrichedMarkdownText.tsx -index 267a2463ec341b677b10943b531f2055cb34662d..9607e4049475aa6565544ee30fa54a4b9eb02e0f 100644 ---- a/src/native/EnrichedMarkdownText.tsx -+++ b/src/native/EnrichedMarkdownText.tsx -@@ -1,7 +1,10 @@ -+import { StyleSheet, View } from 'react-native'; -+import { useMediaSlots } from './useMediaSlots'; - import { useMemo, useCallback, useRef, useEffect } from 'react'; - import EnrichedMarkdownTextNativeComponent from '../EnrichedMarkdownTextNativeComponent'; - import type { MarkdownStyleInternal } from '../EnrichedMarkdownTextNativeComponent'; - import EnrichedMarkdownNativeComponent from '../EnrichedMarkdownNativeComponent'; -+import { toNativeTextLinkRegexConfig } from '../utils/regexParser'; - import { normalizeMarkdownStyle } from '../normalizeMarkdownStyle'; - import { resolveAccessibilityLabels } from '../accessibilityLabelDefaults'; - import { -@@ -120,11 +123,16 @@ const defaultMd4cFlags: Md4cFlags = { - - export const EnrichedMarkdownText = ({ - markdown, -+ linkRegex: _linkRegex, -+ inlineCodeLinkRegex: _inlineCodeLinkRegex, - markdownStyle = {}, - containerStyle, - onLinkPress, - onLinkLongPress, - onImagePress, -+ renderMedia, -+ resolveImageSource, -+ onDocumentAssets, - onTaskListItemPress, - enableTaskListItemToggle = true, - onCopyPress, -@@ -154,6 +162,14 @@ export const EnrichedMarkdownText = ({ - ellipsizeMode, - ...rest - }: EnrichedMarkdownTextProps) => { -+ const linkRegex = useMemo( -+ () => toNativeTextLinkRegexConfig(_linkRegex), -+ [_linkRegex] -+ ); -+ const inlineCodeLinkRegex = useMemo( -+ () => toNativeTextLinkRegexConfig(_inlineCodeLinkRegex), -+ [_inlineCodeLinkRegex] -+ ); - const normalizedStyleRef = useRef(null); - const normalized = normalizeMarkdownStyle(markdownStyle); - // normalizeMarkdownStyle returns cached objects for structurally equal inputs, -@@ -341,6 +357,8 @@ export const EnrichedMarkdownText = ({ - - const sharedProps = { - markdown, -+ linkRegex, -+ inlineCodeLinkRegex, - markdownStyle: normalizedStyle, - onLinkPress: handleLinkPress, - onLinkLongPress: handleLinkLongPress, -@@ -379,11 +397,52 @@ export const EnrichedMarkdownText = ({ - ...rest, - }; - -+ // Include native recognition configs when composed with the optional text -+ // recognition API. Asset revisions must follow all parser inputs. -+ const nativeParserProps: Record = sharedProps; -+ const media = useMediaSlots( -+ markdown, -+ JSON.stringify([ -+ normalizedMd4cFlags, -+ streamingAnimation, -+ normalizedStreamingConfig, -+ flavor, -+ !!renderMedia, -+ !!onDocumentAssets, -+ !!resolveImageSource, -+ nativeParserProps.linkRegex, -+ nativeParserProps.inlineCodeLinkRegex, -+ ]), -+ flavor === 'github' ? renderMedia : undefined, -+ flavor === 'github' ? onDocumentAssets : undefined, -+ flavor === 'github' ? resolveImageSource : undefined -+ ); -+ - if (flavor === 'github') { -- return ; -+ if (renderMedia) { -+ return ( -+ -+ -+ {media.slots} -+ -+ ); -+ } -+ return ( -+ -+ ); - } - - return ; - }; - - export default EnrichedMarkdownText; -+ -+const mediaStyles = StyleSheet.create({ native: { alignSelf: 'stretch' } }); -diff --git a/src/native/useImageSources.ts b/src/native/useImageSources.ts -new file mode 100644 -index 0000000000000000000000000000000000000000..18a6c59b6b4337f8d5e37e42134fc252773f33e8 ---- /dev/null -+++ b/src/native/useImageSources.ts -@@ -0,0 +1,29 @@ -+import { useEffect, useRef, useState } from 'react'; -+import { ImageSourceState } from '../imageSourceState'; -+import type { NativeImageAsset } from '../imageSourceState'; -+import type { EnrichedMarkdownTextProps } from '../types/MarkdownTextProps'; -+ -+export function useImageSources( -+ resolver: EnrichedMarkdownTextProps['resolveImageSource'], -+ continuityStart: number, -+ assetsRevision: number, -+ assets: NativeImageAsset[] -+) { -+ const state = useRef(undefined); -+ if (!state.current) state.current = new ImageSourceState(); -+ const current = state.current; -+ const [, refresh] = useState(0); -+ current.configure(resolver, continuityStart, assets); -+ // Reconcile after every commit. Configure deduplicates layout-only renders. -+ useEffect(() => { -+ current.configure(resolver, continuityStart, assets); -+ current.start(() => refresh((value) => value + 1)); -+ }); -+ useEffect(() => () => current.stop(), [current]); -+ return { -+ enableImageSourceResolution: !!resolver, -+ imageSourcesContinuityStart: resolver ? continuityStart : 1, -+ imageSourcesRevision: resolver ? assetsRevision : -1, -+ imageSources: current.sources(), -+ }; -+} -diff --git a/src/native/useMediaSlots.tsx b/src/native/useMediaSlots.tsx -new file mode 100644 -index 0000000000000000000000000000000000000000..ecdb68f748d980b899b8d4ed3c1b4bbbd290831d ---- /dev/null -+++ b/src/native/useMediaSlots.tsx -@@ -0,0 +1,298 @@ -+import { useRef, useState } from 'react'; -+import { useImageSources } from './useImageSources'; -+import { StyleSheet, View } from 'react-native'; -+import type { LayoutChangeEvent, NativeSyntheticEvent } from 'react-native'; -+import type { -+ DocumentAssetsEventInternal, -+ MediaLayoutEventInternal, -+ MediaFrameInternal, -+} from '../EnrichedMarkdownNativeComponent'; -+import type { EnrichedMarkdownTextProps } from '../types/MarkdownTextProps'; -+import type { MarkdownDocumentAsset, MarkdownMediaAsset } from '../types/media'; -+import { -+ acceptMediaMeasurement, -+ mediaOverrideForFrame, -+ sameMediaSize, -+ validMediaFrames, -+} from '../mediaSlotState'; -+import type { MediaMeasurement } from '../mediaSlotState'; -+ -+type NativeAsset = MarkdownDocumentAsset & { anchor: string }; -+type Manifest = { revision: number; assets: NativeAsset[] }; -+type MediaLayout = MediaLayoutEventInternal & { -+ identities: Record; -+}; -+const stripAnchor = ({ anchor: _anchor, ...asset }: T) => -+ asset; -+const identity = (asset: NativeAsset) => -+ JSON.stringify([ -+ asset.id, -+ asset.kind, -+ asset.url, -+ asset.anchor, -+ asset.eligible, -+ ]); -+const identities = (assets: NativeAsset[]) => -+ Object.fromEntries(assets.map((asset) => [asset.id, identity(asset)])); -+ -+export function useMediaSlots( -+ markdown: string, -+ parserKey: string, -+ renderMedia: EnrichedMarkdownTextProps['renderMedia'], -+ onDocumentAssets: EnrichedMarkdownTextProps['onDocumentAssets'], -+ resolveImageSource: EnrichedMarkdownTextProps['resolveImageSource'] -+) { -+ const document = useRef({ -+ markdown, -+ parserKey, -+ revision: 1, -+ continuityStart: 1, -+ generation: 0, -+ }); -+ if ( -+ document.current.markdown !== markdown || -+ document.current.parserKey !== parserKey -+ ) { -+ const previous = document.current; -+ const append = -+ previous.parserKey === parserKey && -+ previous.markdown.length > 0 && -+ markdown.length > previous.markdown.length && -+ markdown.startsWith(previous.markdown); -+ document.current = { -+ markdown, -+ parserKey, -+ revision: previous.revision + 1, -+ continuityStart: append -+ ? previous.continuityStart -+ : previous.revision + 1, -+ generation: previous.generation + (append ? 0 : 1), -+ }; -+ } -+ const { revision, continuityStart, generation } = document.current; -+ const [manifest, setManifest] = useState(); -+ const acceptedManifest = useRef(undefined); -+ const [layout, setLayout] = useState(); -+ const latestLayout = useRef(undefined); -+ const pendingLayout = useRef(undefined); -+ const [origin, setOrigin] = useState({ x: 0, y: 0 }); -+ const [measurements, setMeasurements] = useState< -+ Record -+ >({}); -+ const reported = useRef(-1); -+ // Only uninterrupted appends with identical parser inputs retain prior data. -+ // Native revalidates each carried decision against the newly accepted AST. -+ const assets = -+ manifest && manifest.revision >= continuityStart ? manifest.assets : []; -+ const frames = -+ layout && layout.revision >= continuityStart ? layout.frames : []; -+ const frameForAsset = (asset: NativeAsset) => -+ layout?.identities[asset.id] === identity(asset) -+ ? frames.find((entry) => entry.id === asset.id) -+ : undefined; -+ const rendered = assets.flatMap((asset) => { -+ if (asset.kind === 'link' || !asset.eligible || !renderMedia) return []; -+ const content = renderMedia(stripAnchor(asset)); -+ if (content == null || typeof content === 'boolean') return []; -+ return [{ asset, content }]; -+ }); -+ const imageSources = useImageSources( -+ resolveImageSource, -+ continuityStart, -+ manifest && manifest.revision >= continuityStart ? manifest.revision : -1, -+ assets.filter( -+ (asset): asset is NativeAsset & MarkdownMediaAsset => -+ asset.kind === 'image' && -+ !rendered.some((entry) => entry.asset.id === asset.id) -+ ) -+ ); -+ const overrides = rendered.map(({ asset }) => { -+ const measurement = measurements[asset.id]; -+ const box = mediaOverrideForFrame( -+ asset.id, -+ frameForAsset(asset), -+ measurement?.identity === identity(asset) && -+ measurement.generation === generation -+ ? measurement -+ : undefined -+ ); -+ return { -+ id: box.id, -+ height: box.height, -+ width: box.width, -+ url: asset.url, -+ kind: asset.kind, -+ anchor: asset.anchor, -+ }; -+ }); -+ -+ const onNativeDocumentAssets = ( -+ event: NativeSyntheticEvent -+ ) => { -+ if (event.nativeEvent.revision !== document.current.revision) return; -+ const next = event.nativeEvent as unknown as Manifest; -+ acceptedManifest.current = next; -+ setManifest((previous) => -+ previous?.revision === next.revision && -+ JSON.stringify(previous.assets) === JSON.stringify(next.assets) -+ ? previous -+ : next -+ ); -+ // A frame can arrive before its manifest. Stamp only frames of this exact -+ // revision; older frames keep their original occurrence identities. -+ const received = -+ pendingLayout.current?.revision === next.revision -+ ? pendingLayout.current -+ : latestLayout.current?.revision === next.revision -+ ? latestLayout.current -+ : undefined; -+ if (received) { -+ const updated = { ...received, identities: identities(next.assets) }; -+ latestLayout.current = updated; -+ pendingLayout.current = undefined; -+ setLayout(updated); -+ } -+ if (reported.current !== next.revision) { -+ reported.current = next.revision; -+ onDocumentAssets?.({ -+ revision: next.revision, -+ assets: next.assets.map(stripAnchor) as MarkdownDocumentAsset[], -+ }); -+ } -+ }; -+ const onNativeMediaLayout = ( -+ event: NativeSyntheticEvent -+ ) => { -+ const next = event.nativeEvent; -+ if (next.revision !== document.current.revision) return; -+ const valid = validMediaFrames(next.frames); -+ const current = acceptedManifest.current; -+ if (current?.revision !== next.revision) { -+ // Keep mounted slots until the accepted manifest can identify new frames. -+ pendingLayout.current = { revision: next.revision, frames: valid }; -+ return; -+ } -+ const nextLayout = { -+ revision: next.revision, -+ frames: valid, -+ identities: -+ current?.revision === next.revision ? identities(current.assets) : {}, -+ }; -+ latestLayout.current = nextLayout; -+ setLayout((previous) => { -+ if ( -+ previous?.revision === next.revision && -+ JSON.stringify(previous.identities) === -+ JSON.stringify(nextLayout.identities) && -+ previous.frames.length === valid.length && -+ previous.frames.every((frame, index) => { -+ const other = valid[index]!; -+ return ( -+ frame.id === other.id && -+ sameMediaSize(frame.x, other.x) && -+ sameMediaSize(frame.y, other.y) && -+ sameMediaSize(frame.width, other.width) && -+ sameMediaSize(frame.height, other.height) -+ ); -+ }) -+ ) -+ return previous; -+ return nextLayout; -+ }); -+ }; -+ const onNativeLayout = ({ nativeEvent }: LayoutChangeEvent) => { -+ const { x, y } = nativeEvent.layout; -+ setOrigin((previous) => -+ sameMediaSize(previous.x, x) && sameMediaSize(previous.y, y) -+ ? previous -+ : { x, y } -+ ); -+ }; -+ const onSlotLayout = ( -+ asset: NativeAsset & MarkdownMediaAsset, -+ frame: MediaFrameInternal, -+ event: LayoutChangeEvent -+ ) => { -+ const { width, height } = event.nativeEvent.layout; -+ const next = { id: asset.id, width, height }; -+ setMeasurements((previous) => { -+ const current = acceptedManifest.current; -+ const currentAsset = current?.assets.find( -+ (entry) => entry.id === asset.id -+ ); -+ if ( -+ !current || -+ current.revision < document.current.continuityStart || -+ !currentAsset || -+ identity(currentAsset) !== identity(asset) || -+ !acceptMediaMeasurement( -+ revision, -+ document.current.revision, -+ pendingLayout.current?.revision === revision -+ ? pendingLayout.current.frames.find( -+ (entry) => entry.id === frame.id -+ ) -+ : latestLayout.current?.identities[asset.id] === identity(asset) && -+ latestLayout.current.revision >= -+ document.current.continuityStart -+ ? latestLayout.current.frames.find( -+ (entry) => entry.id === frame.id -+ ) -+ : undefined, -+ next, -+ previous[asset.id]?.identity === identity(asset) && -+ previous[asset.id]?.generation === generation -+ ? previous[asset.id] -+ : undefined -+ ) -+ ) -+ return previous; -+ return { -+ ...previous, -+ [asset.id]: { ...next, identity: identity(asset), generation }, -+ }; -+ }); -+ }; -+ -+ const slots = rendered.map(({ asset, content }) => { -+ const frame = frameForAsset(asset); -+ if (!frame) return null; -+ return ( -+ onSlotLayout(asset, frame, event)} -+ > -+ {content} -+ -+ ); -+ }); -+ return { -+ slots, -+ onNativeLayout, -+ nativeProps: { -+ ...imageSources, -+ documentRevision: revision, -+ enableDocumentAssets: -+ !!renderMedia || !!onDocumentAssets || !!resolveImageSource, -+ enableMediaSlots: !!renderMedia, -+ mediaOverridesRevision: -+ manifest && manifest.revision >= continuityStart -+ ? manifest.revision -+ : -1, -+ mediaOverrides: overrides, -+ onDocumentAssets: onNativeDocumentAssets, -+ onMediaLayout: onNativeMediaLayout, -+ }, -+ }; -+} -+ -+const styles = StyleSheet.create({ slot: { position: 'absolute' } }); -diff --git a/src/normalizeMarkdownStyle.ts b/src/normalizeMarkdownStyle.ts -index 6ad61af1a423944dc7e1cd5e0d37e7feda41b20a..c5b4a292c4662a4220382c1f3d1def73e19412ab 100644 ---- a/src/normalizeMarkdownStyle.ts -+++ b/src/normalizeMarkdownStyle.ts -@@ -7,7 +7,10 @@ import type { - MarkdownStyleInternal, - } from './types/MarkdownStyleInternal'; - import { isStyleEqual, normalizeColor, mergeSubStyle } from './styleUtils'; --import { normalizeLinkVariantEntries } from './linkVariantUtils'; -+import { -+ normalizeLinkVariantEntries, -+ normalizeLinkPillStyle, -+} from './linkVariantUtils'; - import { resolveAdmonitionColors } from './admonitionDefaults'; - import { - DEFAULT_HEADING_FONT_WEIGHT, -@@ -339,6 +342,13 @@ export const normalizeMarkdownStyle = ( - ([pattern, override]): LinkVariantEntryInternal => { - return { - pattern, -+ ...normalizeLinkPillStyle(override), -+ iconTintColor: normalizeColor(override.iconTintColor) as -+ | string -+ | undefined, -+ fontFamily: override.fontFamily ?? linkBase.fontFamily, -+ borderColor: (normalizeColor(override.borderColor ?? 'transparent') ?? -+ transparent) as string, - color: ((override.color ? normalizeColor(override.color) : null) ?? - linkBase.color) as string, - underline: override.underline ?? linkBase.underline, -diff --git a/src/normalizeMarkdownStyle.web.ts b/src/normalizeMarkdownStyle.web.ts -index 1ba83c8335880638ce087e86bb19fdfcc87e8224..63709e57df42ad0c2fe02617fa588c9a5df638b5 100644 ---- a/src/normalizeMarkdownStyle.web.ts -+++ b/src/normalizeMarkdownStyle.web.ts -@@ -6,7 +6,10 @@ import type { - MarkdownStyleInternal, - } from './types/MarkdownStyleInternal'; - import { isStyleEqual, mergeSubStyle } from './styleUtils'; --import { normalizeLinkVariantEntries } from './linkVariantUtils'; -+import { -+ normalizeLinkVariantEntries, -+ normalizeLinkPillStyle, -+} from './linkVariantUtils'; - import { resolveAdmonitionColors } from './admonitionDefaults'; - import { - DEFAULT_HEADING_FONT_WEIGHT, -@@ -291,6 +294,10 @@ export const normalizeMarkdownStyle = ( - ([pattern, override]): LinkVariantEntryInternal => { - return { - pattern, -+ ...normalizeLinkPillStyle(override), -+ iconTintColor: override.iconTintColor, -+ fontFamily: override.fontFamily ?? linkBase.fontFamily, -+ borderColor: override.borderColor ?? 'transparent', - color: override.color ?? linkBase.color, - underline: override.underline ?? linkBase.underline, - backgroundColor: override.backgroundColor ?? 'transparent', -diff --git a/src/types/MarkdownStyle.ts b/src/types/MarkdownStyle.ts -index d4b3bb05964a3d19f33fd0b5504f365c183ddea9..0d63fc50f713509723999e9f2ca11cbb59f4fbca 100644 ---- a/src/types/MarkdownStyle.ts -+++ b/src/types/MarkdownStyle.ts -@@ -126,6 +126,22 @@ export interface LinkVariantStyle { - color?: string; - underline?: boolean; - backgroundColor?: string; -+ fontFamily?: string; -+ /** Render the link as one native pill. Original text and URL remain selectable. */ -+ pill?: boolean; -+ /** Presentation label only. Missing or empty uses the original link text. */ -+ label?: string; -+ /** Local file:// image URI. Unreadable files are ignored. Native pills only. */ -+ iconUri?: string; -+ /** Optional source-in icon tint. Omitted preserves original image colors and alpha. */ -+ iconTintColor?: string; -+ borderRadius?: number; -+ paddingHorizontal?: number; -+ paddingVertical?: number; -+ borderWidth?: number; -+ borderColor?: string; -+ /** Maximum pill width in points/DIP. 0 uses the available text width. */ -+ maxWidth?: number; - } - - interface StrongStyle { -@@ -358,7 +374,8 @@ export interface MarkdownStyle { - * - * `color` and `underline` inherit from the base `link` style when omitted. - * `backgroundColor` defaults to `transparent`. -- * `fontFamily` always follows the base `link` style and cannot be overridden per-variant. -+ * `fontFamily` inherits the base `link` family and can be overridden per variant. -+ * `pill: true` enables atomic native presentation with optional label, icon, and geometry. - * - * @example - * linkVariants: { -diff --git a/src/types/MarkdownStyleInternal.ts b/src/types/MarkdownStyleInternal.ts -index 7e1e5ab2a9fdcb1755cd56988cd9464281911d4d..922ae8b74de9e030b8ec3103774231cbc9da1c9d 100644 ---- a/src/types/MarkdownStyleInternal.ts -+++ b/src/types/MarkdownStyleInternal.ts -@@ -109,6 +109,17 @@ export interface LinkVariantEntryInternal { - color: string; - underline: boolean; - backgroundColor: string; -+ fontFamily: string; -+ pill: boolean; -+ label: string; -+ iconUri: string; -+ iconTintColor?: string; -+ borderRadius: number; -+ paddingHorizontal: number; -+ paddingVertical: number; -+ borderWidth: number; -+ borderColor: string; -+ maxWidth: number; - } - - interface StrongStyleInternal { -diff --git a/src/types/MarkdownTextProps.ts b/src/types/MarkdownTextProps.ts -index c088b59d799cc4741f007a97517a1e4cacf95683..fb838c3e7ed163a6c52c14efdcf72ca482044ef8 100644 ---- a/src/types/MarkdownTextProps.ts -+++ b/src/types/MarkdownTextProps.ts -@@ -1,3 +1,9 @@ -+import type { ReactNode } from 'react'; -+import type { -+ MarkdownMediaAsset, -+ MarkdownImageSource, -+ DocumentAssetsEvent, -+} from './media'; - import type { ColorValue, ViewProps, ViewStyle, TextStyle } from 'react-native'; - import type { MarkdownStyle, Md4cFlags } from './MarkdownStyle'; - import type { AccessibilityLabels } from './AccessibilityLabels'; -@@ -122,6 +128,46 @@ export interface EnrichedMarkdownTextProps extends Omit { - * @platform ios, android, web - */ - markdown: string; -+ /** -+ * Render an eligible native media occurrence as a React sibling. Returning -+ * null keeps native rendering. Supports standalone image paragraphs and direct -+ * videos at the document root or in recursive quote/admonition containers in -+ * GitHub flavor on iOS and Android. React content owns interaction -+ * and accessibility; its intrinsic height reserves native layout space. -+ */ -+ renderMedia?: (asset: MarkdownMediaAsset) => ReactNode | null; -+ /** -+ * Resolve image download URI and headers from the accepted native AST. -+ * Null selects native fallback. Pending or rejected resolutions keep a -+ * placeholder. React renderMedia overrides take precedence. Supported only -+ * for GitHub flavor on iOS and Android, including nested/linked images. -+ * Keep the callback identity stable to retain decisions across renders. -+ */ -+ resolveImageSource?: ( -+ asset: MarkdownMediaAsset -+ ) => MarkdownImageSource | null | Promise; -+ /** Native parsed media and link occurrences, including unsupported placements. -+ * Supported in GitHub flavor on iOS and Android. -+ */ -+ onDocumentAssets?: (event: DocumentAssetsEvent) => void; -+ /** -+ * Recognize nonempty matches within parsed plain-text nodes as native links. -+ * The exact matched text is the URL. Existing links and code are excluded. -+ * Uses the input linkRegex conventions: native regex source plus i/s flags. -+ * Other JS flags are not transported; all non-overlapping matches are found. -+ * Patterns must work in NSRegularExpression and java.util.regex.Pattern. -+ * Undefined, null, rejected lookbehinds and invalid native patterns disable it. -+ * @default null -+ * @platform ios, android -+ */ -+ linkRegex?: RegExp | null; -+ /** -+ * Recognize an entire inline-code span as a native link, preserving its code -+ * node and text. Partial matches are ignored. Uses linkRegex conventions. -+ * @default null -+ * @platform ios, android -+ */ -+ inlineCodeLinkRegex?: RegExp | null; - /** - * Style configuration for markdown elements. - * @platform ios, android, web -diff --git a/src/types/media.ts b/src/types/media.ts -new file mode 100644 -index 0000000000000000000000000000000000000000..022d8a784ceacac3fd57ead2155dd899bd9fd4af ---- /dev/null -+++ b/src/types/media.ts -@@ -0,0 +1,40 @@ -+/** Placement in the native parsed document. */ -+export type MarkdownAssetPlacement = -+ | 'block' -+ | 'inline' -+ | 'list' -+ | 'table' -+ | 'blockquote'; -+ -+interface MarkdownAssetDescriptor { -+ /** Occurrence ID, scoped to the component and document lineage. */ -+ id: string; -+ url: string; -+ altText: string; -+ title: string; -+ placement: MarkdownAssetPlacement; -+} -+ -+export interface MarkdownMediaAsset extends MarkdownAssetDescriptor { -+ kind: 'image' | 'video'; -+ /** Whether this placement supports renderMedia. */ -+ eligible: boolean; -+} -+ -+export interface MarkdownLinkAsset extends MarkdownAssetDescriptor { -+ kind: 'link'; -+ eligible: false; -+} -+ -+export type MarkdownDocumentAsset = MarkdownMediaAsset | MarkdownLinkAsset; -+ -+export interface DocumentAssetsEvent { -+ revision: number; -+ assets: MarkdownDocumentAsset[]; -+} -+ -+/** Download transport only; semantic image metadata retains the original URL. */ -+export interface MarkdownImageSource { -+ uri: string; -+ headers?: Record; -+} -diff --git a/src/utils/regexParser.ts b/src/utils/regexParser.ts -index cee4b2c679896d79609bc2a242cf6ca9b2598332..bcdfcef476f7ec879e11026d49f6adadcc5bb0c2 100644 ---- a/src/utils/regexParser.ts -+++ b/src/utils/regexParser.ts -@@ -52,3 +52,11 @@ export const toNativeRegexConfig = ( - isDefault: false, - }; - }; -+ -+/** Renderer recognition is opt-in, including when input normalization falls back. */ -+export const toNativeTextLinkRegexConfig = ( -+ regex: RegExp | undefined | null -+): LinkNativeRegex => { -+ const config = toNativeRegexConfig(regex ?? null); -+ return config.isDefault ? DISABLED_REGEX : config; -+}; -diff --git a/src/web/styles.ts b/src/web/styles.ts -index 77d803d2bc12c38bbfe0fb7b1b89cf16a2dc938a..d21ac2b1d4be8835fe01a803ec4d28f0cdc5288b 100644 ---- a/src/web/styles.ts -+++ b/src/web/styles.ts -@@ -348,7 +348,7 @@ export function linkStyleForUrl( - const backgroundColor = resolved.backgroundColor; - return { - color: resolved.color, -- fontFamily: normalizeFontFamily(base.fontFamily), -+ fontFamily: normalizeFontFamily(resolved.fontFamily), - textDecoration: resolved.underline ? 'underline' : 'none', - ...(backgroundColor && backgroundColor !== 'transparent' - ? { backgroundColor } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a785eca9c594..76721853148a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,7 +106,6 @@ patchedDependencies: expo-notifications@57.0.15: f89252c2c08dc7b3acb8415f319ebbe15fff8c9f88a64ebe1830cd5ac5c9ac40 expo-sharing@57.0.17: 8d2e3b10eb3f52036a9a086800180ec6cebf3b75bccc5b1775117a7244d4ac45 expo-widgets@57.0.15: 319a9ded5db49c5b5215c511a138b33f44c7ea2972eb418192e8d5342fe75ce6 - react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a: b51bef3b188eaad24f1cf0d59fd84a1f187e9862e6ddd38417357f22ec988f37 react-native-gesture-handler@2.32.0: 0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2 react-native-keyboard-controller@1.21.13: 6e4339347bc5bb3c9ea67d85ff5c814058b211c5750f247aba59d07869a2e787 react-native-reanimated@4.5.5: bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d @@ -435,8 +434,8 @@ importers: specifier: 0.86.3 version: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) react-native-enriched-markdown: - specifier: 1.1.0-nightly-20260918-bb2b0942a - version: 1.1.0-nightly-20260918-bb2b0942a(patch_hash=b51bef3b188eaad24f1cf0d59fd84a1f187e9862e6ddd38417357f22ec988f37)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: file:./vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz + version: file:apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) react-native-gesture-handler: specifier: ~2.32.0 version: 2.32.0(patch_hash=0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) @@ -9318,8 +9317,9 @@ packages: '@types/react': '>=18' react: '>=18' - react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a: - resolution: {integrity: sha512-nrxwKa+OJlnf/fKbJzlGy+NZJ5N1D88aiy4eiHBxIqoc67i6DEYOE7rnSRkAPysq8mmnL+nagM2uJLwv4F7e/A==} + react-native-enriched-markdown@file:apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz: + resolution: {integrity: sha512-RCI5b0szfJ8fRL2aM1fjYw3xiJjqeSu/AEN/fgjrLK61M0Y82SoLtzr+o3UzBkOK/G7nmhHvzUtHhjfWl+hP1Q==, tarball: file:apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz} + version: 1.1.0-nightly-20260918-bb2b0942a peerDependencies: katex: '>=0.16.0' react: '*' @@ -20305,7 +20305,7 @@ snapshots: transitivePeerDependencies: - supports-color - react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a(patch_hash=b51bef3b188eaad24f1cf0d59fd84a1f187e9862e6ddd38417357f22ec988f37)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-enriched-markdown@file:apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): dependencies: react: 19.2.3 react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 3098032c8466..e022a437ea77 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -18,7 +18,7 @@ allowBuilds: msw: false node-pty: true sharp: true - react-native-enriched-markdown: true + react-native-enriched-markdown@file:apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz: true utf-8-validate: false workerd: false @@ -193,7 +193,6 @@ patchedDependencies: expo-notifications@57.0.15: patches/expo-notifications@57.0.15.patch expo-sharing@57.0.17: patches/expo-sharing@57.0.17.patch expo-widgets@57.0.15: patches/expo-widgets@57.0.15.patch - react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a: patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch react-native-gesture-handler@2.32.0: patches/react-native-gesture-handler@2.32.0.patch react-native-keyboard-controller@1.21.13: patches/react-native-keyboard-controller@1.21.13.patch # Preserve the final layout frame. Backport of [#10171](https://github.com/software-mansion/react-native-reanimated/pull/10171). diff --git a/scripts/release-smoke.ts b/scripts/release-smoke.ts index 96af9d410280..88407cb7c15f 100644 --- a/scripts/release-smoke.ts +++ b/scripts/release-smoke.ts @@ -45,6 +45,13 @@ function copyWorkspaceManifestFixture(targetRoot: string): void { if (NodeFS.existsSync(patchesDirectory)) { NodeFS.cpSync(patchesDirectory, NodePath.resolve(targetRoot, "patches"), { recursive: true }); } + + const mobileVendorDirectory = NodePath.resolve(repoRoot, "apps/mobile/vendor"); + if (NodeFS.existsSync(mobileVendorDirectory)) { + NodeFS.cpSync(mobileVendorDirectory, NodePath.resolve(targetRoot, "apps/mobile/vendor"), { + recursive: true, + }); + } } function writeMacManifestFixtures(targetRoot: string): { arm64Path: string; x64Path: string } { From 6c0bf49f2a9d59d334dbf24a5c09ea025c26348e Mon Sep 17 00:00:00 2001 From: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com> Date: Sun, 20 Sep 2026 17:31:33 -0700 Subject: [PATCH 07/11] refactor(mobile): separate source text from Markdown integration --- .../assets/file-icons/pierre_agents.png | Bin .../assets/file-icons/pierre_astro.png | Bin .../assets/file-icons/pierre_babel.png | Bin .../assets/file-icons/pierre_bash.png | Bin .../assets/file-icons/pierre_biome.png | Bin .../assets/file-icons/pierre_bootstrap.png | Bin .../assets/file-icons/pierre_browserslist.png | Bin .../assets/file-icons/pierre_bun.png | Bin .../assets/file-icons/pierre_c.png | Bin .../assets/file-icons/pierre_claude.png | Bin .../assets/file-icons/pierre_cpp.png | Bin .../assets/file-icons/pierre_css.png | Bin .../assets/file-icons/pierre_database.png | Bin .../assets/file-icons/pierre_default.png | Bin .../assets/file-icons/pierre_docker.png | Bin .../assets/file-icons/pierre_eslint.png | Bin .../assets/file-icons/pierre_font.png | Bin .../assets/file-icons/pierre_git.png | Bin .../assets/file-icons/pierre_go.png | Bin .../assets/file-icons/pierre_graphql.png | Bin .../assets/file-icons/pierre_html.png | Bin .../assets/file-icons/pierre_image.png | Bin .../assets/file-icons/pierre_javascript.png | Bin .../assets/file-icons/pierre_json.png | Bin .../assets/file-icons/pierre_markdown.png | Bin .../assets/file-icons/pierre_mcp.png | Bin .../assets/file-icons/pierre_nextjs.png | Bin .../assets/file-icons/pierre_npm.png | Bin .../assets/file-icons/pierre_oxc.png | Bin .../assets/file-icons/pierre_pnpm.png | Bin .../assets/file-icons/pierre_postcss.png | Bin .../assets/file-icons/pierre_prettier.png | Bin .../assets/file-icons/pierre_python.png | Bin .../assets/file-icons/pierre_react.png | Bin .../assets/file-icons/pierre_ruby.png | Bin .../assets/file-icons/pierre_rust.png | Bin .../assets/file-icons/pierre_sass.png | Bin .../assets/file-icons/pierre_stylelint.png | Bin .../assets/file-icons/pierre_svelte.png | Bin .../assets/file-icons/pierre_svg.png | Bin .../assets/file-icons/pierre_svgo.png | Bin .../assets/file-icons/pierre_swift.png | Bin .../assets/file-icons/pierre_table.png | Bin .../assets/file-icons/pierre_tailwind.png | Bin .../assets/file-icons/pierre_terraform.png | Bin .../assets/file-icons/pierre_text.png | Bin .../assets/file-icons/pierre_typescript.png | Bin .../assets/file-icons/pierre_video.png | Bin .../assets/file-icons/pierre_vite.png | Bin .../assets/file-icons/pierre_vscode.png | Bin .../assets/file-icons/pierre_vue.png | Bin .../assets/file-icons/pierre_wasm.png | Bin .../assets/file-icons/pierre_webpack.png | Bin .../assets/file-icons/pierre_yml.png | Bin .../assets/file-icons/pierre_zig.png | Bin .../assets/file-icons/pierre_zip.png | Bin .../assets/link-icons/github.png | Bin apps/mobile/{vendor => deps}/README.md | 0 ...kdown-1.1.0-nightly-20260918-bb2b0942a.tgz | Bin .../t3-composer-editor/android/build.gradle | 1 - .../t3composereditor/T3ComposerEditorView.kt | 1 - .../t3composereditor}/T3ContextChip.kt | 4 +- .../ios/T3ComposerEditorView.swift | 2 - .../t3-markdown-text/android/build.gradle | 32 - .../T3MarkdownTextSelectionModule.kt | 302 ------- .../MarkdownSelectionColorTest.kt | 67 -- .../MarkdownSelectionCopyTest.kt | 48 - .../t3-markdown-text/expo-module.config.json | 6 - apps/mobile/modules/t3-markdown-text/index.ts | 16 - .../t3-markdown-text/ios/T3ContextChip.h | 162 ---- .../t3-markdown-text/ios/T3MarkdownText.mm | 829 ------------------ .../ios/T3MarkdownTextComponentDescriptor.h | 13 - .../ios/T3MarkdownTextManager.mm | 36 - .../t3-markdown-text/ios/T3MarkdownTextRun.h | 28 - .../t3-markdown-text/ios/T3MarkdownTextRun.mm | 140 --- .../T3MarkdownTextRunComponentDescriptor.h | 13 - .../ios/T3MarkdownTextRunShadowNode.cpp | 6 - .../ios/T3MarkdownTextRunShadowNode.h | 16 - .../ios/T3MarkdownTextShadowNode.h | 82 -- .../ios/T3MarkdownTextShadowNode.mm | 303 ------- .../modules/t3-markdown-text/package.json | 55 -- .../src/MarkdownTextPrimitive.tsx | 174 ---- .../src/T3MarkdownTextSelectionModule.ts | 30 - .../src/markdownFileIcons.generated.ts | 60 -- .../LICENSE | 0 .../T3SourceText.podspec} | 6 +- .../UPSTREAM.md | 3 +- apps/mobile/modules/t3-source-text/index.ts | 1 + .../ios/T3SourceText.h} | 6 +- .../t3-source-text/ios/T3SourceText.mm | 293 +++++++ .../ios/T3SourceTextComponentDescriptor.h | 14 + .../t3-source-text/ios/T3SourceTextManager.mm | 29 + .../t3-source-text/ios/T3SourceTextRun.h | 20 + .../t3-source-text/ios/T3SourceTextRun.mm | 54 ++ .../ios/T3SourceTextRunComponentDescriptor.h | 14 + .../ios/T3SourceTextRunShadowNode.cpp | 6 + .../ios/T3SourceTextRunShadowNode.h | 14 + .../ios/T3SourceTextShadowNode.h | 45 + .../ios/T3SourceTextShadowNode.mm | 171 ++++ .../modules/t3-source-text/package.json | 35 + .../react-native.config.js | 2 +- .../modules/t3-source-text/src/SourceText.tsx | 52 ++ .../src/T3SourceTextNativeComponent.ts} | 14 +- .../src/T3SourceTextRunNativeComponent.ts} | 21 +- .../src/util.ts | 7 +- apps/mobile/package.json | 6 +- .../scripts/sync-pierre-file-icons.mjs | 10 +- .../mobile/src/components/PierreEntryIcon.tsx | 4 +- .../features/files/FileMarkdownPreview.tsx | 2 +- .../src/features/files/SourceFileSurface.tsx | 17 +- .../src/features/threads/ThreadFeed.tsx | 4 +- .../src/features/threads/fileChipMenu.ts | 4 +- .../src/lib/composerChipPresentation.test.ts | 12 +- .../lib}/composerChipPresentation.ts | 0 .../src/lib/enrichedLinkPresentation.ts | 6 +- .../src/lib/markdownFileIcons.generated.ts | 60 ++ .../src => src/lib}/markdownFileIcons.ts | 0 .../src => src/lib}/markdownLinkIcons.ts | 2 +- apps/mobile/src/lib/markdownLinks.test.ts | 5 +- .../src => src/lib}/markdownLinks.ts | 0 apps/mobile/src/lib/markdownMedia.ts | 2 +- apps/mobile/src/lib/mediaActions.ts | 2 +- .../src/native/EnrichedMarkdownText.tsx | 2 +- .../src/native/SelectableMarkdownText.tsx | 4 +- .../native}/SelectableMarkdownText.types.ts | 0 .../src/native/T3ComposerEditor.ios.tsx | 9 +- .../src/native/T3ComposerEditor.native.tsx | 9 +- .../src/native/useEnrichedLinkVariants.ts | 11 +- .../src/native/useMarkdownImageSource.ts | 4 +- knip.jsonc | 2 +- pnpm-lock.yaml | 46 +- pnpm-workspace.yaml | 2 +- scripts/release-smoke.ts | 8 +- third-party-licenses.config.json | 2 +- 134 files changed, 904 insertions(+), 2564 deletions(-) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_agents.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_astro.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_babel.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_bash.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_biome.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_bootstrap.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_browserslist.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_bun.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_c.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_claude.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_cpp.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_css.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_database.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_default.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_docker.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_eslint.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_font.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_git.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_go.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_graphql.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_html.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_image.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_javascript.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_json.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_markdown.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_mcp.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_nextjs.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_npm.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_oxc.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_pnpm.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_postcss.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_prettier.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_python.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_react.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_ruby.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_rust.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_sass.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_stylelint.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_svelte.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_svg.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_svgo.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_swift.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_table.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_tailwind.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_terraform.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_text.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_typescript.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_video.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_vite.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_vscode.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_vue.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_wasm.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_webpack.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_yml.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_zig.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/file-icons/pierre_zip.png (100%) rename apps/mobile/{modules/t3-markdown-text => }/assets/link-icons/github.png (100%) rename apps/mobile/{vendor => deps}/README.md (100%) rename apps/mobile/{vendor => deps}/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz (100%) rename apps/mobile/modules/{t3-markdown-text/android/src/main/java/expo/modules/t3markdowntext => t3-composer-editor/android/src/main/java/expo/modules/t3composereditor}/T3ContextChip.kt (98%) delete mode 100644 apps/mobile/modules/t3-markdown-text/android/build.gradle delete mode 100644 apps/mobile/modules/t3-markdown-text/android/src/main/java/expo/modules/t3markdowntext/T3MarkdownTextSelectionModule.kt delete mode 100644 apps/mobile/modules/t3-markdown-text/android/src/test/java/expo/modules/t3markdowntext/MarkdownSelectionColorTest.kt delete mode 100644 apps/mobile/modules/t3-markdown-text/android/src/test/java/expo/modules/t3markdowntext/MarkdownSelectionCopyTest.kt delete mode 100644 apps/mobile/modules/t3-markdown-text/expo-module.config.json delete mode 100644 apps/mobile/modules/t3-markdown-text/index.ts delete mode 100644 apps/mobile/modules/t3-markdown-text/ios/T3ContextChip.h delete mode 100644 apps/mobile/modules/t3-markdown-text/ios/T3MarkdownText.mm delete mode 100644 apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextComponentDescriptor.h delete mode 100644 apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextManager.mm delete mode 100644 apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRun.h delete mode 100644 apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRun.mm delete mode 100644 apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRunComponentDescriptor.h delete mode 100644 apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRunShadowNode.cpp delete mode 100644 apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRunShadowNode.h delete mode 100644 apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextShadowNode.h delete mode 100644 apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextShadowNode.mm delete mode 100644 apps/mobile/modules/t3-markdown-text/package.json delete mode 100644 apps/mobile/modules/t3-markdown-text/src/MarkdownTextPrimitive.tsx delete mode 100644 apps/mobile/modules/t3-markdown-text/src/T3MarkdownTextSelectionModule.ts delete mode 100644 apps/mobile/modules/t3-markdown-text/src/markdownFileIcons.generated.ts rename apps/mobile/modules/{t3-markdown-text => t3-source-text}/LICENSE (100%) rename apps/mobile/modules/{t3-markdown-text/T3MarkdownText.podspec => t3-source-text/T3SourceText.podspec} (77%) rename apps/mobile/modules/{t3-markdown-text => t3-source-text}/UPSTREAM.md (82%) create mode 100644 apps/mobile/modules/t3-source-text/index.ts rename apps/mobile/modules/{t3-markdown-text/ios/T3MarkdownText.h => t3-source-text/ios/T3SourceText.h} (55%) create mode 100644 apps/mobile/modules/t3-source-text/ios/T3SourceText.mm create mode 100644 apps/mobile/modules/t3-source-text/ios/T3SourceTextComponentDescriptor.h create mode 100644 apps/mobile/modules/t3-source-text/ios/T3SourceTextManager.mm create mode 100644 apps/mobile/modules/t3-source-text/ios/T3SourceTextRun.h create mode 100644 apps/mobile/modules/t3-source-text/ios/T3SourceTextRun.mm create mode 100644 apps/mobile/modules/t3-source-text/ios/T3SourceTextRunComponentDescriptor.h create mode 100644 apps/mobile/modules/t3-source-text/ios/T3SourceTextRunShadowNode.cpp create mode 100644 apps/mobile/modules/t3-source-text/ios/T3SourceTextRunShadowNode.h create mode 100644 apps/mobile/modules/t3-source-text/ios/T3SourceTextShadowNode.h create mode 100644 apps/mobile/modules/t3-source-text/ios/T3SourceTextShadowNode.mm create mode 100644 apps/mobile/modules/t3-source-text/package.json rename apps/mobile/modules/{t3-markdown-text => t3-source-text}/react-native.config.js (70%) create mode 100644 apps/mobile/modules/t3-source-text/src/SourceText.tsx rename apps/mobile/modules/{t3-markdown-text/src/T3MarkdownTextNativeComponent.ts => t3-source-text/src/T3SourceTextNativeComponent.ts} (76%) rename apps/mobile/modules/{t3-markdown-text/src/T3MarkdownTextRunNativeComponent.ts => t3-source-text/src/T3SourceTextRunNativeComponent.ts} (67%) rename apps/mobile/modules/{t3-markdown-text => t3-source-text}/src/util.ts (83%) rename apps/mobile/{modules/t3-markdown-text => }/scripts/sync-pierre-file-icons.mjs (90%) rename apps/mobile/{modules/t3-markdown-text/src => src/lib}/composerChipPresentation.ts (100%) create mode 100644 apps/mobile/src/lib/markdownFileIcons.generated.ts rename apps/mobile/{modules/t3-markdown-text/src => src/lib}/markdownFileIcons.ts (100%) rename apps/mobile/{modules/t3-markdown-text/src => src/lib}/markdownLinkIcons.ts (88%) rename apps/mobile/{modules/t3-markdown-text/src => src/lib}/markdownLinks.ts (100%) rename apps/mobile/{modules/t3-markdown-text/src => src/native}/SelectableMarkdownText.types.ts (100%) diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_agents.png b/apps/mobile/assets/file-icons/pierre_agents.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_agents.png rename to apps/mobile/assets/file-icons/pierre_agents.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_astro.png b/apps/mobile/assets/file-icons/pierre_astro.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_astro.png rename to apps/mobile/assets/file-icons/pierre_astro.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_babel.png b/apps/mobile/assets/file-icons/pierre_babel.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_babel.png rename to apps/mobile/assets/file-icons/pierre_babel.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_bash.png b/apps/mobile/assets/file-icons/pierre_bash.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_bash.png rename to apps/mobile/assets/file-icons/pierre_bash.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_biome.png b/apps/mobile/assets/file-icons/pierre_biome.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_biome.png rename to apps/mobile/assets/file-icons/pierre_biome.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_bootstrap.png b/apps/mobile/assets/file-icons/pierre_bootstrap.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_bootstrap.png rename to apps/mobile/assets/file-icons/pierre_bootstrap.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_browserslist.png b/apps/mobile/assets/file-icons/pierre_browserslist.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_browserslist.png rename to apps/mobile/assets/file-icons/pierre_browserslist.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_bun.png b/apps/mobile/assets/file-icons/pierre_bun.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_bun.png rename to apps/mobile/assets/file-icons/pierre_bun.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_c.png b/apps/mobile/assets/file-icons/pierre_c.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_c.png rename to apps/mobile/assets/file-icons/pierre_c.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_claude.png b/apps/mobile/assets/file-icons/pierre_claude.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_claude.png rename to apps/mobile/assets/file-icons/pierre_claude.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_cpp.png b/apps/mobile/assets/file-icons/pierre_cpp.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_cpp.png rename to apps/mobile/assets/file-icons/pierre_cpp.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_css.png b/apps/mobile/assets/file-icons/pierre_css.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_css.png rename to apps/mobile/assets/file-icons/pierre_css.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_database.png b/apps/mobile/assets/file-icons/pierre_database.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_database.png rename to apps/mobile/assets/file-icons/pierre_database.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_default.png b/apps/mobile/assets/file-icons/pierre_default.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_default.png rename to apps/mobile/assets/file-icons/pierre_default.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_docker.png b/apps/mobile/assets/file-icons/pierre_docker.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_docker.png rename to apps/mobile/assets/file-icons/pierre_docker.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_eslint.png b/apps/mobile/assets/file-icons/pierre_eslint.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_eslint.png rename to apps/mobile/assets/file-icons/pierre_eslint.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_font.png b/apps/mobile/assets/file-icons/pierre_font.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_font.png rename to apps/mobile/assets/file-icons/pierre_font.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_git.png b/apps/mobile/assets/file-icons/pierre_git.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_git.png rename to apps/mobile/assets/file-icons/pierre_git.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_go.png b/apps/mobile/assets/file-icons/pierre_go.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_go.png rename to apps/mobile/assets/file-icons/pierre_go.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_graphql.png b/apps/mobile/assets/file-icons/pierre_graphql.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_graphql.png rename to apps/mobile/assets/file-icons/pierre_graphql.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_html.png b/apps/mobile/assets/file-icons/pierre_html.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_html.png rename to apps/mobile/assets/file-icons/pierre_html.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_image.png b/apps/mobile/assets/file-icons/pierre_image.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_image.png rename to apps/mobile/assets/file-icons/pierre_image.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_javascript.png b/apps/mobile/assets/file-icons/pierre_javascript.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_javascript.png rename to apps/mobile/assets/file-icons/pierre_javascript.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_json.png b/apps/mobile/assets/file-icons/pierre_json.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_json.png rename to apps/mobile/assets/file-icons/pierre_json.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_markdown.png b/apps/mobile/assets/file-icons/pierre_markdown.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_markdown.png rename to apps/mobile/assets/file-icons/pierre_markdown.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_mcp.png b/apps/mobile/assets/file-icons/pierre_mcp.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_mcp.png rename to apps/mobile/assets/file-icons/pierre_mcp.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_nextjs.png b/apps/mobile/assets/file-icons/pierre_nextjs.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_nextjs.png rename to apps/mobile/assets/file-icons/pierre_nextjs.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_npm.png b/apps/mobile/assets/file-icons/pierre_npm.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_npm.png rename to apps/mobile/assets/file-icons/pierre_npm.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_oxc.png b/apps/mobile/assets/file-icons/pierre_oxc.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_oxc.png rename to apps/mobile/assets/file-icons/pierre_oxc.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_pnpm.png b/apps/mobile/assets/file-icons/pierre_pnpm.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_pnpm.png rename to apps/mobile/assets/file-icons/pierre_pnpm.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_postcss.png b/apps/mobile/assets/file-icons/pierre_postcss.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_postcss.png rename to apps/mobile/assets/file-icons/pierre_postcss.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_prettier.png b/apps/mobile/assets/file-icons/pierre_prettier.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_prettier.png rename to apps/mobile/assets/file-icons/pierre_prettier.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_python.png b/apps/mobile/assets/file-icons/pierre_python.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_python.png rename to apps/mobile/assets/file-icons/pierre_python.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_react.png b/apps/mobile/assets/file-icons/pierre_react.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_react.png rename to apps/mobile/assets/file-icons/pierre_react.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_ruby.png b/apps/mobile/assets/file-icons/pierre_ruby.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_ruby.png rename to apps/mobile/assets/file-icons/pierre_ruby.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_rust.png b/apps/mobile/assets/file-icons/pierre_rust.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_rust.png rename to apps/mobile/assets/file-icons/pierre_rust.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_sass.png b/apps/mobile/assets/file-icons/pierre_sass.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_sass.png rename to apps/mobile/assets/file-icons/pierre_sass.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_stylelint.png b/apps/mobile/assets/file-icons/pierre_stylelint.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_stylelint.png rename to apps/mobile/assets/file-icons/pierre_stylelint.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_svelte.png b/apps/mobile/assets/file-icons/pierre_svelte.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_svelte.png rename to apps/mobile/assets/file-icons/pierre_svelte.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_svg.png b/apps/mobile/assets/file-icons/pierre_svg.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_svg.png rename to apps/mobile/assets/file-icons/pierre_svg.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_svgo.png b/apps/mobile/assets/file-icons/pierre_svgo.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_svgo.png rename to apps/mobile/assets/file-icons/pierre_svgo.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_swift.png b/apps/mobile/assets/file-icons/pierre_swift.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_swift.png rename to apps/mobile/assets/file-icons/pierre_swift.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_table.png b/apps/mobile/assets/file-icons/pierre_table.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_table.png rename to apps/mobile/assets/file-icons/pierre_table.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_tailwind.png b/apps/mobile/assets/file-icons/pierre_tailwind.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_tailwind.png rename to apps/mobile/assets/file-icons/pierre_tailwind.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_terraform.png b/apps/mobile/assets/file-icons/pierre_terraform.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_terraform.png rename to apps/mobile/assets/file-icons/pierre_terraform.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_text.png b/apps/mobile/assets/file-icons/pierre_text.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_text.png rename to apps/mobile/assets/file-icons/pierre_text.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_typescript.png b/apps/mobile/assets/file-icons/pierre_typescript.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_typescript.png rename to apps/mobile/assets/file-icons/pierre_typescript.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_video.png b/apps/mobile/assets/file-icons/pierre_video.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_video.png rename to apps/mobile/assets/file-icons/pierre_video.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_vite.png b/apps/mobile/assets/file-icons/pierre_vite.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_vite.png rename to apps/mobile/assets/file-icons/pierre_vite.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_vscode.png b/apps/mobile/assets/file-icons/pierre_vscode.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_vscode.png rename to apps/mobile/assets/file-icons/pierre_vscode.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_vue.png b/apps/mobile/assets/file-icons/pierre_vue.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_vue.png rename to apps/mobile/assets/file-icons/pierre_vue.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_wasm.png b/apps/mobile/assets/file-icons/pierre_wasm.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_wasm.png rename to apps/mobile/assets/file-icons/pierre_wasm.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_webpack.png b/apps/mobile/assets/file-icons/pierre_webpack.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_webpack.png rename to apps/mobile/assets/file-icons/pierre_webpack.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_yml.png b/apps/mobile/assets/file-icons/pierre_yml.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_yml.png rename to apps/mobile/assets/file-icons/pierre_yml.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_zig.png b/apps/mobile/assets/file-icons/pierre_zig.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_zig.png rename to apps/mobile/assets/file-icons/pierre_zig.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_zip.png b/apps/mobile/assets/file-icons/pierre_zip.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/file-icons/pierre_zip.png rename to apps/mobile/assets/file-icons/pierre_zip.png diff --git a/apps/mobile/modules/t3-markdown-text/assets/link-icons/github.png b/apps/mobile/assets/link-icons/github.png similarity index 100% rename from apps/mobile/modules/t3-markdown-text/assets/link-icons/github.png rename to apps/mobile/assets/link-icons/github.png diff --git a/apps/mobile/vendor/README.md b/apps/mobile/deps/README.md similarity index 100% rename from apps/mobile/vendor/README.md rename to apps/mobile/deps/README.md diff --git a/apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz b/apps/mobile/deps/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz similarity index 100% rename from apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz rename to apps/mobile/deps/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz diff --git a/apps/mobile/modules/t3-composer-editor/android/build.gradle b/apps/mobile/modules/t3-composer-editor/android/build.gradle index 0a3e7ed7e17b..9425c8f7de36 100644 --- a/apps/mobile/modules/t3-composer-editor/android/build.gradle +++ b/apps/mobile/modules/t3-composer-editor/android/build.gradle @@ -20,7 +20,6 @@ android { dependencies { implementation project(':expo-modules-core') - implementation project(':t3tools-mobile-markdown-text') testImplementation 'junit:junit:4.13.2' testImplementation 'org.robolectric:robolectric:4.16.1' } diff --git a/apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ComposerEditorView.kt b/apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ComposerEditorView.kt index 35d796b7876f..d5cb5030987f 100644 --- a/apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ComposerEditorView.kt +++ b/apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ComposerEditorView.kt @@ -29,7 +29,6 @@ import android.widget.EditText import expo.modules.kotlin.AppContext import expo.modules.kotlin.viewevent.EventDispatcher import expo.modules.kotlin.views.ExpoView -import expo.modules.t3markdowntext.T3ContextChip import org.json.JSONObject import kotlin.math.max diff --git a/apps/mobile/modules/t3-markdown-text/android/src/main/java/expo/modules/t3markdowntext/T3ContextChip.kt b/apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ContextChip.kt similarity index 98% rename from apps/mobile/modules/t3-markdown-text/android/src/main/java/expo/modules/t3markdowntext/T3ContextChip.kt rename to apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ContextChip.kt index df0dd88724e0..0c6757a588a1 100644 --- a/apps/mobile/modules/t3-markdown-text/android/src/main/java/expo/modules/t3markdowntext/T3ContextChip.kt +++ b/apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ContextChip.kt @@ -1,4 +1,4 @@ -package expo.modules.t3markdowntext +package expo.modules.t3composereditor import android.graphics.Canvas import android.graphics.Color @@ -11,7 +11,7 @@ import android.text.TextUtils import kotlin.math.ceil import kotlin.math.min -/** Shared by editable spans and inline chat images so their metrics and colors agree. */ +/** Draws the context chips embedded in the composer. */ class T3ContextChip( content: Content, fontSize: Float, diff --git a/apps/mobile/modules/t3-composer-editor/ios/T3ComposerEditorView.swift b/apps/mobile/modules/t3-composer-editor/ios/T3ComposerEditorView.swift index 50ac2afbcb46..324eed704319 100644 --- a/apps/mobile/modules/t3-composer-editor/ios/T3ComposerEditorView.swift +++ b/apps/mobile/modules/t3-composer-editor/ios/T3ComposerEditorView.swift @@ -928,8 +928,6 @@ public final class T3ComposerEditorView: ExpoView, UITextViewDelegate, UITextDro iconImage: UIImage?, style: ComposerChipStyle ) -> UIImage { - // Kept in step with `T3ContextChipVectorIcon` in the markdown module: a chip drawn here and - // the same chip drawn in a sent message have to be the same picture. let chipFontSize = fontSize * 0.86 let font = UIFont(name: "DMSans-Medium", size: chipFontSize) ?? UIFont.systemFont(ofSize: chipFontSize, weight: .medium) diff --git a/apps/mobile/modules/t3-markdown-text/android/build.gradle b/apps/mobile/modules/t3-markdown-text/android/build.gradle deleted file mode 100644 index 5b7e372006f3..000000000000 --- a/apps/mobile/modules/t3-markdown-text/android/build.gradle +++ /dev/null @@ -1,32 +0,0 @@ -apply plugin: 'com.android.library' -apply plugin: 'org.jetbrains.kotlin.android' - -group = 'com.t3tools.markdowntext' -version = '0.0.0' - -android { - namespace 'expo.modules.t3markdowntext' - compileSdk rootProject.ext.compileSdkVersion - - testOptions { - unitTests.includeAndroidResources = true - } - - defaultConfig { - minSdkVersion rootProject.ext.minSdkVersion - targetSdkVersion rootProject.ext.targetSdkVersion - } -} - -dependencies { - implementation project(':expo-modules-core') - implementation 'com.facebook.react:react-android' - testImplementation 'junit:junit:4.13.2' - testImplementation 'org.robolectric:robolectric:4.16.1' -} - -tasks.withType(Test).configureEach { - javaLauncher = javaToolchains.launcherFor { - languageVersion = JavaLanguageVersion.of(21) - } -} diff --git a/apps/mobile/modules/t3-markdown-text/android/src/main/java/expo/modules/t3markdowntext/T3MarkdownTextSelectionModule.kt b/apps/mobile/modules/t3-markdown-text/android/src/main/java/expo/modules/t3markdowntext/T3MarkdownTextSelectionModule.kt deleted file mode 100644 index bca3c6430304..000000000000 --- a/apps/mobile/modules/t3-markdown-text/android/src/main/java/expo/modules/t3markdowntext/T3MarkdownTextSelectionModule.kt +++ /dev/null @@ -1,302 +0,0 @@ -package expo.modules.t3markdowntext - -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context -import android.graphics.Bitmap -import android.graphics.Canvas -import android.graphics.Color -import android.graphics.Paint -import android.graphics.Typeface -import android.os.Build -import android.text.Spannable -import android.text.SpannableStringBuilder -import android.text.Spanned -import android.text.TextPaint -import android.text.style.ReplacementSpan -import android.view.ActionMode -import android.view.Menu -import android.view.MenuItem -import android.widget.TextView -import android.util.Base64 -import android.util.LruCache -import com.facebook.react.bridge.ReactContext -import com.facebook.react.common.assets.ReactFontManager -import com.facebook.react.uimanager.UIManagerHelper -import expo.modules.kotlin.modules.Module -import expo.modules.kotlin.modules.ModuleDefinition -import kotlin.math.max -import kotlin.math.min -import org.json.JSONObject -import org.json.JSONArray -import java.net.URLEncoder -import java.io.ByteArrayOutputStream -import kotlin.math.ceil - -private const val OBJECT_REPLACEMENT_CHARACTER = "\uFFFC" - -// Match React Native's measurement buffer. Android orders tied line-height -// spans differently in SpannableString, shifting inline images once RN's -// span priorities are exhausted. -private object MarkdownSpannableFactory : Spannable.Factory() { - override fun newSpannable(source: CharSequence): Spannable = - SpannableStringBuilder(source) -} - -internal fun copyTextWithoutInlineImages( - text: CharSequence, - start: Int, - end: Int -): String { - if (text !is Spanned) return text.subSequence(start, end).toString() - - fun isInlineImage(index: Int): Boolean = - index >= 0 && text[index].toString() == OBJECT_REPLACEMENT_CHARACTER && - text.getSpans(index, index + 1, ReplacementSpan::class.java).isNotEmpty() - - return buildString { - for (index in start until end) { - // The renderer inserts one NBSP after each image to keep its label on the same line. - // Inspect the original text even when selection starts after the image. - val isIconSpacer = text[index] == '\u00A0' && isInlineImage(index - 1) - if (!isInlineImage(index) && !isIconSpacer) append(text[index]) - } - } -} - -private fun canonicalSelection( - originalText: String, - start: Int, - end: Int, - ranges: JSONArray? -): String? { - if (ranges == null) return null - val canonical = StringBuilder(originalText) - var hasContext = false - for (index in ranges.length() - 1 downTo 0) { - val range = ranges.optJSONObject(index) ?: continue - val first = max(start, range.optInt("start")) - val last = min(end, range.optInt("end")) - if (last > first) { - canonical.replace(first - start, last - start, range.optString("text")) - hasContext = true - } - } - return if (hasContext) canonical.toString().replace(OBJECT_REPLACEMENT_CHARACTER, "") else null -} - -private fun selectedContextRecords(records: JSONArray, selectedText: String): JSONArray { - val ids = mutableSetOf() - for (index in 0 until records.length()) { - val record = records.getJSONObject(index) - if (selectedText.contains("/${record.optString("contextId")})")) { - ids.add(record.optString("contextId")) - if (record.has("screenshotContextId")) ids.add(record.getString("screenshotContextId")) - } - } - val copied = JSONArray() - for (index in 0 until records.length()) { - val record = records.getJSONObject(index) - if (ids.contains(record.optString("contextId"))) copied.put(record) - } - return copied -} - -private fun contextClipData(selectedText: String, fragment: String): ClipData { - val payload = runCatching { JSONObject(fragment) }.getOrNull() - val records = payload?.optJSONArray("records") - val copied = records?.let { selectedContextRecords(it, selectedText) } - if (payload == null || copied == null || copied.length() == 0) { - return ClipData.newPlainText(null, selectedText) - } - payload.put("records", copied) - val attribute = URLEncoder.encode(payload.toString(), "UTF-8").replace("+", "%20") - val escaped = selectedText.replace("&", "&").replace("<", "<").replace(">", ">") - return ClipData.newHtmlText( - null, - selectedText, - "
    $escaped
    " - ) -} - -private class SanitizingSelectionActionModeCallback( - private val textView: TextView, - private val delegate: ActionMode.Callback?, - var contextClipboardConfig: String -) : ActionMode.Callback { - override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean = - delegate?.onCreateActionMode(mode, menu) ?: true - - override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean = - delegate?.onPrepareActionMode(mode, menu) ?: false - - override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { - if (item.itemId == android.R.id.copy && copySelection()) { - mode.finish() - return true - } - return delegate?.onActionItemClicked(mode, item) ?: false - } - - private fun copySelection(): Boolean { - val start = min(textView.selectionStart, textView.selectionEnd) - val end = max(textView.selectionStart, textView.selectionEnd) - if (start < 0 || end <= start) return false - val originalText = textView.text.subSequence(start, end).toString() - val config = runCatching { JSONObject(contextClipboardConfig) }.getOrNull() - val canonical = canonicalSelection(originalText, start, end, config?.optJSONArray("ranges")) - val selectedText = canonical ?: copyTextWithoutInlineImages(textView.text, start, end) - val handled = canonical != null || selectedText != originalText - if (handled) { - val clipboard = - textView.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - val clip = if (canonical != null) { - contextClipData(selectedText, config?.optString("fragment") ?: "") - } else { - ClipData.newPlainText(null, selectedText) - } - clipboard.setPrimaryClip(clip) - } - return handled - } - - override fun onDestroyActionMode(mode: ActionMode) { - delegate?.onDestroyActionMode(mode) - } -} - -internal fun applySelectionHandleColor(textView: TextView, color: Int) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) return - textView.textSelectHandle?.mutate()?.apply { setTint(color) }?.let(textView::setTextSelectHandle) - textView.textSelectHandleLeft?.mutate()?.apply { - setTint(color) - }?.let(textView::setTextSelectHandleLeft) - textView.textSelectHandleRight?.mutate()?.apply { - setTint(color) - }?.let(textView::setTextSelectHandleRight) -} - -class T3MarkdownTextSelectionModule : Module() { - private val chipImages = LruCache>(128) - - /** - * Metrics of the paragraph font a chip sits in, so the inline box it reports can be sized - * from the same ascent and descent the surrounding text lays out with. - */ - private fun paragraphFontMetrics(text: JSONObject?, scale: Float): Paint.FontMetricsInt = - TextPaint(Paint.ANTI_ALIAS_FLAG).apply { - textSize = (text?.optDouble("fontSize", 15.0)?.toFloat() ?: 15f).coerceIn(6f, 80f) * scale - val fontFamily = text?.optString("fontFamily").orEmpty() - typeface = if (fontFamily.isEmpty()) { - Typeface.DEFAULT - } else { - ReactFontManager.getInstance() - .getTypeface(fontFamily, Typeface.NORMAL, appContext.reactContext?.assets) - } - }.fontMetricsInt - - private fun setSelectionHandleColor(reactTag: Int, color: Int) { - val reactContext = appContext.reactContext as? ReactContext ?: return - reactContext.runOnUiQueueThread { - val textView = runCatching { - UIManagerHelper.getUIManagerForReactTag(reactContext, reactTag)?.resolveView(reactTag) - }.getOrNull() as? TextView ?: return@runOnUiQueueThread - applySelectionHandleColor(textView, color) - } - } - - override fun definition() = ModuleDefinition { - Name("T3MarkdownTextSelection") - - Function("setSelectionHandleColor") { reactTag: Int, color: Int -> - setSelectionHandleColor(reactTag, color) - } - - Function("renderContextChip") { payloadJson: String -> - val resources = appContext.reactContext?.resources ?: return@Function null - val metrics = resources.displayMetrics - val fontScale = resources.configuration.fontScale - val key = "${metrics.density}:$fontScale:${metrics.widthPixels}:$payloadJson" - chipImages.get(key)?.let { return@Function it } - val payload = JSONObject(payloadJson) - val chip = T3ContextChip( - content = T3ContextChip.Content( - label = payload.optString("label").take(4096), - symbol = payload.optString("symbol", "doc") - ), - // The line box around the chip is measured with `fontScale` below, so the chip has to - // carry it too, or it shrinks against the words beside it at a larger text size. - fontSize = - payload.optDouble("fontSize", 12.0).toFloat().coerceIn(10f, 40f) * - metrics.density * fontScale, - colors = T3ContextChip.Colors( - accent = T3ContextChip.color(payload.optString("accent"), Color.GRAY), - foreground = T3ContextChip.color(payload.optString("foreground"), Color.BLACK), - border = T3ContextChip.color(payload.optString("border"), Color.GRAY) - ), - maximumWidth = (metrics.widthPixels - 80 * metrics.density).coerceAtLeast(100f), - density = metrics.density, - ) - // toInt() truncates, so a fractional pixel of the chip would fall outside the bitmap - // and take the right-hand border with it. Round up: a spare column costs nothing. - // One spare pixel of transparency on each side. Whatever rounding happens between the - // bitmap's pixels and the box's dp then falls on padding instead of on the border. - val bleed = 1 - val bitmap = Bitmap.createBitmap( - ceil(chip.width).toInt() + bleed * 2, - ceil(chip.height).toInt() + bleed * 2, - Bitmap.Config.ARGB_8888 - ) - chip.draw(Canvas(bitmap), bleed.toFloat(), bleed.toFloat()) - val bytes = ByteArrayOutputStream() - bitmap.compress(Bitmap.CompressFormat.PNG, 100, bytes) - bitmap.recycle() - // React Native sits an inline view's box on the text baseline and grows the line's - // ascent to fit it, so a box as tall as the chip lifts the chip above the words and - // pushes the baseline down. Report a box no taller than the paragraph font's ascent, - // which leaves the line exactly as tall as a line of plain text, plus where inside - // that box the bitmap must sit so the chip centres on the font's ascent/descent box: - // the same rule the composer's ReplacementSpan uses to draw its chips. - val lineMetrics = paragraphFontMetrics( - payload.optJSONObject("text"), - fontScale * metrics.density, - ) - val ascent = -lineMetrics.ascent - val descent = lineMetrics.descent - val bitmapWidth = ceil(chip.width) + bleed * 2 - val bitmapHeight = ceil(chip.height) + bleed * 2 - val result = mapOf( - "uri" to - "data:image/png;base64,${Base64.encodeToString(bytes.toByteArray(), Base64.NO_WRAP)}", - // Layout rounds dp back to whole pixels. Reporting a hair less than the bitmap lets - // that rounding land inside the image and crop its right-hand border, so round the - // box up: an extra fraction of a pixel is invisible, a missing border is not. - "width" to bitmapWidth / metrics.density, - "height" to bitmapHeight / metrics.density, - "boxHeight" to ascent / metrics.density, - "offsetY" to (ascent + descent - bitmapHeight) / 2f / metrics.density, - ) - chipImages.put(key, result) - result - } - - Function("installCopySanitizer") { reactTag: Int, contextClipboardConfig: String -> - val reactContext = appContext.reactContext as? ReactContext ?: return@Function - reactContext.runOnUiQueueThread { - val textView = - runCatching { - UIManagerHelper.getUIManagerForReactTag(reactContext, reactTag)?.resolveView(reactTag) - } - .getOrNull() as? TextView ?: return@runOnUiQueueThread - val currentCallback = textView.customSelectionActionModeCallback - if (currentCallback is SanitizingSelectionActionModeCallback) { - currentCallback.contextClipboardConfig = contextClipboardConfig - return@runOnUiQueueThread - } - textView.setSpannableFactory(MarkdownSpannableFactory) - textView.customSelectionActionModeCallback = - SanitizingSelectionActionModeCallback(textView, currentCallback, contextClipboardConfig) - } - } - } -} diff --git a/apps/mobile/modules/t3-markdown-text/android/src/test/java/expo/modules/t3markdowntext/MarkdownSelectionColorTest.kt b/apps/mobile/modules/t3-markdown-text/android/src/test/java/expo/modules/t3markdowntext/MarkdownSelectionColorTest.kt deleted file mode 100644 index 81703090a3f0..000000000000 --- a/apps/mobile/modules/t3-markdown-text/android/src/test/java/expo/modules/t3markdowntext/MarkdownSelectionColorTest.kt +++ /dev/null @@ -1,67 +0,0 @@ -package expo.modules.t3markdowntext - -import android.graphics.Bitmap -import android.graphics.Canvas -import android.graphics.Color -import android.graphics.drawable.ColorDrawable -import android.graphics.drawable.Drawable -import android.widget.TextView -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.RuntimeEnvironment -import org.robolectric.annotation.Config -import org.robolectric.annotation.GraphicsMode - -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [36], manifest = Config.NONE) -@GraphicsMode(GraphicsMode.Mode.NATIVE) -class MarkdownSelectionColorTest { - private fun textView() = TextView(RuntimeEnvironment.getApplication()).apply { - setTextSelectHandle(ColorDrawable(Color.WHITE)) - setTextSelectHandleLeft(ColorDrawable(Color.WHITE)) - setTextSelectHandleRight(ColorDrawable(Color.WHITE)) - } - - private fun renderedColor(drawable: Drawable?): Int { - requireNotNull(drawable) - val bitmap = Bitmap.createBitmap(4, 4, Bitmap.Config.ARGB_8888) - drawable.setBounds(0, 0, 4, 4) - drawable.draw(Canvas(bitmap)) - val color = bitmap.getPixel(2, 2) - bitmap.recycle() - return color - } - - @Test - fun retintsAllHandlesWhenTheThemeChangesWithoutChangingTheHighlight() { - val text = textView() - val highlight = 0x52FF0088 - text.highlightColor = highlight - - for (color in listOf(Color.MAGENTA, Color.GREEN, Color.MAGENTA)) { - applySelectionHandleColor(text, color) - assertEquals(color, renderedColor(text.textSelectHandle)) - assertEquals(color, renderedColor(text.textSelectHandleLeft)) - assertEquals(color, renderedColor(text.textSelectHandleRight)) - assertEquals(highlight, text.highlightColor) - } - } - - @Test - fun doesNotTintOtherTextViewsSharingDrawableState() { - val original = ColorDrawable(Color.WHITE) - val first = textView().apply { - setTextSelectHandleLeft(original.constantState!!.newDrawable()) - } - val second = textView().apply { - setTextSelectHandleLeft(original.constantState!!.newDrawable()) - } - - applySelectionHandleColor(first, Color.MAGENTA) - - assertEquals(Color.MAGENTA, renderedColor(first.textSelectHandleLeft)) - assertEquals(Color.WHITE, renderedColor(second.textSelectHandleLeft)) - } -} diff --git a/apps/mobile/modules/t3-markdown-text/android/src/test/java/expo/modules/t3markdowntext/MarkdownSelectionCopyTest.kt b/apps/mobile/modules/t3-markdown-text/android/src/test/java/expo/modules/t3markdowntext/MarkdownSelectionCopyTest.kt deleted file mode 100644 index da9012ee1665..000000000000 --- a/apps/mobile/modules/t3-markdown-text/android/src/test/java/expo/modules/t3markdowntext/MarkdownSelectionCopyTest.kt +++ /dev/null @@ -1,48 +0,0 @@ -package expo.modules.t3markdowntext - -import android.graphics.drawable.ColorDrawable -import android.text.SpannableString -import android.text.Spanned -import android.text.style.ImageSpan -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config - -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [36], manifest = Config.NONE) -class MarkdownSelectionCopyTest { - private fun withIcon(value: String): SpannableString = SpannableString(value).apply { - val index = value.indexOf('\uFFFC') - setSpan(ImageSpan(ColorDrawable()), index, index + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) - } - - @Test - fun removesIconAndInjectedSpacer() { - val text = withIcon("\uFFFC\u00A0main.go:12 starts the server.") - assertEquals("main.go:12 starts the server.", copyTextWithoutInlineImages(text, 0, text.length)) - } - - @Test - fun removesSpacerWhenSelectionStartsAfterIcon() { - val text = withIcon("\uFFFC\u00A0main.go:12 starts the server.") - assertEquals("main.go:12", copyTextWithoutInlineImages(text, 1, 12)) - } - - @Test - fun preservesAuthoredWhitespaceAndLiteralObjectCharacters() { - val text = withIcon("before\u00A0 \uFFFC\u00A0\u00A0 main.go after\u00A0\uFFFC\u00A0") - assertEquals( - "before\u00A0 \u00A0 main.go after\u00A0\uFFFC\u00A0", - copyTextWithoutInlineImages(text, 0, text.length) - ) - } - - @Test - fun preservesTextWithoutImageSpans() { - val text = "\uFFFC\u00A0main.go" - assertEquals(text, copyTextWithoutInlineImages(text, 0, text.length)) - assertEquals(text, copyTextWithoutInlineImages(SpannableString(text), 0, text.length)) - } -} diff --git a/apps/mobile/modules/t3-markdown-text/expo-module.config.json b/apps/mobile/modules/t3-markdown-text/expo-module.config.json deleted file mode 100644 index f41f760ee7ca..000000000000 --- a/apps/mobile/modules/t3-markdown-text/expo-module.config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "platforms": ["android"], - "android": { - "modules": ["expo.modules.t3markdowntext.T3MarkdownTextSelectionModule"] - } -} diff --git a/apps/mobile/modules/t3-markdown-text/index.ts b/apps/mobile/modules/t3-markdown-text/index.ts deleted file mode 100644 index 4793a8785346..000000000000 --- a/apps/mobile/modules/t3-markdown-text/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -export { markdownFileIconSource } from "./src/markdownFileIcons"; -export { - resolveMarkdownFileIcon, - resolveMarkdownLinkPresentation, - type MarkdownFileIcon, - type MarkdownLinkPresentation, -} from "./src/markdownLinks"; -export { composerChipSizeSuffix, contextChipPresentation } from "./src/composerChipPresentation"; -export { MarkdownTextPrimitive } from "./src/MarkdownTextPrimitive"; -export type { - MarkdownFileContextMenu, - MarkdownFileContextMenuAction, - NativeMarkdownTextStyle, - SelectableMarkdownSkill, - SelectableMarkdownTextProps, -} from "./src/SelectableMarkdownText.types"; diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3ContextChip.h b/apps/mobile/modules/t3-markdown-text/ios/T3ContextChip.h deleted file mode 100644 index 625b7ca97c7b..000000000000 --- a/apps/mobile/modules/t3-markdown-text/ios/T3ContextChip.h +++ /dev/null @@ -1,162 +0,0 @@ -#pragma once - -#import - -// Used by both the shadow measurement and UITextView rendering paths. -static NSDictionary *T3ContextChipPayload(NSString *uri) -{ - if (![uri hasPrefix:@"chip:"]) return nil; - NSData *data = [[uri substringFromIndex:5] dataUsingEncoding:NSUTF8StringEncoding]; - id payload = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; - if (![payload isKindOfClass:NSDictionary.class]) return nil; - // Every consumer draws or substitutes `label`; a missing or non-string one would raise inside - // `replaceCharactersInRange:withString:` while a message is rendering. - if (![payload[@"label"] isKindOfClass:NSString.class]) return nil; - return payload; -} - -static UIColor *T3ContextChipColor(NSString *hex) -{ - unsigned int rgb = 0; - if (![hex isKindOfClass:NSString.class] || hex.length != 7) return UIColor.labelColor; - [[NSScanner scannerWithString:[hex substringFromIndex:1]] scanHexInt:&rgb]; - return [UIColor colorWithRed:((rgb >> 16) & 255) / 255.0 - green:((rgb >> 8) & 255) / 255.0 - blue:(rgb & 255) / 255.0 alpha:1]; -} - -static UIColor *T3ContextChipBlend(UIColor *accent, UIColor *base, CGFloat weight) -{ - CGFloat ar = 0, ag = 0, ab = 0, aa = 0, br = 0, bg = 0, bb = 0, ba = 0; - [accent getRed:&ar green:&ag blue:&ab alpha:&aa]; - [base getRed:&br green:&bg blue:&bb alpha:&ba]; - return [UIColor colorWithRed:ar * weight + br * (1 - weight) - green:ag * weight + bg * (1 - weight) - blue:ab * weight + bb * (1 - weight) - alpha:aa * weight + ba * (1 - weight)]; -} - -// Some chip glyphs have no SF Symbol that reads correctly: the pull request one would land on -// `arrow.triangle.branch`, a road-sign fork that says "branch", not "pull request". Draw those -// from the same lucide geometry web and Android use so one chip looks alike on every surface. -static UIImage *T3ContextChipVectorIcon(NSString *symbol, CGFloat size, UIColor *color) -{ - if (![symbol isEqualToString:@"git-pull-request"]) return nil; - UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] - initWithSize:CGSizeMake(size, size)]; - return [renderer imageWithActions:^(UIGraphicsImageRendererContext *context) { - CGFloat s = size / 24.0; // lucide authors on a 24pt grid. - UIBezierPath *path = [UIBezierPath bezierPath]; - [path appendPath:[UIBezierPath bezierPathWithArcCenter:CGPointMake(18 * s, 18 * s) - radius:3 * s startAngle:0 - endAngle:M_PI * 2 clockwise:YES]]; - [path appendPath:[UIBezierPath bezierPathWithArcCenter:CGPointMake(6 * s, 6 * s) - radius:3 * s startAngle:0 - endAngle:M_PI * 2 clockwise:YES]]; - [path moveToPoint:CGPointMake(13 * s, 6 * s)]; - [path addLineToPoint:CGPointMake(16 * s, 6 * s)]; - [path addCurveToPoint:CGPointMake(18 * s, 8 * s) - controlPoint1:CGPointMake(17.1 * s, 6 * s) - controlPoint2:CGPointMake(18 * s, 6.9 * s)]; - [path addLineToPoint:CGPointMake(18 * s, 15 * s)]; - [path moveToPoint:CGPointMake(6 * s, 9 * s)]; - [path addLineToPoint:CGPointMake(6 * s, 21 * s)]; - path.lineWidth = 2 * s; - path.lineCapStyle = kCGLineCapRound; - path.lineJoinStyle = kCGLineJoinRound; - [color setStroke]; - [path stroke]; - }]; -} - -// Centres the chip on the run font's ascent/descent box, the rule the composer span and -// Android use, so the chip lands in the same place beside the words on every surface. -static inline CGRect T3ContextChipBounds(UIFont *font, CGSize size) -{ - CGFloat y = font != nil ? (font.ascender + font.descender - size.height) / 2 : -3; - return CGRectMake(0, y, size.width, size.height); -} - -// A bare attachment string carries none of the run's attributes. Losing the paragraph -// style at a paragraph's first character drops its line height, and losing the font lets -// a chip-only line shrink to the bitmap, so the placeholder keeps both, plus the run -// colour so a later re-apply (after an image loads) still tints with it. -static inline NSAttributedString *T3MarkdownTextAttachmentString( - NSTextAttachment *attachment, NSDictionary *runAttributes) -{ - NSMutableAttributedString *string = - [[NSAttributedString attributedStringWithAttachment:attachment] mutableCopy]; - for (NSAttributedStringKey key in - @[ - NSFontAttributeName, NSParagraphStyleAttributeName, NSForegroundColorAttributeName, - NSBaselineOffsetAttributeName - ]) { - id value = runAttributes[key]; - if (value != nil) { - [string addAttribute:key value:value range:NSMakeRange(0, string.length)]; - } - } - return string; -} - -static UIFont *T3ContextChipFont(NSDictionary *payload) -{ - CGFloat size = MAX(10, MIN(40, [payload[@"fontSize"] doubleValue])); - size *= payload[@"fontSizeMultiplier"] != nil ? [payload[@"fontSizeMultiplier"] doubleValue] : 1; - return [UIFont fontWithName:@"DMSans-Medium" size:size] - ?: [UIFont systemFontOfSize:size weight:UIFontWeightMedium]; -} - -static inline CGSize T3ContextChipSize(NSDictionary *payload, CGFloat maximumWidth) -{ - UIFont *font = T3ContextChipFont(payload); - NSString *label = payload[@"label"]; - CGFloat textWidth = [label sizeWithAttributes:@{ NSFontAttributeName: font }].width; - return CGSizeMake(MIN(maximumWidth, ceil(textWidth + font.pointSize * 2.5)), - ceil(font.pointSize * 1.41)); -} - -static inline UIImage *T3ContextChipImage(NSDictionary *payload, CGSize size, UIImage *fileIcon) -{ - static NSCache *cache; - static dispatch_once_t once; - dispatch_once(&once, ^{ cache = [NSCache new]; cache.countLimit = 256; }); - NSData *data = [NSJSONSerialization dataWithJSONObject:payload options:NSJSONWritingSortedKeys error:nil]; - NSString *key = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - key = [key stringByAppendingString:NSStringFromCGSize(size)]; - if (fileIcon != nil) key = [key stringByAppendingString:@":file-icon"]; - UIImage *cached = [cache objectForKey:key]; - if (cached) return cached; - UIFont *font = T3ContextChipFont(payload); - CGFloat em = font.pointSize; - UIColor *accent = T3ContextChipColor(payload[@"accent"]); - UIColor *foreground = T3ContextChipBlend(accent, T3ContextChipColor(payload[@"foreground"]), 0.22); - UIColor *border = T3ContextChipBlend(accent, T3ContextChipColor(payload[@"border"]), 0.34); - UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size]; - UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext *context) { - UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect: - CGRectInset(CGRectMake(0, 0, size.width, size.height), 0.5, 0.5) - cornerRadius:em * 0.5]; - [[accent colorWithAlphaComponent:0.11] setFill]; - [path fill]; - [border setStroke]; - path.lineWidth = 1; - [path stroke]; - CGFloat iconSize = em * 1.17; - UIImage *icon = fileIcon - ?: T3ContextChipVectorIcon(payload[@"symbol"], iconSize, foreground) - ?: [[UIImage systemImageNamed:payload[@"symbol"] - withConfiguration:[UIImageSymbolConfiguration configurationWithPointSize:em weight:UIImageSymbolWeightMedium]] - imageWithTintColor:foreground renderingMode:UIImageRenderingModeAlwaysOriginal]; - [icon drawInRect:CGRectMake(em * 0.5, (size.height - iconSize) / 2, iconSize, iconSize)]; - NSMutableParagraphStyle *paragraph = [NSMutableParagraphStyle new]; - paragraph.lineBreakMode = NSLineBreakByTruncatingMiddle; - CGFloat x = em * 2; - [payload[@"label"] drawInRect:CGRectMake(x, (size.height - font.lineHeight) / 2, - MAX(0, size.width - x - em * 0.5), font.lineHeight) - withAttributes:@{ NSFontAttributeName: font, NSForegroundColorAttributeName: foreground, - NSParagraphStyleAttributeName: paragraph }]; - }]; - [cache setObject:image forKey:key]; - return image; -} diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownText.mm b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownText.mm deleted file mode 100644 index 533c13108865..000000000000 --- a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownText.mm +++ /dev/null @@ -1,829 +0,0 @@ -#import "T3MarkdownText.h" -#import "T3MarkdownTextShadowNode.h" -#import "T3MarkdownTextComponentDescriptor.h" -#import "T3MarkdownTextRun.h" -#import "T3ContextChip.h" -#import -#import - -#import -#import -#import -#import -#import "RCTFabricComponentsPlugins.h" - -using namespace facebook::react; - -@interface T3ContextChipAccessibilityElement : UIAccessibilityElement -@property(nonatomic, weak) T3MarkdownTextRun *run; -@end - -@implementation T3ContextChipAccessibilityElement -- (BOOL)accessibilityActivate -{ - if (self.run == nil) return NO; - [self.run onPress]; - return YES; -} -@end - -/** Preserve canonical references and their payload when copying a native text selection. */ -@interface T3ContextCopyTextView : UITextView -@property(nonatomic, copy) NSDictionary *contextClipboardConfig; -@end - -@implementation T3ContextCopyTextView -// Read-only text still supports selecting the entire document after selecting a word. -- (BOOL)canPerformAction:(SEL)action withSender:(id)sender -{ - if (action == @selector(selectAll:)) { - return self.selectable && self.text.length > 0 && self.selectedRange.length < self.text.length; - } - return [super canPerformAction:action withSender:sender]; -} - -- (void)copy:(id)sender -{ - NSRange selected = self.selectedRange; - NSArray *ranges = self.contextClipboardConfig[@"ranges"]; - if (selected.location == NSNotFound || selected.length == 0 || NSMaxRange(selected) > self.text.length || ranges.count == 0) { - [super copy:sender]; - return; - } - NSMutableString *text = [[self.text substringWithRange:selected] mutableCopy]; - BOOL hasContext = NO; - for (NSDictionary *range in [ranges reverseObjectEnumerator]) { - NSUInteger start = [range[@"start"] unsignedIntegerValue]; - NSUInteger end = [range[@"end"] unsignedIntegerValue]; - if (end <= start || end > self.text.length) continue; - NSRange overlap = NSIntersectionRange(selected, NSMakeRange(start, end - start)); - if (overlap.length == 0 || ![range[@"text"] isKindOfClass:NSString.class]) continue; - [text replaceCharactersInRange:NSMakeRange(overlap.location - selected.location, overlap.length) withString:range[@"text"]]; - hasContext = YES; - } - if (!hasContext) { [super copy:sender]; return; } - [text replaceOccurrencesOfString:@"\uFFFC\u00A0" withString:@"" options:0 range:NSMakeRange(0, text.length)]; - NSString *fragment = self.contextClipboardConfig[@"fragment"]; - NSMutableDictionary *payload = [[NSJSONSerialization JSONObjectWithData:[fragment dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:nil] mutableCopy]; - NSArray *records = payload[@"records"]; - NSMutableArray *copied = [NSMutableArray array]; - NSMutableSet *screenshots = [NSMutableSet set]; - for (NSDictionary *record in records) { - if ([text containsString:[NSString stringWithFormat:@"/%@)", record[@"contextId"]]]) { - [copied addObject:record]; - if ([record[@"screenshotContextId"] isKindOfClass:NSString.class]) [screenshots addObject:record[@"screenshotContextId"]]; - } - } - for (NSDictionary *record in records) { - if ([screenshots containsObject:record[@"contextId"]] && ![copied containsObject:record]) [copied addObject:record]; - } - payload[@"records"] = copied; - NSData *encoded = payload ? [NSJSONSerialization dataWithJSONObject:payload options:0 error:nil] : nil; - NSMutableDictionary *item = [@{@"public.utf8-plain-text": text} mutableCopy]; - if (encoded && copied.count > 0) { - NSString *raw = [[NSString alloc] initWithData:encoded encoding:NSUTF8StringEncoding]; - NSString *attribute = [raw stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.alphanumericCharacterSet]; - NSString *escaped = [[[text stringByReplacingOccurrencesOfString:@"&" withString:@"&"] stringByReplacingOccurrencesOfString:@"<" withString:@"<"] stringByReplacingOccurrencesOfString:@">" withString:@">"]; - item[@"app.t3.context-fragment"] = encoded; - item[@"public.html"] = [[NSString stringWithFormat:@"
    %@
    ", attribute, escaped] dataUsingEncoding:NSUTF8StringEncoding]; - } - UIPasteboard.generalPasteboard.items = @[item]; -} -@end - -static void T3MarkdownTextApplyParagraphStyles( - NSMutableAttributedString *attributedString, - const std::vector &styleRanges) -{ - for (const auto &styleRange : styleRanges) { - if (styleRange.length == 0 || styleRange.location >= attributedString.length) { - continue; - } - - const NSRange markerRange = NSMakeRange( - styleRange.location, - MIN(styleRange.length, attributedString.length - styleRange.location)); - const NSRange paragraphRange = [attributedString.string paragraphRangeForRange:markerRange]; - const NSParagraphStyle *existingStyle = - [attributedString attribute:NSParagraphStyleAttributeName - atIndex:paragraphRange.location - effectiveRange:nil]; - NSMutableParagraphStyle *paragraphStyle = - existingStyle ? [existingStyle mutableCopy] : [NSMutableParagraphStyle new]; - paragraphStyle.firstLineHeadIndent = styleRange.firstLineHeadIndent; - paragraphStyle.headIndent = styleRange.headIndent; - paragraphStyle.paragraphSpacing = styleRange.paragraphSpacing; - paragraphStyle.tabStops = @[ - [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft - location:styleRange.headIndent - options:@{}] - ]; - paragraphStyle.defaultTabInterval = styleRange.headIndent; - [attributedString addAttribute:NSParagraphStyleAttributeName - value:paragraphStyle - range:paragraphRange]; - } -} - -static void T3MarkdownTextApplyAttachments( - NSMutableAttributedString *attributedString, - const std::vector &attachmentRanges, - NSDictionary *images) -{ - for (const auto &attachmentRange : attachmentRanges) { - if (attachmentRange.length == 0 || attachmentRange.location >= attributedString.length) { - continue; - } - - NSString *imageUri = [NSString stringWithUTF8String:attachmentRange.imageUri.c_str()]; - NSTextAttachment *attachment = [[NSTextAttachment alloc] init]; - UIImage *image = images[imageUri]; - const BOOL isSymbol = [imageUri hasPrefix:@"sf:"]; - if (isSymbol) { - image = [UIImage systemImageNamed:[imageUri substringFromIndex:3]]; - } - NSDictionary *runAttributes = - [attributedString attributesAtIndex:attachmentRange.location effectiveRange:nil]; - UIColor *foregroundColor = runAttributes[NSForegroundColorAttributeName]; - if (image != nil && (isSymbol || attachmentRange.tintWithForeground)) { - image = [image imageWithTintColor:foregroundColor ?: UIColor.labelColor - renderingMode:UIImageRenderingModeAlwaysOriginal]; - } - attachment.image = image ?: [[UIImage alloc] init]; - const CGFloat attachmentSize = T3MarkdownTextAttachmentSize(attachmentRange); - attachment.bounds = CGRectMake( - 0, - T3MarkdownTextAttachmentBaselineOffset(attachmentRange), - attachmentSize, - attachmentSize); - NSDictionary *chip = T3ContextChipPayload(imageUri); - if (chip != nil) { - CGSize size = CGSizeMake(attachmentRange.chipWidth, attachmentRange.chipHeight); - attachment.bounds = T3ContextChipBounds(runAttributes[NSFontAttributeName], size); - NSString *iconUri = [chip[@"iconUri"] isKindOfClass:NSString.class] ? chip[@"iconUri"] : nil; - attachment.image = T3ContextChipImage(chip, size, iconUri ? images[iconUri] : nil); - } - const NSRange range = NSMakeRange( - attachmentRange.location, - MIN(attachmentRange.length, attributedString.length - attachmentRange.location)); - [attributedString replaceCharactersInRange:range - withAttributedString:T3MarkdownTextAttachmentString(attachment, runAttributes)]; - } -} - -@protocol T3MarkdownOutsideTapTarget -- (void)clearSelectionForOutsideTapWithHitView:(UIView *)hitView; -@end - -@interface T3MarkdownOutsideTapCoordinator : NSObject - -- (instancetype)initWithWindow:(UIWindow *)window; -- (void)addTarget:(id)target; -- (void)removeTarget:(id)target; - -@end - -static const void *T3MarkdownOutsideTapCoordinatorKey = - &T3MarkdownOutsideTapCoordinatorKey; - -@implementation T3MarkdownOutsideTapCoordinator { - __weak UIWindow *_window; - UITapGestureRecognizer *_recognizer; - NSHashTable> *_targets; -} - -- (instancetype)initWithWindow:(UIWindow *)window -{ - if (self = [super init]) { - _window = window; - _targets = [NSHashTable weakObjectsHashTable]; - _recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self - action:@selector(handleTap:)]; - _recognizer.cancelsTouchesInView = NO; - _recognizer.delegate = self; - [window addGestureRecognizer:_recognizer]; - } - return self; -} - -- (void)addTarget:(id)target -{ - [_targets addObject:target]; -} - -- (void)removeTarget:(id)target -{ - [_targets removeObject:target]; - if (_targets.count > 0) { - return; - } - - UIWindow *window = _window; - [window removeGestureRecognizer:_recognizer]; - if (objc_getAssociatedObject(window, T3MarkdownOutsideTapCoordinatorKey) == self) { - objc_setAssociatedObject( - window, - T3MarkdownOutsideTapCoordinatorKey, - nil, - OBJC_ASSOCIATION_RETAIN_NONATOMIC); - } -} - -- (void)handleTap:(UITapGestureRecognizer *)sender -{ - UIWindow *window = _window; - if (window == nil) { - return; - } - - UIView *hitView = [window hitTest:[sender locationInView:window] withEvent:nil]; - if (hitView == nil) { - return; - } - for (id target in _targets.allObjects) { - [target clearSelectionForOutsideTapWithHitView:hitView]; - } -} - -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer - shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer -{ - return YES; -} - -@end - -static T3MarkdownOutsideTapCoordinator * -T3MarkdownOutsideTapCoordinatorForWindow(UIWindow *window) -{ - T3MarkdownOutsideTapCoordinator *coordinator = - objc_getAssociatedObject(window, T3MarkdownOutsideTapCoordinatorKey); - if (coordinator == nil) { - coordinator = [[T3MarkdownOutsideTapCoordinator alloc] initWithWindow:window]; - objc_setAssociatedObject( - window, - T3MarkdownOutsideTapCoordinatorKey, - coordinator, - OBJC_ASSOCIATION_RETAIN_NONATOMIC); - } - return coordinator; -} - -@interface T3MarkdownText () - -@end - -@interface T3MarkdownText () -@end - -@implementation T3MarkdownText { - UIView * _view; - T3ContextCopyTextView * _textView; - T3MarkdownTextShadowNode::ConcreteState::Shared _state; - __weak UIWindow * _outsideTapWindow; - BOOL _suppressSelectionChange; - NSMutableDictionary * _attachmentImages; - NSMutableSet * _pendingAttachmentUris; - UILongPressGestureRecognizer *_longPressGestureRecognizer; - UITapGestureRecognizer *_pressGestureRecognizer; - NSArray *_contextAccessibilityElements; -} - -+ (ComponentDescriptorProvider)componentDescriptorProvider -{ - return concreteComponentDescriptorProvider(); -} - -- (instancetype)initWithFrame:(CGRect)frame -{ - if (self = [super initWithFrame:frame]) { - static const auto defaultProps = std::make_shared(); - _props = defaultProps; - - _view = [[UIView alloc] init]; - self.contentView = _view; - self.clipsToBounds = true; - - _textView = [[T3ContextCopyTextView alloc] init]; - _attachmentImages = [[NSMutableDictionary alloc] init]; - _pendingAttachmentUris = [[NSMutableSet alloc] init]; - _textView.scrollEnabled = false; - _textView.editable = false; - _textView.textContainerInset = UIEdgeInsetsZero; - _textView.textContainer.lineFragmentPadding = 0; - _textView.delegate = self; - // Chat text supports selection and contextual actions, but not drag-and-drop. - _textView.textDragInteraction.enabled = NO; - _textView.linkTextAttributes = @{}; - // Must match RCTTextLayoutManager, which measures with usesFontLeading = NO. - _textView.layoutManager.usesFontLeading = NO; - [self addSubview:_textView]; - - _longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self - action:@selector(handleLongPressIfNecessary:)]; - _longPressGestureRecognizer.delegate = self; - - _pressGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self - action:@selector(handlePressIfNecessary:)]; - _pressGestureRecognizer.delegate = self; - [_pressGestureRecognizer requireGestureRecognizerToFail:_longPressGestureRecognizer]; - - [_textView addGestureRecognizer:_pressGestureRecognizer]; - [_textView addGestureRecognizer:_longPressGestureRecognizer]; - } - - return self; -} - -- (void)didMoveToWindow -{ - [super didMoveToWindow]; - if (_outsideTapWindow == self.window) { - return; - } - if (_outsideTapWindow != nil) { - T3MarkdownOutsideTapCoordinator *coordinator = - objc_getAssociatedObject(_outsideTapWindow, T3MarkdownOutsideTapCoordinatorKey); - [coordinator removeTarget:self]; - } - _outsideTapWindow = self.window; - if (_outsideTapWindow != nil) { - [T3MarkdownOutsideTapCoordinatorForWindow(_outsideTapWindow) addTarget:self]; - } -} - -- (void)dealloc -{ - T3MarkdownOutsideTapCoordinator *coordinator = - objc_getAssociatedObject(_outsideTapWindow, T3MarkdownOutsideTapCoordinatorKey); - [coordinator removeTarget:self]; -} - -- (NSArray *)accessibilityElements -{ - return _contextAccessibilityElements ?: [super accessibilityElements]; -} - -// See RCTParagraphComponentView -- (void)prepareForRecycle -{ - [super prepareForRecycle]; - T3MarkdownOutsideTapCoordinator *coordinator = - objc_getAssociatedObject(_outsideTapWindow, T3MarkdownOutsideTapCoordinatorKey); - [coordinator removeTarget:self]; - _outsideTapWindow = nil; - _state.reset(); - - // Reset the frame to zero so that when it properly lays out on the next use - _textView.frame = CGRectZero; - _textView.attributedText = nil; - _contextAccessibilityElements = nil; -} - -- (void)layoutSubviews -{ - [super layoutSubviews]; - // _textView's frame is assigned inside drawRect, which only fires when - // state changes. Trigger a redraw whenever the host frame moves out from - // under it (rotation, parent relayout) so the text view resizes and - // onTextLayout re-fires with the new line wrapping. - if (!CGRectEqualToRect(_textView.frame, _view.frame)) { - [self setNeedsDisplay]; - } -} - -- (void)drawRect:(CGRect)rect -{ - if (!_state) { - return; - } - - const auto &props = *std::static_pointer_cast(_props); - - const auto attrString = _state->getData().attributedString; - NSMutableAttributedString *convertedAttrString = - [RCTNSAttributedStringFromAttributedString(attrString) mutableCopy]; - T3MarkdownTextApplyParagraphStyles( - convertedAttrString, - _state->getData().paragraphStyleRanges); - T3MarkdownTextApplyAttachments( - convertedAttrString, - _state->getData().attachmentRanges, - _attachmentImages); - // Matches the shadow node so drawn lines sit where measurement put them. - RCTApplyBaselineOffset(convertedAttrString); - NSUInteger runLocation = 0; - for (UIView *child in self.subviews) { - if (![child isKindOfClass:[T3MarkdownTextRun class]]) { - continue; - } - - T3MarkdownTextRun *textChild = (T3MarkdownTextRun *)child; - const NSRange runRange = NSMakeRange(runLocation, textChild.text.length); - runLocation = NSMaxRange(runRange); - if (![textChild hasContextMenu] || runRange.length == 0 || - NSMaxRange(runRange) > convertedAttrString.length) { - continue; - } - - NSURL *link = [NSURL URLWithString: - [NSString stringWithFormat:@"t3-markdown-run://%ld", (long)textChild.tag]]; - if (link != nil) { - // A glyph must not be both a link and an attachment. UIKit caches them as - // different text-item classes and can send `attachment` to a cached link - // on a later tap. Attachment actions already use primaryActionForTextItem. - [convertedAttrString enumerateAttribute:NSAttachmentAttributeName - inRange:runRange - options:0 - usingBlock:^(id attachment, NSRange range, BOOL *stop) { - if (attachment == nil) { - [convertedAttrString addAttribute:NSLinkAttributeName value:link range:range]; - } - }]; - } - } - [self loadAttachmentImages:_state->getData().attachmentRanges]; - - // Setting attributedText clears any active text selection, and re-assigning - // the frame triggers a layout flush that has the same effect. Bail out - // entirely when nothing actually changed so a JS-side state update made in - // response to onSelectionChange doesn't deselect what the user is selecting. - const BOOL textChanged = ![_textView.attributedText isEqualToAttributedString:convertedAttrString]; - const BOOL frameChanged = !CGRectEqualToRect(_textView.frame, _view.frame); - if (!textChanged && !frameChanged) { - return; - } - if (textChanged) { - // Reassigning attributedText clears any active selection. Save it and - // restore after, while suppressing the synthetic textViewDidChangeSelection - // events the clear-then-restore would otherwise produce — those would - // round-trip to JS and re-trigger this same path, causing a loop. - const NSRange savedRange = _textView.selectedRange; - _suppressSelectionChange = YES; - _textView.attributedText = convertedAttrString; - NSMutableString *accessibleText = [convertedAttrString.string mutableCopy]; - for (auto it = _state->getData().attachmentRanges.rbegin(); - it != _state->getData().attachmentRanges.rend(); ++it) { - NSDictionary *chip = T3ContextChipPayload([NSString stringWithUTF8String:it->imageUri.c_str()]); - if (chip != nil && it->location < accessibleText.length) { - [accessibleText replaceCharactersInRange:NSMakeRange(it->location, 1) withString:chip[@"label"]]; - } - } - _textView.accessibilityLabel = accessibleText; - if (savedRange.length > 0 && NSMaxRange(savedRange) <= _textView.attributedText.length) { - _textView.selectedRange = savedRange; - } - _suppressSelectionChange = NO; - } - if (frameChanged) { - _textView.frame = _view.frame; - } - - // Text attachments have no native link element. Expose their existing runs - // at the measured glyph bounds, without inserting views into text layout. - NSMutableArray *accessibleElements = [NSMutableArray arrayWithObject:_textView]; - for (UIView *child in self.subviews) { - if (![child isKindOfClass:T3MarkdownTextRun.class]) continue; - T3MarkdownTextRun *run = (T3MarkdownTextRun *)child; - run.contextChipInteractive = NO; - } - for (const auto &attachmentRange : _state->getData().attachmentRanges) { - NSDictionary *chip = T3ContextChipPayload( - [NSString stringWithUTF8String:attachmentRange.imageUri.c_str()]); - if (![chip[@"interactive"] boolValue]) continue; - NSRange range = NSMakeRange(attachmentRange.location, 1); - T3MarkdownTextRun *run = [self childForCharacterRange:range]; - if (!run || NSMaxRange(range) > convertedAttrString.length) continue; - NSRange glyphRange = [_textView.layoutManager glyphRangeForCharacterRange:range actualCharacterRange:nil]; - CGRect bounds = [_textView.layoutManager boundingRectForGlyphRange:glyphRange - inTextContainer:_textView.textContainer]; - bounds = CGRectOffset(bounds, _textView.textContainerInset.left, _textView.textContainerInset.top); - run.contextChipInteractive = YES; - T3ContextChipAccessibilityElement *element = - [[T3ContextChipAccessibilityElement alloc] initWithAccessibilityContainer:self]; - element.run = run; - element.accessibilityLabel = chip[@"label"]; - element.accessibilityTraits = UIAccessibilityTraitButton; - element.accessibilityFrameInContainerSpace = [_textView convertRect:bounds toView:self]; - [accessibleElements addObject:element]; - } - _contextAccessibilityElements = accessibleElements; - - __block std::vector lines; - const int maxLines = props.numberOfLines; - [_textView.layoutManager enumerateLineFragmentsForGlyphRange:NSMakeRange(0, convertedAttrString.string.length) usingBlock:^(CGRect rect, - CGRect usedRect, - NSTextContainer * _Nonnull textContainer, - NSRange glyphRange, - BOOL * _Nonnull stop) { - const auto charRange = [self->_textView.layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:nil]; - const auto line = [self->_textView.text substringWithRange:charRange]; - lines.push_back(line.UTF8String); - // enumerateLineFragments overshoots maximumNumberOfLines by one on iOS - // 18, so cap explicitly. - if (maxLines > 0 && lines.size() >= (size_t)maxLines) { - *stop = YES; - } - }]; - - if (_eventEmitter != nullptr) { - std::dynamic_pointer_cast(_eventEmitter) - ->onTextLayout(facebook::react::T3MarkdownTextEventEmitter::OnTextLayout{static_cast(self.tag), lines}); - }; -} - -- (void)loadAttachmentImages:(const std::vector &)attachmentRanges -{ - for (const auto &attachmentRange : attachmentRanges) { - NSString *imageUri = [NSString stringWithUTF8String:attachmentRange.imageUri.c_str()]; - if ([imageUri hasPrefix:@"sf:"]) { - continue; - } - NSDictionary *chip = T3ContextChipPayload(imageUri); - if (chip != nil) { - imageUri = [chip[@"iconUri"] isKindOfClass:NSString.class] ? chip[@"iconUri"] : nil; - if (imageUri.length == 0) continue; - } - if (_attachmentImages[imageUri] != nil || [_pendingAttachmentUris containsObject:imageUri]) { - continue; - } - - NSURL *url = [NSURL URLWithString:imageUri]; - if (url == nil) { - continue; - } - if (url.isFileURL) { - UIImage *image = [UIImage imageWithContentsOfFile:url.path]; - if (image != nil) { - _attachmentImages[imageUri] = image; - dispatch_async(dispatch_get_main_queue(), ^{ - [self refreshDisplayedAttachments]; - }); - } - continue; - } - - [_pendingAttachmentUris addObject:imageUri]; - [[[NSURLSession sharedSession] dataTaskWithURL:url - completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { - UIImage *image = data == nil ? nil : [UIImage imageWithData:data]; - dispatch_async(dispatch_get_main_queue(), ^{ - [self->_pendingAttachmentUris removeObject:imageUri]; - if (image != nil) { - self->_attachmentImages[imageUri] = image; - [self refreshDisplayedAttachments]; - } - }); - }] resume]; - } -} - -- (void)refreshDisplayedAttachments -{ - if (!_state || _textView.attributedText == nil) { - return; - } - - NSMutableAttributedString *attributedText = [_textView.attributedText mutableCopy]; - T3MarkdownTextApplyAttachments( - attributedText, - _state->getData().attachmentRanges, - _attachmentImages); - - const NSRange savedRange = _textView.selectedRange; - _suppressSelectionChange = YES; - _textView.attributedText = attributedText; - if (savedRange.location != NSNotFound && - NSMaxRange(savedRange) <= _textView.attributedText.length) { - _textView.selectedRange = savedRange; - } - _suppressSelectionChange = NO; - [_textView setNeedsDisplay]; -} - -- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps -{ - const auto &oldViewProps = *std::static_pointer_cast(_props); - const auto &newViewProps = *std::static_pointer_cast(props); - if (oldViewProps.contextClipboardConfig != newViewProps.contextClipboardConfig) { - NSString *config = RCTNSStringFromString(newViewProps.contextClipboardConfig); - _textView.contextClipboardConfig = config.length ? [NSJSONSerialization JSONObjectWithData:[config dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil] : nil; - } - - if (oldViewProps.numberOfLines != newViewProps.numberOfLines) { - _textView.textContainer.maximumNumberOfLines = newViewProps.numberOfLines; - } - - if (oldViewProps.selectable != newViewProps.selectable) { - _textView.selectable = newViewProps.selectable; - } - - if (oldViewProps.allowFontScaling != newViewProps.allowFontScaling) { - if (@available(iOS 11.0, *)) { - _textView.adjustsFontForContentSizeCategory = newViewProps.allowFontScaling; - } - } - - if (oldViewProps.ellipsizeMode != newViewProps.ellipsizeMode) { - if (newViewProps.ellipsizeMode == T3MarkdownTextEllipsizeMode::Head) { - _textView.textContainer.lineBreakMode = NSLineBreakMode::NSLineBreakByTruncatingHead; - } else if (newViewProps.ellipsizeMode == T3MarkdownTextEllipsizeMode::Middle) { - _textView.textContainer.lineBreakMode = NSLineBreakMode::NSLineBreakByTruncatingMiddle; - } else if (newViewProps.ellipsizeMode == T3MarkdownTextEllipsizeMode::Tail) { - _textView.textContainer.lineBreakMode = NSLineBreakMode::NSLineBreakByTruncatingTail; - } else if (newViewProps.ellipsizeMode == T3MarkdownTextEllipsizeMode::Clip) { - _textView.textContainer.lineBreakMode = NSLineBreakMode::NSLineBreakByClipping; - } - } - - - // I'm not sure if this is really the right way to handle this style. This means that the entire _view_ the text - // is in will have this background color applied. To apply it just to a particular part of a string, you'd need - // to do Hello. - // This is how the base component works though, so we'll go with it for now. Can change later if we want. - if (oldViewProps.backgroundColor != newViewProps.backgroundColor) { - _textView.backgroundColor = RCTUIColorFromSharedColor(newViewProps.backgroundColor); - } - - [super updateProps:props oldProps:oldProps]; -} - -// See RCTParagraphComponentView -- (void)updateState:(const facebook::react::State::Shared &)state oldState:(const facebook::react::State::Shared &)oldState -{ - _state = std::static_pointer_cast(state); - [self setNeedsDisplay]; -} - -// MARK: - UIGestureRecognizerDelegate - -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer -{ - return YES; -} - -- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer -{ - if (gestureRecognizer != _longPressGestureRecognizer && - gestureRecognizer != _pressGestureRecognizer) { - return YES; - } - - const auto location = [self getLocationOfPress:gestureRecognizer]; - const auto child = [self getTouchChild:location]; - return ![child hasContextMenu]; -} - -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch -{ - return YES; -} - -- (void)clearSelectionForOutsideTapWithHitView:(UIView *)hitView -{ - if ([hitView isDescendantOfView:self]) { - return; - } - // Defer past the current event loop turn so any in-flight edit-menu action - // (Copy / Define / Look Up / …) reads the live selection before we clear it. - UITextView *textView = _textView; - dispatch_async(dispatch_get_main_queue(), ^{ - UITextRange *range = textView.selectedTextRange; - if (range != nil && !range.isEmpty) { - textView.selectedTextRange = nil; - } - }); -} - -// MARK: - Touch handling - -- (nullable T3MarkdownTextRun *)childForCharacterRange:(NSRange)characterRange -{ - NSUInteger location = 0; - for (UIView *child in self.subviews) { - if (![child isKindOfClass:[T3MarkdownTextRun class]]) { - continue; - } - - T3MarkdownTextRun *textChild = (T3MarkdownTextRun *)child; - const NSRange range = NSMakeRange(location, textChild.text.length); - if (NSIntersectionRange(range, characterRange).length > 0) { - return textChild; - } - location = NSMaxRange(range); - } - return nil; -} - -- (CGPoint)getLocationOfPress:(UIGestureRecognizer*)sender -{ - return [sender locationInView:_textView]; -} - -- (T3MarkdownTextRun*)getTouchChild:(CGPoint)location -{ - const auto charIndex = [_textView.layoutManager characterIndexForPoint:location - inTextContainer:_textView.textContainer - fractionOfDistanceBetweenInsertionPoints:nil - ]; - - int currIndex = -1; - for (UIView* child in self.subviews) { - if (![child isKindOfClass:[T3MarkdownTextRun class]]) { - continue; - } - - T3MarkdownTextRun* textChild = (T3MarkdownTextRun*)child; - - // This is UTF16 code units!! - currIndex += textChild.text.length; - - if (charIndex <= currIndex) { - return textChild; - } - } - - return nil; -} - -- (void)handlePressIfNecessary:(UITapGestureRecognizer*)sender -{ - const auto location = [self getLocationOfPress:sender]; - const auto child = [self getTouchChild:location]; - - if (child) { - [child onPress]; - } -} - -- (void)handleLongPressIfNecessary:(UILongPressGestureRecognizer*)sender -{ - if (sender.state != UIGestureRecognizerStateBegan) { - return; - } - - const auto location = [self getLocationOfPress:sender]; - const auto child = [self getTouchChild:location]; - - if (child) { - [child onLongPress]; - } -} - -// MARK: - UITextViewDelegate - -- (nullable UIAction *)textView:(UITextView *)textView - primaryActionForTextItem:(UITextItem *)textItem - defaultAction:(UIAction *)defaultAction API_AVAILABLE(ios(17.0)) -{ - T3MarkdownTextRun *child = [self childForCharacterRange:textItem.range]; - if (![child hasContextMenu] && !child.contextChipInteractive) { - return defaultAction; - } - - __weak T3MarkdownTextRun *weakChild = child; - return [UIAction actionWithHandler:^(__kindof UIAction *action) { - [weakChild onPress]; - }]; -} - -- (nullable UITextItemMenuConfiguration *)textView:(UITextView *)textView - menuConfigurationForTextItem:(UITextItem *)textItem - defaultMenu:(UIMenu *)defaultMenu API_AVAILABLE(ios(17.0)) -{ - T3MarkdownTextRun *child = [self childForCharacterRange:textItem.range]; - UIMenu *menu = [child contextMenu]; - if (child.contextChipInteractive && menu == nil) return nil; - return [UITextItemMenuConfiguration configurationWithMenu:menu ?: defaultMenu]; -} - -- (void)textViewDidChangeSelection:(UITextView *)textView -{ - if (_suppressSelectionChange) { - return; - } - if (_eventEmitter == nullptr) { - return; - } - - const NSRange selectedRange = textView.selectedRange; - if (selectedRange.location == NSNotFound) { - return; - } - - // Fires on programmatic selection changes too (e.g. the outside-tap clear - // in handleOutsideTap:), so JS will see a synthetic empty-range event then. - std::dynamic_pointer_cast(_eventEmitter) - ->onSelectionChange(facebook::react::T3MarkdownTextEventEmitter::OnSelectionChange{ - static_cast(self.tag), - static_cast(selectedRange.location), - static_cast(selectedRange.location + selectedRange.length), - }); -} - -Class T3MarkdownTextCls(void) -{ - return T3MarkdownText.class; -} - -@end diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextComponentDescriptor.h b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextComponentDescriptor.h deleted file mode 100644 index 77e21d585100..000000000000 --- a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextComponentDescriptor.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "T3MarkdownTextShadowNode.h" - -#include -#include - -namespace facebook::react { -using T3MarkdownTextComponentDescriptor = ConcreteComponentDescriptor; - -void T3MarkdownTextSpec_registerComponentDescriptorsFromCodegen( - std::shared_ptr registry); -} diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextManager.mm b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextManager.mm deleted file mode 100644 index 3ca2b1eee5b9..000000000000 --- a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextManager.mm +++ /dev/null @@ -1,36 +0,0 @@ -#import -#import -#import "RCTBridge.h" -#import "Utils.h" - -@interface T3MarkdownTextManager : RCTViewManager -@end - -@implementation T3MarkdownTextManager - -RCT_EXPORT_MODULE(T3MarkdownText) - -- (UIView *)view -{ - return [[UIView alloc] init]; -} - -RCT_CUSTOM_VIEW_PROPERTY(color, NSString, UIView) -{ -} - -@end - -@interface T3MarkdownTextRunManager : RCTViewManager -@end - -@implementation T3MarkdownTextRunManager - -RCT_EXPORT_MODULE(T3MarkdownTextRun) - -- (UIView *)view -{ - return nil; -} - -@end diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRun.h b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRun.h deleted file mode 100644 index f5f812451b70..000000000000 --- a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRun.h +++ /dev/null @@ -1,28 +0,0 @@ -// This guard prevent this file to be compiled in the old architecture. -#ifdef RCT_NEW_ARCH_ENABLED -#import -#import -#import - -#ifndef T3MarkdownTextRunNativeComponent_h -#define T3MarkdownTextRunNativeComponent_h - -NS_ASSUME_NONNULL_BEGIN - -@interface T3MarkdownTextRun : RCTViewComponentView - -@property (nonatomic, copy, nullable) NSString *text; -@property (nonatomic, assign) BOOL contextChipInteractive; - -- (nullable UIMenu *)contextMenu; -- (BOOL)hasContextMenu; -- (void)onContextMenuAction:(NSString *)actionIdentifier; -- (void)onPress; -- (void)onLongPress; - -@end - -NS_ASSUME_NONNULL_END - -#endif /* UitextviewViewNativeComponent_h */ -#endif /* RCT_NEW_ARCH_ENABLED */ diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRun.mm b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRun.mm deleted file mode 100644 index d2de6884396f..000000000000 --- a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRun.mm +++ /dev/null @@ -1,140 +0,0 @@ -#import "T3MarkdownTextRun.h" -#import "T3MarkdownText.h" -#import "T3MarkdownTextRunComponentDescriptor.h" -#import -#import -#import -#import "RCTFabricComponentsPlugins.h" -#import "Utils.h" - -using namespace facebook::react; - -@interface T3MarkdownTextRun () - -@end - -@implementation T3MarkdownTextRun { - NSString * _text; - NSString * _contextMenuConfig; -} - -+ (ComponentDescriptorProvider)componentDescriptorProvider -{ - return concreteComponentDescriptorProvider(); -} - -- (instancetype)initWithFrame:(CGRect)frame -{ - if (self = [super initWithFrame:frame]) { - static const auto defaultProps = std::make_shared(); - _props = defaultProps; - } - return self; -} - -- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps -{ - const auto &oldViewProps = *std::static_pointer_cast(_props); - const auto &newViewProps = *std::static_pointer_cast(props); - - if (newViewProps.text != oldViewProps.text) { - NSString *text = [NSString stringWithUTF8String:newViewProps.text.c_str()]; - _text = text; - } - - if (newViewProps.contextMenuConfig != oldViewProps.contextMenuConfig) { - _contextMenuConfig = [NSString stringWithUTF8String:newViewProps.contextMenuConfig.c_str()]; - } - - [super updateProps:props oldProps:oldProps]; -} - -- (BOOL)hasContextMenu -{ - return _contextMenuConfig.length > 0; -} - -- (nullable UIMenu *)contextMenu -{ - if (_contextMenuConfig.length == 0) { - return nil; - } - - NSData *data = [_contextMenuConfig dataUsingEncoding:NSUTF8StringEncoding]; - NSDictionary *config = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; - if (![config isKindOfClass:[NSDictionary class]]) { - return nil; - } - - NSArray *actionConfigs = config[@"actions"]; - if (![actionConfigs isKindOfClass:[NSArray class]] || actionConfigs.count == 0) { - return nil; - } - - NSMutableArray *actions = [NSMutableArray arrayWithCapacity:actionConfigs.count]; - __weak T3MarkdownTextRun *weakSelf = self; - for (NSDictionary *actionConfig in actionConfigs) { - if (![actionConfig isKindOfClass:[NSDictionary class]]) { - continue; - } - NSString *actionIdentifier = actionConfig[@"id"]; - NSString *title = actionConfig[@"title"]; - if (![actionIdentifier isKindOfClass:[NSString class]] || - ![title isKindOfClass:[NSString class]]) { - continue; - } - - UIAction *action = [UIAction actionWithTitle:title - image:nil - identifier:actionIdentifier - handler:^(__kindof UIAction *selectedAction) { - [weakSelf onContextMenuAction:selectedAction.identifier]; - }]; - if ([actionConfig[@"disabled"] boolValue]) { - action.attributes = UIMenuElementAttributesDisabled; - } - [actions addObject:action]; - } - - if (actions.count == 0) { - return nil; - } - NSString *title = [config[@"title"] isKindOfClass:[NSString class]] ? config[@"title"] : @""; - return [UIMenu menuWithTitle:title children:actions]; -} - -- (void)onContextMenuAction:(NSString *)actionIdentifier -{ - if (_eventEmitter != nullptr) { - std::dynamic_pointer_cast(_eventEmitter) - ->onContextMenuAction(facebook::react::T3MarkdownTextRunEventEmitter::OnContextMenuAction{ - static_cast(self.tag), - actionIdentifier.UTF8String, - }); - } -} - -- (void)onPress { - if (_eventEmitter != nullptr) { - std::dynamic_pointer_cast(_eventEmitter) - ->onPress(facebook::react::T3MarkdownTextRunEventEmitter::OnPress{}); - } -} - -- (void)onLongPress { - if (_eventEmitter != nullptr) { - std::dynamic_pointer_cast(_eventEmitter) - ->onLongPress(facebook::react::T3MarkdownTextRunEventEmitter::OnLongPress{}); - } -} - -+ (BOOL)shouldBeRecycled { - return NO; -} - -Class T3MarkdownTextRunCls(void) -{ - return T3MarkdownTextRun.class; -} - -@end diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRunComponentDescriptor.h b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRunComponentDescriptor.h deleted file mode 100644 index 61f9e1a129ee..000000000000 --- a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRunComponentDescriptor.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "T3MarkdownTextRunShadowNode.h" - -#include -#include - -namespace facebook::react { -using T3MarkdownTextRunComponentDescriptor = ConcreteComponentDescriptor; - -void T3MarkdownTextRunSpec_registerComponentDescriptorsFromCodegen( - std::shared_ptr registry); -} diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRunShadowNode.cpp b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRunShadowNode.cpp deleted file mode 100644 index a1af619205df..000000000000 --- a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRunShadowNode.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "T3MarkdownTextRunShadowNode.h" - -namespace facebook::react { - -extern const char T3MarkdownTextRunComponentName[] = "T3MarkdownTextRun"; -} // namespace facebook::react diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRunShadowNode.h b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRunShadowNode.h deleted file mode 100644 index c00bd1f24079..000000000000 --- a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextRunShadowNode.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace facebook::react { -extern const char T3MarkdownTextRunComponentName[]; - -using T3MarkdownTextRunShadowNode = ConcreteViewShadowNode< - T3MarkdownTextRunComponentName, - T3MarkdownTextRunProps, - T3MarkdownTextRunEventEmitter, - T3MarkdownTextRunState>; -} diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextShadowNode.h b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextShadowNode.h deleted file mode 100644 index 0f7b284594bb..000000000000 --- a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextShadowNode.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace facebook::react { - -extern const char T3MarkdownTextComponentName[]; - -struct T3MarkdownTextParagraphStyleRange { - size_t location; - size_t length; - Float firstLineHeadIndent; - Float headIndent; - Float paragraphSpacing; -}; - -struct T3MarkdownTextAttachmentRange { - size_t location; - size_t length; - std::string imageUri; - /// Recolor the loaded image with the run's foreground color, like `sf:` symbols. - bool tintWithForeground; - Float chipWidth = 0; - Float chipHeight = 0; -}; - -inline Float T3MarkdownTextAttachmentSize(const T3MarkdownTextAttachmentRange &) { - return 14; -} - -inline Float T3MarkdownTextAttachmentBaselineOffset( - const T3MarkdownTextAttachmentRange &) { - return -2; -} - -class T3MarkdownTextStateReal final { - public: - AttributedString attributedString; - std::vector paragraphStyleRanges; - std::vector attachmentRanges; -}; - -class T3MarkdownTextShadowNode final : public ConcreteViewShadowNode< -T3MarkdownTextComponentName, -T3MarkdownTextProps, -T3MarkdownTextEventEmitter, -T3MarkdownTextStateReal> { -public: - using ConcreteViewShadowNode::ConcreteViewShadowNode; - - T3MarkdownTextShadowNode( - const ShadowNode& sourceShadowNode, - const ShadowNodeFragment& fragment - ); - - static ShadowNodeTraits BaseTraits() { - auto traits = ConcreteViewShadowNode::BaseTraits(); - traits.set(ShadowNodeTraits::Trait::LeafYogaNode); - traits.set(ShadowNodeTraits::Trait::MeasurableYogaNode); - return traits; - } - - void layout(LayoutContext layoutContext) override; - - Size measureContent( - const LayoutContext& layoutContext, - const LayoutConstraints& layoutConstraints) const override; - -private: - mutable AttributedString _attributedString; - mutable std::vector _paragraphStyleRanges; - mutable std::vector _attachmentRanges; -}; -} // namespace facebook::React diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextShadowNode.mm b/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextShadowNode.mm deleted file mode 100644 index e1cc7c2046b2..000000000000 --- a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownTextShadowNode.mm +++ /dev/null @@ -1,303 +0,0 @@ -#include "T3MarkdownTextShadowNode.h" -#include "T3MarkdownTextRunShadowNode.h" -#import "T3ContextChip.h" -#include -#import - -#include -#include - -namespace facebook::react { - -static constexpr Float ParagraphStyleEncodingOffset = 1000; -static constexpr auto FileAttachmentNativeIdPrefix = "t3-file:"; -static constexpr auto SkillAttachmentNativeIdPrefix = "t3-skill:"; -static constexpr auto LinkAttachmentNativeIdPrefix = "t3-link:"; - -static void applyParagraphStyles( - NSMutableAttributedString *attributedString, - const std::vector &styleRanges) -{ - for (const auto &styleRange : styleRanges) { - if (styleRange.length == 0 || styleRange.location >= attributedString.length) { - continue; - } - - const NSRange markerRange = NSMakeRange( - styleRange.location, - MIN(styleRange.length, attributedString.length - styleRange.location)); - const NSRange paragraphRange = [attributedString.string paragraphRangeForRange:markerRange]; - const NSParagraphStyle *existingStyle = - [attributedString attribute:NSParagraphStyleAttributeName - atIndex:paragraphRange.location - effectiveRange:nil]; - NSMutableParagraphStyle *paragraphStyle = - existingStyle ? [existingStyle mutableCopy] : [NSMutableParagraphStyle new]; - paragraphStyle.firstLineHeadIndent = styleRange.firstLineHeadIndent; - paragraphStyle.headIndent = styleRange.headIndent; - paragraphStyle.paragraphSpacing = styleRange.paragraphSpacing; - paragraphStyle.tabStops = @[ - [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft - location:styleRange.headIndent - options:@{}] - ]; - paragraphStyle.defaultTabInterval = styleRange.headIndent; - [attributedString addAttribute:NSParagraphStyleAttributeName - value:paragraphStyle - range:paragraphRange]; - } -} - -static void applyAttachments( - NSMutableAttributedString *attributedString, - const std::vector &attachmentRanges) -{ - for (const auto &attachmentRange : attachmentRanges) { - if (attachmentRange.length == 0 || attachmentRange.location >= attributedString.length) { - continue; - } - - NSTextAttachment *attachment = [[NSTextAttachment alloc] init]; - attachment.image = [[UIImage alloc] init]; - const CGFloat attachmentSize = T3MarkdownTextAttachmentSize(attachmentRange); - attachment.bounds = CGRectMake( - 0, - T3MarkdownTextAttachmentBaselineOffset(attachmentRange), - attachmentSize, - attachmentSize); - NSDictionary *runAttributes = - [attributedString attributesAtIndex:attachmentRange.location effectiveRange:nil]; - if (attachmentRange.chipWidth > 0) { - attachment.bounds = T3ContextChipBounds( - runAttributes[NSFontAttributeName], - CGSizeMake(attachmentRange.chipWidth, attachmentRange.chipHeight)); - } - const NSRange range = NSMakeRange( - attachmentRange.location, - MIN(attachmentRange.length, attributedString.length - attachmentRange.location)); - [attributedString replaceCharactersInRange:range - withAttributedString:T3MarkdownTextAttachmentString(attachment, runAttributes)]; - } -} - -T3MarkdownTextShadowNode::T3MarkdownTextShadowNode( - const ShadowNode& sourceShadowNode, - const ShadowNodeFragment& fragment -) : ConcreteViewShadowNode(sourceShadowNode, fragment) { -}; - -Size T3MarkdownTextShadowNode::measureContent( - const LayoutContext& layoutContext, - const LayoutConstraints& layoutConstraints) const { - const auto &baseProps = getConcreteProps(); - - auto baseTextAttributes = TextAttributes::defaultTextAttributes(); - baseTextAttributes.backgroundColor = baseProps.backgroundColor; - baseTextAttributes.allowFontScaling = baseProps.allowFontScaling; - - Float fontSizeMultiplier = 1.0; - if (baseTextAttributes.allowFontScaling) { - fontSizeMultiplier = layoutContext.fontSizeMultiplier; - } - - auto baseAttributedString = AttributedString{}; - auto paragraphStyleRanges = std::vector{}; - auto attachmentRanges = std::vector{}; - size_t utf16Offset = 0; - const auto &children = getChildren(); - for (size_t i = 0; i < children.size(); i++) { - const auto child = children[i].get(); - if (auto textViewChild = dynamic_cast(child)) { - auto &props = textViewChild->getConcreteProps(); - auto fragment = AttributedString::Fragment{}; - auto textAttributes = TextAttributes::defaultTextAttributes(); - - textAttributes.allowFontScaling = baseProps.allowFontScaling; - textAttributes.backgroundColor = props.backgroundColor; - textAttributes.fontSize = props.fontSize * fontSizeMultiplier; - textAttributes.lineHeight = props.lineHeight * fontSizeMultiplier; - textAttributes.foregroundColor = props.color; - const bool hasParagraphStyle = props.shadowRadius >= ParagraphStyleEncodingOffset; - if (!hasParagraphStyle) { - textAttributes.textShadowColor = props.shadowColor; - textAttributes.textShadowOffset = props.shadowOffset; - textAttributes.textShadowRadius = props.shadowRadius; - } - textAttributes.letterSpacing = props.letterSpacing; - textAttributes.textDecorationColor = props.textDecorationColor; - textAttributes.fontFamily = props.fontFamily; - - if (props.fontStyle == T3MarkdownTextRunFontStyle::Italic) { - textAttributes.fontStyle = FontStyle::Italic; - } else { - textAttributes.fontStyle = FontStyle::Normal; - } - - if (props.fontWeight == T3MarkdownTextRunFontWeight::Bold) { - textAttributes.fontWeight = FontWeight::Bold; - } else if (props.fontWeight == T3MarkdownTextRunFontWeight::UltraLight) { - textAttributes.fontWeight = FontWeight::UltraLight; - } else if (props.fontWeight == T3MarkdownTextRunFontWeight::Light) { - textAttributes.fontWeight = FontWeight::Light; - } else if (props.fontWeight == T3MarkdownTextRunFontWeight::Medium) { - textAttributes.fontWeight = FontWeight::Medium; - } else if (props.fontWeight == T3MarkdownTextRunFontWeight::Semibold) { - textAttributes.fontWeight = FontWeight::Semibold; - } else if (props.fontWeight == T3MarkdownTextRunFontWeight::Heavy) { - textAttributes.fontWeight = FontWeight::Heavy; - } else { - textAttributes.fontWeight = FontWeight::Regular; - } - - if (props.textDecorationLine == T3MarkdownTextRunTextDecorationLine::LineThrough) { - textAttributes.textDecorationLineType = TextDecorationLineType::Strikethrough; - } else if (props.textDecorationLine == T3MarkdownTextRunTextDecorationLine::Underline) { - textAttributes.textDecorationLineType = TextDecorationLineType::Underline; - } else { - textAttributes.textDecorationLineType = TextDecorationLineType::None; - } - - if (props.textDecorationStyle == T3MarkdownTextRunTextDecorationStyle::Solid) { - textAttributes.textDecorationStyle = TextDecorationStyle::Solid; - } else if (props.textDecorationStyle == T3MarkdownTextRunTextDecorationStyle::Dotted) { - textAttributes.textDecorationStyle = TextDecorationStyle::Dotted; - } else if (props.textDecorationStyle == T3MarkdownTextRunTextDecorationStyle::Dashed) { - textAttributes.textDecorationStyle = TextDecorationStyle::Dashed; - } else if (props.textDecorationStyle == T3MarkdownTextRunTextDecorationStyle::Double) { - textAttributes.textDecorationStyle = TextDecorationStyle::Double; - } - - if (props.textAlign == T3MarkdownTextRunTextAlign::Left) { - textAttributes.alignment = TextAlignment::Left; - } else if (props.textAlign == T3MarkdownTextRunTextAlign::Right) { - textAttributes.alignment = TextAlignment::Right; - } else if (props.textAlign == T3MarkdownTextRunTextAlign::Center) { - textAttributes.alignment = TextAlignment::Center; - } else if (props.textAlign == T3MarkdownTextRunTextAlign::Justify) { - textAttributes.alignment = TextAlignment::Justified; - } else if (props.textAlign == T3MarkdownTextRunTextAlign::Auto) { - textAttributes.alignment = TextAlignment::Natural; - } - - textAttributes.backgroundColor = props.backgroundColor; - - fragment.string = props.text; - fragment.textAttributes = textAttributes; - - NSString *fragmentText = [NSString stringWithUTF8String:props.text.c_str()]; - const size_t fragmentLength = fragmentText.length; - if (hasParagraphStyle) { - paragraphStyleRanges.push_back(T3MarkdownTextParagraphStyleRange{ - utf16Offset, - fragmentLength, - props.shadowOffset.width, - props.shadowOffset.height, - props.shadowRadius - ParagraphStyleEncodingOffset, - }); - } - if (props.nativeId.rfind("t3-chip:", 0) == 0 && fragmentLength > 0) { - const std::string uri = props.nativeId.substr(3); - NSMutableDictionary *payload = - [T3ContextChipPayload([NSString stringWithUTF8String:uri.c_str()]) mutableCopy]; - // Chips must scale with the paragraph or smaller Dynamic Type sizes clip them. - // Store the scaled payload so measurement and the rendered bitmap use the same font. - payload[@"fontSizeMultiplier"] = @(fontSizeMultiplier); - NSData *data = [NSJSONSerialization dataWithJSONObject:payload options:0 error:nil]; - NSString *scaledUri = [@"chip:" stringByAppendingString: - [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]]; - const CGFloat maxWidth = std::isfinite(layoutConstraints.maximumSize.width) - ? layoutConstraints.maximumSize.width : 320; - const CGSize size = T3ContextChipSize(payload, maxWidth); - attachmentRanges.push_back(T3MarkdownTextAttachmentRange{ - utf16Offset, 1, std::string(scaledUri.UTF8String), false, - static_cast(size.width), static_cast(size.height), - }); - } else if (props.nativeId.rfind(FileAttachmentNativeIdPrefix, 0) == 0 && fragmentLength > 0) { - attachmentRanges.push_back(T3MarkdownTextAttachmentRange{ - utf16Offset, - 1, - props.nativeId.substr(std::char_traits::length(FileAttachmentNativeIdPrefix)), - false, - }); - } else if ( - props.nativeId.rfind(SkillAttachmentNativeIdPrefix, 0) == 0 && fragmentLength > 0) { - attachmentRanges.push_back(T3MarkdownTextAttachmentRange{ - utf16Offset, - 1, - props.nativeId.substr( - std::char_traits::length(SkillAttachmentNativeIdPrefix)), - false, - }); - } else if ( - props.nativeId.rfind(LinkAttachmentNativeIdPrefix, 0) == 0 && fragmentLength > 0) { - attachmentRanges.push_back(T3MarkdownTextAttachmentRange{ - utf16Offset, - 1, - props.nativeId.substr(std::char_traits::length(LinkAttachmentNativeIdPrefix)), - true, - }); - } - utf16Offset += fragmentLength; - baseAttributedString.appendFragment(std::move(fragment)); - } - } - - _attributedString = baseAttributedString; - _paragraphStyleRanges = paragraphStyleRanges; - _attachmentRanges = attachmentRanges; - - NSMutableAttributedString *convertedAttributedString = - [RCTNSAttributedStringFromAttributedString(baseAttributedString) mutableCopy]; - applyParagraphStyles(convertedAttributedString, paragraphStyleRanges); - applyAttachments(convertedAttributedString, attachmentRanges); - // TextKit stacks a paragraph's extra line height above the glyphs. React Native's own - // layout manager centres them with a baseline offset; do the same, after attachments - // so chips shift with the words. - RCTApplyBaselineOffset(convertedAttributedString); - - const CGFloat maximumWidth = std::isfinite(layoutConstraints.maximumSize.width) - ? layoutConstraints.maximumSize.width - : CGFLOAT_MAX; - NSTextStorage *textStorage = - [[NSTextStorage alloc] initWithAttributedString:convertedAttributedString]; - NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; - layoutManager.usesFontLeading = NO; - NSTextContainer *textContainer = - [[NSTextContainer alloc] initWithSize:CGSizeMake(maximumWidth, CGFLOAT_MAX)]; - textContainer.lineFragmentPadding = 0; - textContainer.maximumNumberOfLines = baseProps.numberOfLines; - if (baseProps.ellipsizeMode == T3MarkdownTextEllipsizeMode::Head) { - textContainer.lineBreakMode = NSLineBreakByTruncatingHead; - } else if (baseProps.ellipsizeMode == T3MarkdownTextEllipsizeMode::Middle) { - textContainer.lineBreakMode = NSLineBreakByTruncatingMiddle; - } else if (baseProps.ellipsizeMode == T3MarkdownTextEllipsizeMode::Tail) { - textContainer.lineBreakMode = NSLineBreakByTruncatingTail; - } else { - textContainer.lineBreakMode = NSLineBreakByClipping; - } - [layoutManager addTextContainer:textContainer]; - [textStorage addLayoutManager:layoutManager]; - [layoutManager ensureLayoutForTextContainer:textContainer]; - const CGRect usedRect = [layoutManager usedRectForTextContainer:textContainer]; - - return { - std::clamp( - static_cast(std::ceil(usedRect.size.width)), - layoutConstraints.minimumSize.width, - layoutConstraints.maximumSize.width), - std::clamp( - static_cast(std::ceil(usedRect.size.height)), - layoutConstraints.minimumSize.height, - layoutConstraints.maximumSize.height), - }; -} - -void T3MarkdownTextShadowNode::layout(LayoutContext layoutContext) { - ensureUnsealed(); - setStateData(T3MarkdownTextStateReal{ - _attributedString, - _paragraphStyleRanges, - _attachmentRanges, - }); -} -} diff --git a/apps/mobile/modules/t3-markdown-text/package.json b/apps/mobile/modules/t3-markdown-text/package.json deleted file mode 100644 index 5b9180b154cd..000000000000 --- a/apps/mobile/modules/t3-markdown-text/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "@t3tools/mobile-markdown-text", - "version": "0.0.0", - "private": true, - "source": "./index.ts", - "files": [ - "android", - "assets", - "expo-module.config.json", - "ios", - "src", - "index.ts", - "LICENSE", - "UPSTREAM.md", - "T3MarkdownText.podspec", - "react-native.config.js" - ], - "main": "./index.ts", - "types": "./index.ts", - "react-native": "./index.ts", - "exports": { - ".": "./index.ts", - "./file-icons": "./src/markdownFileIcons.ts", - "./link-icons": "./src/markdownLinkIcons.ts", - "./links": "./src/markdownLinks.ts", - "./markdown": "./src/composerChipPresentation.ts", - "./primitive": "./src/MarkdownTextPrimitive.tsx", - "./types": "./src/SelectableMarkdownText.types.ts" - }, - "peerDependencies": { - "@t3tools/client-runtime": "*", - "@t3tools/shared": "*", - "expo": "*", - "expo-asset": "*", - "expo-clipboard": "*", - "expo-haptics": "*", - "expo-symbols": "*", - "react": "*", - "react-native": "*" - }, - "codegenConfig": { - "name": "T3MarkdownTextSpec", - "type": "all", - "jsSrcsDir": "src", - "ios": { - "componentProvider": { - "T3MarkdownText": "T3MarkdownText", - "T3MarkdownTextRun": "T3MarkdownTextRun" - } - }, - "outputDir": { - "ios": "ios/generated" - } - } -} diff --git a/apps/mobile/modules/t3-markdown-text/src/MarkdownTextPrimitive.tsx b/apps/mobile/modules/t3-markdown-text/src/MarkdownTextPrimitive.tsx deleted file mode 100644 index 1e9394bd6eca..000000000000 --- a/apps/mobile/modules/t3-markdown-text/src/MarkdownTextPrimitive.tsx +++ /dev/null @@ -1,174 +0,0 @@ -import React, { type Ref } from "react"; -import { - findNodeHandle, - Platform, - processColor, - StyleSheet, - Text as RNText, - type ColorValue, - type TextProps, - type ViewStyle, -} from "react-native"; -import { setMarkdownSelectionHandleColor } from "./T3MarkdownTextSelectionModule"; -import T3MarkdownTextRunNativeComponent from "./T3MarkdownTextRunNativeComponent"; -import T3MarkdownTextNativeComponent from "./T3MarkdownTextNativeComponent"; -import { flattenStyles } from "./util"; - -const TextAncestorContext = React.createContext<[boolean, ViewStyle]>([ - false, - StyleSheet.create({}), -]); - -const textDefaults = { - allowFontScaling: true, - selectable: true, -} satisfies TextProps; - -const useTextAncestorContext = () => React.useContext(TextAncestorContext); - -/** - * Event fired by `onSelectionChange`. `start`/`end` are 0-based UTF-16 indices - * into the rendered string. `start === end` means the selection was cleared. - */ -export type SelectionChangeEvent = { - nativeEvent: { target: number; start: number; end: number }; -}; - -export type ContextMenuActionEvent = { - nativeEvent: { target: number; actionIdentifier: string }; -}; - -/** - * `onTextLayout` is not offered: the native view reports plain line strings - * while the React Native Text fallback reports measured `TextLayoutLine`s. - */ -export type MarkdownTextPrimitiveProps = Omit & { - nativeTextRef?: Ref; - selectionHandleColor?: ColorValue; - uiTextView?: boolean; - contextMenuConfig?: string; - contextClipboardConfig?: string; - onContextMenuAction?: (event: ContextMenuActionEvent) => void; - /** - * Fired when the native text selection changes. Only fires on iOS when - * `uiTextView` is true. Note: fires on every selection-edge adjustment - * (e.g. dragging a selection handle), so consumers driving expensive work - * off this event should debounce. - */ - onSelectionChange?: (event: SelectionChangeEvent) => void; -}; - -function MarkdownTextPrimitiveChild({ - style, - children, - nativeTextRef: _nativeTextRef, - ...rest -}: MarkdownTextPrimitiveProps) { - const [isAncestor, rootStyle] = useTextAncestorContext(); - - // Flatten the styles, and apply the root styles when needed - const flattenedStyle = React.useMemo(() => flattenStyles(rootStyle, style), [rootStyle, style]); - const contextValue = React.useMemo<[boolean, ViewStyle]>( - () => [true, flattenedStyle], - [flattenedStyle], - ); - let childPosition = 0; - const nativeChildren = React.Children.toArray(children).map((child) => { - const position = childPosition; - childPosition += 1; - - if (React.isValidElement(child)) { - return child; - } - if (typeof child !== "string" && typeof child !== "number") { - return null; - } - - const text = child.toString(); - return ( - // @ts-expect-error The generated run props do not include inherited Text props. - - ); - }); - - if (!isAncestor) { - // Press handlers are delivered by the text runs; the container never sees them. - const { onPress: _onPress, onLongPress: _onLongPress, ...containerProps } = rest; - return ( - - - {nativeChildren} - - - ); - } - - return <>{nativeChildren}; -} - -function MarkdownTextPrimitiveInner({ nativeTextRef, ...props }: MarkdownTextPrimitiveProps) { - const [isAncestor] = useTextAncestorContext(); - - // Even if the uiTextView prop is set, we can still default to using - // normal selection (i.e. base RN text) if the text doesn't need to be - // selectable - if ((!props.selectable || !props.uiTextView) && !isAncestor) { - return ; - } - return ; -} - -function AndroidMarkdownText({ - nativeTextRef, - selectionHandleColor, - onLayout, - contextClipboardConfig: _contextClipboardConfig, - ...props -}: MarkdownTextPrimitiveProps) { - const textRef = React.useRef(null); - React.useImperativeHandle(nativeTextRef, () => textRef.current, []); - const color = processColor(selectionHandleColor); - const applyHandleColor = React.useCallback(() => { - if (!textRef.current || typeof color !== "number") return; - const reactTag = findNodeHandle(textRef.current); - if (reactTag !== null) setMarkdownSelectionHandleColor(reactTag, color); - }, [color]); - - // RN's selectionColor only sets the highlight. Retint mounted handles when - // the theme changes, and after layout when the native view first exists. - React.useEffect(applyHandleColor, [applyHandleColor]); - - return ( - { - applyHandleColor(); - onLayout?.(event); - }} - /> - ); -} - -export function MarkdownTextPrimitive({ - selectionHandleColor, - ...props -}: MarkdownTextPrimitiveProps) { - if (Platform.OS === "android" && selectionHandleColor !== undefined) { - return ; - } - if (Platform.OS !== "ios") { - const { nativeTextRef, contextClipboardConfig: _contextClipboardConfig, ...textProps } = props; - return ; - } - return ; -} diff --git a/apps/mobile/modules/t3-markdown-text/src/T3MarkdownTextSelectionModule.ts b/apps/mobile/modules/t3-markdown-text/src/T3MarkdownTextSelectionModule.ts deleted file mode 100644 index 56d8f6d4e0f8..000000000000 --- a/apps/mobile/modules/t3-markdown-text/src/T3MarkdownTextSelectionModule.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { requireOptionalNativeModule } from "expo"; - -interface T3MarkdownTextSelectionNativeModule { - readonly setSelectionHandleColor?: (reactTag: number, color: number) => void; - readonly installCopySanitizer: (reactTag: number, contextClipboardConfig: string) => void; - readonly renderContextChip?: (payloadJson: string) => { - readonly uri: string; - readonly width: number; - readonly height: number; - /** Inline box height: the paragraph font's ascent, so the line box never grows. */ - readonly boxHeight: number; - /** Bitmap top relative to the box top; negative when the chip overhangs the box. */ - readonly offsetY: number; - } | null; -} - -const nativeModule = - requireOptionalNativeModule("T3MarkdownTextSelection"); - -export function installMarkdownCopySanitizer(reactTag: number, contextClipboardConfig = ""): void { - nativeModule?.installCopySanitizer(reactTag, contextClipboardConfig); -} - -export function setMarkdownSelectionHandleColor(reactTag: number, color: number): void { - nativeModule?.setSelectionHandleColor?.(reactTag, color); -} - -export function renderAndroidContextChip(payloadJson: string) { - return nativeModule?.renderContextChip?.(payloadJson) ?? null; -} diff --git a/apps/mobile/modules/t3-markdown-text/src/markdownFileIcons.generated.ts b/apps/mobile/modules/t3-markdown-text/src/markdownFileIcons.generated.ts deleted file mode 100644 index fb0209b6a990..000000000000 --- a/apps/mobile/modules/t3-markdown-text/src/markdownFileIcons.generated.ts +++ /dev/null @@ -1,60 +0,0 @@ -import type { ImageSourcePropType } from "react-native"; - -export const MARKDOWN_FILE_ICON_SOURCES = { - agents: require("../assets/file-icons/pierre_agents.png"), - astro: require("../assets/file-icons/pierre_astro.png"), - babel: require("../assets/file-icons/pierre_babel.png"), - bash: require("../assets/file-icons/pierre_bash.png"), - biome: require("../assets/file-icons/pierre_biome.png"), - bootstrap: require("../assets/file-icons/pierre_bootstrap.png"), - browserslist: require("../assets/file-icons/pierre_browserslist.png"), - bun: require("../assets/file-icons/pierre_bun.png"), - c: require("../assets/file-icons/pierre_c.png"), - claude: require("../assets/file-icons/pierre_claude.png"), - cpp: require("../assets/file-icons/pierre_cpp.png"), - css: require("../assets/file-icons/pierre_css.png"), - database: require("../assets/file-icons/pierre_database.png"), - default: require("../assets/file-icons/pierre_default.png"), - docker: require("../assets/file-icons/pierre_docker.png"), - eslint: require("../assets/file-icons/pierre_eslint.png"), - font: require("../assets/file-icons/pierre_font.png"), - git: require("../assets/file-icons/pierre_git.png"), - go: require("../assets/file-icons/pierre_go.png"), - graphql: require("../assets/file-icons/pierre_graphql.png"), - html: require("../assets/file-icons/pierre_html.png"), - image: require("../assets/file-icons/pierre_image.png"), - javascript: require("../assets/file-icons/pierre_javascript.png"), - json: require("../assets/file-icons/pierre_json.png"), - markdown: require("../assets/file-icons/pierre_markdown.png"), - mcp: require("../assets/file-icons/pierre_mcp.png"), - nextjs: require("../assets/file-icons/pierre_nextjs.png"), - npm: require("../assets/file-icons/pierre_npm.png"), - oxc: require("../assets/file-icons/pierre_oxc.png"), - pnpm: require("../assets/file-icons/pierre_pnpm.png"), - postcss: require("../assets/file-icons/pierre_postcss.png"), - prettier: require("../assets/file-icons/pierre_prettier.png"), - python: require("../assets/file-icons/pierre_python.png"), - react: require("../assets/file-icons/pierre_react.png"), - ruby: require("../assets/file-icons/pierre_ruby.png"), - rust: require("../assets/file-icons/pierre_rust.png"), - sass: require("../assets/file-icons/pierre_sass.png"), - stylelint: require("../assets/file-icons/pierre_stylelint.png"), - svelte: require("../assets/file-icons/pierre_svelte.png"), - svg: require("../assets/file-icons/pierre_svg.png"), - svgo: require("../assets/file-icons/pierre_svgo.png"), - swift: require("../assets/file-icons/pierre_swift.png"), - table: require("../assets/file-icons/pierre_table.png"), - tailwind: require("../assets/file-icons/pierre_tailwind.png"), - terraform: require("../assets/file-icons/pierre_terraform.png"), - text: require("../assets/file-icons/pierre_text.png"), - typescript: require("../assets/file-icons/pierre_typescript.png"), - video: require("../assets/file-icons/pierre_video.png"), - vite: require("../assets/file-icons/pierre_vite.png"), - vscode: require("../assets/file-icons/pierre_vscode.png"), - vue: require("../assets/file-icons/pierre_vue.png"), - wasm: require("../assets/file-icons/pierre_wasm.png"), - webpack: require("../assets/file-icons/pierre_webpack.png"), - yml: require("../assets/file-icons/pierre_yml.png"), - zig: require("../assets/file-icons/pierre_zig.png"), - zip: require("../assets/file-icons/pierre_zip.png"), -} as const satisfies Readonly>; diff --git a/apps/mobile/modules/t3-markdown-text/LICENSE b/apps/mobile/modules/t3-source-text/LICENSE similarity index 100% rename from apps/mobile/modules/t3-markdown-text/LICENSE rename to apps/mobile/modules/t3-source-text/LICENSE diff --git a/apps/mobile/modules/t3-markdown-text/T3MarkdownText.podspec b/apps/mobile/modules/t3-source-text/T3SourceText.podspec similarity index 77% rename from apps/mobile/modules/t3-markdown-text/T3MarkdownText.podspec rename to apps/mobile/modules/t3-source-text/T3SourceText.podspec index 0ac471faf24d..c44f8c100f6b 100644 --- a/apps/mobile/modules/t3-markdown-text/T3MarkdownText.podspec +++ b/apps/mobile/modules/t3-source-text/T3SourceText.podspec @@ -4,10 +4,10 @@ package = JSON.parse(File.read(File.join(__dir__, "package.json"))) new_arch_enabled = ENV["RCT_NEW_ARCH_ENABLED"] == "1" Pod::Spec.new do |s| - s.name = "T3MarkdownText" + s.name = "T3SourceText" s.version = package["version"] - s.summary = "Native selectable markdown renderer for T3 Code mobile." - s.description = "Fabric-backed attributed text and markdown rendering primitives owned by T3 Code." + s.summary = "Native selectable source text for T3 Code mobile." + s.description = "Fabric-backed styled source text with whole-document selection." s.homepage = "https://t3tools.com" s.license = { :type => "MIT", :file => "LICENSE" } s.author = { "T3 Tools" => "hello@t3tools.com" } diff --git a/apps/mobile/modules/t3-markdown-text/UPSTREAM.md b/apps/mobile/modules/t3-source-text/UPSTREAM.md similarity index 82% rename from apps/mobile/modules/t3-markdown-text/UPSTREAM.md rename to apps/mobile/modules/t3-source-text/UPSTREAM.md index e478d965478d..4b4b6e43cdb7 100644 --- a/apps/mobile/modules/t3-markdown-text/UPSTREAM.md +++ b/apps/mobile/modules/t3-source-text/UPSTREAM.md @@ -7,6 +7,5 @@ version `2.2.0`, commit `addc08fea303608f070fe1eeba4bc075f181c4af`. The upstream project is Copyright (c) 2024-25 Bluesky PBC and licensed under the MIT License included in this directory. -T3 Code has substantially modified and renamed the implementation, integrated -its source-file preview text primitive, and owns the resulting module going forward. This is not +T3 Code has substantially modified and renamed the implementation, limited it to selectable source-file text, and owns the resulting module going forward. This is not an upstream package dependency or a compatibility fork. diff --git a/apps/mobile/modules/t3-source-text/index.ts b/apps/mobile/modules/t3-source-text/index.ts new file mode 100644 index 000000000000..0d2823b10af7 --- /dev/null +++ b/apps/mobile/modules/t3-source-text/index.ts @@ -0,0 +1 @@ +export { SourceText } from "./src/SourceText"; diff --git a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownText.h b/apps/mobile/modules/t3-source-text/ios/T3SourceText.h similarity index 55% rename from apps/mobile/modules/t3-markdown-text/ios/T3MarkdownText.h rename to apps/mobile/modules/t3-source-text/ios/T3SourceText.h index f9c05a19819f..6fc6f2686d46 100644 --- a/apps/mobile/modules/t3-markdown-text/ios/T3MarkdownText.h +++ b/apps/mobile/modules/t3-source-text/ios/T3SourceText.h @@ -1,11 +1,11 @@ #import #import -#ifndef T3MarkdownTextNativeComponent_h -#define T3MarkdownTextNativeComponent_h +#ifndef T3SourceTextNativeComponent_h +#define T3SourceTextNativeComponent_h NS_ASSUME_NONNULL_BEGIN -@interface T3MarkdownText : RCTViewComponentView +@interface T3SourceText : RCTViewComponentView @end NS_ASSUME_NONNULL_END diff --git a/apps/mobile/modules/t3-source-text/ios/T3SourceText.mm b/apps/mobile/modules/t3-source-text/ios/T3SourceText.mm new file mode 100644 index 000000000000..e0a5d1a2bd72 --- /dev/null +++ b/apps/mobile/modules/t3-source-text/ios/T3SourceText.mm @@ -0,0 +1,293 @@ +#import "T3SourceText.h" +#import "RCTFabricComponentsPlugins.h" +#import "T3SourceTextComponentDescriptor.h" +#import "T3SourceTextShadowNode.h" +#import +#import +#import +#import +#import +#import + +using namespace facebook::react; + +@interface T3SourceTextView : UITextView +@end + +@implementation T3SourceTextView +- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { + // Read-only UITextViews must still allow selecting the whole file. + if (action == @selector(selectAll:)) { + return self.selectable && self.text.length > 0 && + self.selectedRange.length < self.text.length; + } + return [super canPerformAction:action withSender:sender]; +} +@end + +@protocol T3SourceTextOutsideTapTarget +- (void)clearSelectionForOutsideTapWithHitView:(UIView *)hitView; +@end + +@interface T3SourceTextOutsideTapCoordinator + : NSObject + +- (instancetype)initWithWindow:(UIWindow *)window; +- (void)addTarget:(id)target; +- (void)removeTarget:(id)target; + +@end + +static const void *T3SourceTextOutsideTapCoordinatorKey = + &T3SourceTextOutsideTapCoordinatorKey; + +@implementation T3SourceTextOutsideTapCoordinator { + __weak UIWindow *_window; + UITapGestureRecognizer *_recognizer; + NSHashTable> *_targets; +} + +- (instancetype)initWithWindow:(UIWindow *)window { + if (self = [super init]) { + _window = window; + _targets = [NSHashTable weakObjectsHashTable]; + _recognizer = + [[UITapGestureRecognizer alloc] initWithTarget:self + action:@selector(handleTap:)]; + _recognizer.cancelsTouchesInView = NO; + _recognizer.delegate = self; + [window addGestureRecognizer:_recognizer]; + } + return self; +} + +- (void)addTarget:(id)target { + [_targets addObject:target]; +} + +- (void)removeTarget:(id)target { + [_targets removeObject:target]; + if (_targets.count > 0) { + return; + } + + UIWindow *window = _window; + [window removeGestureRecognizer:_recognizer]; + if (objc_getAssociatedObject(window, T3SourceTextOutsideTapCoordinatorKey) == + self) { + objc_setAssociatedObject(window, T3SourceTextOutsideTapCoordinatorKey, nil, + OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } +} + +- (void)handleTap:(UITapGestureRecognizer *)sender { + UIWindow *window = _window; + if (window == nil) { + return; + } + + UIView *hitView = [window hitTest:[sender locationInView:window] + withEvent:nil]; + if (hitView == nil) { + return; + } + for (id target in _targets.allObjects) { + [target clearSelectionForOutsideTapWithHitView:hitView]; + } +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer + shouldRecognizeSimultaneouslyWithGestureRecognizer: + (UIGestureRecognizer *)otherGestureRecognizer { + return YES; +} + +@end + +static T3SourceTextOutsideTapCoordinator * +T3SourceTextOutsideTapCoordinatorForWindow(UIWindow *window) { + T3SourceTextOutsideTapCoordinator *coordinator = + objc_getAssociatedObject(window, T3SourceTextOutsideTapCoordinatorKey); + if (coordinator == nil) { + coordinator = + [[T3SourceTextOutsideTapCoordinator alloc] initWithWindow:window]; + objc_setAssociatedObject(window, T3SourceTextOutsideTapCoordinatorKey, + coordinator, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + return coordinator; +} + +@interface T3SourceText () +@end + +@implementation T3SourceText { + UIView *_view; + T3SourceTextView *_textView; + T3SourceTextShadowNode::ConcreteState::Shared _state; + __weak UIWindow *_outsideTapWindow; + BOOL _suppressSelectionChange; +} + ++ (ComponentDescriptorProvider)componentDescriptorProvider { + return concreteComponentDescriptorProvider(); +} + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = + std::make_shared(); + _props = defaultProps; + _view = [[UIView alloc] init]; + self.contentView = _view; + self.clipsToBounds = YES; + _textView = [[T3SourceTextView alloc] init]; + _textView.scrollEnabled = NO; + _textView.editable = NO; + _textView.textContainerInset = UIEdgeInsetsZero; + _textView.textContainer.lineFragmentPadding = 0; + _textView.delegate = self; + _textView.textDragInteraction.enabled = NO; + _textView.layoutManager.usesFontLeading = NO; + [self addSubview:_textView]; + } + return self; +} + +- (void)didMoveToWindow { + [super didMoveToWindow]; + if (_outsideTapWindow == self.window) + return; + T3SourceTextOutsideTapCoordinator *coordinator = objc_getAssociatedObject( + _outsideTapWindow, T3SourceTextOutsideTapCoordinatorKey); + [coordinator removeTarget:self]; + _outsideTapWindow = self.window; + if (_outsideTapWindow != nil) { + [T3SourceTextOutsideTapCoordinatorForWindow(_outsideTapWindow) + addTarget:self]; + } +} + +- (void)dealloc { + T3SourceTextOutsideTapCoordinator *coordinator = objc_getAssociatedObject( + _outsideTapWindow, T3SourceTextOutsideTapCoordinatorKey); + [coordinator removeTarget:self]; +} + +- (void)prepareForRecycle { + [super prepareForRecycle]; + T3SourceTextOutsideTapCoordinator *coordinator = objc_getAssociatedObject( + _outsideTapWindow, T3SourceTextOutsideTapCoordinatorKey); + [coordinator removeTarget:self]; + _outsideTapWindow = nil; + _state.reset(); + _textView.frame = CGRectZero; + _textView.attributedText = nil; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + if (!CGRectEqualToRect(_textView.frame, _view.frame)) + [self setNeedsDisplay]; +} + +- (void)drawRect:(CGRect)rect { + if (!_state) + return; + NSMutableAttributedString *text = [RCTNSAttributedStringFromAttributedString( + _state->getData().attributedString) mutableCopy]; + RCTApplyBaselineOffset(text); + const BOOL textChanged = + ![_textView.attributedText isEqualToAttributedString:text]; + const BOOL frameChanged = !CGRectEqualToRect(_textView.frame, _view.frame); + if (!textChanged && !frameChanged) + return; + if (textChanged) { + const NSRange savedRange = _textView.selectedRange; + _suppressSelectionChange = YES; + _textView.attributedText = text; + if (savedRange.location != NSNotFound && savedRange.length > 0 && + NSMaxRange(savedRange) <= text.length) { + _textView.selectedRange = savedRange; + } + _suppressSelectionChange = NO; + } + if (frameChanged) + _textView.frame = _view.frame; +} + +- (void)updateProps:(Props::Shared const &)props + oldProps:(Props::Shared const &)oldProps { + const auto &oldViewProps = + *std::static_pointer_cast(_props); + const auto &newViewProps = + *std::static_pointer_cast(props); + if (oldViewProps.numberOfLines != newViewProps.numberOfLines) { + _textView.textContainer.maximumNumberOfLines = newViewProps.numberOfLines; + } + if (oldViewProps.selectable != newViewProps.selectable) + _textView.selectable = newViewProps.selectable; + if (oldViewProps.allowFontScaling != newViewProps.allowFontScaling) { + _textView.adjustsFontForContentSizeCategory = newViewProps.allowFontScaling; + } + if (oldViewProps.ellipsizeMode != newViewProps.ellipsizeMode) { + switch (newViewProps.ellipsizeMode) { + case T3SourceTextEllipsizeMode::Head: + _textView.textContainer.lineBreakMode = NSLineBreakByTruncatingHead; + break; + case T3SourceTextEllipsizeMode::Middle: + _textView.textContainer.lineBreakMode = NSLineBreakByTruncatingMiddle; + break; + case T3SourceTextEllipsizeMode::Tail: + _textView.textContainer.lineBreakMode = NSLineBreakByTruncatingTail; + break; + case T3SourceTextEllipsizeMode::Clip: + _textView.textContainer.lineBreakMode = NSLineBreakByClipping; + break; + } + } + if (oldViewProps.backgroundColor != newViewProps.backgroundColor) { + _textView.backgroundColor = + RCTUIColorFromSharedColor(newViewProps.backgroundColor); + } + [super updateProps:props oldProps:oldProps]; +} + +- (void)updateState:(const facebook::react::State::Shared &)state + oldState:(const facebook::react::State::Shared &)oldState { + _state = + std::static_pointer_cast( + state); + [self setNeedsDisplay]; +} + +- (void)clearSelectionForOutsideTapWithHitView:(UIView *)hitView { + if ([hitView isDescendantOfView:self]) + return; + UITextView *textView = _textView; + // Allow a pending native Copy action to consume its selection first. + dispatch_async(dispatch_get_main_queue(), ^{ + UITextRange *range = textView.selectedTextRange; + if (range != nil && !range.isEmpty) + textView.selectedTextRange = nil; + }); +} + +- (void)textViewDidChangeSelection:(UITextView *)textView { + if (_suppressSelectionChange || _eventEmitter == nullptr) + return; + const NSRange range = textView.selectedRange; + if (range.location == NSNotFound) + return; + std::dynamic_pointer_cast( + _eventEmitter) + ->onSelectionChange( + facebook::react::T3SourceTextEventEmitter::OnSelectionChange{ + static_cast(self.tag), static_cast(range.location), + static_cast(NSMaxRange(range))}); +} + +Class T3SourceTextCls(void) { + return T3SourceText.class; +} +@end diff --git a/apps/mobile/modules/t3-source-text/ios/T3SourceTextComponentDescriptor.h b/apps/mobile/modules/t3-source-text/ios/T3SourceTextComponentDescriptor.h new file mode 100644 index 000000000000..1fb4728f7a0b --- /dev/null +++ b/apps/mobile/modules/t3-source-text/ios/T3SourceTextComponentDescriptor.h @@ -0,0 +1,14 @@ +#pragma once + +#include "T3SourceTextShadowNode.h" + +#include +#include + +namespace facebook::react { +using T3SourceTextComponentDescriptor = + ConcreteComponentDescriptor; + +void T3SourceTextSpec_registerComponentDescriptorsFromCodegen( + std::shared_ptr registry); +} // namespace facebook::react diff --git a/apps/mobile/modules/t3-source-text/ios/T3SourceTextManager.mm b/apps/mobile/modules/t3-source-text/ios/T3SourceTextManager.mm new file mode 100644 index 000000000000..33e86d04d301 --- /dev/null +++ b/apps/mobile/modules/t3-source-text/ios/T3SourceTextManager.mm @@ -0,0 +1,29 @@ +#import "RCTBridge.h" +#import +#import + +@interface T3SourceTextManager : RCTViewManager +@end + +@implementation T3SourceTextManager + +RCT_EXPORT_MODULE(T3SourceText) + +- (UIView *)view { + return [[UIView alloc] init]; +} + +@end + +@interface T3SourceTextRunManager : RCTViewManager +@end + +@implementation T3SourceTextRunManager + +RCT_EXPORT_MODULE(T3SourceTextRun) + +- (UIView *)view { + return nil; +} + +@end diff --git a/apps/mobile/modules/t3-source-text/ios/T3SourceTextRun.h b/apps/mobile/modules/t3-source-text/ios/T3SourceTextRun.h new file mode 100644 index 000000000000..a01cce872959 --- /dev/null +++ b/apps/mobile/modules/t3-source-text/ios/T3SourceTextRun.h @@ -0,0 +1,20 @@ +// This guard prevent this file to be compiled in the old architecture. +#ifdef RCT_NEW_ARCH_ENABLED +#import +#import +#import + +#ifndef T3SourceTextRunNativeComponent_h +#define T3SourceTextRunNativeComponent_h + +NS_ASSUME_NONNULL_BEGIN + +@interface T3SourceTextRun : RCTViewComponentView + +@property(nonatomic, copy, nullable) NSString *text; +@end + +NS_ASSUME_NONNULL_END + +#endif /* UitextviewViewNativeComponent_h */ +#endif /* RCT_NEW_ARCH_ENABLED */ diff --git a/apps/mobile/modules/t3-source-text/ios/T3SourceTextRun.mm b/apps/mobile/modules/t3-source-text/ios/T3SourceTextRun.mm new file mode 100644 index 000000000000..25234e8580fd --- /dev/null +++ b/apps/mobile/modules/t3-source-text/ios/T3SourceTextRun.mm @@ -0,0 +1,54 @@ +#import "T3SourceTextRun.h" +#import "RCTFabricComponentsPlugins.h" +#import "T3SourceTextRunComponentDescriptor.h" +#import +#import + +using namespace facebook::react; + +@interface T3SourceTextRun () + +@end + +@implementation T3SourceTextRun { + NSString *_text; +} + ++ (ComponentDescriptorProvider)componentDescriptorProvider { + return concreteComponentDescriptorProvider< + T3SourceTextRunComponentDescriptor>(); +} + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = + std::make_shared(); + _props = defaultProps; + } + return self; +} + +- (void)updateProps:(Props::Shared const &)props + oldProps:(Props::Shared const &)oldProps { + const auto &oldViewProps = + *std::static_pointer_cast(_props); + const auto &newViewProps = + *std::static_pointer_cast(props); + + if (newViewProps.text != oldViewProps.text) { + NSString *text = [NSString stringWithUTF8String:newViewProps.text.c_str()]; + _text = text; + } + + [super updateProps:props oldProps:oldProps]; +} + ++ (BOOL)shouldBeRecycled { + return NO; +} + +Class T3SourceTextRunCls(void) { + return T3SourceTextRun.class; +} + +@end diff --git a/apps/mobile/modules/t3-source-text/ios/T3SourceTextRunComponentDescriptor.h b/apps/mobile/modules/t3-source-text/ios/T3SourceTextRunComponentDescriptor.h new file mode 100644 index 000000000000..854ad2c6f678 --- /dev/null +++ b/apps/mobile/modules/t3-source-text/ios/T3SourceTextRunComponentDescriptor.h @@ -0,0 +1,14 @@ +#pragma once + +#include "T3SourceTextRunShadowNode.h" + +#include +#include + +namespace facebook::react { +using T3SourceTextRunComponentDescriptor = + ConcreteComponentDescriptor; + +void T3SourceTextRunSpec_registerComponentDescriptorsFromCodegen( + std::shared_ptr registry); +} // namespace facebook::react diff --git a/apps/mobile/modules/t3-source-text/ios/T3SourceTextRunShadowNode.cpp b/apps/mobile/modules/t3-source-text/ios/T3SourceTextRunShadowNode.cpp new file mode 100644 index 000000000000..3e9348f5dbbb --- /dev/null +++ b/apps/mobile/modules/t3-source-text/ios/T3SourceTextRunShadowNode.cpp @@ -0,0 +1,6 @@ +#include "T3SourceTextRunShadowNode.h" + +namespace facebook::react { + +extern const char T3SourceTextRunComponentName[] = "T3SourceTextRun"; +} // namespace facebook::react diff --git a/apps/mobile/modules/t3-source-text/ios/T3SourceTextRunShadowNode.h b/apps/mobile/modules/t3-source-text/ios/T3SourceTextRunShadowNode.h new file mode 100644 index 000000000000..e4f92ea130cf --- /dev/null +++ b/apps/mobile/modules/t3-source-text/ios/T3SourceTextRunShadowNode.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include +#include +#include + +namespace facebook::react { +extern const char T3SourceTextRunComponentName[]; + +using T3SourceTextRunShadowNode = + ConcreteViewShadowNode; +} // namespace facebook::react diff --git a/apps/mobile/modules/t3-source-text/ios/T3SourceTextShadowNode.h b/apps/mobile/modules/t3-source-text/ios/T3SourceTextShadowNode.h new file mode 100644 index 000000000000..2cf761f75713 --- /dev/null +++ b/apps/mobile/modules/t3-source-text/ios/T3SourceTextShadowNode.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace facebook::react { + +extern const char T3SourceTextComponentName[]; + +class T3SourceTextStateReal final { +public: + AttributedString attributedString; +}; + +class T3SourceTextShadowNode final + : public ConcreteViewShadowNode { +public: + using ConcreteViewShadowNode::ConcreteViewShadowNode; + + T3SourceTextShadowNode(const ShadowNode &sourceShadowNode, + const ShadowNodeFragment &fragment); + + static ShadowNodeTraits BaseTraits() { + auto traits = ConcreteViewShadowNode::BaseTraits(); + traits.set(ShadowNodeTraits::Trait::LeafYogaNode); + traits.set(ShadowNodeTraits::Trait::MeasurableYogaNode); + return traits; + } + + void layout(LayoutContext layoutContext) override; + + Size + measureContent(const LayoutContext &layoutContext, + const LayoutConstraints &layoutConstraints) const override; + +private: + mutable AttributedString _attributedString; +}; +} // namespace facebook::react diff --git a/apps/mobile/modules/t3-source-text/ios/T3SourceTextShadowNode.mm b/apps/mobile/modules/t3-source-text/ios/T3SourceTextShadowNode.mm new file mode 100644 index 000000000000..e0b82bb2dbb9 --- /dev/null +++ b/apps/mobile/modules/t3-source-text/ios/T3SourceTextShadowNode.mm @@ -0,0 +1,171 @@ +#include "T3SourceTextShadowNode.h" +#include "T3SourceTextRunShadowNode.h" +#include +#import + +#include +#include + +namespace facebook::react { + +T3SourceTextShadowNode::T3SourceTextShadowNode( + const ShadowNode &sourceShadowNode, const ShadowNodeFragment &fragment) + : ConcreteViewShadowNode(sourceShadowNode, fragment){}; + +Size T3SourceTextShadowNode::measureContent( + const LayoutContext &layoutContext, + const LayoutConstraints &layoutConstraints) const { + const auto &baseProps = getConcreteProps(); + + auto baseTextAttributes = TextAttributes::defaultTextAttributes(); + baseTextAttributes.backgroundColor = baseProps.backgroundColor; + baseTextAttributes.allowFontScaling = baseProps.allowFontScaling; + + Float fontSizeMultiplier = 1.0; + if (baseTextAttributes.allowFontScaling) { + fontSizeMultiplier = layoutContext.fontSizeMultiplier; + } + + auto baseAttributedString = AttributedString{}; + const auto &children = getChildren(); + for (size_t i = 0; i < children.size(); i++) { + const auto child = children[i].get(); + if (auto textViewChild = + dynamic_cast(child)) { + auto &props = textViewChild->getConcreteProps(); + auto fragment = AttributedString::Fragment{}; + auto textAttributes = TextAttributes::defaultTextAttributes(); + + textAttributes.allowFontScaling = baseProps.allowFontScaling; + textAttributes.backgroundColor = props.backgroundColor; + textAttributes.fontSize = props.fontSize * fontSizeMultiplier; + textAttributes.lineHeight = props.lineHeight * fontSizeMultiplier; + textAttributes.foregroundColor = props.color; + textAttributes.textShadowColor = props.shadowColor; + textAttributes.textShadowOffset = props.shadowOffset; + textAttributes.textShadowRadius = props.shadowRadius; + textAttributes.letterSpacing = props.letterSpacing; + textAttributes.textDecorationColor = props.textDecorationColor; + textAttributes.fontFamily = props.fontFamily; + + if (props.fontStyle == T3SourceTextRunFontStyle::Italic) { + textAttributes.fontStyle = FontStyle::Italic; + } else { + textAttributes.fontStyle = FontStyle::Normal; + } + + if (props.fontWeight == T3SourceTextRunFontWeight::Bold) { + textAttributes.fontWeight = FontWeight::Bold; + } else if (props.fontWeight == T3SourceTextRunFontWeight::UltraLight) { + textAttributes.fontWeight = FontWeight::UltraLight; + } else if (props.fontWeight == T3SourceTextRunFontWeight::Light) { + textAttributes.fontWeight = FontWeight::Light; + } else if (props.fontWeight == T3SourceTextRunFontWeight::Medium) { + textAttributes.fontWeight = FontWeight::Medium; + } else if (props.fontWeight == T3SourceTextRunFontWeight::Semibold) { + textAttributes.fontWeight = FontWeight::Semibold; + } else if (props.fontWeight == T3SourceTextRunFontWeight::Heavy) { + textAttributes.fontWeight = FontWeight::Heavy; + } else { + textAttributes.fontWeight = FontWeight::Regular; + } + + if (props.textDecorationLine == + T3SourceTextRunTextDecorationLine::LineThrough) { + textAttributes.textDecorationLineType = + TextDecorationLineType::Strikethrough; + } else if (props.textDecorationLine == + T3SourceTextRunTextDecorationLine::Underline) { + textAttributes.textDecorationLineType = + TextDecorationLineType::Underline; + } else { + textAttributes.textDecorationLineType = TextDecorationLineType::None; + } + + if (props.textDecorationStyle == + T3SourceTextRunTextDecorationStyle::Solid) { + textAttributes.textDecorationStyle = TextDecorationStyle::Solid; + } else if (props.textDecorationStyle == + T3SourceTextRunTextDecorationStyle::Dotted) { + textAttributes.textDecorationStyle = TextDecorationStyle::Dotted; + } else if (props.textDecorationStyle == + T3SourceTextRunTextDecorationStyle::Dashed) { + textAttributes.textDecorationStyle = TextDecorationStyle::Dashed; + } else if (props.textDecorationStyle == + T3SourceTextRunTextDecorationStyle::Double) { + textAttributes.textDecorationStyle = TextDecorationStyle::Double; + } + + if (props.textAlign == T3SourceTextRunTextAlign::Left) { + textAttributes.alignment = TextAlignment::Left; + } else if (props.textAlign == T3SourceTextRunTextAlign::Right) { + textAttributes.alignment = TextAlignment::Right; + } else if (props.textAlign == T3SourceTextRunTextAlign::Center) { + textAttributes.alignment = TextAlignment::Center; + } else if (props.textAlign == T3SourceTextRunTextAlign::Justify) { + textAttributes.alignment = TextAlignment::Justified; + } else if (props.textAlign == T3SourceTextRunTextAlign::Auto) { + textAttributes.alignment = TextAlignment::Natural; + } + + textAttributes.backgroundColor = props.backgroundColor; + + fragment.string = props.text; + fragment.textAttributes = textAttributes; + + baseAttributedString.appendFragment(std::move(fragment)); + } + } + + _attributedString = baseAttributedString; + + NSMutableAttributedString *convertedAttributedString = + [RCTNSAttributedStringFromAttributedString(baseAttributedString) + mutableCopy]; + // Match React Native's baseline offset in both measurement and rendering. + RCTApplyBaselineOffset(convertedAttributedString); + + const CGFloat maximumWidth = + std::isfinite(layoutConstraints.maximumSize.width) + ? layoutConstraints.maximumSize.width + : CGFLOAT_MAX; + NSTextStorage *textStorage = [[NSTextStorage alloc] + initWithAttributedString:convertedAttributedString]; + NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; + layoutManager.usesFontLeading = NO; + NSTextContainer *textContainer = [[NSTextContainer alloc] + initWithSize:CGSizeMake(maximumWidth, CGFLOAT_MAX)]; + textContainer.lineFragmentPadding = 0; + textContainer.maximumNumberOfLines = baseProps.numberOfLines; + if (baseProps.ellipsizeMode == T3SourceTextEllipsizeMode::Head) { + textContainer.lineBreakMode = NSLineBreakByTruncatingHead; + } else if (baseProps.ellipsizeMode == T3SourceTextEllipsizeMode::Middle) { + textContainer.lineBreakMode = NSLineBreakByTruncatingMiddle; + } else if (baseProps.ellipsizeMode == T3SourceTextEllipsizeMode::Tail) { + textContainer.lineBreakMode = NSLineBreakByTruncatingTail; + } else { + textContainer.lineBreakMode = NSLineBreakByClipping; + } + [layoutManager addTextContainer:textContainer]; + [textStorage addLayoutManager:layoutManager]; + [layoutManager ensureLayoutForTextContainer:textContainer]; + const CGRect usedRect = + [layoutManager usedRectForTextContainer:textContainer]; + + return { + std::clamp(static_cast(std::ceil(usedRect.size.width)), + layoutConstraints.minimumSize.width, + layoutConstraints.maximumSize.width), + std::clamp(static_cast(std::ceil(usedRect.size.height)), + layoutConstraints.minimumSize.height, + layoutConstraints.maximumSize.height), + }; +} + +void T3SourceTextShadowNode::layout(LayoutContext layoutContext) { + ensureUnsealed(); + setStateData(T3SourceTextStateReal{ + _attributedString, + }); +} +} // namespace facebook::react diff --git a/apps/mobile/modules/t3-source-text/package.json b/apps/mobile/modules/t3-source-text/package.json new file mode 100644 index 000000000000..3441386059ed --- /dev/null +++ b/apps/mobile/modules/t3-source-text/package.json @@ -0,0 +1,35 @@ +{ + "name": "@t3tools/mobile-source-text", + "version": "0.0.0", + "private": true, + "files": [ + "ios", + "src", + "index.ts", + "LICENSE", + "UPSTREAM.md", + "T3SourceText.podspec", + "react-native.config.js" + ], + "main": "./index.ts", + "types": "./index.ts", + "react-native": "./index.ts", + "peerDependencies": { + "react": "*", + "react-native": "*" + }, + "codegenConfig": { + "name": "T3SourceTextSpec", + "type": "components", + "jsSrcsDir": "src", + "ios": { + "componentProvider": { + "T3SourceText": "T3SourceText", + "T3SourceTextRun": "T3SourceTextRun" + } + }, + "outputDir": { + "ios": "ios/generated" + } + } +} diff --git a/apps/mobile/modules/t3-markdown-text/react-native.config.js b/apps/mobile/modules/t3-source-text/react-native.config.js similarity index 70% rename from apps/mobile/modules/t3-markdown-text/react-native.config.js rename to apps/mobile/modules/t3-source-text/react-native.config.js index 6b10ea26eec9..33e020928492 100644 --- a/apps/mobile/modules/t3-markdown-text/react-native.config.js +++ b/apps/mobile/modules/t3-source-text/react-native.config.js @@ -2,7 +2,7 @@ module.exports = { dependency: { platforms: { ios: { - podspecPath: "T3MarkdownText.podspec", + podspecPath: "T3SourceText.podspec", }, android: null, }, diff --git a/apps/mobile/modules/t3-source-text/src/SourceText.tsx b/apps/mobile/modules/t3-source-text/src/SourceText.tsx new file mode 100644 index 000000000000..946c7553979e --- /dev/null +++ b/apps/mobile/modules/t3-source-text/src/SourceText.tsx @@ -0,0 +1,52 @@ +import React, { type Ref } from "react"; +import { Platform, StyleSheet, Text, type TextProps, type TextStyle } from "react-native"; +import T3SourceTextRunNativeComponent from "./T3SourceTextRunNativeComponent"; +import T3SourceTextNativeComponent from "./T3SourceTextNativeComponent"; +import { flattenStyles } from "./util"; + +const TextAncestorContext = React.createContext<[boolean, TextStyle]>([false, {}]); + +export type SourceTextProps = Omit & { + nativeTextRef?: Ref; + onSelectionChange?: (event: { + nativeEvent: { target: number; start: number; end: number }; + }) => void; +}; + +/** One selectable document on iOS, with nested runs carrying syntax colors. */ +export function SourceText({ style, children, nativeTextRef, ...props }: SourceTextProps) { + const [isAncestor, rootStyle] = React.useContext(TextAncestorContext); + const flattenedStyle = React.useMemo(() => flattenStyles(rootStyle, style), [rootStyle, style]); + const contextValue = React.useMemo<[boolean, TextStyle]>( + () => [true, StyleSheet.flatten([rootStyle, style])], + [rootStyle, style], + ); + if (Platform.OS !== "ios") { + const { onSelectionChange: _onSelectionChange, ...textProps } = props; + return ( + + {children} + + ); + } + const runs = React.Children.toArray(children).map((child, index) => { + if (React.isValidElement(child)) return child; + if (typeof child !== "string" && typeof child !== "number") return null; + return ( + + ); + }); + if (isAncestor) return <>{runs}; + return ( + + + {runs} + + + ); +} diff --git a/apps/mobile/modules/t3-markdown-text/src/T3MarkdownTextNativeComponent.ts b/apps/mobile/modules/t3-source-text/src/T3SourceTextNativeComponent.ts similarity index 76% rename from apps/mobile/modules/t3-markdown-text/src/T3MarkdownTextNativeComponent.ts rename to apps/mobile/modules/t3-source-text/src/T3SourceTextNativeComponent.ts index f6a78ea541eb..fc18bcf18a3a 100644 --- a/apps/mobile/modules/t3-markdown-text/src/T3MarkdownTextNativeComponent.ts +++ b/apps/mobile/modules/t3-source-text/src/T3SourceTextNativeComponent.ts @@ -10,12 +10,8 @@ interface TargetedEvent { target: Int32; } -interface TextLayoutEvent extends TargetedEvent { - lines: string[]; -} - /** - * Event fired when text selection changes in the MarkdownTextPrimitive. + * Event fired when text selection changes in the SourceText. * @property target - The view tag identifier * @property start - The start index of the selected range (0-based) * @property end - The end index of the selected range (0-based, exclusive) @@ -28,29 +24,27 @@ interface SelectionChangeEvent extends TargetedEvent { type EllipsizeMode = "head" | "middle" | "tail" | "clip"; interface NativeProps extends ViewProps { - contextClipboardConfig?: string; numberOfLines?: Int32; allowFontScaling?: WithDefault; ellipsizeMode?: WithDefault; selectable?: boolean; - onTextLayout?: BubblingEventHandler; /** * Callback fired when the text selection changes. * * @example * ```tsx - * { * console.log('Selection:', event.nativeEvent.start, event.nativeEvent.end); * }} * > * Selectable text - * + * * ``` */ onSelectionChange?: BubblingEventHandler; } -export default codegenNativeComponent("T3MarkdownText", { +export default codegenNativeComponent("T3SourceText", { excludedPlatforms: ["android"], }); diff --git a/apps/mobile/modules/t3-markdown-text/src/T3MarkdownTextRunNativeComponent.ts b/apps/mobile/modules/t3-source-text/src/T3SourceTextRunNativeComponent.ts similarity index 67% rename from apps/mobile/modules/t3-markdown-text/src/T3MarkdownTextRunNativeComponent.ts rename to apps/mobile/modules/t3-source-text/src/T3SourceTextRunNativeComponent.ts index 040e44bc18b5..cf0d2a6ea031 100644 --- a/apps/mobile/modules/t3-markdown-text/src/T3MarkdownTextRunNativeComponent.ts +++ b/apps/mobile/modules/t3-source-text/src/T3SourceTextRunNativeComponent.ts @@ -1,20 +1,7 @@ import type { ColorValue, ViewProps } from "react-native"; -import type { - BubblingEventHandler, - Float, - Int32, - WithDefault, -} from "react-native/Libraries/Types/CodegenTypes"; +import type { Float, WithDefault } from "react-native/Libraries/Types/CodegenTypes"; import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent"; -interface TargetedEvent { - target: Int32; -} - -interface ContextMenuActionEvent extends TargetedEvent { - actionIdentifier: string; -} - type TextDecorationLine = "none" | "underline" | "line-through"; type TextDecorationStyle = "solid" | "double" | "dotted" | "dashed"; @@ -46,12 +33,8 @@ interface NativeProps extends ViewProps { textDecorationColor?: ColorValue; textAlign?: WithDefault; shadowRadius?: WithDefault; - contextMenuConfig?: string; - onPress?: BubblingEventHandler; - onLongPress?: BubblingEventHandler; - onContextMenuAction?: BubblingEventHandler; } -export default codegenNativeComponent("T3MarkdownTextRun", { +export default codegenNativeComponent("T3SourceTextRun", { excludedPlatforms: ["android"], }); diff --git a/apps/mobile/modules/t3-markdown-text/src/util.ts b/apps/mobile/modules/t3-source-text/src/util.ts similarity index 83% rename from apps/mobile/modules/t3-markdown-text/src/util.ts rename to apps/mobile/modules/t3-source-text/src/util.ts index d9f33d3a2ef5..ccdd189edbea 100644 --- a/apps/mobile/modules/t3-markdown-text/src/util.ts +++ b/apps/mobile/modules/t3-source-text/src/util.ts @@ -1,10 +1,15 @@ import { type StyleProp, StyleSheet, type TextStyle } from "react-native"; -import type { NativeFontWeight } from "./T3MarkdownTextRunNativeComponent"; +import type { NativeFontWeight } from "./T3SourceTextRunNativeComponent"; export function flattenStyles(rootStyle: TextStyle, style: StyleProp) { const flattenedStyle = StyleSheet.flatten([rootStyle, style]) as TextStyle; + const textDecorationLine = flattenedStyle.textDecorationLine; return { ...flattenedStyle, + textDecorationLine: + textDecorationLine === "underline" || textDecorationLine === "line-through" + ? textDecorationLine + : ("none" as const), fontWeight: fontWeightToNativeProp(flattenedStyle.fontWeight ?? "normal"), backgroundColor: flattenedStyle.backgroundColor ? flattenedStyle.backgroundColor diff --git a/apps/mobile/package.json b/apps/mobile/package.json index ab5ee0a59f23..0b11a4f22ecd 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -40,7 +40,7 @@ "config:preview": "APP_VARIANT=preview expo config", "config:prod": "APP_VARIANT=production expo config", "profile:android:hermes": "mkdir -p profiles/review && react-native profile-hermes profiles/review", - "sync:pierre-icons": "node modules/t3-markdown-text/scripts/sync-pierre-file-icons.mjs", + "sync:pierre-icons": "node scripts/sync-pierre-file-icons.mjs", "generate": "node --disable-warning=MODULE_TYPELESS_PACKAGE_JSON scripts/generate-uniwind-themes.mts", "test": "vp test run", "typecheck": "tsc --noEmit" @@ -66,8 +66,8 @@ "@shikijs/themes": "4.2.0", "@t3tools/client-runtime": "workspace:*", "@t3tools/contracts": "workspace:*", - "@t3tools/mobile-markdown-text": "file:./modules/t3-markdown-text", "@t3tools/mobile-review-diff-native": "file:./modules/t3-review-diff", + "@t3tools/mobile-source-text": "file:./modules/t3-source-text", "@t3tools/mobile-terminal-native": "file:./modules/t3-terminal", "@t3tools/shared": "workspace:*", "@tabler/icons-react-native": "^3.44.0", @@ -112,7 +112,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "react-native": "0.86.3", - "react-native-enriched-markdown": "file:./vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz", + "react-native-enriched-markdown": "file:./deps/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz", "react-native-gesture-handler": "~2.32.0", "react-native-image-viewing": "^0.2.2", "react-native-keyboard-controller": "1.21.13", diff --git a/apps/mobile/modules/t3-markdown-text/scripts/sync-pierre-file-icons.mjs b/apps/mobile/scripts/sync-pierre-file-icons.mjs similarity index 90% rename from apps/mobile/modules/t3-markdown-text/scripts/sync-pierre-file-icons.mjs rename to apps/mobile/scripts/sync-pierre-file-icons.mjs index fdbb03382eef..edb0cb467592 100644 --- a/apps/mobile/modules/t3-markdown-text/scripts/sync-pierre-file-icons.mjs +++ b/apps/mobile/scripts/sync-pierre-file-icons.mjs @@ -6,10 +6,10 @@ import * as NodeURL from "node:url"; import { getBuiltInSpriteSheet } from "@pierre/trees"; const scriptDirectory = NodePath.dirname(NodeURL.fileURLToPath(import.meta.url)); -const moduleDirectory = NodePath.resolve(scriptDirectory, ".."); -const repositoryRoot = NodePath.resolve(moduleDirectory, "../../../.."); -const outputDirectory = NodePath.join(moduleDirectory, "assets/file-icons"); -const generatedModulePath = NodePath.join(moduleDirectory, "src/markdownFileIcons.generated.ts"); +const appDirectory = NodePath.resolve(scriptDirectory, ".."); +const repositoryRoot = NodePath.resolve(appDirectory, "../.."); +const outputDirectory = NodePath.join(appDirectory, "assets/file-icons"); +const generatedModulePath = NodePath.join(appDirectory, "src/lib/markdownFileIcons.generated.ts"); const webIconSource = NodeFS.readFileSync( NodePath.join(repositoryRoot, "apps/web/src/pierre-icons.ts"), "utf8", @@ -129,6 +129,6 @@ for (const [token, symbolId] of Object.entries(customIcons)) { const tokens = [...new Set([...builtInTokens, ...Object.keys(customIcons)])].sort(); const generatedSource = `import type { ImageSourcePropType } from "react-native";\n\nexport const MARKDOWN_FILE_ICON_SOURCES = {\n${tokens - .map((token) => ` ${token}: require("../assets/file-icons/pierre_${token}.png"),`) + .map((token) => ` ${token}: require("../../assets/file-icons/pierre_${token}.png"),`) .join("\n")}\n} as const satisfies Readonly>;\n`; NodeFS.writeFileSync(generatedModulePath, generatedSource); diff --git a/apps/mobile/src/components/PierreEntryIcon.tsx b/apps/mobile/src/components/PierreEntryIcon.tsx index cb73f5b7b180..7ae7a4b70090 100644 --- a/apps/mobile/src/components/PierreEntryIcon.tsx +++ b/apps/mobile/src/components/PierreEntryIcon.tsx @@ -1,8 +1,8 @@ import { SymbolView } from "../components/AppSymbol"; import { Image, type ImageStyle, type StyleProp } from "react-native"; -import { markdownFileIconSource } from "@t3tools/mobile-markdown-text/file-icons"; -import { resolveMarkdownFileIcon } from "@t3tools/mobile-markdown-text/links"; +import { markdownFileIconSource } from "../lib/markdownFileIcons"; +import { resolveMarkdownFileIcon } from "../lib/markdownLinks"; export function PierreEntryIcon(props: { readonly path: string; diff --git a/apps/mobile/src/features/files/FileMarkdownPreview.tsx b/apps/mobile/src/features/files/FileMarkdownPreview.tsx index c5e4c5430db6..0aa4e9d72356 100644 --- a/apps/mobile/src/features/files/FileMarkdownPreview.tsx +++ b/apps/mobile/src/features/files/FileMarkdownPreview.tsx @@ -15,7 +15,7 @@ import { } from "../threads/ThreadMarkdownImage"; import { ThreadMarkdownVideo } from "../threads/ThreadMarkdownVideo"; import { resolveMarkdownMediaPreview } from "../../lib/markdownMedia"; -import { normalizeNativeMarkdownUrl } from "@t3tools/mobile-markdown-text/links"; +import { normalizeNativeMarkdownUrl } from "../../lib/markdownLinks"; import { FilePreviewModal, type FilePreviewSource } from "../../components/FilePreviewModal"; import { useMarkdownImageSource } from "../../native/useMarkdownImageSource"; import { useAppearancePreferences } from "../settings/appearance/AppearancePreferencesProvider"; diff --git a/apps/mobile/src/features/files/SourceFileSurface.tsx b/apps/mobile/src/features/files/SourceFileSurface.tsx index c7c2310ba936..8d52dfa593f9 100644 --- a/apps/mobile/src/features/files/SourceFileSurface.tsx +++ b/apps/mobile/src/features/files/SourceFileSurface.tsx @@ -31,7 +31,7 @@ import { NATIVE_SOURCE_CONTENT_WIDTH, nativeSourceRowId, } from "./nativeSourceFileAdapter"; -import { MarkdownTextPrimitive } from "@t3tools/mobile-markdown-text/primitive"; +import { SourceText } from "@t3tools/mobile-source-text"; import { boundedSelectableSourceTokens, prepareSourceFileDocument } from "./source-file-document"; import { sourceHighlightAtom } from "./sourceHighlightingState"; @@ -270,14 +270,13 @@ function JavaScriptSourceFileSurface(props: SourceFileSurfaceProps) { [codeSurface, codeWordBreak, targetIndex, tokens], ); - // One selectable text for the whole file. On iOS `uiTextView` renders a real `UITextView`, + // One selectable text for the whole file. On iOS the primitive renders a real `UITextView`, // which selects across every line, wraps, and lays out long documents through TextKit; on // Android the primitive is an RN `Text`, which selects across its nested children. Either // way "select all" takes the file rather than a line, which a `FlatList` row can never do // because each row is its own selection scope. const selectableBlock = props.selectable ? ( - 0 ? lineTokens.map((token, tokenIndex) => ( - {token.content} - + )) : line; return ( - + {body} {index < lines.length - 1 ? "\n" : ""} - + ); }) : normalizedContents} - + ) : null; const list = ( diff --git a/apps/mobile/src/features/threads/ThreadFeed.tsx b/apps/mobile/src/features/threads/ThreadFeed.tsx index 665432acc451..5f11c8e3e211 100644 --- a/apps/mobile/src/features/threads/ThreadFeed.tsx +++ b/apps/mobile/src/features/threads/ThreadFeed.tsx @@ -120,13 +120,13 @@ import { import { resolveNativeMarkdownTypography } from "../../lib/appearancePreferences"; import { useAppearancePreferences } from "../settings/appearance/AppearancePreferencesProvider"; import { PierreEntryIcon } from "../../components/PierreEntryIcon"; -import { markdownFileIconSource } from "@t3tools/mobile-markdown-text/file-icons"; +import { markdownFileIconSource } from "../../lib/markdownFileIcons"; import { enrichedContextLinkPresentation } from "../../lib/enrichedLinkPresentation"; import { useMarkdownImageSource } from "../../native/useMarkdownImageSource"; import { normalizeNativeMarkdownUrl, resolveMarkdownLinkPresentation, -} from "@t3tools/mobile-markdown-text/links"; +} from "../../lib/markdownLinks"; import { deriveThreadFeedPresentation, deriveUnsettledTurnId, diff --git a/apps/mobile/src/features/threads/fileChipMenu.ts b/apps/mobile/src/features/threads/fileChipMenu.ts index 9f82e089444d..b0c8f378dfbc 100644 --- a/apps/mobile/src/features/threads/fileChipMenu.ts +++ b/apps/mobile/src/features/threads/fileChipMenu.ts @@ -1,7 +1,7 @@ import { fileBasename } from "@t3tools/client-runtime/markdown-links"; import type { ThreadId } from "@t3tools/contracts"; -import { resolveMarkdownLinkPresentation } from "@t3tools/mobile-markdown-text/links"; -import type { MarkdownFileContextMenu } from "@t3tools/mobile-markdown-text/types"; +import { resolveMarkdownLinkPresentation } from "../../lib/markdownLinks"; +import type { MarkdownFileContextMenu } from "../../native/SelectableMarkdownText.types"; import { hostPreviewMimeTypeFromExtension } from "@t3tools/shared/filePreview"; import { diff --git a/apps/mobile/src/lib/composerChipPresentation.test.ts b/apps/mobile/src/lib/composerChipPresentation.test.ts index 93f52ed523af..3e0af9834522 100644 --- a/apps/mobile/src/lib/composerChipPresentation.test.ts +++ b/apps/mobile/src/lib/composerChipPresentation.test.ts @@ -2,14 +2,14 @@ import { describe, expect, it } from "vite-plus/test"; describe("composerChipSizeSuffix", () => { it("labels attachment records with a human size, matching web's chip", async () => { - const { composerChipSizeSuffix } = await import("@t3tools/mobile-markdown-text/markdown"); + const { composerChipSizeSuffix } = await import("./composerChipPresentation"); expect(composerChipSizeSuffix({ kind: "file", sizeBytes: 1024 })).toBe("1 KB"); expect(composerChipSizeSuffix({ kind: "file", sizeBytes: 3_700_000 })).toBe("3.5 MB"); expect(composerChipSizeSuffix({ kind: "image", sizeBytes: 2048 })).toBe("2 KB"); }); it("adds nothing for records that carry no bytes", async () => { - const { composerChipSizeSuffix } = await import("@t3tools/mobile-markdown-text/markdown"); + const { composerChipSizeSuffix } = await import("./composerChipPresentation"); // Terminal/review/PR chips have no size to show. expect(composerChipSizeSuffix({ kind: "terminal" })).toBe(""); expect(composerChipSizeSuffix({ kind: "file" })).toBe(""); @@ -19,7 +19,7 @@ describe("composerChipSizeSuffix", () => { describe("contextChipPresentation image detection", () => { it("treats a picture attached through the file picker as an image", async () => { - const { contextChipPresentation } = await import("@t3tools/mobile-markdown-text/markdown"); + const { contextChipPresentation } = await import("./composerChipPresentation"); // The document picker types every pick as `file`, so the name has to carry the intent. expect( contextChipPresentation("file", { kind: "file", name: "IMG_4997.PNG", mimeType: "" }), @@ -34,7 +34,7 @@ describe("contextChipPresentation image detection", () => { }); it("leaves genuine documents and videos alone", async () => { - const { contextChipPresentation } = await import("@t3tools/mobile-markdown-text/markdown"); + const { contextChipPresentation } = await import("./composerChipPresentation"); expect( contextChipPresentation("file", { kind: "file", name: "notes.txt", mimeType: "text/plain" }), ).toEqual({ accent: "#0090cd", symbol: "doc" }); @@ -46,7 +46,7 @@ describe("contextChipPresentation image detection", () => { describe("pull request chip status", () => { const chip = async (state: string, isDraft = false) => { - const { contextChipPresentation } = await import("@t3tools/mobile-markdown-text/markdown"); + const { contextChipPresentation } = await import("./composerChipPresentation"); return contextChipPresentation("review-comment", { kind: "review-comment", sectionId: "pull-request:10978", @@ -73,7 +73,7 @@ describe("pull request chip status", () => { }); it("falls back to the generic pull request chip when the state is unknown", async () => { - const { contextChipPresentation } = await import("@t3tools/mobile-markdown-text/markdown"); + const { contextChipPresentation } = await import("./composerChipPresentation"); // An older server may send no metadata at all; the chip still has to render. expect( contextChipPresentation("review-comment", { diff --git a/apps/mobile/modules/t3-markdown-text/src/composerChipPresentation.ts b/apps/mobile/src/lib/composerChipPresentation.ts similarity index 100% rename from apps/mobile/modules/t3-markdown-text/src/composerChipPresentation.ts rename to apps/mobile/src/lib/composerChipPresentation.ts diff --git a/apps/mobile/src/lib/enrichedLinkPresentation.ts b/apps/mobile/src/lib/enrichedLinkPresentation.ts index 5dd3cae68492..5ea8fd1afad1 100644 --- a/apps/mobile/src/lib/enrichedLinkPresentation.ts +++ b/apps/mobile/src/lib/enrichedLinkPresentation.ts @@ -1,7 +1,7 @@ import type { ComposerContextRecord } from "@t3tools/contracts"; -import { contextChipPresentation } from "@t3tools/mobile-markdown-text/markdown"; -import type { MarkdownFileIcon } from "@t3tools/mobile-markdown-text/links"; -import type { SelectableMarkdownSkill } from "@t3tools/mobile-markdown-text/types"; +import { contextChipPresentation } from "./composerChipPresentation"; +import type { MarkdownFileIcon } from "./markdownLinks"; +import type { SelectableMarkdownSkill } from "../native/SelectableMarkdownText.types"; import { parseComposerContextHref } from "@t3tools/shared/composerContextReferences"; const CONTEXT_ICONS: Readonly> = { diff --git a/apps/mobile/src/lib/markdownFileIcons.generated.ts b/apps/mobile/src/lib/markdownFileIcons.generated.ts new file mode 100644 index 000000000000..e097b51a87a3 --- /dev/null +++ b/apps/mobile/src/lib/markdownFileIcons.generated.ts @@ -0,0 +1,60 @@ +import type { ImageSourcePropType } from "react-native"; + +export const MARKDOWN_FILE_ICON_SOURCES = { + agents: require("../../assets/file-icons/pierre_agents.png"), + astro: require("../../assets/file-icons/pierre_astro.png"), + babel: require("../../assets/file-icons/pierre_babel.png"), + bash: require("../../assets/file-icons/pierre_bash.png"), + biome: require("../../assets/file-icons/pierre_biome.png"), + bootstrap: require("../../assets/file-icons/pierre_bootstrap.png"), + browserslist: require("../../assets/file-icons/pierre_browserslist.png"), + bun: require("../../assets/file-icons/pierre_bun.png"), + c: require("../../assets/file-icons/pierre_c.png"), + claude: require("../../assets/file-icons/pierre_claude.png"), + cpp: require("../../assets/file-icons/pierre_cpp.png"), + css: require("../../assets/file-icons/pierre_css.png"), + database: require("../../assets/file-icons/pierre_database.png"), + default: require("../../assets/file-icons/pierre_default.png"), + docker: require("../../assets/file-icons/pierre_docker.png"), + eslint: require("../../assets/file-icons/pierre_eslint.png"), + font: require("../../assets/file-icons/pierre_font.png"), + git: require("../../assets/file-icons/pierre_git.png"), + go: require("../../assets/file-icons/pierre_go.png"), + graphql: require("../../assets/file-icons/pierre_graphql.png"), + html: require("../../assets/file-icons/pierre_html.png"), + image: require("../../assets/file-icons/pierre_image.png"), + javascript: require("../../assets/file-icons/pierre_javascript.png"), + json: require("../../assets/file-icons/pierre_json.png"), + markdown: require("../../assets/file-icons/pierre_markdown.png"), + mcp: require("../../assets/file-icons/pierre_mcp.png"), + nextjs: require("../../assets/file-icons/pierre_nextjs.png"), + npm: require("../../assets/file-icons/pierre_npm.png"), + oxc: require("../../assets/file-icons/pierre_oxc.png"), + pnpm: require("../../assets/file-icons/pierre_pnpm.png"), + postcss: require("../../assets/file-icons/pierre_postcss.png"), + prettier: require("../../assets/file-icons/pierre_prettier.png"), + python: require("../../assets/file-icons/pierre_python.png"), + react: require("../../assets/file-icons/pierre_react.png"), + ruby: require("../../assets/file-icons/pierre_ruby.png"), + rust: require("../../assets/file-icons/pierre_rust.png"), + sass: require("../../assets/file-icons/pierre_sass.png"), + stylelint: require("../../assets/file-icons/pierre_stylelint.png"), + svelte: require("../../assets/file-icons/pierre_svelte.png"), + svg: require("../../assets/file-icons/pierre_svg.png"), + svgo: require("../../assets/file-icons/pierre_svgo.png"), + swift: require("../../assets/file-icons/pierre_swift.png"), + table: require("../../assets/file-icons/pierre_table.png"), + tailwind: require("../../assets/file-icons/pierre_tailwind.png"), + terraform: require("../../assets/file-icons/pierre_terraform.png"), + text: require("../../assets/file-icons/pierre_text.png"), + typescript: require("../../assets/file-icons/pierre_typescript.png"), + video: require("../../assets/file-icons/pierre_video.png"), + vite: require("../../assets/file-icons/pierre_vite.png"), + vscode: require("../../assets/file-icons/pierre_vscode.png"), + vue: require("../../assets/file-icons/pierre_vue.png"), + wasm: require("../../assets/file-icons/pierre_wasm.png"), + webpack: require("../../assets/file-icons/pierre_webpack.png"), + yml: require("../../assets/file-icons/pierre_yml.png"), + zig: require("../../assets/file-icons/pierre_zig.png"), + zip: require("../../assets/file-icons/pierre_zip.png"), +} as const satisfies Readonly>; diff --git a/apps/mobile/modules/t3-markdown-text/src/markdownFileIcons.ts b/apps/mobile/src/lib/markdownFileIcons.ts similarity index 100% rename from apps/mobile/modules/t3-markdown-text/src/markdownFileIcons.ts rename to apps/mobile/src/lib/markdownFileIcons.ts diff --git a/apps/mobile/modules/t3-markdown-text/src/markdownLinkIcons.ts b/apps/mobile/src/lib/markdownLinkIcons.ts similarity index 88% rename from apps/mobile/modules/t3-markdown-text/src/markdownLinkIcons.ts rename to apps/mobile/src/lib/markdownLinkIcons.ts index 568a51005798..5ff492f6fb3c 100644 --- a/apps/mobile/modules/t3-markdown-text/src/markdownLinkIcons.ts +++ b/apps/mobile/src/lib/markdownLinkIcons.ts @@ -4,7 +4,7 @@ import type { MarkdownLinkIcon } from "./markdownLinks"; // Black-on-transparent marks; callers tint them with the link color. const MARKDOWN_LINK_ICON_SOURCES = { - github: require("../assets/link-icons/github.png"), + github: require("../../assets/link-icons/github.png"), } as const satisfies Readonly>; export function markdownLinkIconSource(icon: MarkdownLinkIcon): ImageSourcePropType { diff --git a/apps/mobile/src/lib/markdownLinks.test.ts b/apps/mobile/src/lib/markdownLinks.test.ts index 38f1f5211421..b04ab738afcd 100644 --- a/apps/mobile/src/lib/markdownLinks.test.ts +++ b/apps/mobile/src/lib/markdownLinks.test.ts @@ -1,9 +1,6 @@ import { describe, expect, it } from "vite-plus/test"; -import { - resolveMarkdownLinkIcon, - resolveMarkdownLinkPresentation, -} from "@t3tools/mobile-markdown-text/links"; +import { resolveMarkdownLinkIcon, resolveMarkdownLinkPresentation } from "./markdownLinks"; describe("resolveMarkdownLinkIcon", () => { it("gives GitHub hosts the brand mark and everything else the generic glyph", () => { diff --git a/apps/mobile/modules/t3-markdown-text/src/markdownLinks.ts b/apps/mobile/src/lib/markdownLinks.ts similarity index 100% rename from apps/mobile/modules/t3-markdown-text/src/markdownLinks.ts rename to apps/mobile/src/lib/markdownLinks.ts diff --git a/apps/mobile/src/lib/markdownMedia.ts b/apps/mobile/src/lib/markdownMedia.ts index b1b616f0e442..223c2f9faec4 100644 --- a/apps/mobile/src/lib/markdownMedia.ts +++ b/apps/mobile/src/lib/markdownMedia.ts @@ -1,6 +1,6 @@ import { resolveMediaSource } from "@t3tools/client-runtime/media-source"; import type { EnvironmentId, ThreadId } from "@t3tools/contracts"; -import { normalizeNativeMarkdownUrl } from "@t3tools/mobile-markdown-text/links"; +import { normalizeNativeMarkdownUrl } from "./markdownLinks"; import type { FilePreviewSource } from "../components/FilePreviewModal"; import type { MediaVideoPreviewSource } from "./videoPreviewSource"; diff --git a/apps/mobile/src/lib/mediaActions.ts b/apps/mobile/src/lib/mediaActions.ts index d2fef103a3a9..661706791865 100644 --- a/apps/mobile/src/lib/mediaActions.ts +++ b/apps/mobile/src/lib/mediaActions.ts @@ -2,7 +2,7 @@ import { useNavigation } from "@react-navigation/native"; import type { MediaActionId } from "@t3tools/client-runtime/media-actions"; import type { MediaReference } from "@t3tools/client-runtime/media-reference"; import type { AssetResource, EnvironmentId, ThreadId } from "@t3tools/contracts"; -import { normalizeNativeMarkdownUrl } from "@t3tools/mobile-markdown-text/links"; +import { normalizeNativeMarkdownUrl } from "./markdownLinks"; import { useEffect, useRef, useState } from "react"; import { Alert } from "react-native"; diff --git a/apps/mobile/src/native/EnrichedMarkdownText.tsx b/apps/mobile/src/native/EnrichedMarkdownText.tsx index d087d3b33400..c501660089f6 100644 --- a/apps/mobile/src/native/EnrichedMarkdownText.tsx +++ b/apps/mobile/src/native/EnrichedMarkdownText.tsx @@ -6,7 +6,7 @@ import { type MarkdownStyle, type MarkdownMediaAsset, } from "react-native-enriched-markdown"; -import type { SelectableMarkdownTextProps } from "@t3tools/mobile-markdown-text/types"; +import type { SelectableMarkdownTextProps } from "./SelectableMarkdownText.types"; import { useAppearancePreferences } from "../features/settings/appearance/AppearancePreferencesProvider"; import { AndroidAnchoredMenu } from "../components/AndroidAnchoredMenu"; diff --git a/apps/mobile/src/native/SelectableMarkdownText.tsx b/apps/mobile/src/native/SelectableMarkdownText.tsx index daf840ceb4cc..89ec6fcaf81e 100644 --- a/apps/mobile/src/native/SelectableMarkdownText.tsx +++ b/apps/mobile/src/native/SelectableMarkdownText.tsx @@ -1,6 +1,6 @@ import { useMemo } from "react"; import { Platform } from "react-native"; -import type { SelectableMarkdownTextProps } from "@t3tools/mobile-markdown-text/types"; +import type { SelectableMarkdownTextProps } from "./SelectableMarkdownText.types"; import { MobileEnrichedMarkdownText } from "./EnrichedMarkdownText"; import { themeColorWithAlpha } from "../lib/mobileTheme"; @@ -15,7 +15,7 @@ export type { MarkdownLinkCustomization, NativeMarkdownTextStyle, SelectableMarkdownSkill, -} from "@t3tools/mobile-markdown-text/types"; +} from "./SelectableMarkdownText.types"; export function SelectableMarkdownText(props: SelectableMarkdownTextProps) { const theme = useUniwindTheme(); diff --git a/apps/mobile/modules/t3-markdown-text/src/SelectableMarkdownText.types.ts b/apps/mobile/src/native/SelectableMarkdownText.types.ts similarity index 100% rename from apps/mobile/modules/t3-markdown-text/src/SelectableMarkdownText.types.ts rename to apps/mobile/src/native/SelectableMarkdownText.types.ts diff --git a/apps/mobile/src/native/T3ComposerEditor.ios.tsx b/apps/mobile/src/native/T3ComposerEditor.ios.tsx index 5b1a28d5df1c..939fbd0b0512 100644 --- a/apps/mobile/src/native/T3ComposerEditor.ios.tsx +++ b/apps/mobile/src/native/T3ComposerEditor.ios.tsx @@ -15,12 +15,9 @@ import { import type { NativeSyntheticEvent, StyleProp, ViewProps, ViewStyle } from "react-native"; import { Image, StyleSheet } from "react-native"; -import { markdownFileIconSource } from "@t3tools/mobile-markdown-text/file-icons"; -import { - composerChipSizeSuffix, - contextChipPresentation, -} from "@t3tools/mobile-markdown-text/markdown"; -import { resolveMarkdownFileIcon } from "@t3tools/mobile-markdown-text/links"; +import { markdownFileIconSource } from "../lib/markdownFileIcons"; +import { composerChipSizeSuffix, contextChipPresentation } from "../lib/composerChipPresentation"; +import { resolveMarkdownFileIcon } from "../lib/markdownLinks"; import { useUniwindTheme } from "../lib/useUniwindTheme"; import { createNativeComposerTheme } from "../lib/nativeComposerTheme"; import { useFontFamily } from "../lib/useFontFamily"; diff --git a/apps/mobile/src/native/T3ComposerEditor.native.tsx b/apps/mobile/src/native/T3ComposerEditor.native.tsx index 7f18bae0570a..d8d5bdb6321a 100644 --- a/apps/mobile/src/native/T3ComposerEditor.native.tsx +++ b/apps/mobile/src/native/T3ComposerEditor.native.tsx @@ -16,12 +16,9 @@ import { import type { NativeSyntheticEvent, ViewProps } from "react-native"; import { Image, Platform, StyleSheet } from "react-native"; -import { markdownFileIconSource } from "@t3tools/mobile-markdown-text/file-icons"; -import { - composerChipSizeSuffix, - contextChipPresentation, -} from "@t3tools/mobile-markdown-text/markdown"; -import { resolveMarkdownFileIcon } from "@t3tools/mobile-markdown-text/links"; +import { markdownFileIconSource } from "../lib/markdownFileIcons"; +import { composerChipSizeSuffix, contextChipPresentation } from "../lib/composerChipPresentation"; +import { resolveMarkdownFileIcon } from "../lib/markdownLinks"; import { MOBILE_TYPOGRAPHY } from "../lib/typography"; import { useNativePaste } from "../lib/useNativePaste"; import { useFontFamily } from "../lib/useFontFamily"; diff --git a/apps/mobile/src/native/useEnrichedLinkVariants.ts b/apps/mobile/src/native/useEnrichedLinkVariants.ts index acb2a844e042..b7a3f793eacd 100644 --- a/apps/mobile/src/native/useEnrichedLinkVariants.ts +++ b/apps/mobile/src/native/useEnrichedLinkVariants.ts @@ -2,13 +2,10 @@ import { Asset } from "expo-asset"; import { useEffect, useMemo, useState } from "react"; import type { ImageSourcePropType } from "react-native"; import type { MarkdownDocumentAsset, MarkdownStyle } from "react-native-enriched-markdown"; -import { markdownFileIconSource } from "@t3tools/mobile-markdown-text/file-icons"; -import { markdownLinkIconSource } from "@t3tools/mobile-markdown-text/link-icons"; -import { - resolveMarkdownLinkIcon, - resolveMarkdownLinkPresentation, -} from "@t3tools/mobile-markdown-text/links"; -import type { SelectableMarkdownTextProps } from "@t3tools/mobile-markdown-text/types"; +import { markdownFileIconSource } from "../lib/markdownFileIcons"; +import { markdownLinkIconSource } from "../lib/markdownLinkIcons"; +import { resolveMarkdownLinkIcon, resolveMarkdownLinkPresentation } from "../lib/markdownLinks"; +import type { SelectableMarkdownTextProps } from "./SelectableMarkdownText.types"; import { enrichedContextLinkPresentation, diff --git a/apps/mobile/src/native/useMarkdownImageSource.ts b/apps/mobile/src/native/useMarkdownImageSource.ts index 052060ba48f4..32eeac51b85f 100644 --- a/apps/mobile/src/native/useMarkdownImageSource.ts +++ b/apps/mobile/src/native/useMarkdownImageSource.ts @@ -1,8 +1,8 @@ import { resolveMobileMarkdownMediaSource } from "../lib/markdownMediaSource"; import { resolveAssetUrl } from "@t3tools/client-runtime/state/assets"; import type { EnvironmentId, ThreadId } from "@t3tools/contracts"; -import type { MarkdownImageSourceResolver } from "@t3tools/mobile-markdown-text/types"; -import { normalizeNativeMarkdownUrl } from "@t3tools/mobile-markdown-text/links"; +import type { MarkdownImageSourceResolver } from "./SelectableMarkdownText.types"; +import { normalizeNativeMarkdownUrl } from "../lib/markdownLinks"; import { useCallback } from "react"; import * as Option from "effect/Option"; diff --git a/knip.jsonc b/knip.jsonc index 5e87b4d5bc55..8e96acf89796 100644 --- a/knip.jsonc +++ b/knip.jsonc @@ -72,7 +72,7 @@ "@t3tools/mobile-terminal-native", ], }, - "apps/mobile/modules/t3-markdown-text": { + "apps/mobile/modules/t3-source-text": { // React Native codegen discovers component specifications by filename. "entry": ["src/*NativeComponent.ts!"], }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 76721853148a..9e346b86a622 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -295,12 +295,12 @@ importers: '@t3tools/contracts': specifier: workspace:* version: link:../../packages/contracts - '@t3tools/mobile-markdown-text': - specifier: file:./modules/t3-markdown-text - version: file:apps/mobile/modules/t3-markdown-text(fd2defbaa44d0c14a2784c8bacd94382) '@t3tools/mobile-review-diff-native': specifier: file:./modules/t3-review-diff version: file:apps/mobile/modules/t3-review-diff + '@t3tools/mobile-source-text': + specifier: file:./modules/t3-source-text + version: file:apps/mobile/modules/t3-source-text(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) '@t3tools/mobile-terminal-native': specifier: file:./modules/t3-terminal version: file:apps/mobile/modules/t3-terminal @@ -434,8 +434,8 @@ importers: specifier: 0.86.3 version: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) react-native-enriched-markdown: - specifier: file:./vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz - version: file:apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + specifier: file:./deps/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz + version: file:apps/mobile/deps/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) react-native-gesture-handler: specifier: ~2.32.0 version: 2.32.0(patch_hash=0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) @@ -4693,22 +4693,15 @@ packages: resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} - '@t3tools/mobile-markdown-text@file:apps/mobile/modules/t3-markdown-text': - resolution: {directory: apps/mobile/modules/t3-markdown-text, type: directory} + '@t3tools/mobile-review-diff-native@file:apps/mobile/modules/t3-review-diff': + resolution: {directory: apps/mobile/modules/t3-review-diff, type: directory} + + '@t3tools/mobile-source-text@file:apps/mobile/modules/t3-source-text': + resolution: {directory: apps/mobile/modules/t3-source-text, type: directory} peerDependencies: - '@t3tools/client-runtime': '*' - '@t3tools/shared': '*' - expo: '*' - expo-asset: '*' - expo-clipboard: '*' - expo-haptics: '*' - expo-symbols: '*' react: '*' react-native: '*' - '@t3tools/mobile-review-diff-native@file:apps/mobile/modules/t3-review-diff': - resolution: {directory: apps/mobile/modules/t3-review-diff, type: directory} - '@t3tools/mobile-terminal-native@file:apps/mobile/modules/t3-terminal': resolution: {directory: apps/mobile/modules/t3-terminal, type: directory} @@ -9317,8 +9310,8 @@ packages: '@types/react': '>=18' react: '>=18' - react-native-enriched-markdown@file:apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz: - resolution: {integrity: sha512-RCI5b0szfJ8fRL2aM1fjYw3xiJjqeSu/AEN/fgjrLK61M0Y82SoLtzr+o3UzBkOK/G7nmhHvzUtHhjfWl+hP1Q==, tarball: file:apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz} + react-native-enriched-markdown@file:apps/mobile/deps/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz: + resolution: {integrity: sha512-RCI5b0szfJ8fRL2aM1fjYw3xiJjqeSu/AEN/fgjrLK61M0Y82SoLtzr+o3UzBkOK/G7nmhHvzUtHhjfWl+hP1Q==, tarball: file:apps/mobile/deps/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz} version: 1.1.0-nightly-20260918-bb2b0942a peerDependencies: katex: '>=0.16.0' @@ -14790,20 +14783,13 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@t3tools/mobile-markdown-text@file:apps/mobile/modules/t3-markdown-text(fd2defbaa44d0c14a2784c8bacd94382)': + '@t3tools/mobile-review-diff-native@file:apps/mobile/modules/t3-review-diff': {} + + '@t3tools/mobile-source-text@file:apps/mobile/modules/t3-source-text(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)': dependencies: - '@t3tools/client-runtime': link:packages/client-runtime - '@t3tools/shared': link:packages/shared - expo: 57.0.18(41fd11498a34454c91128cdad32f22f8) - expo-asset: 57.0.15(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@7.0.2) - expo-clipboard: 57.0.1(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - expo-haptics: 57.0.2(expo@57.0.18) - expo-symbols: 57.0.2(expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) react: 19.2.3 react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - '@t3tools/mobile-review-diff-native@file:apps/mobile/modules/t3-review-diff': {} - '@t3tools/mobile-terminal-native@file:apps/mobile/modules/t3-terminal': {} '@tabler/icons-react-native@3.44.0(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react@19.2.3)': @@ -20305,7 +20291,7 @@ snapshots: transitivePeerDependencies: - supports-color - react-native-enriched-markdown@file:apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-enriched-markdown@file:apps/mobile/deps/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): dependencies: react: 19.2.3 react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e022a437ea77..19f1aa8fd546 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -18,7 +18,7 @@ allowBuilds: msw: false node-pty: true sharp: true - react-native-enriched-markdown@file:apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz: true + react-native-enriched-markdown@file:apps/mobile/deps/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz: true utf-8-validate: false workerd: false diff --git a/scripts/release-smoke.ts b/scripts/release-smoke.ts index 88407cb7c15f..3d706ffce483 100644 --- a/scripts/release-smoke.ts +++ b/scripts/release-smoke.ts @@ -17,7 +17,7 @@ const workspaceFiles = [ "apps/desktop/package.json", "apps/web/package.json", "apps/mobile/package.json", - "apps/mobile/modules/t3-markdown-text/package.json", + "apps/mobile/modules/t3-source-text/package.json", "apps/mobile/modules/t3-review-diff/package.json", "apps/mobile/modules/t3-terminal/package.json", "apps/marketing/package.json", @@ -46,9 +46,9 @@ function copyWorkspaceManifestFixture(targetRoot: string): void { NodeFS.cpSync(patchesDirectory, NodePath.resolve(targetRoot, "patches"), { recursive: true }); } - const mobileVendorDirectory = NodePath.resolve(repoRoot, "apps/mobile/vendor"); - if (NodeFS.existsSync(mobileVendorDirectory)) { - NodeFS.cpSync(mobileVendorDirectory, NodePath.resolve(targetRoot, "apps/mobile/vendor"), { + const mobileDepsDirectory = NodePath.resolve(repoRoot, "apps/mobile/deps"); + if (NodeFS.existsSync(mobileDepsDirectory)) { + NodeFS.cpSync(mobileDepsDirectory, NodePath.resolve(targetRoot, "apps/mobile/deps"), { recursive: true, }); } diff --git a/third-party-licenses.config.json b/third-party-licenses.config.json index d72ad7f2e6e1..a72dbb00b4d2 100644 --- a/third-party-licenses.config.json +++ b/third-party-licenses.config.json @@ -139,7 +139,7 @@ "bundles": ["mobile"], "license": "MIT", "name": "react-native-uitextview", - "noticeFile": "apps/mobile/modules/t3-markdown-text/LICENSE", + "noticeFile": "apps/mobile/modules/t3-source-text/LICENSE", "sourceUrl": "https://github.com/bluesky-social/react-native-uitextview", "version": "2.2.0" }, From ed257f3c2f24241a985d704299601e9374f0e648 Mon Sep 17 00:00:00 2001 From: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com> Date: Sun, 20 Sep 2026 18:17:42 -0700 Subject: [PATCH 08/11] feat(mobile): show native context menus for Markdown links --- apps/mobile/deps/README.md | 8 +-- ...0260918-bb2b0942a-link-context-menu-v2.tgz | Bin 0 -> 1018227 bytes ...kdown-1.1.0-nightly-20260918-bb2b0942a.tgz | Bin 1012334 -> 0 bytes apps/mobile/package.json | 2 +- .../src/native/EnrichedMarkdownText.tsx | 48 ++++++++++++++++-- pnpm-lock.yaml | 10 ++-- pnpm-workspace.yaml | 2 +- 7 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 apps/mobile/deps/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a-link-context-menu-v2.tgz delete mode 100644 apps/mobile/deps/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz diff --git a/apps/mobile/deps/README.md b/apps/mobile/deps/README.md index 47294491ae97..da0daf4bbd1d 100644 --- a/apps/mobile/deps/README.md +++ b/apps/mobile/deps/README.md @@ -3,9 +3,11 @@ The tarball contains the prepared `react-native-enriched-markdown` package based on upstream [bb2b0942](https://github.com/software-mansion/enriched-markdown/commit/bb2b0942a55555463fe129899d9c922038f10c41), including the prototype's generic API extensions and native fixes. It replaces -the pnpm patch without changing the library's runtime sources. JS, TypeScript -declarations, generated native bindings, native sources, and the MIT license are -included. Enriched's postinstall restores its grammar dependencies as usual. +the original pnpm patch and includes opt-in per-link context menus on iOS 17+. +JS, TypeScript declarations, generated native bindings, native sources, and the +MIT license are included. Enriched's postinstall restores its grammar dependencies +as usual. T3 supplies menu titles, actions and callbacks in JS through +`linkContextMenus`; the native package contains no app-specific menu actions. To inspect the package, extract it with `tar -xzf `. The resulting `package/` directory contains the sources as well as the built outputs. diff --git a/apps/mobile/deps/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a-link-context-menu-v2.tgz b/apps/mobile/deps/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a-link-context-menu-v2.tgz new file mode 100644 index 0000000000000000000000000000000000000000..b40d8f3daad3768c0f4054455dc44ba3788ce0da GIT binary patch literal 1018227 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%0DVlPR`!EI@tup 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 |YmAsm|>(NNy4mscJ{vGiR| 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

    7v?h1qe2%_SG?mlqM<*flR16ncRI9kyf9t0 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 - -const MONO_FONT_FAMILY = Platform.select({ - ios: "ui-monospace", - android: "monospace", - default: "monospace", -}); - -function nodeKey(node: MarkdownNode, index: number): string { - return `${node.type}:${nativeMarkdownNodePosition(node, index)}`; -} - -/** Code inside markdown scales with the base text size (12pt at the default 15pt body). */ -function codeBlockFontSize(textStyle: NativeMarkdownTextStyle): number { - return Math.max(10, Math.round(textStyle.fontSize * 0.8)); -} - -function codeBlockLineHeight(textStyle: NativeMarkdownTextStyle): number { - return codeBlockFontSize(textStyle) + 6; -} - -function nodeText(node: MarkdownNode): string { - if (node.content !== undefined) { - return node.content; - } - return (node.children ?? []).map(nodeText).join(""); -} - -function documentFor(node: MarkdownNode): MarkdownNode { - return node.type === "document" ? node : { type: "document", children: [node] }; -} - -function SelectableNode(props: { - readonly node: MarkdownNode; - readonly skills: ReadonlyArray; - readonly textStyle: NativeMarkdownTextStyle; - readonly onLinkPress?: (href: string) => void; -}) { - return ( - - ); -} - -const HighlightedCodeLine = memo(function HighlightedCodeLine(props: { - readonly tokens: ReadonlyArray; - readonly color: string; - readonly newline: boolean; -}) { - let offset = 0; - const children = []; - for (const token of props.tokens) { - if (!token.content) continue; - children.push( - - {token.content} - , - ); - offset += token.content.length; - } - return ( - - {children} - {props.newline ? "\n" : ""} - - ); -}); - -function HighlightedCodeText(props: { - readonly content: string; - readonly highlighted: HighlightedCode | null; - readonly textStyle: NativeMarkdownTextStyle; -}) { - // The text root provides inherited styles through context. A new style object - // would rerender every token even when its completed line is unchanged. - const fontSize = codeBlockFontSize(props.textStyle); - const lineHeight = codeBlockLineHeight(props.textStyle); - const style = useMemo( - () => ({ - color: props.textStyle.codeColor, - fontFamily: MONO_FONT_FAMILY, - fontSize, - lineHeight, - }), - [props.textStyle.codeColor, fontSize, lineHeight], - ); - let offset = 0; - const lines = []; - if (props.highlighted) { - for (const tokens of props.highlighted) { - lines.push( - , - ); - offset += tokens.reduce((length, token) => length + token.content.length, 0) + 1; - } - } - return ( - - {props.highlighted ? lines : props.content} - - ); -} - -function NativeCodeBlock(props: { - readonly node: MarkdownNode; - readonly textStyle: NativeMarkdownTextStyle; - readonly highlightCode: MarkdownCodeHighlighter; - readonly compact?: boolean; -}) { - const content = nodeText(props.node).replace(/\n$/, ""); - const colorScheme = useColorScheme(); - const theme = colorScheme === "dark" ? "dark" : "light"; - const highlighted = useHighlightedCode(content, props.node.language, theme, props.highlightCode); - const languageLabel = props.node.language?.toUpperCase() ?? "CODE"; - return ( - - - - {languageLabel} - - - - - - - - ); -} - -function collectTableRows(node: MarkdownNode): MarkdownNode[] { - const rows: MarkdownNode[] = []; - const visit = (child: MarkdownNode) => { - if (child.type === "table_row") { - rows.push(child); - return; - } - for (const nested of child.children ?? []) { - visit(nested); - } - }; - visit(node); - return rows; -} - -function NativeTable(props: { - readonly node: MarkdownNode; - readonly skills: ReadonlyArray; - readonly textStyle: NativeMarkdownTextStyle; - readonly onLinkPress?: (href: string) => void; -}) { - const rows = collectTableRows(props.node); - return ( - - - {rows.map((row, rowIndex) => ( - - {(row.children ?? []).map((cell, cellIndex) => ( - - - rowIndex === 0 || cell.isHeader ? { ...run, bold: true } : run, - )} - textStyle={props.textStyle} - onLinkPress={props.onLinkPress} - /> - - ))} - - ))} - - - ); -} - -function NativeMarkdownImage(props: { - readonly node: MarkdownNode; - readonly skills: ReadonlyArray; - readonly textStyle: NativeMarkdownTextStyle; - readonly onLinkPress?: (href: string) => void; -}) { - const renderImage = useContext(MarkdownImageRendererContext); - const href = props.node.href; - if (!href) { - return ( - - ); - } - - if (renderImage) { - const rendered = renderImage({ - href, - alt: props.node.alt ?? null, - title: props.node.title ?? null, - }); - if (rendered != null) { - return <>{rendered}; - } - } - - return ( - - - {props.node.alt ? ( - - {props.node.alt} - - ) : null} - - ); -} - -function inlineGroups(nodes: ReadonlyArray): MarkdownNode[] { - const groups: MarkdownNode[] = []; - let inline: MarkdownNode[] = []; - const flush = () => { - if (inline.length === 0) { - return; - } - groups.push({ type: "paragraph", children: inline }); - inline = []; - }; - - for (const node of nodes) { - if (node.type === "image") { - flush(); - groups.push(node); - } else { - inline.push(node); - } - } - flush(); - return groups; -} - -function NativeMixedParagraph(props: { - readonly node: MarkdownNode; - readonly skills: ReadonlyArray; - readonly textStyle: NativeMarkdownTextStyle; - readonly onLinkPress?: (href: string) => void; -}) { - return ( - - {inlineGroups(props.node.children ?? []).map((child, index) => - child.type === "image" ? ( - - ) : ( - - ), - )} - - ); -} - -function NativeList(props: { - readonly node: MarkdownNode; - readonly skills: ReadonlyArray; - readonly textStyle: NativeMarkdownTextStyle; - readonly highlightCode: MarkdownCodeHighlighter; - readonly onLinkPress?: (href: string) => void; - readonly depth: number; -}) { - const ordered = props.node.ordered ?? false; - const start = props.node.start ?? 1; - const nested = props.depth > 0; - return ( - - {(props.node.children ?? []).map((item, index) => { - const taskMarker = item.type === "task_list_item"; - const marker = taskMarker - ? item.checked - ? "☑︎" - : "☐︎" - : ordered - ? `${start + index}.` - : props.depth % 3 === 1 - ? "◦" - : props.depth % 3 === 2 - ? "▪︎" - : "•"; - const markerWidth = ordered ? 28 : taskMarker ? 20 : 18; - const markerOffset = taskMarker ? 3 : ordered ? 0 : 2; - return ( - - - - {marker} - - - - {nativeMarkdownListItemBlocks(item).map((child, childIndex) => ( - - ))} - - - ); - })} - - ); -} - -export function NativeMarkdownBlock(props: { - readonly node: MarkdownNode; - readonly skills: ReadonlyArray; - readonly textStyle: NativeMarkdownTextStyle; - readonly highlightCode: MarkdownCodeHighlighter; - readonly onLinkPress?: (href: string) => void; - readonly depth?: number; - readonly compact?: boolean; -}) { - const depth = props.depth ?? 0; - switch (props.node.type) { - case "document": - return ( - - {(props.node.children ?? []).map((child, index) => ( - - ))} - - ); - case "code_block": - return ( - - ); - case "table": - return ( - - ); - case "image": - return ( - - ); - case "horizontal_rule": - return ( - - ); - case "blockquote": - return ( - - {(props.node.children ?? []).map((child, index) => ( - - ))} - - ); - case "list": - return ( - - ); - case "paragraph": - return (props.node.children ?? []).some((child) => child.type === "image") ? ( - - ) : ( - - ); - case "html_block": - case "math_block": - return ( - - - - ); - case "table_head": - case "table_body": - case "table_row": - case "table_cell": - case "list_item": - case "task_list_item": - return ( - - {(props.node.children ?? []).map((child, index) => ( - - ))} - - ); - default: - return ( - - ); - } -} diff --git a/apps/mobile/modules/t3-markdown-text/src/NativeMarkdownSelectableText.tsx b/apps/mobile/modules/t3-markdown-text/src/NativeMarkdownSelectableText.tsx deleted file mode 100644 index 1d9c2b93ede8..000000000000 --- a/apps/mobile/modules/t3-markdown-text/src/NativeMarkdownSelectableText.tsx +++ /dev/null @@ -1,438 +0,0 @@ -import { createContext, useCallback, useContext, useMemo } from "react"; -import { decodeComposerContextFragment } from "@t3tools/shared/composerContextClipboard"; -import { - findNodeHandle, - Image, - Linking, - Platform, - StyleSheet, - Text as RNText, - type TextStyle, - useColorScheme, - View, -} from "react-native"; - -import { MarkdownTextPrimitive } from "./MarkdownTextPrimitive"; -import { markdownFileIconSource } from "./markdownFileIcons"; -import { markdownLinkIconSource } from "./markdownLinkIcons"; -import { resolveMarkdownFileIcon, resolveMarkdownLinkIcon } from "./markdownLinks"; -import type { NativeMarkdownTextRun } from "./nativeMarkdownText"; -import { nativeMarkdownContextCopyRanges } from "./nativeMarkdownText"; -import type { - MarkdownFileContextMenu, - NativeMarkdownTextStyle, -} from "./SelectableMarkdownText.types"; -import { - installMarkdownCopySanitizer, - renderAndroidContextChip, -} from "./T3MarkdownTextSelectionModule"; -import { parseComposerContextHref } from "@t3tools/shared/composerContextReferences"; -import { contextChipPresentation } from "./nativeMarkdownText"; - -export const MarkdownContextClipboardContext = createContext(""); - -export interface MarkdownFileContextMenuHandlers { - readonly fileContextMenu: (href: string) => MarkdownFileContextMenu | undefined; - readonly onFileContextMenuAction: (href: string, actionId: string) => void; -} - -/** Set by SelectableMarkdownText so file chips anywhere in the block tree get the same menu. */ -export const MarkdownFileContextMenuContext = createContext( - null, -); - -const EXTERNAL_LINK_PREFIX = "◉ "; -const INLINE_ATTACHMENT_PREFIX = "\uFFFC\u00A0"; -const SKILL_ICON_PLACEHOLDER = "\uFFFC"; -// React Native turns a run whose whole text is U+FFFC into a bare inline-view attachment -// with no font or paragraph style, so a chip opening a paragraph would drop its line -// height. Any other single character keeps the run's attributes; the native side swaps it -// for the chip attachment either way. -const IOS_CHIP_PLACEHOLDER = "\u200B"; -const PARAGRAPH_STYLE_ENCODING_OFFSET = 1000; -const MONO_FONT_FAMILY = Platform.select({ - ios: "ui-monospace", - android: "monospace", - default: "monospace", -}); -const styles = StyleSheet.create({ - inlineIcon: { - width: 14, - height: 14, - marginHorizontal: 3, - transform: [{ translateY: 2 }], - }, -}); - -function runKeySignature(run: NativeMarkdownTextRun): string { - return [ - run.text, - run.bold, - run.italic, - run.strikethrough, - run.code, - run.href, - run.externalHost, - run.fileIcon, - run.skillName, - run.skillLabel, - run.sourceText, - run.role, - run.headingLevel, - run.depth, - run.spacing, - run.firstLineHeadIndent, - run.headIndent, - run.paragraphSpacing, - ].join(":"); -} - -const DEFAULT_BODY_FONT_SIZE = 15; -const DEFAULT_HEADING_FONT_SIZES = [22, 19, 17, 16, 15, 15] as const; - -function resolveHeadingFontSize(textStyle: NativeMarkdownTextStyle, headingLevel: number): number { - const index = Math.max(0, Math.min(5, headingLevel - 1)); - const configured = textStyle.headingFontSizes?.[index]; - if (typeof configured === "number" && Number.isFinite(configured)) { - return configured; - } - - const scale = textStyle.fontSize / DEFAULT_BODY_FONT_SIZE; - return Math.max(12, Math.round((DEFAULT_HEADING_FONT_SIZES[index] ?? 15) * scale)); -} - -function runStyle(run: NativeMarkdownTextRun, textStyle: NativeMarkdownTextStyle): TextStyle { - const isFile = run.fileIcon != null; - const isSkill = run.skillName != null; - const headingLevel = Math.max(1, Math.min(6, run.headingLevel ?? 1)); - const headingFontSize = resolveHeadingFontSize(textStyle, headingLevel); - const isHeading = run.role === "heading"; - const isCodeBlock = run.role === "code-block" || run.role === "code-language"; - const hasParagraphStyle = run.headIndent !== undefined; - const textDecorationLine = run.strikethrough - ? "line-through" - : run.href && !isFile - ? "underline" - : "none"; - - return { - color: isFile - ? textStyle.fileTextColor - : isSkill - ? textStyle.skillTextColor - : run.href - ? textStyle.linkColor - : isHeading - ? textStyle.strongColor - : run.role === "quote-marker" - ? textStyle.quoteMarkerColor - : run.role === "divider" - ? textStyle.dividerColor - : run.role === "code-language" - ? textStyle.mutedColor - : run.role === "list-marker" - ? textStyle.mutedColor - : isCodeBlock - ? textStyle.codeColor - : run.code - ? textStyle.inlineCodeColor - : run.bold - ? textStyle.strongColor - : textStyle.color, - fontFamily: - isFile || isSkill - ? textStyle.boldFontFamily - : run.code || isCodeBlock - ? MONO_FONT_FAMILY - : isHeading - ? textStyle.headingFontFamily - : run.bold - ? textStyle.boldFontFamily - : textStyle.fontFamily, - fontSize: - run.role === "spacer" - ? (run.spacing ?? 10) - : run.role === "list-break" - ? textStyle.fontSize - : isHeading - ? headingFontSize - : run.role === "code-language" - ? Math.max(10, Math.round(textStyle.fontSize * 0.73)) - : run.code || isCodeBlock - ? Math.max(12, textStyle.fontSize - 2) - : textStyle.fontSize, - lineHeight: - run.role === "spacer" - ? (run.spacing ?? 10) - : run.role === "list-break" - ? textStyle.lineHeight + (run.spacing ?? 0) - : isHeading - ? Math.max(headingFontSize + 6, textStyle.lineHeight + 2) - : isCodeBlock - ? Math.max(16, textStyle.lineHeight - 2) - : textStyle.lineHeight, - fontStyle: run.italic ? "italic" : "normal", - fontWeight: isHeading || run.bold || isFile || isSkill ? "700" : "400", - textDecorationLine, - backgroundColor: isCodeBlock - ? textStyle.codeBlockBackgroundColor - : parseComposerContextHref(run.href ?? "") - ? textStyle.codeBackgroundColor - : undefined, - ...(hasParagraphStyle - ? { - shadowColor: "transparent", - shadowOffset: { - width: run.firstLineHeadIndent ?? 0, - height: run.headIndent, - }, - shadowRadius: PARAGRAPH_STYLE_ENCODING_OFFSET + (run.paragraphSpacing ?? 0), - } - : {}), - }; -} - -export function NativeMarkdownSelectableText(props: { - readonly runs: ReadonlyArray; - readonly textStyle: NativeMarkdownTextStyle; - readonly onLinkPress?: (href: string) => void; -}) { - const colorScheme = useColorScheme(); - const menu = useContext(MarkdownFileContextMenuContext); - const contextClipboardFragment = useContext(MarkdownContextClipboardContext); - const contextRecords = useMemo( - () => decodeComposerContextFragment(contextClipboardFragment)?.records ?? [], - [contextClipboardFragment], - ); - const containsInlineIcon = props.runs.some( - (run) => - run.fileIcon != null || - run.skillName != null || - parseComposerContextHref(run.href ?? "") !== null || - (run.externalHost != null && resolveMarkdownLinkIcon(run.externalHost) !== null), - ); - const keyedRuns = useMemo(() => { - const occurrences = new Map(); - const prefixedExternalLinks = new Set(); - return props.runs.map((run) => { - const signature = runKeySignature(run); - const occurrence = occurrences.get(signature) ?? 0; - occurrences.set(signature, occurrence + 1); - - let text = run.text; - let linkIcon = null; - const contextReference = parseComposerContextHref(run.href ?? ""); - const contextRecord = contextReference - ? contextRecords.find((record) => record.contextId === contextReference.contextId) - : undefined; - const chip = - contextReference || run.skillName || run.fileIcon - ? { - ...contextChipPresentation( - contextReference?.kind ?? (run.skillName ? "skill" : "mention"), - contextRecord, - ), - label: run.skillLabel ?? run.text, - interactive: Boolean(run.href), - iconUri: - !contextReference && run.fileIcon - ? Image.resolveAssetSource(markdownFileIconSource(run.fileIcon)).uri - : contextRecord?.kind === "mention" && "path" in contextRecord - ? Image.resolveAssetSource( - markdownFileIconSource(resolveMarkdownFileIcon(contextRecord.path)), - ).uri - : undefined, - fontSize: props.textStyle.fontSize * 0.8, - foreground: props.textStyle.color, - border: props.textStyle.contextChipBorderColor ?? props.textStyle.dividerColor, - } - : null; - // Android sizes the chip's inline box from the paragraph font so the line box stays - // the height of a plain text line; see renderContextChip. - const androidChip = - Platform.OS === "android" && chip - ? renderAndroidContextChip( - JSON.stringify({ - ...chip, - text: { - fontFamily: props.textStyle.fontFamily, - fontSize: props.textStyle.fontSize, - }, - }), - ) - : null; - if (androidChip) { - text = ""; - } else if (chip && Platform.OS === "ios") { - text = IOS_CHIP_PLACEHOLDER; - } else if (run.fileIcon && Platform.OS === "ios") { - text = `${INLINE_ATTACHMENT_PREFIX}${text}`; - } else if (run.skillName && run.skillLabel) { - text = - Platform.OS === "ios" - ? `${SKILL_ICON_PLACEHOLDER}\u00A0${run.skillLabel}` - : `$${run.skillName}`; - } else if (run.externalHost && run.href && !prefixedExternalLinks.has(run.href)) { - prefixedExternalLinks.add(run.href); - linkIcon = resolveMarkdownLinkIcon(run.externalHost); - if (linkIcon === null) { - text = `${EXTERNAL_LINK_PREFIX}${text}`; - } else if (Platform.OS === "ios") { - text = `${INLINE_ATTACHMENT_PREFIX}${text}`; - } - } - - return { key: `${signature}:${occurrence}`, run, text, linkIcon, chip, androidChip }; - }); - }, [props.runs, props.textStyle, contextRecords]); - const ranges = nativeMarkdownContextCopyRanges( - keyedRuns.map(({ run, text, linkIcon, androidChip }) => ({ - run, - text, - inlineImageLength: - Platform.OS === "android" && (androidChip || run.fileIcon || linkIcon) ? 1 : 0, - })), - ); - const contextClipboardConfig = ranges.length - ? JSON.stringify({ fragment: contextClipboardFragment, ranges }) - : ""; - const attachAndroidText = useCallback( - (textView: RNText | null) => { - if (Platform.OS !== "android" || !containsInlineIcon || !textView) return; - const reactTag = findNodeHandle(textView); - if (reactTag !== null) installMarkdownCopySanitizer(reactTag, contextClipboardConfig); - }, - [containsInlineIcon, contextClipboardConfig], - ); - // T3MarkdownText only rebuilds its attributed string during native layout. A - // color-only child update can otherwise leave the previous appearance cached. - const appearanceKey = [ - colorScheme ?? "unspecified", - props.textStyle.fontSize, - props.textStyle.lineHeight, - props.textStyle.headingFontSizes?.join(","), - props.textStyle.color, - props.textStyle.strongColor, - props.textStyle.mutedColor, - props.textStyle.linkColor, - props.textStyle.inlineCodeColor, - props.textStyle.codeColor, - props.textStyle.codeBackgroundColor, - props.textStyle.codeBlockBackgroundColor, - props.textStyle.fileTextColor, - props.textStyle.skillTextColor, - props.textStyle.quoteMarkerColor, - props.textStyle.dividerColor, - props.textStyle.contextChipBorderColor, - ].join(":"); - - return ( - run.skillLabel ?? run.text).join("") - : undefined - } - uiTextView - selectable - selectionColor={props.textStyle.selectionColor} - selectionHandleColor={props.textStyle.selectionHandleColor} - style={{ - flexShrink: 1, - minWidth: 0, - color: props.textStyle.color, - fontFamily: props.textStyle.fontFamily, - fontSize: props.textStyle.fontSize, - lineHeight: props.textStyle.lineHeight, - }} - > - {keyedRuns.map(({ key, run, text, linkIcon, chip, androidChip }) => { - const href = run.href; - const contextMenu = run.fileIcon && href ? menu?.fileContextMenu(href) : undefined; - const onPress = href - ? () => { - if (props.onLinkPress) props.onLinkPress(href); - else void Linking.openURL(href); - } - : undefined; - return ( - menu.onFileContextMenuAction(href, event.nativeEvent.actionIdentifier) - : undefined - } - > - {androidChip ? ( - // The inline box sits on the baseline and is only as tall as the font's - // ascent, so it never changes the line's height. The bitmap hangs off that - // box (views in text are not clipped) to centre the chip on the text. - { - if (event.nativeEvent.actionName === "activate") onPress(); - } - : undefined - } - style={{ width: androidChip.width, height: androidChip.boxHeight }} - > - - - ) : Platform.OS === "android" && run.fileIcon ? ( - - ) : Platform.OS === "android" && linkIcon ? ( - - ) : null} - {text} - - ); - })} - - ); -} diff --git a/apps/mobile/modules/t3-markdown-text/src/SelectableMarkdownText.tsx b/apps/mobile/modules/t3-markdown-text/src/SelectableMarkdownText.tsx deleted file mode 100644 index 8e59256b12b8..000000000000 --- a/apps/mobile/modules/t3-markdown-text/src/SelectableMarkdownText.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import { useMemo } from "react"; -import { View } from "react-native"; -import { parseMarkdownWithOptions } from "react-native-nitro-markdown/headless"; - -import { - nativeMarkdownChunkSpacing, - nativeMarkdownDocumentChunks, - nativeMarkdownDocumentRuns, - nativeMarkdownWithPreservedSoftBreaks, -} from "./nativeMarkdownText"; -import { MarkdownImageRendererContext, NativeMarkdownBlock } from "./NativeMarkdownBlock"; -import { - MarkdownContextClipboardContext, - MarkdownFileContextMenuContext, - NativeMarkdownSelectableText, - type MarkdownFileContextMenuHandlers, -} from "./NativeMarkdownSelectableText"; -import type { - SelectableMarkdownSkill, - SelectableMarkdownTextProps, -} from "./SelectableMarkdownText.types"; - -const EMPTY_SKILLS: ReadonlyArray = []; - -export type { - MarkdownCodeHighlighter, - MarkdownHighlightedToken, - MarkdownImageRenderer, - MarkdownImageRequest, - NativeMarkdownTextStyle, - SelectableMarkdownSkill, - SelectableMarkdownTextProps, -} from "./SelectableMarkdownText.types"; - -export function hasNativeSelectableMarkdownText(): boolean { - return true; -} - -export function SelectableMarkdownText({ - markdown, - contextClipboardFragment, - skills = EMPTY_SKILLS, - textStyle, - highlightCode, - preserveSoftBreaks = false, - onLinkPress, - fileContextMenu, - onFileContextMenuAction, - renderImage, - marginTop = 0, - marginBottom = 0, -}: SelectableMarkdownTextProps) { - const chunks = useMemo(() => { - const parsedDocument = parseMarkdownWithOptions(markdown, { - gfm: true, - html: true, - math: false, - }); - const document = preserveSoftBreaks - ? nativeMarkdownWithPreservedSoftBreaks(parsedDocument) - : parsedDocument; - return nativeMarkdownDocumentChunks(document).map((chunk) => - chunk.kind === "selectable" - ? { - ...chunk, - runs: nativeMarkdownDocumentRuns(chunk.node, skills), - } - : chunk, - ); - }, [markdown, preserveSoftBreaks, skills]); - - const fileContextMenuHandlers = useMemo( - () => - fileContextMenu && onFileContextMenuAction - ? { fileContextMenu, onFileContextMenuAction } - : null, - [fileContextMenu, onFileContextMenuAction], - ); - - return ( - - - - {/* A percentage width here creates a cyclic intrinsic measurement inside - shrink-to-fit containers such as user-message bubbles. Yoga then gives - the native text node an unbounded second pass and the parent only clips - the resulting single-line width instead of reflowing it. */} - - {chunks.map((chunk, index) => { - const content = - chunk.kind === "rich" ? ( - - ) : ( - - ); - - return ( - - {content} - - ); - })} - - - - - ); -} diff --git a/apps/mobile/modules/t3-markdown-text/src/SelectableMarkdownText.types.ts b/apps/mobile/modules/t3-markdown-text/src/SelectableMarkdownText.types.ts index adfa34365af6..19839882d491 100644 --- a/apps/mobile/modules/t3-markdown-text/src/SelectableMarkdownText.types.ts +++ b/apps/mobile/modules/t3-markdown-text/src/SelectableMarkdownText.types.ts @@ -22,29 +22,6 @@ export interface NativeMarkdownTextStyle { readonly headingFontSizes?: ReadonlyArray; } -export interface MarkdownHighlightedToken { - readonly content: string; - readonly color: string | null; - readonly fontStyle: number | null; -} - -export interface MarkdownCodeHighlightInput { - /** Identity of the mounted code block, for incremental highlighting. */ - readonly session?: object; - readonly code: string; - readonly language?: string | null; - readonly theme: "light" | "dark"; -} -export interface MarkdownCodeHighlighter { - ( - input: MarkdownCodeHighlightInput, - ): Promise>>; - /** Optional synchronous result for a small append to an already warm block. */ - read?: ( - input: MarkdownCodeHighlightInput, - ) => ReadonlyArray> | undefined; -} - export interface SelectableMarkdownSkill { readonly name: string; readonly displayName?: string | null; @@ -77,10 +54,7 @@ export interface MarkdownFileContextMenu { export interface SelectableMarkdownTextProps { readonly markdown: string; - /** Opaque context payload supplied by the host for native selection copy. */ - readonly contextClipboardFragment?: string; readonly textStyle: NativeMarkdownTextStyle; - readonly highlightCode: MarkdownCodeHighlighter; readonly skills?: ReadonlyArray; readonly preserveSoftBreaks?: boolean; readonly onLinkPress?: (href: string) => void; diff --git a/apps/mobile/modules/t3-markdown-text/src/composerChipPresentation.ts b/apps/mobile/modules/t3-markdown-text/src/composerChipPresentation.ts new file mode 100644 index 000000000000..853ae43f8791 --- /dev/null +++ b/apps/mobile/modules/t3-markdown-text/src/composerChipPresentation.ts @@ -0,0 +1,87 @@ +import { formatAttachmentSize } from "@t3tools/client-runtime/state/attachments"; +import { imageMimeType } from "@t3tools/shared/image"; +import { videoMimeType } from "@t3tools/shared/video"; +/** + * Every accent shares a lightness so no kind reads heavier than another; only hue carries + * identity. These are the sRGB form of the same OKLCH set web uses, so a chip looks the + * same on every surface. See `composerInlineChip.ts`. + */ +const CONTEXT_CHIP_PRESENTATIONS = { + image: { accent: "#d55665", symbol: "photo" }, + video: { accent: "#d06217", symbol: "play.rectangle" }, + file: { accent: "#0090cd", symbol: "doc" }, + mention: { accent: "#0096af", symbol: "doc" }, + terminal: { accent: "#009f6e", symbol: "terminal" }, + element: { accent: "#b87501", symbol: "cursorarrow.click" }, + "preview-annotation": { accent: "#b87501", symbol: "cursorarrow.click" }, + "review-comment": { accent: "#8a70dd", symbol: "text.bubble" }, + "pull-request": { accent: "#7079e4", symbol: "git-pull-request" }, + skill: { accent: "#b261be", symbol: "cube" }, +} as const; + +/** + * The size an attachment chip reports beside its name, matching web. Rendered as its own + * smaller run, so it carries no separator. Only attachment-backed records have bytes. + */ +export function composerChipSizeSuffix(record?: { + readonly kind?: string; + readonly sizeBytes?: number; +}): string { + if (record?.kind !== "file" && record?.kind !== "image") return ""; + return typeof record.sizeBytes === "number" ? formatAttachmentSize(record.sizeBytes) : ""; +} + +/** + * A pull request chip is coloured by what the pull request *is*, the way web colours it and + * the way the forge itself does: green open, grey draft, purple merged, red closed. The glyph + * stays the same across all four, as it does on web — state is carried by colour alone. + */ +const PULL_REQUEST_CHIP_PRESENTATIONS = { + open: { accent: "#009f6e", symbol: "git-pull-request" }, + draft: { accent: "#7f8793", symbol: "git-pull-request" }, + merged: { accent: "#8a70dd", symbol: "git-pull-request" }, + closed: { accent: "#d55665", symbol: "git-pull-request" }, +} as const; + +export function contextChipPresentation( + kind: string, + record?: { + readonly kind?: string; + readonly name?: string; + readonly mimeType?: string; + readonly sectionId?: string; + readonly pullRequest?: { + readonly state?: string; + readonly isDraft?: boolean; + }; + }, +) { + const presentationKind = + kind === "file" && + videoMimeType({ + name: record?.name ?? "", + mimeType: record?.mimeType ?? "", + }) + ? "video" + : // A picture chosen through the file picker is typed `file`, but it is still a + // picture: it reads as one to the user and should not wear the generic file chip. + kind === "file" && + imageMimeType({ name: record?.name ?? "", mimeType: record?.mimeType ?? "" }) !== null + ? "image" + : kind === "review-comment" && record?.sectionId?.startsWith("pull-request:") + ? "pull-request" + : kind; + if (presentationKind === "pull-request") { + const pullRequest = record?.pullRequest; + const state = + pullRequest?.state === "open" && pullRequest.isDraft === true + ? "draft" + : (pullRequest?.state ?? ""); + if (Object.hasOwn(PULL_REQUEST_CHIP_PRESENTATIONS, state)) { + return PULL_REQUEST_CHIP_PRESENTATIONS[state as keyof typeof PULL_REQUEST_CHIP_PRESENTATIONS]; + } + } + return Object.hasOwn(CONTEXT_CHIP_PRESENTATIONS, presentationKind) + ? CONTEXT_CHIP_PRESENTATIONS[presentationKind as keyof typeof CONTEXT_CHIP_PRESENTATIONS] + : CONTEXT_CHIP_PRESENTATIONS.file; +} diff --git a/apps/mobile/modules/t3-markdown-text/src/nativeMarkdownText.ts b/apps/mobile/modules/t3-markdown-text/src/nativeMarkdownText.ts deleted file mode 100644 index 04682874db0c..000000000000 --- a/apps/mobile/modules/t3-markdown-text/src/nativeMarkdownText.ts +++ /dev/null @@ -1,964 +0,0 @@ -import type { MarkdownNode } from "react-native-nitro-markdown/headless"; -import { collectComposerInlineTokens } from "@t3tools/shared/composerInlineTokens"; -import { imageMimeType } from "@t3tools/shared/image"; -import { videoMimeType } from "@t3tools/shared/video"; -/** - * Every accent shares a lightness so no kind reads heavier than another; only hue carries - * identity. These are the sRGB form of the same OKLCH set web uses, so a chip looks the - * same on every surface. See `composerInlineChip.ts`. - */ -const CONTEXT_CHIP_PRESENTATIONS = { - image: { accent: "#d55665", symbol: "photo" }, - video: { accent: "#d06217", symbol: "play.rectangle" }, - file: { accent: "#0090cd", symbol: "doc" }, - mention: { accent: "#0096af", symbol: "doc" }, - terminal: { accent: "#009f6e", symbol: "terminal" }, - element: { accent: "#b87501", symbol: "cursorarrow.click" }, - "preview-annotation": { accent: "#b87501", symbol: "cursorarrow.click" }, - "review-comment": { accent: "#8a70dd", symbol: "text.bubble" }, - "pull-request": { accent: "#7079e4", symbol: "git-pull-request" }, - skill: { accent: "#b261be", symbol: "cube" }, -} as const; - -/** - * The size an attachment chip reports beside its name, matching web. Rendered as its own - * smaller run, so it carries no separator. Only attachment-backed records have bytes. - */ -export function composerChipSizeSuffix(record?: { - readonly kind?: string; - readonly sizeBytes?: number; -}): string { - if (record?.kind !== "file" && record?.kind !== "image") return ""; - return typeof record.sizeBytes === "number" ? formatAttachmentSize(record.sizeBytes) : ""; -} - -/** - * A pull request chip is coloured by what the pull request *is*, the way web colours it and - * the way the forge itself does: green open, grey draft, purple merged, red closed. The glyph - * stays the same across all four, as it does on web — state is carried by colour alone. - */ -const PULL_REQUEST_CHIP_PRESENTATIONS = { - open: { accent: "#009f6e", symbol: "git-pull-request" }, - draft: { accent: "#7f8793", symbol: "git-pull-request" }, - merged: { accent: "#8a70dd", symbol: "git-pull-request" }, - closed: { accent: "#d55665", symbol: "git-pull-request" }, -} as const; - -export function contextChipPresentation( - kind: string, - record?: { - readonly kind?: string; - readonly name?: string; - readonly mimeType?: string; - readonly sectionId?: string; - readonly pullRequest?: { - readonly state?: string; - readonly isDraft?: boolean; - }; - }, -) { - const presentationKind = - kind === "file" && - videoMimeType({ - name: record?.name ?? "", - mimeType: record?.mimeType ?? "", - }) - ? "video" - : // A picture chosen through the file picker is typed `file`, but it is still a - // picture: it reads as one to the user and should not wear the generic file chip. - kind === "file" && - imageMimeType({ name: record?.name ?? "", mimeType: record?.mimeType ?? "" }) !== null - ? "image" - : kind === "review-comment" && record?.sectionId?.startsWith("pull-request:") - ? "pull-request" - : kind; - if (presentationKind === "pull-request") { - const pullRequest = record?.pullRequest; - const state = - pullRequest?.state === "open" && pullRequest.isDraft === true - ? "draft" - : (pullRequest?.state ?? ""); - if (Object.hasOwn(PULL_REQUEST_CHIP_PRESENTATIONS, state)) { - return PULL_REQUEST_CHIP_PRESENTATIONS[state as keyof typeof PULL_REQUEST_CHIP_PRESENTATIONS]; - } - } - return Object.hasOwn(CONTEXT_CHIP_PRESENTATIONS, presentationKind) - ? CONTEXT_CHIP_PRESENTATIONS[presentationKind as keyof typeof CONTEXT_CHIP_PRESENTATIONS] - : CONTEXT_CHIP_PRESENTATIONS.file; -} -import { formatAttachmentSize } from "@t3tools/client-runtime/state/attachments"; -import { - formatComposerContextReference, - parseComposerContextHref, -} from "@t3tools/shared/composerContextReferences"; - -/** Native selections count UTF-16 display units, including each inline image placeholder. */ -export function nativeMarkdownContextCopyRanges( - runs: ReadonlyArray<{ - readonly run: { - readonly href?: string; - readonly text: string; - readonly skillName?: string; - readonly fileIcon?: string; - readonly sourceText?: string; - }; - readonly text: string; - readonly inlineImageLength: number; - }>, -) { - let offset = 0; - return runs.flatMap(({ run, text, inlineImageLength }) => { - const start = offset; - offset += text.length + inlineImageLength; - const reference = parseComposerContextHref(run.href ?? ""); - const source = reference - ? formatComposerContextReference({ ...reference, label: run.text }) - : run.skillName - ? `$${run.skillName}` - : run.fileIcon && run.href - ? (run.sourceText ?? `[${run.text}](<${run.href}>)`) - : null; - return source === null ? [] : [{ start, end: offset, text: source }]; - }); -} - -import type { SelectableMarkdownSkill } from "./SelectableMarkdownText.types"; -import { - resolveMarkdownInlineCodePresentation, - resolveMarkdownLinkPresentation, - type MarkdownFileIcon, -} from "./markdownLinks"; - -export interface NativeMarkdownTextRun { - readonly text: string; - readonly bold?: boolean; - readonly italic?: boolean; - readonly strikethrough?: boolean; - readonly code?: boolean; - readonly href?: string; - readonly externalHost?: string; - readonly fileIcon?: MarkdownFileIcon; - readonly skillName?: string; - readonly skillLabel?: string; - readonly sourceText?: string; - readonly role?: - | "body" - | "heading" - | "list-marker" - | "list-break" - | "quote-marker" - | "code-block" - | "code-language" - | "divider" - | "spacer"; - readonly headingLevel?: number; - readonly depth?: number; - readonly spacing?: number; - readonly firstLineHeadIndent?: number; - readonly headIndent?: number; - readonly paragraphSpacing?: number; -} - -export type NativeMarkdownDocumentChunk = - | { - readonly kind: "selectable"; - readonly key: string; - readonly node: MarkdownNode; - } - | { - readonly kind: "rich"; - readonly key: string; - readonly node: MarkdownNode; - }; - -interface RunContext { - readonly bold: boolean; - readonly italic: boolean; - readonly strikethrough: boolean; - readonly code: boolean; - readonly href?: string; - readonly externalHost?: string; - readonly fileIcon?: MarkdownFileIcon; - readonly role?: NativeMarkdownTextRun["role"]; - readonly headingLevel?: number; - readonly depth?: number; - readonly spacing?: number; - readonly firstLineHeadIndent?: number; - readonly headIndent?: number; - readonly paragraphSpacing?: number; -} - -const EMPTY_CONTEXT: RunContext = { - bold: false, - italic: false, - strikethrough: false, - code: false, -}; - -const INLINE_HTML_TAG_PATTERN = /<\/?(?:kbd|mark|sub|sup|u)(?:\s[^>]*)?>/gi; - -function decodeCodePoint(codePoint: number, entity: string): string { - if (!Number.isInteger(codePoint) || codePoint < 0 || codePoint > 0x10ffff) { - return entity; - } - return String.fromCodePoint(codePoint); -} - -function decodeHtmlEntitiesOnce(value: string): string { - return value.replace( - /&(?:#(\d+)|#x([0-9a-f]+)|amp|apos|gt|lt|nbsp|quot);/gi, - (entity, decimal: string | undefined, hexadecimal: string | undefined) => { - if (decimal) { - return decodeCodePoint(Number.parseInt(decimal, 10), entity); - } - if (hexadecimal) { - return decodeCodePoint(Number.parseInt(hexadecimal, 16), entity); - } - switch (entity.toLowerCase()) { - case "&": - return "&"; - case "'": - return "'"; - case ">": - return ">"; - case "<": - return "<"; - case " ": - return "\u00a0"; - case """: - return '"'; - default: - return entity; - } - }, - ); -} - -function decodeHtmlEntities(value: string): string { - let decoded = value; - for (let pass = 0; pass < 2; pass += 1) { - const next = decodeHtmlEntitiesOnce(decoded); - if (next === decoded) { - break; - } - decoded = next; - } - return decoded; -} - -function textNodeContent(value: string): string { - return decodeHtmlEntities(value).replace(INLINE_HTML_TAG_PATTERN, ""); -} - -function inlineHtmlText(value: string): string { - if (/^$/i.test(value.trim())) { - return "\n"; - } - return decodeHtmlEntities(value.replace(/<[^>]+>/g, "")); -} - -function sameRunStyle(left: NativeMarkdownTextRun, right: NativeMarkdownTextRun): boolean { - return ( - left.bold === right.bold && - left.italic === right.italic && - left.strikethrough === right.strikethrough && - left.code === right.code && - left.href === right.href && - left.externalHost === right.externalHost && - left.fileIcon === right.fileIcon && - left.skillName === right.skillName && - left.skillLabel === right.skillLabel && - left.role === right.role && - left.headingLevel === right.headingLevel && - left.depth === right.depth && - left.spacing === right.spacing && - left.firstLineHeadIndent === right.firstLineHeadIndent && - left.headIndent === right.headIndent && - left.paragraphSpacing === right.paragraphSpacing - ); -} - -function appendRun( - runs: NativeMarkdownTextRun[], - text: string, - context: RunContext, -): NativeMarkdownTextRun[] { - if (text.length === 0) { - return runs; - } - - const run: NativeMarkdownTextRun = { - text, - ...(context.bold ? { bold: true } : {}), - ...(context.italic ? { italic: true } : {}), - ...(context.strikethrough ? { strikethrough: true } : {}), - ...(context.code ? { code: true } : {}), - ...(context.href ? { href: context.href } : {}), - ...(context.externalHost ? { externalHost: context.externalHost } : {}), - ...(context.fileIcon ? { fileIcon: context.fileIcon } : {}), - ...(context.role ? { role: context.role } : {}), - ...(context.headingLevel ? { headingLevel: context.headingLevel } : {}), - ...(context.depth ? { depth: context.depth } : {}), - ...(context.spacing ? { spacing: context.spacing } : {}), - ...(context.firstLineHeadIndent !== undefined - ? { firstLineHeadIndent: context.firstLineHeadIndent } - : {}), - ...(context.headIndent !== undefined ? { headIndent: context.headIndent } : {}), - ...(context.paragraphSpacing !== undefined - ? { paragraphSpacing: context.paragraphSpacing } - : {}), - }; - const previous = runs.at(-1); - if (previous && sameRunStyle(previous, run)) { - runs[runs.length - 1] = { ...previous, text: previous.text + run.text }; - return runs; - } - - runs.push(run); - return runs; -} - -const SKILL_TOKEN_REGEX = - /(^|\s)\p{Sc}(?![0-9][0-9_]*(?:[kKmMbBtT]|[eE][0-9]+)?(?:\s|$))(?=[a-zA-Z0-9:_-]*[a-zA-Z])([a-zA-Z0-9][a-zA-Z0-9:_-]*)(?=\s|$)/gu; - -function formatSkillLabel(skill: SelectableMarkdownSkill): string { - const displayName = skill.displayName?.trim(); - if (displayName) { - return displayName; - } - return skill.name - .split(/[\s:_-]+/) - .filter(Boolean) - .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)) - .join(" "); -} - -function decorateSkillRuns( - runs: ReadonlyArray, - skills: ReadonlyArray, -): ReadonlyArray { - if (skills.length === 0) { - return runs; - } - const skillByName = new Map(skills.map((skill) => [skill.name, skill])); - const decorated: NativeMarkdownTextRun[] = []; - - for (const run of runs) { - if (run.code || run.href || run.fileIcon || run.role === "code-block") { - decorated.push(run); - continue; - } - - let cursor = 0; - let matched = false; - for (const match of run.text.matchAll(SKILL_TOKEN_REGEX)) { - const prefix = match[1] ?? ""; - const name = match[2] ?? ""; - const skill = skillByName.get(name); - if (!skill) { - continue; - } - const start = (match.index ?? 0) + prefix.length; - const end = (match.index ?? 0) + match[0].length; - if (start > cursor) { - decorated.push({ ...run, text: run.text.slice(cursor, start) }); - } - decorated.push({ - ...run, - text: run.text.slice(start, end), - skillName: name, - skillLabel: formatSkillLabel(skill), - }); - cursor = end; - matched = true; - } - if (!matched) { - decorated.push(run); - } else if (cursor < run.text.length) { - decorated.push({ ...run, text: run.text.slice(cursor) }); - } - } - - return decorated; -} - -function decorateMentionRuns(runs: ReadonlyArray) { - return runs.flatMap((run) => { - if (run.code || run.href || run.skillName || run.role === "code-block") return [run]; - const decorated: NativeMarkdownTextRun[] = []; - let cursor = 0; - for (const token of collectComposerInlineTokens(`${run.text} `)) { - if (token.type !== "mention" || !token.source.startsWith("@")) continue; - // Sentence punctuation is not part of an unquoted file reference. - const path = token.source.startsWith('@"') - ? token.value - : token.value.replace(/[.,;!?]+$/, ""); - const presentation = resolveMarkdownLinkPresentation(path); - if (presentation.kind !== "file") continue; - const end = token.end - (token.value.length - path.length); - if (token.start > cursor) - decorated.push({ ...run, text: run.text.slice(cursor, token.start) }); - decorated.push({ - ...run, - text: presentation.label, - href: presentation.href, - fileIcon: presentation.icon, - sourceText: run.text.slice(token.start, end), - }); - cursor = end; - } - if (cursor < run.text.length) decorated.push({ ...run, text: run.text.slice(cursor) }); - return decorated; - }); -} - -function appendChildren( - runs: NativeMarkdownTextRun[], - node: MarkdownNode, - context: RunContext, -): NativeMarkdownTextRun[] { - for (const child of node.children ?? []) { - appendNode(runs, child, context); - } - return runs; -} - -function nodeTextContent(node: MarkdownNode): string { - if (node.content !== undefined) { - return node.content; - } - return (node.children ?? []).map(nodeTextContent).join(""); -} - -function appendNode( - runs: NativeMarkdownTextRun[], - node: MarkdownNode, - context: RunContext, -): NativeMarkdownTextRun[] { - switch (node.type) { - case "text": - case "math_inline": - return appendRun(runs, textNodeContent(nodeTextContent(node)), context); - case "html_inline": - return appendRun(runs, inlineHtmlText(nodeTextContent(node)), context); - case "code_inline": { - const content = nodeTextContent(node); - const presentation = context.href ? null : resolveMarkdownInlineCodePresentation(content); - return presentation - ? appendRun(runs, presentation.label, { - ...context, - href: presentation.href, - fileIcon: presentation.icon, - }) - : appendRun(runs, content, { ...context, code: true }); - } - case "soft_break": - return appendRun(runs, " ", context); - case "line_break": - return appendRun(runs, "\n", context); - case "bold": - return appendChildren(runs, node, { ...context, bold: true }); - case "italic": - return appendChildren(runs, node, { ...context, italic: true }); - case "strikethrough": - return appendChildren(runs, node, { ...context, strikethrough: true }); - case "link": { - const reference = parseComposerContextHref(node.href ?? ""); - if (reference) { - // Build the link in isolation: adjacent links with the same href and - // style would otherwise merge into one run, collapsing two chips and - // their copy ranges into a single reference with a combined label. - const referenceRuns: NativeMarkdownTextRun[] = []; - appendChildren(referenceRuns, node, { - ...context, - href: node.href, - fileIcon: - reference.kind === "image" ? "image" : reference.kind === "terminal" ? "bash" : "text", - }); - runs.push(...referenceRuns); - return runs; - } - const presentation = resolveMarkdownLinkPresentation(node.href ?? ""); - if (presentation.kind === "file") { - return appendRun(runs, presentation.label, { - ...context, - href: presentation.href, - fileIcon: presentation.icon, - }); - } - if (presentation.kind === "external") { - return appendChildren(runs, node, { - ...context, - href: presentation.href, - externalHost: presentation.host, - }); - } - return appendChildren(runs, node, { - ...context, - ...(presentation.href ? { href: presentation.href } : {}), - }); - } - case "image": - return appendRun(runs, node.alt ?? node.title ?? "", context); - default: - return appendChildren(runs, node, context); - } -} - -export function nativeMarkdownTextRuns(node: MarkdownNode): ReadonlyArray { - return appendChildren([], node, EMPTY_CONTEXT); -} - -export function nativeMarkdownWithPreservedSoftBreaks(node: MarkdownNode): MarkdownNode { - const children = node.children?.map(nativeMarkdownWithPreservedSoftBreaks); - return { - ...node, - ...(node.type === "soft_break" ? { type: "line_break" as const } : {}), - ...(children ? { children } : {}), - }; -} - -function appendBlockTerminator( - runs: NativeMarkdownTextRun[], - context: RunContext, -): NativeMarkdownTextRun[] { - return appendRun(runs, "\n", context); -} - -function appendSpacer(runs: NativeMarkdownTextRun[], spacing: number): NativeMarkdownTextRun[] { - return appendRun(runs, "\n", { ...EMPTY_CONTEXT, role: "spacer", spacing }); -} - -function appendInlineChildren( - runs: NativeMarkdownTextRun[], - node: MarkdownNode, - context: RunContext, -): NativeMarkdownTextRun[] { - for (const child of node.children ?? []) { - appendNode(runs, child, context); - } - return runs; -} - -function isInlineNode(node: MarkdownNode): boolean { - return ( - node.type === "text" || - node.type === "bold" || - node.type === "italic" || - node.type === "strikethrough" || - node.type === "link" || - node.type === "image" || - node.type === "code_inline" || - node.type === "math_inline" || - node.type === "html_inline" || - node.type === "soft_break" || - node.type === "line_break" - ); -} - -export function nativeMarkdownListItemBlocks(node: MarkdownNode): ReadonlyArray { - const blocks: MarkdownNode[] = []; - let inlineNodes: MarkdownNode[] = []; - const flushInlineNodes = () => { - if (inlineNodes.length === 0) { - return; - } - blocks.push({ type: "paragraph", children: inlineNodes }); - inlineNodes = []; - }; - - for (const child of node.children ?? []) { - if (isInlineNode(child)) { - inlineNodes.push(child); - continue; - } - - flushInlineNodes(); - blocks.push(child); - } - flushInlineNodes(); - return blocks; -} - -function appendListItem( - runs: NativeMarkdownTextRun[], - node: MarkdownNode, - marker: string, - depth: number, - markerColumnWidth: number, -): NativeMarkdownTextRun[] { - const firstLineHeadIndent = Math.max(0, depth - 1) * 20; - appendRun(runs, `${marker}\t`, { - ...EMPTY_CONTEXT, - role: "list-marker", - depth, - firstLineHeadIndent, - headIndent: firstLineHeadIndent + markerColumnWidth, - paragraphSpacing: 2, - }); - - const children = node.children ?? []; - let wroteInlineContent = false; - for (const child of children) { - if (child.type === "paragraph") { - appendInlineChildren(runs, child, { - ...EMPTY_CONTEXT, - role: "body", - depth, - }); - wroteInlineContent = true; - continue; - } - if (child.type === "list") { - if (wroteInlineContent) { - appendBlockTerminator(runs, { - ...EMPTY_CONTEXT, - role: "list-break", - depth, - spacing: 1, - }); - } - appendList(runs, child, depth + 1); - wroteInlineContent = false; - continue; - } - if (isInlineNode(child)) { - appendNode(runs, child, { - ...EMPTY_CONTEXT, - role: "body", - depth, - }); - wroteInlineContent = true; - continue; - } - appendDocumentBlock(runs, child, depth); - wroteInlineContent = true; - } - - if (wroteInlineContent) { - appendBlockTerminator(runs, { - ...EMPTY_CONTEXT, - role: "list-break", - depth, - spacing: depth === 1 ? 4 : 2, - }); - } - return runs; -} - -function appendList( - runs: NativeMarkdownTextRun[], - node: MarkdownNode, - depth: number, -): NativeMarkdownTextRun[] { - const ordered = node.ordered ?? false; - const start = node.start ?? 1; - const children = node.children ?? []; - const markers = children.map((child, index) => - child.type === "task_list_item" - ? child.checked - ? "☑︎" - : "☐︎" - : ordered - ? `${start + index}.` - : depth % 3 === 2 - ? "◦" - : depth % 3 === 0 - ? "▪︎" - : "•", - ); - const markerWidth = ordered - ? Math.max(0, ...markers.map((marker) => Array.from(marker).length)) - : 0; - - for (const [index, child] of children.entries()) { - const marker = markers[index] ?? "•"; - const alignedMarker = - child.type === "task_list_item" - ? marker - : ordered - ? `${"\u2007".repeat(Math.max(0, markerWidth - Array.from(marker).length))}${marker}` - : marker; - const markerColumnWidth = - child.type === "task_list_item" ? 28 : ordered ? 10 + markerWidth * 8 : 24; - appendListItem(runs, child, alignedMarker, depth, markerColumnWidth); - } - return runs; -} - -function appendQuoteBlock( - runs: NativeMarkdownTextRun[], - node: MarkdownNode, - depth: number, -): NativeMarkdownTextRun[] { - for (const [index, child] of (node.children ?? []).entries()) { - if (index > 0) { - appendBlockTerminator(runs, { ...EMPTY_CONTEXT, role: "body", depth }); - } - appendRun(runs, "│\u00a0", { - ...EMPTY_CONTEXT, - role: "quote-marker", - depth, - }); - if (child.type === "paragraph") { - appendInlineChildren(runs, child, { - ...EMPTY_CONTEXT, - role: "body", - depth, - }); - } else { - appendDocumentBlock(runs, child, depth); - } - } - appendBlockTerminator(runs, { ...EMPTY_CONTEXT, role: "body", depth }); - return runs; -} - -function appendTableRow( - runs: NativeMarkdownTextRun[], - node: MarkdownNode, - depth: number, -): NativeMarkdownTextRun[] { - const cells = node.children ?? []; - for (const [index, cell] of cells.entries()) { - if (index > 0) { - appendRun(runs, "\u00a0│\u00a0", { - ...EMPTY_CONTEXT, - role: "divider", - depth, - }); - } - appendInlineChildren(runs, cell, { - ...EMPTY_CONTEXT, - role: "body", - bold: cell.isHeader ?? false, - depth, - }); - } - appendBlockTerminator(runs, { ...EMPTY_CONTEXT, role: "body", depth }); - return runs; -} - -function appendTable( - runs: NativeMarkdownTextRun[], - node: MarkdownNode, - depth: number, -): NativeMarkdownTextRun[] { - const visit = (child: MarkdownNode) => { - if (child.type === "table_row") { - appendTableRow(runs, child, depth); - return; - } - for (const nested of child.children ?? []) { - visit(nested); - } - }; - visit(node); - return runs; -} - -function appendDocumentBlock( - runs: NativeMarkdownTextRun[], - node: MarkdownNode, - depth = 0, -): NativeMarkdownTextRun[] { - switch (node.type) { - case "document": { - const children = node.children ?? []; - for (const [index, child] of children.entries()) { - if (index > 0) { - const previous = children[index - 1]; - appendSpacer( - runs, - child.type === "heading" ? 20 : previous?.type === "heading" ? 10 : 12, - ); - } - appendDocumentBlock(runs, child, depth); - } - return runs; - } - case "heading": { - const context: RunContext = { - ...EMPTY_CONTEXT, - role: "heading", - headingLevel: node.level ?? 1, - depth, - }; - appendInlineChildren(runs, node, context); - return appendBlockTerminator(runs, context); - } - case "paragraph": { - const context: RunContext = { ...EMPTY_CONTEXT, role: "body", depth }; - appendInlineChildren(runs, node, context); - return appendBlockTerminator(runs, context); - } - case "list": - return appendList(runs, node, depth + 1); - case "blockquote": - return appendQuoteBlock(runs, node, depth); - case "code_block": { - if (node.language) { - appendRun(runs, `${node.language.toUpperCase()}\n`, { - ...EMPTY_CONTEXT, - role: "code-language", - code: true, - depth, - }); - } - const content = nodeTextContent(node); - appendRun(runs, content, { - ...EMPTY_CONTEXT, - role: "code-block", - code: true, - depth, - }); - if (!content.endsWith("\n")) { - appendBlockTerminator(runs, { - ...EMPTY_CONTEXT, - role: "code-block", - code: true, - depth, - }); - } - return runs; - } - case "horizontal_rule": - appendRun(runs, "────────────────────────\n", { - ...EMPTY_CONTEXT, - role: "divider", - depth, - }); - return runs; - case "table": - return appendTable(runs, node, depth); - case "html_block": - appendRun(runs, inlineHtmlText(nodeTextContent(node)), { - ...EMPTY_CONTEXT, - role: "body", - depth, - }); - return appendBlockTerminator(runs, { ...EMPTY_CONTEXT, role: "body", depth }); - case "math_block": - appendRun(runs, nodeTextContent(node), { ...EMPTY_CONTEXT, role: "body", depth }); - return appendBlockTerminator(runs, { ...EMPTY_CONTEXT, role: "body", depth }); - default: - appendInlineChildren(runs, node, { ...EMPTY_CONTEXT, role: "body", depth }); - return appendBlockTerminator(runs, { ...EMPTY_CONTEXT, role: "body", depth }); - } -} - -function containsRichBlock(node: MarkdownNode): boolean { - if ( - node.type === "code_block" || - node.type === "blockquote" || - node.type === "table" || - node.type === "image" || - node.type === "horizontal_rule" || - node.type === "html_block" || - node.type === "math_block" - ) { - return true; - } - return (node.children ?? []).some(containsRichBlock); -} - -/** - * Sibling identity for React keys. A source offset survives appends while the - * document streams; the child index is the fallback for offset-free nodes. The - * two never share a namespace, so a positioned node cannot collide with an - * offset-free sibling whose index happens to equal its offset. - */ -export function nativeMarkdownNodePosition(node: MarkdownNode, index: number): string { - return node.beg === undefined ? `index:${index}` : `offset:${node.beg}`; -} - -export function nativeMarkdownDocumentChunks( - document: MarkdownNode, -): ReadonlyArray { - const chunks: NativeMarkdownDocumentChunk[] = []; - let selectableNodes: MarkdownNode[] = []; - let selectableStart = 0; - - const flushSelectable = () => { - const first = selectableNodes[0]; - if (!first) { - return; - } - chunks.push({ - kind: "selectable", - key: `selectable:${nativeMarkdownNodePosition(first, selectableStart)}`, - node: { - type: "document", - children: selectableNodes, - }, - }); - selectableNodes = []; - }; - - for (const [index, child] of (document.children ?? []).entries()) { - if (!containsRichBlock(child)) { - if (selectableNodes.length === 0) { - selectableStart = index; - } - selectableNodes.push(child); - continue; - } - - flushSelectable(); - chunks.push({ - kind: "rich", - key: `rich:${child.type}:${nativeMarkdownNodePosition(child, index)}`, - node: child, - }); - } - flushSelectable(); - return chunks; -} - -function topLevelNodes(node: MarkdownNode): ReadonlyArray { - return node.type === "document" ? (node.children ?? []) : [node]; -} - -export function nativeMarkdownChunkSpacing( - previous: NativeMarkdownDocumentChunk | undefined, - current: NativeMarkdownDocumentChunk, -): number { - if (!previous) { - return 0; - } - - const previousLast = topLevelNodes(previous.node).at(-1); - const currentFirst = topLevelNodes(current.node)[0]; - - if (currentFirst?.type === "heading") { - return 20; - } - if (previousLast?.type === "heading") { - return 10; - } - if (previousLast?.type === "list" && currentFirst?.type === "list") { - return 12; - } - return 14; -} - -export function nativeMarkdownDocumentRuns( - node: MarkdownNode, - skills: ReadonlyArray = [], -): ReadonlyArray { - const runs = appendDocumentBlock([], node); - while (runs.length > 0) { - const lastIndex = runs.length - 1; - const last = runs[lastIndex]; - if (!last?.text.endsWith("\n")) { - break; - } - const text = last.text.slice(0, -1); - if (text.length === 0) { - runs.pop(); - } else { - runs[lastIndex] = { ...last, text }; - } - } - return decorateMentionRuns(decorateSkillRuns(runs, skills)); -} diff --git a/apps/mobile/modules/t3-markdown-text/src/pendingCodeHighlight.test.ts b/apps/mobile/modules/t3-markdown-text/src/pendingCodeHighlight.test.ts deleted file mode 100644 index 19516e782524..000000000000 --- a/apps/mobile/modules/t3-markdown-text/src/pendingCodeHighlight.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { expect, it } from "vite-plus/test"; -import { pendingCodeHighlight } from "./pendingCodeHighlight"; - -it("keeps completed colors and exact current text without retaining an edited tail", () => { - const colored = [ - [{ content: "const n = 1;", color: "red", fontStyle: 0 }], - [{ content: "partial", color: "blue", fontStyle: 0 }], - ]; - const result = pendingCodeHighlight( - "const n = 1;\npartial", - "const n = 1;\nchanged\nnext", - colored, - )!; - expect(result[0]).toBe(colored[0]); - expect(result.map((line) => line.map((token) => token.content).join("")).join("\n")).toBe( - "const n = 1;\nchanged\nnext", - ); - expect( - result - .slice(1) - .flat() - .every((token) => token.color === null), - ).toBe(true); - expect( - pendingCodeHighlight("const n = 1;\npartial", "const n = 2;\npartial", colored), - ).toBeNull(); - expect(pendingCodeHighlight("partial", "other", colored)).toBeNull(); -}); diff --git a/apps/mobile/modules/t3-markdown-text/src/pendingCodeHighlight.ts b/apps/mobile/modules/t3-markdown-text/src/pendingCodeHighlight.ts deleted file mode 100644 index 308997fc83a8..000000000000 --- a/apps/mobile/modules/t3-markdown-text/src/pendingCodeHighlight.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { MarkdownHighlightedToken } from "./SelectableMarkdownText.types"; - -/** Keep finished lines colored while the current line awaits highlighting. */ -export function pendingCodeHighlight( - previousCode: string, - code: string, - tokens: ReadonlyArray>, -): ReadonlyArray> | null { - const end = previousCode.lastIndexOf("\n") + 1; - if (!end || !code.startsWith(previousCode.slice(0, end))) return null; - const completedLines = previousCode.slice(0, end).split("\n").length - 1; - return [ - ...tokens.slice(0, completedLines), - ...code - .slice(end) - .split("\n") - .map((content) => [{ content, color: null, fontStyle: null }]), - ]; -} diff --git a/apps/mobile/modules/t3-markdown-text/src/useHighlightedCode.test.tsx b/apps/mobile/modules/t3-markdown-text/src/useHighlightedCode.test.tsx deleted file mode 100644 index c4fcaa597db5..000000000000 --- a/apps/mobile/modules/t3-markdown-text/src/useHighlightedCode.test.tsx +++ /dev/null @@ -1,189 +0,0 @@ -import { act, useLayoutEffect } from "react"; -import { createRoot, type Root } from "react-dom/client"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vite-plus/test"; - -import type { MarkdownCodeHighlighter } from "./SelectableMarkdownText.types"; -import { useHighlightedCode, type HighlightedCode } from "./useHighlightedCode"; - -type Deferred = { - readonly code: string; - readonly resolve: (tokens: HighlightedCode) => void; -}; - -/** One colored line per newline-separated line, so a line's color proves where it came from. */ -function tokensFor(code: string, color: string): HighlightedCode { - return code.split("\n").map((content) => [{ content, color, fontStyle: 0 }]); -} - -function lineText(tokens: HighlightedCode | null): string | null { - return tokens?.map((line) => line.map((token) => token.content).join("")).join("\n") ?? null; -} - -function lineColors(tokens: HighlightedCode | null): ReadonlyArray { - return tokens?.map((line) => line[0]?.color ?? null) ?? []; -} - -const deferred: Deferred[] = []; -const readResults = new Map(); -let renders = 0; -let result: HighlightedCode | null = null; -let root: Root; - -const highlightCode: MarkdownCodeHighlighter = Object.assign( - vi.fn( - (input: { code: string }) => - new Promise((resolve) => { - deferred.push({ code: input.code, resolve }); - }), - ), - { - read: vi.fn((input: { code: string }) => readResults.get(input.code)), - }, -); - -function Probe(props: { - readonly code: string; - readonly language?: string; - readonly theme?: "light" | "dark"; -}) { - const tokens = useHighlightedCode( - props.code, - props.language ?? "ts", - props.theme ?? "dark", - highlightCode, - ); - useLayoutEffect(() => { - renders += 1; - result = tokens; - }); - return null; -} - -async function render(props: Parameters[0]) { - await act(() => root.render()); -} - -async function resolveAsync(index: number, color: string) { - const pending = deferred[index]; - if (!pending) throw new Error(`no pending highlight at ${index}`); - await act(async () => { - pending.resolve(tokensFor(pending.code, color)); - }); -} - -beforeEach(async () => { - // The probe has no DOM output, but ReactDOM needs an event target. - const document = { - nodeType: 9, - addEventListener() {}, - removeEventListener() {}, - }; - const container = { - nodeType: 1, - tagName: "DIV", - namespaceURI: "http://www.w3.org/1999/xhtml", - ownerDocument: document, - addEventListener() {}, - removeEventListener() {}, - }; - vi.stubGlobal("document", document); - vi.stubGlobal("window", { document, HTMLIFrameElement: EventTarget }); - vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true); - deferred.length = 0; - readResults.clear(); - renders = 0; - result = null; - vi.mocked(highlightCode).mockClear(); - vi.mocked(highlightCode.read!).mockClear(); - root = createRoot(container as unknown as HTMLElement); -}); - -afterEach(async () => { - await act(() => root.unmount()); - vi.unstubAllGlobals(); -}); - -// Every test uses a distinct language so the module-level token cache from an -// earlier test can never satisfy a later one. -describe("useHighlightedCode", () => { - it("keeps colors from the latest synchronous read when a later read misses", async () => { - const language = "sync-baseline"; - await render({ code: "a", language }); - expect(result).toBeNull(); - await resolveAsync(0, "async"); - expect(lineColors(result)).toEqual(["async"]); - - readResults.set("a\nb", tokensFor("a\nb", "sync-1")); - readResults.set("a\nb\nc", tokensFor("a\nb\nc", "sync-2")); - const rendersBeforeAppends = renders; - await render({ code: "a\nb", language }); - await render({ code: "a\nb\nc", language }); - expect(lineColors(result)).toEqual(["sync-2", "sync-2", "sync-2"]); - // A synchronous hit is one render per append: no state update, no highlighter call. - expect(renders - rendersBeforeAppends).toBe(2); - expect(highlightCode).toHaveBeenCalledTimes(1); - - await render({ code: "a\nb\nc\nd", language }); - expect(highlightCode).toHaveBeenCalledTimes(2); - expect(lineText(result)).toBe("a\nb\nc\nd"); - // Lines before the previous code's final newline are the completed ones. - expect(lineColors(result)).toEqual(["sync-2", "sync-2", null, null]); - - await resolveAsync(1, "async-2"); - expect(lineColors(result)).toEqual(["async-2", "async-2", "async-2", "async-2"]); - }); - - it("does not show obsolete text after a non-append edit", async () => { - const language = "non-append"; - await render({ code: "a\nb", language }); - await resolveAsync(0, "async"); - readResults.set("a\nb\nc", tokensFor("a\nb\nc", "sync")); - await render({ code: "a\nb\nc", language }); - expect(lineColors(result)).toEqual(["sync", "sync", "sync"]); - - await render({ code: "x\nb\nc", language }); - expect(result).toBeNull(); - await resolveAsync(1, "async-2"); - expect(lineText(result)).toBe("x\nb\nc"); - }); - - it("never reuses colors across a language or theme change", async () => { - const language = "theme-change"; - await render({ code: "a\nb", language }); - await resolveAsync(0, "async"); - readResults.set("a\nb\nc", tokensFor("a\nb\nc", "sync")); - await render({ code: "a\nb\nc", language }); - expect(lineColors(result)).toEqual(["sync", "sync", "sync"]); - - await render({ code: "a\nb\nc\nd", language, theme: "light" }); - expect(result).toBeNull(); - await render({ code: "a\nb\nc\nd", language: `${language}-other` }); - expect(result).toBeNull(); - }); - - it("ignores an asynchronous completion that is older than the current code", async () => { - const language = "stale-async"; - await render({ code: "a\nb", language }); - await resolveAsync(0, "async"); - - await render({ code: "a\nb\nc", language }); - expect(deferred).toHaveLength(2); - expect(lineColors(result)).toEqual(["async", null, null]); - - readResults.set("a\nb\nc\nd", tokensFor("a\nb\nc\nd", "sync")); - await render({ code: "a\nb\nc\nd", language }); - expect(lineColors(result)).toEqual(["sync", "sync", "sync", "sync"]); - - await render({ code: "a\nb\nc\nd\ne", language }); - expect(deferred).toHaveLength(3); - expect(lineColors(result)).toEqual(["sync", "sync", "sync", null, null]); - - // The older request finishes after newer synchronous results exist. - await resolveAsync(1, "stale"); - expect(lineText(result)).toBe("a\nb\nc\nd\ne"); - expect(lineColors(result)).toEqual(["sync", "sync", "sync", null, null]); - - await resolveAsync(2, "async-3"); - expect(lineColors(result)).toEqual(["async-3", "async-3", "async-3", "async-3", "async-3"]); - }); -}); diff --git a/apps/mobile/modules/t3-markdown-text/src/useHighlightedCode.ts b/apps/mobile/modules/t3-markdown-text/src/useHighlightedCode.ts deleted file mode 100644 index dd86dc3af9af..000000000000 --- a/apps/mobile/modules/t3-markdown-text/src/useHighlightedCode.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { useEffect, useMemo, useRef, useState } from "react"; - -import { pendingCodeHighlight } from "./pendingCodeHighlight"; -import type { - MarkdownCodeHighlighter, - MarkdownHighlightedToken, -} from "./SelectableMarkdownText.types"; - -export type HighlightedCode = ReadonlyArray>; - -interface HighlightedCodeResult { - readonly key: string; - readonly code: string; - readonly language: string | undefined; - readonly theme: "light" | "dark"; - readonly tokens: HighlightedCode | null; -} - -const highlightedCodeCache = new Map(); -const highlightedCodePromiseCache = new Map>(); -const HIGHLIGHTED_CODE_CACHE_LIMIT = 64; - -function codeHighlightCacheKey( - code: string, - language: string | undefined, - theme: "light" | "dark", -): string { - return `${theme}:${language ?? "text"}:${code}`; -} - -function cacheHighlightedCode(key: string, tokens: HighlightedCode): void { - highlightedCodeCache.delete(key); - highlightedCodeCache.set(key, tokens); - - while (highlightedCodeCache.size > HIGHLIGHTED_CODE_CACHE_LIMIT) { - const oldestKey = highlightedCodeCache.keys().next().value; - if (oldestKey === undefined) { - break; - } - highlightedCodeCache.delete(oldestKey); - } -} - -function loadHighlightedCode( - code: string, - language: string | undefined, - theme: "light" | "dark", - highlightCode: MarkdownCodeHighlighter, - session: object, -): Promise { - const key = codeHighlightCacheKey(code, language, theme); - const cached = highlightedCodeCache.get(key); - if (cached) { - return Promise.resolve(cached); - } - - const pending = highlightedCodePromiseCache.get(key); - if (pending) { - return pending; - } - - const promise = highlightCode({ code, language, theme, session }) - .then((tokens) => { - cacheHighlightedCode(key, tokens); - highlightedCodePromiseCache.delete(key); - return tokens; - }) - .catch((error) => { - highlightedCodePromiseCache.delete(key); - throw error; - }); - highlightedCodePromiseCache.set(key, promise); - return promise; -} - -/** - * Tokens for a code block, or null while nothing usable exists yet. A cached or - * synchronous result renders in the same pass. Otherwise the most recent - * completed result seeds `pendingCodeHighlight` so finished lines keep their - * colors while the asynchronous highlighter catches up. - */ -export function useHighlightedCode( - code: string, - language: string | undefined, - theme: "light" | "dark", - highlightCode: MarkdownCodeHighlighter, -): HighlightedCode | null { - const [session] = useState(() => ({})); - const key = codeHighlightCacheKey(code, language, theme); - const ready = useMemo( - () => highlightedCodeCache.get(key) ?? highlightCode.read?.({ code, language, theme, session }), - [code, language, theme, key, highlightCode, session], - ); - const [highlighted, setHighlighted] = useState(() => ({ - code, - language, - theme, - key, - tokens: highlightedCodeCache.get(key) ?? null, - })); - // Synchronous reads never touch state, so each append costs one render. The - // ref remembers the newest of them, and is cleared whenever an asynchronous - // result commits so `highlighted` is the baseline again from then on. - const latestRead = useRef(null); - - useEffect(() => { - if (ready) { - latestRead.current = { code, language, theme, key, tokens: ready }; - return; - } - let active = true; - const commit = (tokens: HighlightedCode | null) => { - latestRead.current = null; - setHighlighted({ code, language, theme, key, tokens }); - }; - const cached = highlightedCodeCache.get(key); - if (cached) { - cacheHighlightedCode(key, cached); - commit(cached); - return () => { - active = false; - }; - } - - void loadHighlightedCode(code, language, theme, highlightCode, session) - .then((tokens) => { - if (active) { - commit(tokens); - } - }) - .catch(() => { - if (active) { - commit(null); - } - }); - return () => { - active = false; - }; - }, [code, highlightCode, key, language, theme, ready, session]); - - if (ready) return ready; - // oxlint-disable-next-line react/refs -- Written only after commit; a discarded render never advances it. - const baseline = latestRead.current ?? highlighted; - if (baseline.key === key) return baseline.tokens; - if (baseline.tokens && baseline.language === language && baseline.theme === theme) { - return pendingCodeHighlight(baseline.code, code, baseline.tokens); - } - return null; -} diff --git a/apps/mobile/package.json b/apps/mobile/package.json index dba137f30472..8ca84f850ca8 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -112,10 +112,10 @@ "react": "19.2.3", "react-dom": "19.2.3", "react-native": "0.86.3", + "react-native-enriched-markdown": "1.1.0-nightly-20260918-bb2b0942a", "react-native-gesture-handler": "~2.32.0", "react-native-image-viewing": "^0.2.2", "react-native-keyboard-controller": "1.21.13", - "react-native-nitro-markdown": "^0.5.0", "react-native-nitro-modules": "0.35.9", "react-native-reanimated": "4.5.5", "react-native-safe-area-context": "~5.7.0", @@ -137,8 +137,9 @@ "tailwindcss": "^4.0.0", "typescript": "catalog:" }, - "overrides": { - "react-native-nitro-markdown": "file:deps/react-native-nitro-markdown-0.5.0.tgz" + "enriched-markdown": { + "enableMath": false, + "enableVideo": false }, "expo": { "install": { diff --git a/apps/mobile/src/features/files/FileMarkdownPreview.tsx b/apps/mobile/src/features/files/FileMarkdownPreview.tsx index dcd29d71d5c9..867d465b7ae2 100644 --- a/apps/mobile/src/features/files/FileMarkdownPreview.tsx +++ b/apps/mobile/src/features/files/FileMarkdownPreview.tsx @@ -2,20 +2,11 @@ import type { EnvironmentId, ThreadId } from "@t3tools/contracts"; import { resolveMediaSource } from "@t3tools/client-runtime/media-source"; import { getBrowseDirectoryPath } from "@t3tools/client-runtime/state/projects"; import { useCallback, useMemo, useState } from "react"; -import { - Markdown, - type CustomRenderers, - type NodeStyleOverrides, - type PartialMarkdownTheme, -} from "react-native-nitro-markdown"; -import { RefreshControl, ScrollView, Text as NativeText, View } from "react-native"; +import { RefreshControl, ScrollView, View } from "react-native"; import { tryOpenExternalUrl } from "../../lib/openExternalUrl"; import { useFontFamily } from "../../lib/useFontFamily"; -import { - resolveMarkdownFontSizes, - resolveNativeMarkdownTypography, -} from "../../lib/appearancePreferences"; +import { resolveNativeMarkdownTypography } from "../../lib/appearancePreferences"; import { useUniwindTheme } from "../../lib/useUniwindTheme"; import { ThreadMarkdownImage, @@ -23,7 +14,6 @@ import { } from "../threads/ThreadMarkdownImage"; import { useAppearancePreferences } from "../settings/appearance/AppearancePreferencesProvider"; import { - hasNativeSelectableMarkdownText, SelectableMarkdownText, type MarkdownImageRenderer, type NativeMarkdownTextStyle, @@ -31,18 +21,11 @@ import { import { resolveWorkspaceFilePath } from "./filePath"; interface MarkdownPreviewStyles { - readonly theme: PartialMarkdownTheme; - readonly styles: NodeStyleOverrides; - readonly renderers: CustomRenderers; readonly nativeTextStyle: NativeMarkdownTextStyle; } -function useMarkdownPreviewStyles(renderImage?: MarkdownImageRenderer): MarkdownPreviewStyles { +function useMarkdownPreviewStyles(): MarkdownPreviewStyles { const { appearance } = useAppearancePreferences(); - const markdownFontSizes = useMemo( - () => resolveMarkdownFontSizes(appearance.baseFontSize), - [appearance.baseFontSize], - ); const nativeMarkdownTypography = useMemo( () => resolveNativeMarkdownTypography(appearance.baseFontSize), [appearance.baseFontSize], @@ -52,104 +35,14 @@ function useMarkdownPreviewStyles(renderImage?: MarkdownImageRenderer): Markdown const strong = theme["--color-md-strong"]; const link = theme["--color-md-link"]; const blockquoteBorder = theme["--color-md-blockquote-border"]; - const blockquoteBackground = theme["--color-md-blockquote-bg"]; const codeBackground = theme["--color-md-code-bg"]; const codeText = theme["--color-md-code-text"]; const horizontalRule = theme["--color-md-hr"]; const regularFontFamily = useFontFamily("regular"); - const mediumFontFamily = useFontFamily("medium"); const boldFontFamily = useFontFamily("bold"); return useMemo(() => { - const renderers: CustomRenderers = { - link: ({ href, children }) => ( - { - if (href) { - void tryOpenExternalUrl(href, "markdown-link"); - } - }} - style={{ - color: link, - textDecorationLine: "none", - }} - > - {children} - - ), - image: ({ node }) => - node.href && renderImage - ? (renderImage({ - href: node.href, - alt: node.alt ?? null, - title: node.title ?? null, - }) ?? undefined) - : undefined, - }; - return { - theme: { - colors: { - text: body, - heading: strong, - link, - blockquote: blockquoteBorder, - border: horizontalRule, - surface: "transparent", - surfaceLight: blockquoteBackground, - accent: link, - tableBorder: horizontalRule, - tableHeader: blockquoteBackground, - tableHeaderText: strong, - tableRowOdd: blockquoteBackground, - tableRowEven: "transparent", - code: codeText, - codeBackground, - }, - }, - styles: { - text: { - color: body, - fontFamily: regularFontFamily, - fontSize: markdownFontSizes.m, - lineHeight: markdownFontSizes.bodyLineHeight, - }, - heading: { - color: strong, - fontFamily: boldFontFamily, - }, - strong: { - color: strong, - fontFamily: boldFontFamily, - }, - link: { - color: link, - fontFamily: mediumFontFamily, - }, - blockquote: { - backgroundColor: blockquoteBackground, - borderLeftColor: blockquoteBorder, - borderLeftWidth: 3, - paddingLeft: 12, - }, - code: { - backgroundColor: codeBackground, - color: codeText, - fontFamily: "ui-monospace", - }, - codeBlock: { - backgroundColor: codeBackground, - borderRadius: 12, - color: codeText, - fontFamily: "ui-monospace", - padding: 12, - }, - hr: { - backgroundColor: horizontalRule, - }, - }, - renderers, nativeTextStyle: { color: body, strongColor: strong, @@ -172,18 +65,14 @@ function useMarkdownPreviewStyles(renderImage?: MarkdownImageRenderer): Markdown }, }; }, [ - blockquoteBackground, blockquoteBorder, body, codeBackground, codeText, horizontalRule, link, - markdownFontSizes, - mediumFontFamily, nativeMarkdownTypography, regularFontFamily, - renderImage, strong, boldFontFamily, ]); @@ -245,7 +134,7 @@ export function FileMarkdownPreview(props: { }, [markdownDirectory, props.environmentId, props.threadId, props.captured], ); - const styles = useMarkdownPreviewStyles(renderImage); + const styles = useMarkdownPreviewStyles(); const onLinkPress = useCallback((href: string) => { void tryOpenExternalUrl(href, "markdown-link"); }, []); @@ -264,23 +153,12 @@ export function FileMarkdownPreview(props: { } > - {hasNativeSelectableMarkdownText() ? ( - - ) : ( - - {props.markdown} - - )} + ); diff --git a/apps/mobile/src/features/threads/ThreadFeed.tsx b/apps/mobile/src/features/threads/ThreadFeed.tsx index 20848cd2ad10..97a29ba9ee7b 100644 --- a/apps/mobile/src/features/threads/ThreadFeed.tsx +++ b/apps/mobile/src/features/threads/ThreadFeed.tsx @@ -17,7 +17,6 @@ import type { TurnId, } from "@t3tools/contracts"; import { renderAssistantCitationsAsText } from "@t3tools/shared/assistantCitations"; -import { encodeComposerContextFragment } from "@t3tools/shared/composerContextClipboard"; import { parseComposerContextHref, collectComposerContextReferences, @@ -61,12 +60,6 @@ import { type ReactNode, type RefObject, } from "react"; -import { - Markdown, - type CustomRenderers, - type NodeStyleOverrides, - type PartialMarkdownTheme, -} from "react-native-nitro-markdown"; import { ActivityIndicator, Alert, @@ -76,10 +69,7 @@ import { type NativeScrollEvent, type NativeSyntheticEvent, Pressable, - ScrollView, StyleSheet, - Text as NativeText, - type ColorValue, useWindowDimensions, View, } from "react-native"; @@ -97,9 +87,7 @@ import { copyTextWithHaptic } from "../../lib/copyTextWithHaptic"; import { tryOpenExternalUrl } from "../../lib/openExternalUrl"; import { downloadAndShareAttachment } from "../../lib/attachmentDownload"; import { hasWideMarkdownBlock } from "../../lib/wideMarkdownBlocks"; -import { faviconUrlForOrigin } from "@t3tools/shared/favicon"; import { - hasNativeSelectableMarkdownText, SelectableMarkdownText, type MarkdownFileContextMenu, type MarkdownImageRenderer, @@ -120,7 +108,6 @@ import { } from "../../lib/videoPreviewSource"; import { CopyTextButton } from "../../components/CopyTextButton"; import { parseReviewCommentMessageSegments } from "../review/reviewCommentSelection"; -import type { ReviewDiffTheme } from "../review/shikiReviewHighlighter"; import { ReviewCommentCard, useReviewCommentColors, @@ -133,18 +120,11 @@ import { deriveThreadWorkLogSizing, type LayoutVariant, } from "../../lib/layout"; -import { - resolveMarkdownFontSizes, - resolveNativeMarkdownTypography, -} from "../../lib/appearancePreferences"; +import { resolveNativeMarkdownTypography } from "../../lib/appearancePreferences"; import { useAppearancePreferences } from "../settings/appearance/AppearancePreferencesProvider"; -import { markdownFileIconSource } from "@t3tools/mobile-markdown-text/file-icons"; import { PierreEntryIcon } from "../../components/PierreEntryIcon"; -import { markdownLinkIconSource } from "@t3tools/mobile-markdown-text/link-icons"; import { normalizeNativeMarkdownUrl, - resolveMarkdownInlineCodePresentation, - resolveMarkdownLinkIcon, resolveMarkdownLinkPresentation, } from "@t3tools/mobile-markdown-text/links"; import { @@ -173,7 +153,6 @@ import { } from "./thread-work-log"; import { appendPendingThreadMessages, type PendingThreadFeedEntry } from "./pending-thread-feed"; import type { QueuedThreadMessage } from "../../state/thread-outbox-model"; -import { useMarkdownCodeHighlight } from "./markdownCodeHighlightState"; import { assetEnvironment, useAssetUrl, @@ -601,117 +580,15 @@ function ThreadMarkdownVideo(props: { readonly source: MediaVideoPreviewSource } ); } -const MARKDOWN_MONO_FONT = Platform.select({ - ios: "ui-monospace", - android: "monospace", - default: "monospace", -}); - interface MarkdownStyleSets { readonly user: MarkdownStyleSet; readonly assistant: MarkdownStyleSet; } interface MarkdownStyleSet { - readonly theme: PartialMarkdownTheme; - readonly styles: NodeStyleOverrides; - readonly renderers: CustomRenderers; readonly nativeTextStyle: NativeMarkdownTextStyle; } -const failedMarkdownFaviconHosts = new Set(); -const MarkdownLinkLabelContext = createContext(false); -const markdownLinkStyles = StyleSheet.create({ - inlineIcon: { - width: 14, - height: 14, - marginHorizontal: 3, - transform: [{ translateY: 2 }], - flexShrink: 0, - }, - favicon: { - borderRadius: 3, - }, -}); - -const MarkdownExternalLink = memo(function MarkdownExternalLink(props: { - readonly children: ReactNode; - readonly color: string; - readonly host: string; - readonly href: string; - readonly onPress: (href: string) => void; -}) { - const [failedHost, setFailedHost] = useState(null); - const linkIcon = resolveMarkdownLinkIcon(props.host); - const faviconUrl = linkIcon ? null : faviconUrlForOrigin(`https://${props.host}`); - - return ( - props.onPress(props.href)} - style={{ - color: props.color, - textDecorationLine: "none", - }} - > - {linkIcon ? ( - - ) : faviconUrl !== null && - failedHost !== props.host && - !failedMarkdownFaviconHosts.has(props.host) ? ( - { - failedMarkdownFaviconHosts.add(props.host); - setFailedHost(props.host); - }} - /> - ) : ( - {" ◉ "} - )} - {props.children} - - ); -}); - -function MarkdownInlineCode(props: { - readonly content: string; - readonly textColor: string; - readonly codeColor: string; - readonly fontSize: number; - readonly lineHeight: number; - readonly onLinkPress: (href: string) => void; -}) { - const insideLink = useContext(MarkdownLinkLabelContext); - const presentation = insideLink ? null : resolveMarkdownInlineCodePresentation(props.content); - return ( - props.onLinkPress(presentation.href) : undefined} - style={{ - color: presentation ? props.textColor : props.codeColor, - fontSize: props.fontSize, - lineHeight: props.lineHeight, - }} - > - {presentation ? ( - - ) : null} - {presentation?.label ?? props.content} - - ); -} - const ARTIFACT_TEMPLATE_SYMBOL_BY_KIND: Record< CodexArtifactTemplate["artifactKind"], AppSymbolName @@ -805,7 +682,7 @@ const AssistantMarkdownContent = memo(function AssistantMarkdownContent(props: { if (segment.markdown.trim().length === 0) return null; const markdown = renderCodexFileCitationsAsMarkdown(segment.markdown); - return hasNativeSelectableMarkdownText() ? ( + return ( - ) : ( - - {markdown} - ); }); }); -function MarkdownCodeBlock(props: { - readonly backgroundColor: string; - readonly borderColor: string; - readonly content: string; - readonly copyTintColor: ColorValue; - readonly headerTextColor: string; - readonly fontSize: number; - readonly highlightCode: boolean; - readonly language?: string | null; - readonly lineHeight: number; - readonly textColor: string; - readonly theme: ReviewDiffTheme; -}) { - const content = props.content.replace(/\n$/, ""); - const languageLabel = props.language?.trim() || "text"; - const highlighted = useMarkdownCodeHighlight({ - code: content, - enabled: props.highlightCode && Boolean(props.language?.trim()), - language: props.language, - theme: props.theme, - }); - let tokenOffset = 0; - - return ( - - - - {languageLabel} - - - - - - {highlighted - ? highlighted.map((line, lineIndex) => { - const lineStartOffset = tokenOffset; - const lineText = line.map((token) => token.content).join(""); - const renderedLine = ( - - {line.map((token) => { - const startOffset = tokenOffset; - tokenOffset += token.content.length; - const fontStyle = - token.fontStyle !== null && (token.fontStyle & 1) === 1 - ? ("italic" as const) - : ("normal" as const); - const fontWeight = - token.fontStyle !== null && (token.fontStyle & 2) === 2 - ? ("700" as const) - : ("400" as const); - - return ( - - {token.content} - - ); - })} - {lineIndex + 1 < highlighted.length ? "\n" : ""} - - ); - if (lineIndex + 1 < highlighted.length) { - tokenOffset += 1; - } - return renderedLine; - }) - : content} - - - - ); -} - -function useMarkdownStyles( - onLinkPress: (href: string) => void, - renderImage: MarkdownImageRenderer, -): MarkdownStyleSets { - const { appearance, themeAppearance } = useAppearancePreferences(); - const markdownFontSizes = useMemo( - () => resolveMarkdownFontSizes(appearance.baseFontSize), - [appearance.baseFontSize], - ); +function useMarkdownStyles(): MarkdownStyleSets { + const { appearance } = useAppearancePreferences(); const nativeMarkdownTypography = useMemo( () => resolveNativeMarkdownTypography(appearance.baseFontSize), [appearance.baseFontSize], ); - const themeMode = themeAppearance; const theme = useUniwindTheme(); const markdownBodyColor = theme["--color-md-body"]; const markdownStrongColor = theme["--color-md-strong"]; const markdownLinkColor = theme["--color-md-link"]; - const markdownBlockquoteBg = theme["--color-md-blockquote-bg"]; const markdownBlockquoteBorder = theme["--color-md-blockquote-border"]; const markdownCodeBg = theme["--color-md-code-bg"]; const markdownCodeText = theme["--color-md-code-text"]; @@ -979,289 +720,14 @@ function useMarkdownStyles( const markdownUserCodeText = theme["--color-md-user-code-text"]; const markdownUserInlineCodeText = theme["--color-user-bubble-foreground-muted"]; const markdownUserFenceBg = theme["--color-md-user-fence-bg"]; - const markdownUserFenceText = theme["--color-md-user-fence-text"]; - const iconSubtleColor = theme["--color-icon-subtle"]; const inlineSkillForeground = theme["--color-inline-skill-foreground"]; const userBubbleSkillForeground = theme["--color-user-bubble-skill-foreground"]; - const userBubbleForegroundMuted = theme["--color-user-bubble-foreground-muted"]; const regularFontFamily = useFontFamily("regular"); const boldFontFamily = useFontFamily("bold"); return useMemo(() => { - const baseTheme: PartialMarkdownTheme = { - colors: { - text: markdownBodyColor, - heading: markdownStrongColor, - link: markdownLinkColor, - blockquote: markdownBlockquoteBorder, - border: markdownHrColor, - surface: "transparent", - surfaceLight: markdownBlockquoteBg, - accent: markdownLinkColor, - tableBorder: markdownHrColor, - tableHeader: markdownBlockquoteBg, - tableHeaderText: markdownStrongColor, - tableRowOdd: "transparent", - tableRowEven: "transparent", - }, - spacing: { - xs: 4, - s: 4, - m: 8, - l: 8, - xl: 16, - }, - fontSizes: { - s: markdownFontSizes.s, - m: markdownFontSizes.m, - h1: markdownFontSizes.h1, - h2: markdownFontSizes.h2, - h3: markdownFontSizes.h3, - h4: markdownFontSizes.h4, - h5: markdownFontSizes.h5, - h6: markdownFontSizes.h6, - }, - fontFamilies: { - regular: regularFontFamily, - heading: boldFontFamily, - mono: MARKDOWN_MONO_FONT, - }, - headingWeight: "700", - borderRadius: { - s: 4, - m: 8, - l: 12, - }, - showCodeLanguage: false, - }; - - const baseStyles: NodeStyleOverrides = { - document: { flexShrink: 1 }, - paragraph: { marginTop: 0, marginBottom: 10 }, - list: { marginTop: 4, marginBottom: 8 }, - list_item: { marginTop: 0, marginBottom: 4 }, - task_list_item: { marginTop: 0, marginBottom: 4 }, - text: { lineHeight: markdownFontSizes.bodyLineHeight }, - bold: { - fontWeight: "700", - color: markdownStrongColor, - fontFamily: boldFontFamily, - }, - italic: { fontStyle: "italic" }, - link: { - color: markdownLinkColor, - textDecorationLine: "underline" as const, - }, - blockquote: { - borderLeftWidth: 2, - borderLeftColor: markdownBlockquoteBorder, - paddingLeft: 11, - paddingVertical: 2, - marginLeft: 0, - marginVertical: 10, - }, - heading: { - fontFamily: boldFontFamily, - color: markdownStrongColor, - marginTop: 18, - marginBottom: 8, - }, - horizontal_rule: { - backgroundColor: markdownHrColor, - height: 1, - marginVertical: 12, - }, - }; - - const createMarkdownRenderers = ( - inlineTextColor: string, - inlineCodeTextColor: string, - blockBackgroundColor: string, - blockTextColor: string, - copyTintColor: ColorValue, - preserveSoftBreaks: boolean, - highlightCode: boolean, - ): CustomRenderers => ({ - link: ({ children, href = "" }) => { - const presentation = resolveMarkdownLinkPresentation(href); - if (presentation.kind === "file") { - return ( - onLinkPress(href)} - style={{ color: inlineTextColor }} - > - - {presentation.label} - - ); - } - if (presentation.kind === "external") { - return ( - - - {children} - - - ); - } - const linkHref = presentation.href; - return ( - - { - void tryOpenExternalUrl(linkHref, "markdown-link"); - } - : undefined - } - style={{ color: markdownLinkColor }} - > - {children} - - - ); - }, - list: ({ node, Renderer, ordered = false, start = 1 }) => ( - - {node.children?.map((child, index) => { - const childKey = `${child.type}:${child.beg ?? "unknown"}:${child.end ?? "unknown"}`; - if (child.type === "task_list_item") { - return ( - - ); - } - return ( - - - {ordered ? `${start + index}.` : "•"} - - - - - - ); - })} - - ), - image: ({ node }) => - node.href - ? (renderImage({ - href: node.href, - alt: node.alt ?? null, - title: node.title ?? null, - }) ?? undefined) - : undefined, - code_inline: ({ content }) => ( - - ), - ...(preserveSoftBreaks - ? { - soft_break: () => {"\n"}, - } - : {}), - code_block: ({ content = "", language }) => ( - - ), - }); - - const userTheme: PartialMarkdownTheme = { - ...baseTheme, - colors: { - ...baseTheme.colors, - text: markdownUserBodyColor, - heading: markdownUserBodyColor, - link: markdownUserBodyColor, - code: markdownUserCodeText, - codeBackground: markdownUserCodeBg, - border: markdownUserFenceBg, - }, - }; - const userStyles: NodeStyleOverrides = { - ...baseStyles, - paragraph: { marginTop: 0, marginBottom: 0 }, - bold: { - fontWeight: "700", - color: markdownUserBodyColor, - fontFamily: boldFontFamily, - }, - heading: { - ...baseStyles.heading, - color: markdownUserBodyColor, - marginTop: 8, - marginBottom: 4, - }, - link: { - color: markdownUserBodyColor, - textDecorationLine: "underline" as const, - }, - }; - - const assistantTheme: PartialMarkdownTheme = { - ...baseTheme, - colors: { - ...baseTheme.colors, - code: markdownCodeText, - codeBackground: markdownCodeBg, - border: markdownCodeBg, - }, - }; - const assistantStyles: NodeStyleOverrides = { - ...baseStyles, - }; - return { user: { - theme: userTheme, - styles: userStyles, - renderers: createMarkdownRenderers( - markdownUserCodeText, - markdownUserInlineCodeText, - markdownUserFenceBg, - markdownUserFenceText, - userBubbleForegroundMuted, - true, - false, - ), nativeTextStyle: { color: markdownUserBodyColor, strongColor: markdownUserBodyColor, @@ -1285,17 +751,6 @@ function useMarkdownStyles( }, }, assistant: { - theme: assistantTheme, - styles: assistantStyles, - renderers: createMarkdownRenderers( - markdownCodeText, - markdownInlineCodeText, - markdownCodeBg, - markdownCodeText, - iconSubtleColor, - false, - true, - ), nativeTextStyle: { color: markdownBodyColor, strongColor: markdownStrongColor, @@ -1322,14 +777,11 @@ function useMarkdownStyles( }, [ boldFontFamily, contextChipBorderColor, - iconSubtleColor, inlineSkillForeground, - markdownBlockquoteBg, markdownBlockquoteBorder, markdownBodyColor, markdownCodeBg, markdownCodeText, - markdownFontSizes, markdownHrColor, markdownInlineCodeText, markdownLinkColor, @@ -1338,14 +790,9 @@ function useMarkdownStyles( markdownUserCodeBg, markdownUserCodeText, markdownUserFenceBg, - markdownUserFenceText, markdownUserInlineCodeText, nativeMarkdownTypography, - onLinkPress, regularFontFamily, - renderImage, - themeMode, - userBubbleForegroundMuted, userBubbleSkillForeground, ]); } @@ -1816,7 +1263,7 @@ function UserMessageContent(props: UserMessageContentProps) { }; return ( <> - segment.kind === "review-comment"); - // A message can hold both a review comment and context chips. The fragment travels with every - // text run, so copying from the segmented branch carries the same context as the plain one. - const contextClipboardFragment = props.context - ? (encodeComposerContextFragment({ - version: 1, - source: { environmentId: props.environmentId }, - records: props.context.records, - }) ?? undefined) - : undefined; if (!hasReviewComment) { - if (hasNativeSelectableMarkdownText()) { - return ( - - ); - } return ( - - {text} - + ); } @@ -1891,27 +1316,16 @@ function LegacyUserMessageContent(props: UserMessageContentProps) { return null; } - return hasNativeSelectableMarkdownText() ? ( + return ( - ) : ( - - {text} - ); })} @@ -2275,7 +1689,7 @@ export const ThreadFeed = memo(function ThreadFeed(props: ThreadFeedProps) { }, [props.environmentId, props.threadId, props.workspaceRoot], ); - const markdownStyles = useMarkdownStyles(onMarkdownLinkPress, renderMarkdownImage); + const markdownStyles = useMarkdownStyles(); const reviewCommentColors = useReviewCommentColors(); // One definition of "still live", shared with the fold derivation: two // copies of this test are what let a row and the fold beside it disagree. diff --git a/apps/mobile/src/lib/composerChipPresentation.test.ts b/apps/mobile/src/lib/composerChipPresentation.test.ts new file mode 100644 index 000000000000..93f52ed523af --- /dev/null +++ b/apps/mobile/src/lib/composerChipPresentation.test.ts @@ -0,0 +1,85 @@ +import { describe, expect, it } from "vite-plus/test"; + +describe("composerChipSizeSuffix", () => { + it("labels attachment records with a human size, matching web's chip", async () => { + const { composerChipSizeSuffix } = await import("@t3tools/mobile-markdown-text/markdown"); + expect(composerChipSizeSuffix({ kind: "file", sizeBytes: 1024 })).toBe("1 KB"); + expect(composerChipSizeSuffix({ kind: "file", sizeBytes: 3_700_000 })).toBe("3.5 MB"); + expect(composerChipSizeSuffix({ kind: "image", sizeBytes: 2048 })).toBe("2 KB"); + }); + + it("adds nothing for records that carry no bytes", async () => { + const { composerChipSizeSuffix } = await import("@t3tools/mobile-markdown-text/markdown"); + // Terminal/review/PR chips have no size to show. + expect(composerChipSizeSuffix({ kind: "terminal" })).toBe(""); + expect(composerChipSizeSuffix({ kind: "file" })).toBe(""); + expect(composerChipSizeSuffix(undefined)).toBe(""); + }); +}); + +describe("contextChipPresentation image detection", () => { + it("treats a picture attached through the file picker as an image", async () => { + const { contextChipPresentation } = await import("@t3tools/mobile-markdown-text/markdown"); + // The document picker types every pick as `file`, so the name has to carry the intent. + expect( + contextChipPresentation("file", { kind: "file", name: "IMG_4997.PNG", mimeType: "" }), + ).toEqual({ accent: "#d55665", symbol: "photo" }); + expect( + contextChipPresentation("file", { + kind: "file", + name: "shot", + mimeType: "image/jpeg", + }), + ).toEqual({ accent: "#d55665", symbol: "photo" }); + }); + + it("leaves genuine documents and videos alone", async () => { + const { contextChipPresentation } = await import("@t3tools/mobile-markdown-text/markdown"); + expect( + contextChipPresentation("file", { kind: "file", name: "notes.txt", mimeType: "text/plain" }), + ).toEqual({ accent: "#0090cd", symbol: "doc" }); + expect( + contextChipPresentation("file", { kind: "file", name: "clip.mp4", mimeType: "video/mp4" }), + ).toEqual({ accent: "#d06217", symbol: "play.rectangle" }); + }); +}); + +describe("pull request chip status", () => { + const chip = async (state: string, isDraft = false) => { + const { contextChipPresentation } = await import("@t3tools/mobile-markdown-text/markdown"); + return contextChipPresentation("review-comment", { + kind: "review-comment", + sectionId: "pull-request:10978", + pullRequest: { state, isDraft }, + }); + }; + + it("colours a pull request by its state, the way web and the forge do", async () => { + expect((await chip("open")).accent).toBe("#009f6e"); + expect((await chip("open", true)).accent).toBe("#7f8793"); + expect((await chip("merged")).accent).toBe("#8a70dd"); + expect((await chip("closed")).accent).toBe("#d55665"); + }); + + it("keeps one glyph across every state, so only colour carries the status", async () => { + // Web draws a fixed `git-pull-request` and encodes state in colour alone. A per-state glyph + // here would put mobile out of step with it. + const symbols = await Promise.all( + [chip("open"), chip("open", true), chip("merged"), chip("closed")].map( + async (pending) => (await pending).symbol, + ), + ); + expect(new Set(symbols)).toEqual(new Set(["git-pull-request"])); + }); + + it("falls back to the generic pull request chip when the state is unknown", async () => { + const { contextChipPresentation } = await import("@t3tools/mobile-markdown-text/markdown"); + // An older server may send no metadata at all; the chip still has to render. + expect( + contextChipPresentation("review-comment", { + kind: "review-comment", + sectionId: "pull-request:1", + }).accent, + ).toBe("#7079e4"); + }); +}); diff --git a/apps/mobile/src/lib/nativeMarkdownText.test.ts b/apps/mobile/src/lib/nativeMarkdownText.test.ts deleted file mode 100644 index d934a306aa01..000000000000 --- a/apps/mobile/src/lib/nativeMarkdownText.test.ts +++ /dev/null @@ -1,1176 +0,0 @@ -import { describe, expect, it } from "vite-plus/test"; -import type { MarkdownNode } from "react-native-nitro-markdown/headless"; - -import { - nativeMarkdownChunkSpacing, - nativeMarkdownDocumentChunks, - nativeMarkdownDocumentRuns, - nativeMarkdownListItemBlocks, - nativeMarkdownTextRuns, - nativeMarkdownWithPreservedSoftBreaks, - nativeMarkdownContextCopyRanges, - contextChipPresentation, -} from "@t3tools/mobile-markdown-text/markdown"; - -describe("nativeMarkdownTextRuns", () => { - it("distinguishes video and pull-request context from generic file and review chips", () => { - expect( - contextChipPresentation("file", { - name: "recording.webm", - mimeType: "application/octet-stream", - }), - ).toEqual(contextChipPresentation("video")); - expect(contextChipPresentation("review-comment", { sectionId: "pull-request:284" })).toEqual( - contextChipPresentation("pull-request"), - ); - expect(contextChipPresentation("review-comment", { sectionId: "git:working-tree" })).toEqual( - contextChipPresentation("review-comment"), - ); - }); - - it("renders a video-named file with a declared document MIME type as a file chip", () => { - expect( - contextChipPresentation("file", { - name: "recording.mp4", - mimeType: "application/pdf", - }), - ).toEqual(contextChipPresentation("file")); - }); - - it("maps rendered selection offsets back to canonical references without losing repeated chips", () => { - const href = "t3-context://v1/image/screenshot"; - expect( - nativeMarkdownContextCopyRanges([ - { run: { text: "😀 " }, text: "😀 ", inlineImageLength: 0 }, - { run: { href, text: "Checkout" }, text: "Checkout", inlineImageLength: 1 }, - { run: { text: " then " }, text: " then ", inlineImageLength: 0 }, - { run: { href, text: "Checkout" }, text: "\uFFFC\u00A0Checkout", inlineImageLength: 0 }, - ]), - ).toEqual([ - { start: 3, end: 12, text: "![Checkout](t3-context://v1/image/screenshot)" }, - { start: 18, end: 28, text: "![Checkout](t3-context://v1/image/screenshot)" }, - ]); - }); - it("restores canonical skill and context text from Android's single-image chips", () => { - expect( - nativeMarkdownContextCopyRanges([ - { run: { text: "Use " }, text: "Use ", inlineImageLength: 0 }, - { run: { text: "Playwright", skillName: "playwright" }, text: "", inlineImageLength: 1 }, - { run: { text: " on " }, text: " on ", inlineImageLength: 0 }, - { - run: { text: "Screenshot", href: "t3-context://v1/image/screenshot" }, - text: "", - inlineImageLength: 1, - }, - ]), - ).toEqual([ - { start: 4, end: 5, text: "$playwright" }, - { start: 9, end: 10, text: "![Screenshot](t3-context://v1/image/screenshot)" }, - ]); - }); - it("links a path-shaped code span without changing the same path in prose", () => { - expect( - nativeMarkdownTextRuns({ - type: "paragraph", - children: [ - { type: "text", content: "/tmp/frame.png " }, - { type: "code_inline", content: "/tmp/frame.png" }, - ], - }), - ).toEqual([ - { text: "/tmp/frame.png " }, - { text: "frame.png", href: "/tmp/frame.png", fileIcon: "image" }, - ]); - }); - - it("preserves the destination of a link with a code-formatted label", () => { - expect( - nativeMarkdownTextRuns({ - type: "paragraph", - children: [ - { - type: "link", - href: "https://example.com/docs", - children: [{ type: "code_inline", content: "src/main.ts" }], - }, - ], - }), - ).toEqual([ - { - text: "src/main.ts", - code: true, - href: "https://example.com/docs", - externalHost: "example.com", - }, - ]); - }); - - it("preserves inline emphasis and code styles", () => { - const node: MarkdownNode = { - type: "paragraph", - children: [ - { type: "text", content: "plain " }, - { type: "bold", children: [{ type: "text", content: "bold" }] }, - { type: "text", content: " " }, - { type: "code_inline", content: "const value = 1" }, - ], - }; - - expect(nativeMarkdownTextRuns(node)).toEqual([ - { text: "plain " }, - { text: "bold", bold: true }, - { text: " " }, - { text: "const value = 1", code: true }, - ]); - }); - - it("normalizes external and file links for native presentation", () => { - const node: MarkdownNode = { - type: "paragraph", - children: [ - { - type: "link", - href: "https://example.com/docs", - children: [{ type: "text", content: "Docs" }], - }, - { type: "text", content: " " }, - { - type: "link", - href: "file:///repo/README.md#L12", - children: [{ type: "text", content: "ignored label" }], - }, - ], - }; - - expect(nativeMarkdownTextRuns(node)).toEqual([ - { - text: "Docs", - href: "https://example.com/docs", - externalHost: "example.com", - }, - { text: " " }, - { - text: "README.md:12", - href: "file:///repo/README.md#L12", - fileIcon: "markdown", - }, - ]); - }); - - it("keeps hard breaks and collapses soft breaks", () => { - const node: MarkdownNode = { - type: "paragraph", - children: [ - { type: "text", content: "first" }, - { type: "soft_break" }, - { type: "text", content: "second" }, - { type: "line_break" }, - { type: "text", content: "third" }, - ], - }; - - expect(nativeMarkdownTextRuns(node)).toEqual([{ text: "first second\nthird" }]); - }); - - it("can preserve soft breaks for authored user messages", () => { - const node: MarkdownNode = { - type: "paragraph", - children: [ - { type: "text", content: "first" }, - { type: "soft_break" }, - { type: "text", content: "second" }, - ], - }; - - expect(nativeMarkdownTextRuns(nativeMarkdownWithPreservedSoftBreaks(node))).toEqual([ - { text: "first\nsecond" }, - ]); - }); - - it("normalizes common inline HTML and entities", () => { - const node: MarkdownNode = { - type: "paragraph", - children: [ - { type: "text", content: "Less than: < " }, - { type: "html_inline", content: "" }, - { type: "text", content: "⌘" }, - { type: "html_inline", content: "" }, - { type: "html_inline", content: "
" }, - { type: "html_inline", content: "highlighted" }, - ], - }; - - expect(nativeMarkdownTextRuns(node)).toEqual([{ text: "Less than: < ⌘\nhighlighted" }]); - }); - - it("normalizes double-encoded entities and inline tags emitted as text", () => { - const node: MarkdownNode = { - type: "paragraph", - children: [ - { - type: "text", - content: - "Keyboard: ⌘ + K; Less than: &lt;; Greater than: &gt;", - }, - ], - }; - - expect(nativeMarkdownTextRuns(node)).toEqual([ - { text: "Keyboard: ⌘ + K; Less than: <; Greater than: >" }, - ]); - }); - - it.each([ - ["😀", "😀"], - ["🚀", "🚀"], - ["�", "�"], - ["�", "�"], - ["&#9999999999;", "�"], - ["&#x110000;", "�"], - ])("normalizes numeric entity %s without throwing", (content, expected) => { - const node: MarkdownNode = { - type: "paragraph", - children: [{ type: "text", content }], - }; - - expect(nativeMarkdownTextRuns(node)).toEqual([{ text: expected }]); - }); - - it("reads inline content from nested text nodes", () => { - const node: MarkdownNode = { - type: "paragraph", - children: [ - { - type: "text", - children: [{ type: "text", content: "Plain text" }], - }, - { type: "text", content: " and " }, - { - type: "code_inline", - children: [{ type: "text", content: "inline code" }], - }, - ], - }; - - expect(nativeMarkdownTextRuns(node)).toEqual([ - { text: "Plain text and " }, - { text: "inline code", code: true }, - ]); - }); -}); - -describe("nativeMarkdownDocumentRuns", () => { - it("renders a file mention without swallowing sentence punctuation or changing package references", () => { - const runs = nativeMarkdownDocumentRuns({ - type: "document", - children: [ - { - type: "paragraph", - children: [ - { type: "text", content: "Inspect @src/Checkout.tsx. Use @t3tools/contracts." }, - ], - }, - ], - }); - expect(runs).toEqual([ - { text: "Inspect ", role: "body" }, - { - text: "Checkout.tsx", - role: "body", - href: "src/Checkout.tsx", - fileIcon: "react", - sourceText: "@src/Checkout.tsx", - }, - { text: ". Use @t3tools/contracts.", role: "body" }, - ]); - }); - - it("copies collapsed skill and file chips back to their original references", () => { - expect( - nativeMarkdownContextCopyRanges([ - { run: { text: "$ui", skillName: "ui" }, text: "\uFFFC", inlineImageLength: 0 }, - { run: { text: " and " }, text: " and ", inlineImageLength: 0 }, - { - run: { - text: "Checkout.tsx", - href: "src/Checkout.tsx", - fileIcon: "react", - sourceText: "@src/Checkout.tsx", - }, - text: "\uFFFC", - inlineImageLength: 0, - }, - ]), - ).toEqual([ - { start: 0, end: 1, text: "$ui" }, - { start: 6, end: 7, text: "@src/Checkout.tsx" }, - ]); - }); - - it.each(["$", "€", "£", "¥", "₹", "₩", "₿", "𑿝"])( - "decorates %s skill references as selectable skill links", - (prefix) => { - const node: MarkdownNode = { - type: "document", - children: [ - { - type: "paragraph", - children: [{ type: "text", content: `Use ${prefix}ui for this.` }], - }, - ], - }; - - expect(nativeMarkdownDocumentRuns(node, [{ name: "ui", displayName: "UI" }])).toEqual([ - { text: "Use ", role: "body" }, - { - text: `${prefix}ui`, - role: "body", - skillName: "ui", - skillLabel: "UI", - }, - { text: " for this.", role: "body" }, - ]); - }, - ); - - it("decorates known skill references that begin with a digit", () => { - const node: MarkdownNode = { - type: "document", - children: [ - { - type: "paragraph", - children: [{ type: "text", content: "Use $2spec for this." }], - }, - ], - }; - - expect(nativeMarkdownDocumentRuns(node, [{ name: "2spec", displayName: "2Spec" }])).toEqual([ - { text: "Use ", role: "body" }, - { - text: "$2spec", - role: "body", - skillName: "2spec", - skillLabel: "2Spec", - }, - { text: " for this.", role: "body" }, - ]); - }); - - it("decorates known skill references inside blockquotes", () => { - const node: MarkdownNode = { - type: "blockquote", - children: [ - { - type: "paragraph", - children: [{ type: "text", content: "Use $ui for this." }], - }, - ], - }; - - expect(nativeMarkdownDocumentRuns(node, [{ name: "ui", displayName: "UI" }])).toContainEqual({ - text: "$ui", - role: "body", - skillName: "ui", - skillLabel: "UI", - }); - }); - - it("leaves unknown skill-like text unchanged", () => { - const node: MarkdownNode = { - type: "document", - children: [ - { - type: "paragraph", - children: [{ type: "text", content: "Use $unknown for this." }], - }, - ], - }; - - expect(nativeMarkdownDocumentRuns(node, [])).toEqual([ - { text: "Use $unknown for this.", role: "body" }, - ]); - }); - - it("keeps headings, paragraphs, and lists in one continuous document", () => { - const node: MarkdownNode = { - type: "document", - children: [ - { - type: "heading", - level: 1, - children: [{ type: "text", content: "Header One" }], - }, - { - type: "paragraph", - children: [ - { type: "text", content: "A paragraph with " }, - { type: "bold", children: [{ type: "text", content: "bold text" }] }, - { type: "text", content: "." }, - ], - }, - { - type: "list", - ordered: false, - children: [ - { - type: "list_item", - children: [ - { - type: "paragraph", - children: [{ type: "text", content: "First item" }], - }, - ], - }, - { - type: "list_item", - children: [ - { - type: "paragraph", - children: [{ type: "text", content: "Second item" }], - }, - ], - }, - ], - }, - ], - }; - - const runs = nativeMarkdownDocumentRuns(node); - expect(runs.map((run) => run.text).join("")).toBe( - "Header One\n\nA paragraph with bold text.\n\n•\tFirst item\n•\tSecond item", - ); - expect(runs).toContainEqual({ - text: "Header One\n", - role: "heading", - headingLevel: 1, - }); - expect(runs).toContainEqual({ - text: "bold text", - bold: true, - role: "body", - }); - expect(runs).toContainEqual({ - text: "•\t", - role: "list-marker", - depth: 1, - firstLineHeadIndent: 0, - headIndent: 24, - paragraphSpacing: 2, - }); - }); - - it("uses distinct section, heading-content, and body spacing", () => { - const node: MarkdownNode = { - type: "document", - children: [ - { - type: "paragraph", - children: [{ type: "text", content: "Intro" }], - }, - { - type: "heading", - level: 2, - children: [{ type: "text", content: "Section" }], - }, - { - type: "paragraph", - children: [{ type: "text", content: "First paragraph" }], - }, - { - type: "paragraph", - children: [{ type: "text", content: "Second paragraph" }], - }, - ], - }; - - expect( - nativeMarkdownDocumentRuns(node) - .filter((run) => run.role === "spacer") - .map((run) => run.spacing), - ).toEqual([20, 10, 12]); - }); - - it("renders tight list items whose inline nodes are direct children", () => { - const node: MarkdownNode = { - type: "document", - children: [ - { - type: "list", - children: [ - { - type: "list_item", - children: [ - { - type: "bold", - children: [{ type: "text", content: "Finding:" }], - }, - { type: "text", content: " details with " }, - { type: "code_inline", content: "inline code" }, - { type: "text", content: "." }, - ], - }, - ], - }, - ], - }; - - expect(nativeMarkdownDocumentRuns(node)).toEqual([ - { - text: "•\t", - role: "list-marker", - depth: 1, - firstLineHeadIndent: 0, - headIndent: 24, - paragraphSpacing: 2, - }, - { text: "Finding:", bold: true, role: "body", depth: 1 }, - { text: " details with ", role: "body", depth: 1 }, - { text: "inline code", code: true, role: "body", depth: 1 }, - { text: ".", role: "body", depth: 1 }, - ]); - }); - - it("preserves quotes and fenced code in document runs", () => { - const node: MarkdownNode = { - type: "document", - children: [ - { - type: "blockquote", - children: [ - { - type: "paragraph", - children: [{ type: "text", content: "Read this" }], - }, - ], - }, - { - type: "code_block", - language: "ts", - content: "const answer = 42;", - }, - ], - }; - - const runs = nativeMarkdownDocumentRuns(node); - expect(runs.map((run) => run.text).join("")).toBe("│\u00a0Read this\n\nTS\nconst answer = 42;"); - expect(runs).toContainEqual({ - text: "const answer = 42;", - code: true, - role: "code-block", - }); - }); - - it("reads fenced code content from child text nodes", () => { - const node: MarkdownNode = { - type: "document", - children: [ - { - type: "code_block", - language: "bash", - children: [{ type: "text", content: "pnpm install\n" }], - }, - ], - }; - - expect( - nativeMarkdownDocumentRuns(node) - .map((run) => run.text) - .join(""), - ).toBe("BASH\npnpm install"); - }); - - it("keeps adjacent context links with the same href in separate runs", () => { - const href = "t3-context://v1/terminal/ctx-1"; - const link = (content: string): MarkdownNode => ({ - type: "link", - href, - children: [{ type: "text", content }], - }); - const runs = nativeMarkdownDocumentRuns({ - type: "document", - children: [{ type: "paragraph", children: [link("First"), link("Second")] }], - }); - - // Merging these would render one chip and emit one copy range with a - // combined label for two distinct references. - expect(runs).toEqual([ - { text: "First", role: "body", href, fileIcon: "bash" }, - { text: "Second", role: "body", href, fileIcon: "bash" }, - ]); - }); -}); - -describe("nativeMarkdownListItemBlocks", () => { - it("groups consecutive inline nodes into one paragraph block", () => { - const item: MarkdownNode = { - type: "list_item", - children: [ - { type: "text", content: "Finding: " }, - { type: "bold", children: [{ type: "text", content: "important" }] }, - { type: "text", content: " details." }, - { - type: "list", - children: [ - { - type: "list_item", - children: [{ type: "text", content: "Nested" }], - }, - ], - }, - { type: "text", content: "Trailing prose." }, - ], - }; - - expect(nativeMarkdownListItemBlocks(item)).toEqual([ - { - type: "paragraph", - children: item.children?.slice(0, 3), - }, - item.children?.[3], - { - type: "paragraph", - children: [item.children?.[4]], - }, - ]); - }); -}); - -describe("nativeMarkdownDocumentChunks", () => { - it("renders plain blockquotes as rich blocks so their marker spans wrapped lines", () => { - const blockquote: MarkdownNode = { - type: "blockquote", - beg: 0, - end: 120, - children: [ - { - type: "paragraph", - children: [ - { - type: "text", - content: - "Persistent random per-result keys are the strongest design, even when this text wraps.", - }, - ], - }, - ], - }; - - expect( - nativeMarkdownDocumentChunks({ - type: "document", - children: [blockquote], - }), - ).toEqual([ - { - kind: "rich", - key: "rich:blockquote:offset:0", - node: blockquote, - }, - ]); - }); - - it("keeps headings and plain lists in one selectable document", () => { - const document: MarkdownNode = { - type: "document", - children: [ - { - type: "heading", - level: 2, - children: [{ type: "text", content: "Tasks" }], - }, - { - type: "list", - children: [ - { - type: "task_list_item", - checked: true, - children: [ - { - type: "paragraph", - children: [{ type: "text", content: "Completed" }], - }, - ], - }, - { - type: "list_item", - children: [ - { - type: "paragraph", - children: [{ type: "text", content: "Parent" }], - }, - { - type: "list", - children: [ - { - type: "list_item", - children: [ - { - type: "paragraph", - children: [{ type: "text", content: "Nested" }], - }, - ], - }, - ], - }, - ], - }, - ], - }, - ], - }; - - const chunks = nativeMarkdownDocumentChunks(document); - expect(chunks).toHaveLength(1); - expect(chunks[0]).toMatchObject({ kind: "selectable" }); - expect( - nativeMarkdownDocumentRuns(chunks[0]?.node ?? document) - .map((run) => run.text) - .join(""), - ).toBe("Tasks\n\n☑︎\tCompleted\n•\tParent\n◦\tNested"); - }); - - it("aligns ordered markers while keeping the list in one selectable string", () => { - const document: MarkdownNode = { - type: "document", - children: [ - { - type: "list", - ordered: true, - start: 9, - children: [ - { - type: "list_item", - children: [{ type: "text", content: "Ninth" }], - }, - { - type: "list_item", - children: [{ type: "text", content: "Tenth" }], - }, - ], - }, - ], - }; - - expect( - nativeMarkdownDocumentRuns(document) - .map((run) => run.text) - .join(""), - ).toBe("\u20079.\tNinth\n10.\tTenth"); - }); - - it("keeps prose selectable while exposing rich AST blocks", () => { - const document: MarkdownNode = { - type: "document", - children: [ - { - type: "heading", - level: 1, - beg: 0, - end: 9, - children: [{ type: "text", content: "Install" }], - }, - { - type: "code_block", - language: "bash", - beg: 11, - end: 35, - children: [{ type: "text", content: "pnpm install\n" }], - }, - { - type: "paragraph", - beg: 37, - end: 42, - children: [{ type: "text", content: "Done." }], - }, - ], - }; - - const chunks = nativeMarkdownDocumentChunks(document); - expect(chunks).toHaveLength(3); - expect(chunks[0]).toMatchObject({ kind: "selectable" }); - expect(chunks[1]).toEqual({ - kind: "rich", - key: "rich:code_block:offset:11", - node: document.children?.[1], - }); - expect(chunks[2]).toMatchObject({ kind: "selectable" }); - }); - - it("keeps a list containing fenced code as one rich AST container", () => { - const document: MarkdownNode = { - type: "document", - children: [ - { - type: "list", - beg: 0, - end: 45, - children: [ - { - type: "list_item", - children: [ - { - type: "paragraph", - children: [{ type: "text", content: "Install" }], - }, - { - type: "code_block", - language: "bash", - children: [{ type: "text", content: "pnpm install\n" }], - }, - ], - }, - ], - }, - ], - }; - - expect(nativeMarkdownDocumentChunks(document)).toEqual([ - { - kind: "rich", - key: "rich:list:offset:0", - node: document.children?.[0], - }, - ]); - }); - - it("keeps surrounding prose selectable when rich nodes have no source offsets", () => { - const document: MarkdownNode = { - type: "document", - children: [ - { - type: "heading", - level: 1, - children: [{ type: "text", content: "Before" }], - }, - { type: "horizontal_rule" }, - { - type: "paragraph", - children: [{ type: "text", content: "After." }], - }, - ], - }; - - const chunks = nativeMarkdownDocumentChunks(document); - expect(chunks).toHaveLength(3); - expect(chunks[0]).toMatchObject({ kind: "selectable" }); - expect(chunks[1]).toEqual({ - kind: "rich", - key: "rich:horizontal_rule:index:1", - node: document.children?.[1], - }); - expect(chunks[2]).toMatchObject({ kind: "selectable" }); - }); - - it("keeps offset-free structural lists isolated without promoting the whole document", () => { - const document: MarkdownNode = { - type: "document", - children: [ - { - type: "paragraph", - children: [{ type: "text", content: "Before." }], - }, - { - type: "list", - ordered: true, - children: [ - { - type: "list_item", - children: [ - { - type: "paragraph", - children: [{ type: "text", content: "Install" }], - }, - { - type: "code_block", - language: "bash", - children: [{ type: "text", content: "pnpm install\n" }], - }, - ], - }, - ], - }, - { - type: "paragraph", - children: [{ type: "text", content: "After." }], - }, - ], - }; - - const chunks = nativeMarkdownDocumentChunks(document); - expect(chunks).toHaveLength(3); - expect(chunks[0]).toMatchObject({ kind: "selectable" }); - expect(chunks[1]).toEqual({ - kind: "rich", - key: "rich:list:index:1", - node: document.children?.[1], - }); - expect(chunks[2]).toMatchObject({ kind: "selectable" }); - }); - - it("never collapses a rich subtree into a second markdown parsing pass", () => { - const document: MarkdownNode = { - type: "document", - children: [ - { - type: "paragraph", - children: [{ type: "text", content: "Before." }], - }, - { - type: "blockquote", - children: [ - { - type: "list", - children: [ - { - type: "list_item", - children: [ - { type: "text", content: "Run this" }, - { - type: "code_block", - language: "sh", - children: [{ type: "text", content: "vp check\n" }], - }, - ], - }, - ], - }, - ], - }, - { - type: "paragraph", - children: [{ type: "text", content: "After." }], - }, - ], - }; - - const chunks = nativeMarkdownDocumentChunks(document); - expect(chunks.map((chunk) => chunk.kind)).toEqual(["selectable", "rich", "selectable"]); - expect(chunks[1]).toMatchObject({ - kind: "rich", - node: { type: "blockquote" }, - }); - }); - - it("keys positioned and offset-free siblings in separate namespaces", () => { - const positioned: MarkdownNode = { - type: "blockquote", - beg: 1, - end: 10, - children: [{ type: "paragraph", children: [{ type: "text", content: "Positioned" }] }], - }; - const offsetFree: MarkdownNode = { - type: "blockquote", - children: [{ type: "paragraph", children: [{ type: "text", content: "Generated" }] }], - }; - const chunks = nativeMarkdownDocumentChunks({ - type: "document", - children: [ - { type: "paragraph", beg: 0, end: 0, children: [] }, - offsetFree, - positioned, - { type: "paragraph", children: [{ type: "text", content: "Tail" }] }, - ], - }); - - expect(chunks.map((chunk) => chunk.key)).toEqual([ - "selectable:offset:0", - "rich:blockquote:index:1", - "rich:blockquote:offset:1", - "selectable:index:3", - ]); - }); - - it("gives every offset-free selectable group its own key", () => { - const chunks = nativeMarkdownDocumentChunks({ - type: "document", - children: [ - { type: "paragraph", children: [{ type: "text", content: "One" }] }, - { type: "horizontal_rule" }, - { type: "paragraph", children: [{ type: "text", content: "Two" }] }, - { type: "horizontal_rule" }, - { type: "paragraph", children: [{ type: "text", content: "Three" }] }, - ], - }); - - expect(chunks.map((chunk) => chunk.key)).toEqual([ - "selectable:index:0", - "rich:horizontal_rule:index:1", - "selectable:index:2", - "rich:horizontal_rule:index:3", - "selectable:index:4", - ]); - }); - - it("keeps positioned chunk keys stable while text streams in", () => { - const before: MarkdownNode = { - type: "document", - children: [ - { type: "paragraph", beg: 0, end: 5, children: [{ type: "text", content: "Intro" }] }, - { - type: "code_block", - language: "ts", - beg: 7, - end: 20, - children: [{ type: "text", content: "const a" }], - }, - ], - }; - const after: MarkdownNode = { - type: "document", - children: [ - { type: "paragraph", beg: 0, end: 5, children: [{ type: "text", content: "Intro" }] }, - { - type: "code_block", - language: "ts", - beg: 7, - end: 40, - children: [{ type: "text", content: "const a = 1;\nconst b" }], - }, - ], - }; - - expect(nativeMarkdownDocumentChunks(after).map((chunk) => chunk.key)).toEqual( - nativeMarkdownDocumentChunks(before).map((chunk) => chunk.key), - ); - }); - - it("keeps a plain list in one selectable native text container", () => { - const list: MarkdownNode = { - type: "list", - ordered: false, - children: [ - { - type: "list_item", - children: [{ type: "text", content: "First" }], - }, - ], - }; - - const chunks = nativeMarkdownDocumentChunks({ - type: "document", - children: [list], - }); - - expect(chunks).toHaveLength(1); - expect(chunks[0]).toMatchObject({ - kind: "selectable", - node: { type: "document", children: [list] }, - }); - }); - - it("separates sections more than related rich blocks", () => { - const headingChunk = { - kind: "selectable" as const, - key: "heading", - node: { - type: "document", - children: [ - { - type: "heading", - level: 2, - children: [{ type: "text", content: "Section" }], - }, - ], - } satisfies MarkdownNode, - }; - const firstList = { - kind: "rich" as const, - key: "list-1", - node: { type: "list", children: [] } satisfies MarkdownNode, - }; - const secondList = { - kind: "rich" as const, - key: "list-2", - node: { type: "list", children: [] } satisfies MarkdownNode, - }; - - expect(nativeMarkdownChunkSpacing(undefined, headingChunk)).toBe(0); - expect(nativeMarkdownChunkSpacing(headingChunk, firstList)).toBe(10); - expect(nativeMarkdownChunkSpacing(firstList, secondList)).toBe(12); - expect(nativeMarkdownChunkSpacing(firstList, headingChunk)).toBe(20); - }); -}); - -describe("composerChipSizeSuffix", () => { - it("labels attachment records with a human size, matching web's chip", async () => { - const { composerChipSizeSuffix } = await import("@t3tools/mobile-markdown-text/markdown"); - expect(composerChipSizeSuffix({ kind: "file", sizeBytes: 1024 })).toBe("1 KB"); - expect(composerChipSizeSuffix({ kind: "file", sizeBytes: 3_700_000 })).toBe("3.5 MB"); - expect(composerChipSizeSuffix({ kind: "image", sizeBytes: 2048 })).toBe("2 KB"); - }); - - it("adds nothing for records that carry no bytes", async () => { - const { composerChipSizeSuffix } = await import("@t3tools/mobile-markdown-text/markdown"); - // Terminal/review/PR chips have no size to show. - expect(composerChipSizeSuffix({ kind: "terminal" })).toBe(""); - expect(composerChipSizeSuffix({ kind: "file" })).toBe(""); - expect(composerChipSizeSuffix(undefined)).toBe(""); - }); -}); - -describe("contextChipPresentation image detection", () => { - it("treats a picture attached through the file picker as an image", async () => { - const { contextChipPresentation } = await import("@t3tools/mobile-markdown-text/markdown"); - // The document picker types every pick as `file`, so the name has to carry the intent. - expect( - contextChipPresentation("file", { kind: "file", name: "IMG_4997.PNG", mimeType: "" }), - ).toEqual({ accent: "#d55665", symbol: "photo" }); - expect( - contextChipPresentation("file", { - kind: "file", - name: "shot", - mimeType: "image/jpeg", - }), - ).toEqual({ accent: "#d55665", symbol: "photo" }); - }); - - it("leaves genuine documents and videos alone", async () => { - const { contextChipPresentation } = await import("@t3tools/mobile-markdown-text/markdown"); - expect( - contextChipPresentation("file", { kind: "file", name: "notes.txt", mimeType: "text/plain" }), - ).toEqual({ accent: "#0090cd", symbol: "doc" }); - expect( - contextChipPresentation("file", { kind: "file", name: "clip.mp4", mimeType: "video/mp4" }), - ).toEqual({ accent: "#d06217", symbol: "play.rectangle" }); - }); -}); - -describe("pull request chip status", () => { - const chip = async (state: string, isDraft = false) => { - const { contextChipPresentation } = await import("@t3tools/mobile-markdown-text/markdown"); - return contextChipPresentation("review-comment", { - kind: "review-comment", - sectionId: "pull-request:10978", - pullRequest: { state, isDraft }, - }); - }; - - it("colours a pull request by its state, the way web and the forge do", async () => { - expect((await chip("open")).accent).toBe("#009f6e"); - expect((await chip("open", true)).accent).toBe("#7f8793"); - expect((await chip("merged")).accent).toBe("#8a70dd"); - expect((await chip("closed")).accent).toBe("#d55665"); - }); - - it("keeps one glyph across every state, so only colour carries the status", async () => { - // Web draws a fixed `git-pull-request` and encodes state in colour alone. A per-state glyph - // here would put mobile out of step with it. - const symbols = await Promise.all( - [chip("open"), chip("open", true), chip("merged"), chip("closed")].map( - async (pending) => (await pending).symbol, - ), - ); - expect(new Set(symbols)).toEqual(new Set(["git-pull-request"])); - }); - - it("falls back to the generic pull request chip when the state is unknown", async () => { - const { contextChipPresentation } = await import("@t3tools/mobile-markdown-text/markdown"); - // An older server may send no metadata at all; the chip still has to render. - expect( - contextChipPresentation("review-comment", { - kind: "review-comment", - sectionId: "pull-request:1", - }).accent, - ).toBe("#7079e4"); - }); -}); diff --git a/apps/mobile/src/native/EnrichedMarkdownText.tsx b/apps/mobile/src/native/EnrichedMarkdownText.tsx new file mode 100644 index 000000000000..9b46d65222e1 --- /dev/null +++ b/apps/mobile/src/native/EnrichedMarkdownText.tsx @@ -0,0 +1,152 @@ +import { useMemo } from "react"; +import { Platform, View } from "react-native"; +import { EnrichedMarkdownText, type MarkdownStyle } from "react-native-enriched-markdown"; +import type { SelectableMarkdownTextProps } from "@t3tools/mobile-markdown-text/types"; + +import { useAppearancePreferences } from "../features/settings/appearance/AppearancePreferencesProvider"; + +function enrichedStyle( + style: SelectableMarkdownTextProps["textStyle"], + dark: boolean, +): MarkdownStyle { + const monospace = Platform.OS === "ios" ? "Menlo" : "monospace"; + const body = { + color: style.color, + fontFamily: style.fontFamily, + fontSize: style.fontSize, + lineHeight: style.lineHeight, + marginTop: 0, + marginBottom: 8, + }; + const heading = (level: number) => { + const fontSize = style.headingFontSizes?.[level - 1] ?? style.fontSize * (1.6 - level * 0.1); + return { + ...body, + color: style.strongColor, + fontFamily: style.headingFontFamily, + fontSize, + lineHeight: fontSize * 1.35, + marginTop: 8, + }; + }; + return { + paragraph: body, + h1: heading(1), + h2: heading(2), + h3: heading(3), + h4: heading(4), + h5: heading(5), + h6: heading(6), + strong: { color: style.strongColor, fontFamily: style.boldFontFamily, fontWeight: "normal" }, + link: { color: style.linkColor, underline: false }, + code: { + fontFamily: monospace, + color: style.inlineCodeColor, + backgroundColor: style.codeBackgroundColor, + borderColor: "transparent", + fontSize: style.fontSize * 0.9, + }, + codeBlock: { + ...body, + color: style.codeColor, + backgroundColor: style.codeBlockBackgroundColor, + fontFamily: monospace, + fontSize: style.fontSize * 0.9, + borderRadius: 8, + padding: 12, + borderWidth: 1, + borderColor: style.dividerColor, + syntaxColors: dark + ? { + keyword: "#ff7b72", + string: "#a5d6ff", + number: "#79c0ff", + constant: "#79c0ff", + comment: "#8b949e", + function: "#d2a8ff", + type: "#ffa657", + property: "#79c0ff", + tag: "#7ee787", + attribute: "#79c0ff", + } + : { + keyword: "#cf222e", + string: "#0a3069", + number: "#0550ae", + constant: "#0550ae", + comment: "#6e7781", + function: "#8250df", + type: "#953800", + property: "#0550ae", + tag: "#116329", + attribute: "#0550ae", + }, + }, + blockquote: { + ...body, + color: style.mutedColor, + borderColor: style.quoteMarkerColor, + borderWidth: 2, + gapWidth: 12, + }, + list: { ...body, bulletColor: style.mutedColor, markerColor: style.mutedColor, gapWidth: 6 }, + thematicBreak: { color: style.dividerColor, height: 1, marginTop: 8, marginBottom: 8 }, + table: { + ...body, + borderColor: style.dividerColor, + borderWidth: 1, + headerFontFamily: style.boldFontFamily, + headerTextColor: style.strongColor, + headerBackgroundColor: style.codeBackgroundColor, + rowEvenBackgroundColor: "transparent", + rowOddBackgroundColor: "transparent", + cellPaddingHorizontal: 12, + cellPaddingVertical: 8, + }, + taskList: { + checkedColor: style.linkColor, + checkedTextColor: style.color, + borderColor: style.mutedColor, + checkedStrikethrough: false, + }, + }; +} + +// The Enriched-only spike leaves attachment renderers and chip decorations to +// future app integrations; every Markdown block goes through this native view. +export function MobileEnrichedMarkdownText(props: SelectableMarkdownTextProps) { + const { themeAppearance } = useAppearancePreferences(); + const markdownStyle = useMemo( + () => enrichedStyle(props.textStyle, themeAppearance === "dark"), + [props.textStyle, themeAppearance], + ); + + return ( + + props.onLinkPress?.(url) : undefined} + /> + + ); +} diff --git a/apps/mobile/src/native/SelectableMarkdownText.android.tsx b/apps/mobile/src/native/SelectableMarkdownText.android.tsx deleted file mode 100644 index 17788da414ed..000000000000 --- a/apps/mobile/src/native/SelectableMarkdownText.android.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { - SelectableMarkdownText as T3SelectableMarkdownText, - type SelectableMarkdownTextProps, -} from "@t3tools/mobile-markdown-text/renderer"; -import { useMemo } from "react"; - -import { highlightCodeSnippet } from "../features/review/shikiReviewHighlighter"; -import { themeColorWithAlpha } from "../lib/mobileTheme"; -import { useUniwindTheme } from "../lib/useUniwindTheme"; - -type MobileSelectableMarkdownTextProps = Omit; - -export type { - MarkdownImageRequest, - NativeMarkdownTextStyle, - SelectableMarkdownSkill, -} from "@t3tools/mobile-markdown-text/types"; - -// The renderer falls back to React Native Text outside iOS, so Android can use -// the same Markdown chunking while retaining native text selection. -export function hasNativeSelectableMarkdownText(): boolean { - return true; -} - -export function SelectableMarkdownText(props: MobileSelectableMarkdownTextProps) { - const theme = useUniwindTheme(); - const selectionColor = themeColorWithAlpha(theme["--color-focus"], 0.32); - const selectionHandleColor = theme["--color-focus"]; - const textStyle = useMemo( - () => ({ selectionColor, selectionHandleColor, ...props.textStyle }), - [props.textStyle, selectionColor, selectionHandleColor], - ); - return ( - - ); -} diff --git a/apps/mobile/src/native/SelectableMarkdownText.ios.tsx b/apps/mobile/src/native/SelectableMarkdownText.ios.tsx deleted file mode 100644 index 55c2f818b3d7..000000000000 --- a/apps/mobile/src/native/SelectableMarkdownText.ios.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { - SelectableMarkdownText as T3SelectableMarkdownText, - type SelectableMarkdownTextProps, -} from "@t3tools/mobile-markdown-text/renderer"; - -import { highlightCodeSnippet } from "../features/review/shikiReviewHighlighter"; - -type MobileSelectableMarkdownTextProps = Omit; - -export type { - MarkdownFileContextMenu, - MarkdownFileContextMenuAction, - MarkdownImageRenderer, - MarkdownImageRequest, - NativeMarkdownTextStyle, - SelectableMarkdownSkill, -} from "@t3tools/mobile-markdown-text/types"; - -export function hasNativeSelectableMarkdownText(): boolean { - return true; -} - -export function SelectableMarkdownText(props: MobileSelectableMarkdownTextProps) { - return ; -} diff --git a/apps/mobile/src/native/SelectableMarkdownText.tsx b/apps/mobile/src/native/SelectableMarkdownText.tsx index 8b54df001aef..73e629ad1fd1 100644 --- a/apps/mobile/src/native/SelectableMarkdownText.tsx +++ b/apps/mobile/src/native/SelectableMarkdownText.tsx @@ -1,6 +1,10 @@ -import type { SelectableMarkdownTextProps } from "@t3tools/mobile-markdown-text/renderer"; +import { useMemo } from "react"; +import { Platform } from "react-native"; +import type { SelectableMarkdownTextProps } from "@t3tools/mobile-markdown-text/types"; -type MobileSelectableMarkdownTextProps = Omit; +import { MobileEnrichedMarkdownText } from "./EnrichedMarkdownText"; +import { themeColorWithAlpha } from "../lib/mobileTheme"; +import { useUniwindTheme } from "../lib/useUniwindTheme"; export type { MarkdownFileContextMenu, @@ -11,10 +15,16 @@ export type { SelectableMarkdownSkill, } from "@t3tools/mobile-markdown-text/types"; -export function hasNativeSelectableMarkdownText(): boolean { - return false; -} - -export function SelectableMarkdownText(_props: MobileSelectableMarkdownTextProps) { - return null; +export function SelectableMarkdownText(props: SelectableMarkdownTextProps) { + const theme = useUniwindTheme(); + const selectionColor = themeColorWithAlpha(theme["--color-focus"], 0.32); + const selectionHandleColor = theme["--color-focus"]; + const textStyle = useMemo( + () => + Platform.OS === "android" + ? { selectionColor, selectionHandleColor, ...props.textStyle } + : props.textStyle, + [props.textStyle, selectionColor, selectionHandleColor], + ); + return ; } diff --git a/package.json b/package.json index ab88fbeb4d6e..d0c1900c7177 100644 --- a/package.json +++ b/package.json @@ -59,5 +59,8 @@ "engines": { "node": "^24.13.1" }, - "packageManager": "pnpm@11.10.0" + "packageManager": "pnpm@11.10.0", + "enriched-markdown": { + "enableMath": false + } } diff --git a/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch b/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch new file mode 100644 index 000000000000..4a28c34870c8 --- /dev/null +++ b/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch @@ -0,0 +1,112 @@ +diff --git a/cpp/md4c/md4c.h b/cpp/md4c/md4c.h +index cf965d8cc17cb2724c8d194f5cbd5784298f1e5c..d42080a9262b13a808b50c29794802c473fe1911 100644 +--- a/cpp/md4c/md4c.h ++++ b/cpp/md4c/md4c.h +@@ -26,6 +26,9 @@ + #ifndef MD4C_H + #define MD4C_H + ++/* Isolate the embedded parser from other libraries linking their own MD4C. */ ++#define md_parse enrm_md_parse ++ + #ifdef __cplusplus + extern "C" { + #endif +diff --git a/ios/input/ENRMInputParser.mm b/ios/input/ENRMInputParser.mm +index f82e72b3b838e40d886cf1eb5037b0a406730afe..ca3ae2df35e0e6bbdf2bc57cee0db2a89fbefff9 100644 +--- a/ios/input/ENRMInputParser.mm ++++ b/ios/input/ENRMInputParser.mm +@@ -1,7 +1,7 @@ + #import "ENRMInputParser.h" + #import "ENRMFormattingRange.h" + #import "ENRMInputRemend.h" +-#include "md4c.h" ++#include "../../cpp/md4c/md4c.h" + #include + #include + #include +diff --git a/ios/parser/MarkdownParserBridge.mm b/ios/parser/MarkdownParserBridge.mm +index e700fcee063a5def59cf0a966f69221d627e24fe..9ad621a13b79951fc9f206bf5f2d33544dafc89c 100644 +--- a/ios/parser/MarkdownParserBridge.mm ++++ b/ios/parser/MarkdownParserBridge.mm +@@ -1,5 +1,6 @@ + #import "ENRMMarkdownParser.h" +-#include "MD4CParser.hpp" ++// Resolve our core explicitly; CocoaPods header maps can contain other MD4C parsers. ++#include "../../cpp/parser/MD4CParser.hpp" + #import "MarkdownASTNode.h" + #include "MarkdownASTNode.hpp" + #import +diff --git a/ios/renderer/BaselineShiftTextAttributes.h b/ios/renderer/BaselineShiftTextAttributes.h +index e862a564c4af827fa4ec85ee09a3657e7496d568..b56208c4311e57b3ec7fb1e7a4eda2fe196906cb 100644 +--- a/ios/renderer/BaselineShiftTextAttributes.h ++++ b/ios/renderer/BaselineShiftTextAttributes.h +@@ -2,5 +2,7 @@ + #import "ENRMUIKit.h" + #import + ++extern NSString *const ENRMScriptAttributeName; ++ + void ENRMApplyBaselineShift(NSMutableAttributedString *output, NSRange range, CGFloat fontScale, + CGFloat baselineOffsetScale); +diff --git a/ios/renderer/BaselineShiftTextAttributes.m b/ios/renderer/BaselineShiftTextAttributes.m +index da1d4b40332e83a1f88935632eb835be8876702b..c9d44b48fbd544c963bd7168d4e627a8755063d7 100644 +--- a/ios/renderer/BaselineShiftTextAttributes.m ++++ b/ios/renderer/BaselineShiftTextAttributes.m +@@ -1,5 +1,7 @@ + #import "BaselineShiftTextAttributes.h" + ++NSString *const ENRMScriptAttributeName = @"ENRMScript"; ++ + void ENRMApplyBaselineShift(NSMutableAttributedString *output, NSRange range, CGFloat fontScale, + CGFloat baselineOffsetScale) + { +diff --git a/ios/renderer/SubscriptRenderer.m b/ios/renderer/SubscriptRenderer.m +index f697216589db39e72cef5ed5f3f85ad2d5e009a1..d88f5e15ed79440ace831efe531f47e00d0cbfb2 100644 +--- a/ios/renderer/SubscriptRenderer.m ++++ b/ios/renderer/SubscriptRenderer.m +@@ -18,6 +18,7 @@ + if (range.length == 0) + return; + ++ [output addAttribute:ENRMScriptAttributeName value:@"subscript" range:range]; + ENRMApplyBaselineShift(output, range, _config.subscriptFontScale, -_config.subscriptBaselineOffsetScale); + } + +diff --git a/ios/renderer/SuperscriptRenderer.m b/ios/renderer/SuperscriptRenderer.m +index edba7364733ea7bb312176893387b7906c34353c..308b8de0ecfec3ce5a0b5961bbeafc3bf2f99b56 100644 +--- a/ios/renderer/SuperscriptRenderer.m ++++ b/ios/renderer/SuperscriptRenderer.m +@@ -18,6 +18,7 @@ + if (range.length == 0) + return; + ++ [output addAttribute:ENRMScriptAttributeName value:@"superscript" range:range]; + ENRMApplyBaselineShift(output, range, _config.superscriptFontScale, _config.superscriptBaselineOffsetScale); + } + +diff --git a/ios/utils/MarkdownExtractor.m b/ios/utils/MarkdownExtractor.m +index eb4482c6cdf842dfbd952b8c6cdb9ce836579b53..c6dcd1f6e0807f3561830ff3fa88fde8b204d7a8 100644 +--- a/ios/utils/MarkdownExtractor.m ++++ b/ios/utils/MarkdownExtractor.m +@@ -1,4 +1,5 @@ + #import "MarkdownExtractor.h" ++#import "BaselineShiftTextAttributes.h" + #import "BlockquoteBorder.h" + #import "ENRMFeatureFlags.h" + #import "ENRMImageAttachment.h" +@@ -300,9 +301,11 @@ NSString *_Nullable extractMarkdownFromAttributedString(NSAttributedString *attr + BOOL isStrikethrough = (strikethroughStyle != nil && [strikethroughStyle integerValue] != 0); + NSNumber *underlineStyle = attrs[NSUnderlineStyleAttributeName]; + BOOL isUnderline = (underlineStyle != nil && [underlineStyle integerValue] != 0); +- NSNumber *baselineOffset = attrs[NSBaselineOffsetAttributeName]; +- BOOL isSuperscript = baselineOffset != nil && [baselineOffset doubleValue] > 0; +- BOOL isSubscript = baselineOffset != nil && [baselineOffset doubleValue] < 0; ++ // Line-height alignment also shifts baselines. Only semantic script spans ++ // should produce superscript/subscript Markdown on the clipboard. ++ NSString *script = attrs[ENRMScriptAttributeName]; ++ BOOL isSuperscript = [script isEqualToString:@"superscript"]; ++ BOOL isSubscript = [script isEqualToString:@"subscript"]; + + BOOL isHighlight = [attrs[HighlightAttributeName] boolValue]; + NSString *linkURL = attrs[NSLinkAttributeName]; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a0daed3ff962..6e7e0a72ddf1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,6 +106,7 @@ patchedDependencies: expo-notifications@57.0.15: f89252c2c08dc7b3acb8415f319ebbe15fff8c9f88a64ebe1830cd5ac5c9ac40 expo-sharing@57.0.17: 8d2e3b10eb3f52036a9a086800180ec6cebf3b75bccc5b1775117a7244d4ac45 expo-widgets@57.0.15: 319a9ded5db49c5b5215c511a138b33f44c7ea2972eb418192e8d5342fe75ce6 + react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a: 23cd65b5b41858ca4373112cf3861fddff058ffe04e68f92d56940d895bb1490 react-native-gesture-handler@2.32.0: 0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2 react-native-keyboard-controller@1.21.13: 6e4339347bc5bb3c9ea67d85ff5c814058b211c5750f247aba59d07869a2e787 react-native-nitro-modules@0.35.9: 825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675 @@ -298,7 +299,7 @@ importers: version: link:../../packages/contracts '@t3tools/mobile-markdown-text': specifier: file:./modules/t3-markdown-text - version: file:apps/mobile/modules/t3-markdown-text(6f0a94b6f541bbd4be3f343e27991996) + version: file:apps/mobile/modules/t3-markdown-text(fd2defbaa44d0c14a2784c8bacd94382) '@t3tools/mobile-review-diff-native': specifier: file:./modules/t3-review-diff version: file:apps/mobile/modules/t3-review-diff @@ -434,6 +435,9 @@ importers: react-native: specifier: 0.86.3 version: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react-native-enriched-markdown: + specifier: 1.1.0-nightly-20260918-bb2b0942a + version: 1.1.0-nightly-20260918-bb2b0942a(patch_hash=23cd65b5b41858ca4373112cf3861fddff058ffe04e68f92d56940d895bb1490)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) react-native-gesture-handler: specifier: ~2.32.0 version: 2.32.0(patch_hash=0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) @@ -443,9 +447,6 @@ importers: react-native-keyboard-controller: specifier: 1.21.13 version: 1.21.13(patch_hash=6e4339347bc5bb3c9ea67d85ff5c814058b211c5750f247aba59d07869a2e787)(react-native-reanimated@4.5.5(patch_hash=bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - react-native-nitro-markdown: - specifier: ^0.5.0 - version: 0.5.8(react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) react-native-nitro-modules: specifier: 0.35.9 version: 0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) @@ -4709,7 +4710,6 @@ packages: expo-symbols: '*' react: '*' react-native: '*' - react-native-nitro-markdown: '*' '@t3tools/mobile-review-diff-native@file:apps/mobile/modules/t3-review-diff': resolution: {directory: apps/mobile/modules/t3-review-diff, type: directory} @@ -9322,6 +9322,16 @@ packages: '@types/react': '>=18' react: '>=18' + react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a: + resolution: {integrity: sha512-nrxwKa+OJlnf/fKbJzlGy+NZJ5N1D88aiy4eiHBxIqoc67i6DEYOE7rnSRkAPysq8mmnL+nagM2uJLwv4F7e/A==} + peerDependencies: + katex: '>=0.16.0' + react: '*' + react-native: '*' + peerDependenciesMeta: + katex: + optional: true + react-native-gesture-handler@2.32.0: resolution: {integrity: sha512-uYIMOKlKENORq2SABE+jIjbPU+h5I/sQKcq2v16zRq848nwEp1fWRVwML4QWqijc8UcXJC25o54S8GQd4Mf2OA==} peerDependencies: @@ -9347,20 +9357,6 @@ packages: react-native: '*' react-native-reanimated: '>=3.0.0' - react-native-nitro-markdown@0.5.8: - resolution: {integrity: sha512-bBKmdWgMqZoNozuHzJgc8VxWRSjLnrHAK0bRRvz7gj5FqPxLJz+KhRV0VYZDZgvsR3S8hnmmeEqluTRBTRw+yA==} - peerDependencies: - react: '*' - react-native: '>=0.75.0' - react-native-mathjax-svg: '>=0.9.0' - react-native-nitro-modules: '>=0.35.5' - react-native-svg: '>=13.0.0' - peerDependenciesMeta: - react-native-mathjax-svg: - optional: true - react-native-svg: - optional: true - react-native-nitro-modules@0.35.9: resolution: {integrity: sha512-yCO6eJ85SPPUo4a4an7H5oj6wPCSIT72fbjr5WZ/20n6zswaJ2gNNpnWtg2We0AZwkAOjSqkOJ0Vjc05p6kGiA==} peerDependencies: @@ -14804,7 +14800,7 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@t3tools/mobile-markdown-text@file:apps/mobile/modules/t3-markdown-text(6f0a94b6f541bbd4be3f343e27991996)': + '@t3tools/mobile-markdown-text@file:apps/mobile/modules/t3-markdown-text(fd2defbaa44d0c14a2784c8bacd94382)': dependencies: '@t3tools/client-runtime': link:packages/client-runtime '@t3tools/shared': link:packages/shared @@ -14815,7 +14811,6 @@ snapshots: expo-symbols: 57.0.2(expo-font@57.0.2(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(expo@57.0.18)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) react: 19.2.3 react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - react-native-nitro-markdown: 0.5.8(react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) '@t3tools/mobile-review-diff-native@file:apps/mobile/modules/t3-review-diff': {} @@ -20320,6 +20315,11 @@ snapshots: transitivePeerDependencies: - supports-color + react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a(patch_hash=23cd65b5b41858ca4373112cf3861fddff058ffe04e68f92d56940d895bb1490)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + dependencies: + react: 19.2.3 + react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) + react-native-gesture-handler@2.32.0(patch_hash=0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): dependencies: '@egjs/hammerjs': 2.0.17 @@ -20346,14 +20346,6 @@ snapshots: react-native-is-edge-to-edge: 1.3.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) react-native-reanimated: 4.5.5(patch_hash=bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - react-native-nitro-markdown@0.5.8(react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native-svg@15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): - dependencies: - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - react-native-nitro-modules: 0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - optionalDependencies: - react-native-svg: 15.15.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): dependencies: react: 19.2.3 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 7c7106bd7637..f183db16a6ae 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -18,6 +18,7 @@ allowBuilds: msw: false node-pty: true sharp: true + react-native-enriched-markdown: true utf-8-validate: false workerd: false @@ -192,6 +193,7 @@ patchedDependencies: expo-notifications@57.0.15: patches/expo-notifications@57.0.15.patch expo-sharing@57.0.17: patches/expo-sharing@57.0.17.patch expo-widgets@57.0.15: patches/expo-widgets@57.0.15.patch + react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a: patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch react-native-gesture-handler@2.32.0: patches/react-native-gesture-handler@2.32.0.patch react-native-keyboard-controller@1.21.13: patches/react-native-keyboard-controller@1.21.13.patch react-native-nitro-modules@0.35.9: patches/react-native-nitro-modules@0.35.9.patch diff --git a/vite.config.ts b/vite.config.ts index 4e6530160a25..e837606110c7 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -208,7 +208,7 @@ export default defineConfig({ "apps/mobile/src/lib/useMobileNavigationTheme.ts", "apps/mobile/src/native/T3ComposerEditor.ios.tsx", "apps/mobile/src/native/T3ComposerEditor.native.tsx", - "apps/mobile/src/native/SelectableMarkdownText.android.tsx", + "apps/mobile/src/native/SelectableMarkdownText.tsx", ], rules: { "t3code/no-mobile-uniwind-theme-escape-hatches": ["error", { allowUniwindTheme: true }], From 039c21438975125077dea728bb618f81445a6e92 Mon Sep 17 00:00:00 2001 From: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com> Date: Sun, 20 Sep 2026 16:01:28 -0700 Subject: [PATCH 02/11] feat(mobile): integrate Enriched pills and media APIs --- .../t3-markdown-text/src/CopyTextButton.tsx | 73 - .../src/SelectableMarkdownText.types.ts | 19 +- apps/mobile/package.json | 1 - .../features/files/FileMarkdownPreview.tsx | 119 +- .../src/features/threads/ThreadFeed.tsx | 141 +- .../features/threads/ThreadMarkdownImage.tsx | 94 +- .../features/threads/ThreadMarkdownVideo.tsx | 45 + .../threads/markdownImageSize.test.ts | 18 + .../src/features/threads/markdownImageSize.ts | 28 + .../src/lib/enrichedLinkPresentation.test.ts | 98 + .../src/lib/enrichedLinkPresentation.ts | 58 + .../src/lib/markdownMediaSource.test.ts | 41 + apps/mobile/src/lib/markdownMediaSource.ts | 22 + .../src/native/EnrichedMarkdownText.tsx | 188 +- .../src/native/SelectableMarkdownText.tsx | 2 + .../src/native/useEnrichedLinkVariants.ts | 154 + .../src/native/useMarkdownImageSource.ts | 52 + apps/mobile/src/state/assets.ts | 6 +- ...own@1.1.0-nightly-20260918-bb2b0942a.patch | 9653 ++++++++++++++++- .../react-native-nitro-modules@0.35.9.patch | 16 - pnpm-lock.yaml | 21 +- pnpm-workspace.yaml | 1 - scripts/release-smoke.ts | 1 - third-party-licenses.config.json | 7 - 24 files changed, 10609 insertions(+), 249 deletions(-) delete mode 100644 apps/mobile/modules/t3-markdown-text/src/CopyTextButton.tsx create mode 100644 apps/mobile/src/features/threads/ThreadMarkdownVideo.tsx create mode 100644 apps/mobile/src/lib/enrichedLinkPresentation.test.ts create mode 100644 apps/mobile/src/lib/enrichedLinkPresentation.ts create mode 100644 apps/mobile/src/lib/markdownMediaSource.test.ts create mode 100644 apps/mobile/src/lib/markdownMediaSource.ts create mode 100644 apps/mobile/src/native/useEnrichedLinkVariants.ts create mode 100644 apps/mobile/src/native/useMarkdownImageSource.ts delete mode 100644 patches/react-native-nitro-modules@0.35.9.patch diff --git a/apps/mobile/modules/t3-markdown-text/src/CopyTextButton.tsx b/apps/mobile/modules/t3-markdown-text/src/CopyTextButton.tsx deleted file mode 100644 index ffbc0e2fcb63..000000000000 --- a/apps/mobile/modules/t3-markdown-text/src/CopyTextButton.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { SymbolView } from "expo-symbols"; -import * as Clipboard from "expo-clipboard"; -import * as Haptics from "expo-haptics"; -import { memo, useEffect, useRef, useState } from "react"; -import { Pressable, type ColorValue } from "react-native"; - -const COPY_FEEDBACK_DURATION_MS = 1200; - -function copyTextWithHaptic(value: string): void { - void Clipboard.setStringAsync(value); - void Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); -} - -export const CopyTextButton = memo(function CopyTextButton(props: { - readonly accessibilityLabel: string; - readonly text: string; - readonly tintColor: ColorValue; - readonly copiedTintColor?: ColorValue; - readonly backgroundColor?: ColorValue; - readonly borderColor?: ColorValue; - readonly iconSize?: number; - readonly buttonSize?: number; -}) { - const [copied, setCopied] = useState(false); - const resetTimeoutRef = useRef | null>(null); - - useEffect( - () => () => { - if (resetTimeoutRef.current) { - clearTimeout(resetTimeoutRef.current); - } - }, - [], - ); - - return ( - { - copyTextWithHaptic(props.text); - setCopied(true); - if (resetTimeoutRef.current) { - clearTimeout(resetTimeoutRef.current); - } - resetTimeoutRef.current = setTimeout(() => { - setCopied(false); - resetTimeoutRef.current = null; - }, COPY_FEEDBACK_DURATION_MS); - }} - style={({ pressed }) => ({ - width: props.buttonSize ?? 30, - height: props.buttonSize ?? 30, - alignItems: "center", - justifyContent: "center", - borderRadius: 9, - borderWidth: props.borderColor ? 1 : 0, - borderColor: props.borderColor, - backgroundColor: props.backgroundColor, - opacity: pressed ? 0.52 : 1, - })} - > - - - ); -}); diff --git a/apps/mobile/modules/t3-markdown-text/src/SelectableMarkdownText.types.ts b/apps/mobile/modules/t3-markdown-text/src/SelectableMarkdownText.types.ts index 19839882d491..47edecc2046d 100644 --- a/apps/mobile/modules/t3-markdown-text/src/SelectableMarkdownText.types.ts +++ b/apps/mobile/modules/t3-markdown-text/src/SelectableMarkdownText.types.ts @@ -37,10 +37,17 @@ export interface MarkdownImageRequest { * App-supplied renderer for markdown images. The module cannot load * workspace-relative image paths itself — the host app resolves them (for * example through a signed asset URL) and returns the element to show. - * Returning null falls back to the module's plain remote-URI rendering. + * Returning null keeps Enriched's native media rendering. */ export type MarkdownImageRenderer = (image: MarkdownImageRequest) => import("react").ReactNode; +export type MarkdownImageSourceResolver = ( + image: MarkdownImageRequest, +) => + | { uri: string; headers?: Record } + | null + | Promise<{ uri: string; headers?: Record } | null>; + export interface MarkdownFileContextMenuAction { readonly id: string; readonly title: string; @@ -52,6 +59,13 @@ export interface MarkdownFileContextMenu { readonly actions: ReadonlyArray; } +export interface MarkdownLinkCustomization { + readonly iconTintColor?: string; + readonly color?: string; + readonly label?: string; + readonly icon?: import("react-native").ImageSourcePropType; +} + export interface SelectableMarkdownTextProps { readonly markdown: string; readonly textStyle: NativeMarkdownTextStyle; @@ -60,7 +74,10 @@ export interface SelectableMarkdownTextProps { readonly onLinkPress?: (href: string) => void; readonly fileContextMenu?: (href: string) => MarkdownFileContextMenu | undefined; readonly onFileContextMenuAction?: (href: string, actionId: string) => void; + readonly linkCustomization?: (href: string) => MarkdownLinkCustomization | undefined; readonly renderImage?: MarkdownImageRenderer; + readonly resolveImageSource?: MarkdownImageSourceResolver; + readonly onImagePress?: (href: string) => void; readonly marginTop?: number; readonly marginBottom?: number; } diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 8ca84f850ca8..521e31483a3f 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -116,7 +116,6 @@ "react-native-gesture-handler": "~2.32.0", "react-native-image-viewing": "^0.2.2", "react-native-keyboard-controller": "1.21.13", - "react-native-nitro-modules": "0.35.9", "react-native-reanimated": "4.5.5", "react-native-safe-area-context": "~5.7.0", "react-native-screens": "~4.26.0", diff --git a/apps/mobile/src/features/files/FileMarkdownPreview.tsx b/apps/mobile/src/features/files/FileMarkdownPreview.tsx index 867d465b7ae2..573fa8104e63 100644 --- a/apps/mobile/src/features/files/FileMarkdownPreview.tsx +++ b/apps/mobile/src/features/files/FileMarkdownPreview.tsx @@ -1,5 +1,5 @@ import type { EnvironmentId, ThreadId } from "@t3tools/contracts"; -import { resolveMediaSource } from "@t3tools/client-runtime/media-source"; +import { resolveMobileMarkdownMediaSource } from "../../lib/markdownMediaSource"; import { getBrowseDirectoryPath } from "@t3tools/client-runtime/state/projects"; import { useCallback, useMemo, useState } from "react"; import { RefreshControl, ScrollView, View } from "react-native"; @@ -10,8 +10,14 @@ import { resolveNativeMarkdownTypography } from "../../lib/appearancePreferences import { useUniwindTheme } from "../../lib/useUniwindTheme"; import { ThreadMarkdownImage, + ThreadMarkdownImageView, ThreadMarkdownImageUnavailable, } from "../threads/ThreadMarkdownImage"; +import { ThreadMarkdownVideo } from "../threads/ThreadMarkdownVideo"; +import { resolveMarkdownMediaPreview } from "../../lib/markdownMedia"; +import { normalizeNativeMarkdownUrl } from "@t3tools/mobile-markdown-text/links"; +import { FilePreviewModal, type FilePreviewSource } from "../../components/FilePreviewModal"; +import { useMarkdownImageSource } from "../../native/useMarkdownImageSource"; import { useAppearancePreferences } from "../settings/appearance/AppearancePreferencesProvider"; import { SelectableMarkdownText, @@ -89,6 +95,7 @@ export function FileMarkdownPreview(props: { readonly onRefresh?: () => Promise | void; }) { const [isPullRefreshing, setIsPullRefreshing] = useState(false); + const [expandedFile, setExpandedFile] = useState(null); const handlePullToRefresh = useCallback(async () => { if (!props.onRefresh) { return; @@ -106,35 +113,124 @@ export function FileMarkdownPreview(props: { ); const renderImage = useCallback( (image) => { - const media = resolveMediaSource(image.href, { + const media = resolveMobileMarkdownMediaSource(image.href, { threadId: props.threadId ?? undefined, workspaceRoot: markdownDirectory, imageEmbed: true, }); if (media?.access === "direct") { - return null; + if (media.kind === "video") { + return ( + + ); + } + return ( + + ); } - if ( - props.captured || - media === null || - media.kind !== "image" || - media.access === "unavailable" - ) { + if (props.captured || media === null || media.access === "unavailable") { return ; } + if (media.kind === "video") { + if (!props.threadId) { + return ( + + ); + } + const preview = props.threadId + ? resolveMarkdownMediaPreview(image.href, { + environmentId: props.environmentId, + threadId: props.threadId, + workspaceRoot: markdownDirectory, + }) + : null; + return preview?.kind === "video" ? ( + + ) : ( + + ); + } return ( undefined} + onPressPreview={setExpandedFile} /> ); }, [markdownDirectory, props.environmentId, props.threadId, props.captured], ); const styles = useMarkdownPreviewStyles(); + const resolveImageSource = useMarkdownImageSource({ + environmentId: props.environmentId, + threadId: props.threadId, + workspaceRoot: markdownDirectory, + captured: props.captured, + }); + const onImagePress = useCallback( + (href: string) => { + if (props.captured) return; + const direct = resolveMobileMarkdownMediaSource(href, { + threadId: props.threadId ?? undefined, + workspaceRoot: markdownDirectory, + imageEmbed: true, + }); + if (direct?.access === "direct" && direct.kind === "image") { + setExpandedFile({ + kind: "image", + uri: normalizeNativeMarkdownUrl(direct.uri), + name: direct.name, + }); + return; + } + if (!props.threadId) { + if (direct?.access === "environment" && direct.kind === "image") { + setExpandedFile({ + kind: "image", + name: direct.name, + environmentId: props.environmentId, + resource: direct.resource, + srcFragment: direct.srcFragment, + }); + } + return; + } + const media = resolveMarkdownMediaPreview(href, { + environmentId: props.environmentId, + threadId: props.threadId, + workspaceRoot: markdownDirectory, + }); + if (media?.kind === "image") setExpandedFile(media.source); + }, + [markdownDirectory, props.environmentId, props.threadId, props.captured], + ); const onLinkPress = useCallback((href: string) => { void tryOpenExternalUrl(href, "markdown-link"); }, []); @@ -157,8 +253,11 @@ export function FileMarkdownPreview(props: { markdown={props.markdown} onLinkPress={onLinkPress} renderImage={renderImage} + resolveImageSource={resolveImageSource} + onImagePress={onImagePress} textStyle={styles.nativeTextStyle} /> + setExpandedFile(null)} /> ); diff --git a/apps/mobile/src/features/threads/ThreadFeed.tsx b/apps/mobile/src/features/threads/ThreadFeed.tsx index 97a29ba9ee7b..665432acc451 100644 --- a/apps/mobile/src/features/threads/ThreadFeed.tsx +++ b/apps/mobile/src/features/threads/ThreadFeed.tsx @@ -21,6 +21,7 @@ import { parseComposerContextHref, collectComposerContextReferences, replaceComposerContextReferences, + formatComposerContextReference, } from "@t3tools/shared/composerContextReferences"; import { ComposerContextSheet } from "../../components/ComposerContextSheet"; import { writeComposerContextClipboard } from "../../lib/composerContextClipboard"; @@ -47,7 +48,6 @@ import { SymbolView, type AppSymbolName } from "../../components/AppSymbol"; import { HeaderHeightContext } from "@react-navigation/elements"; import { useFocusEffect, useNavigation } from "@react-navigation/native"; import { - createContext, memo, useCallback, useContext, @@ -91,6 +91,8 @@ import { SelectableMarkdownText, type MarkdownFileContextMenu, type MarkdownImageRenderer, + type MarkdownLinkCustomization, + type MarkdownImageSourceResolver, type NativeMarkdownTextStyle, type SelectableMarkdownSkill, } from "../../native/SelectableMarkdownText"; @@ -98,14 +100,9 @@ import { import { AppText as Text } from "../../components/AppText"; import { VideoPreviewModal, type VideoPreviewSource } from "../../components/VideoPreviewModal"; import { VideoAttachmentTile } from "../../components/VideoAttachmentTile"; -import { MediaVideoPlayer } from "../../components/MediaVideoPlayer"; +import { ThreadMarkdownVideo, ThreadMediaVisibleContext } from "./ThreadMarkdownVideo"; import { resolveMarkdownMediaPreview } from "../../lib/markdownMedia"; -import { - attachmentVideoPreviewSource, - mediaVideoPreviewUri, - mediaVideoThumbnailKey, - type MediaVideoPreviewSource, -} from "../../lib/videoPreviewSource"; +import { attachmentVideoPreviewSource } from "../../lib/videoPreviewSource"; import { CopyTextButton } from "../../components/CopyTextButton"; import { parseReviewCommentMessageSegments } from "../review/reviewCommentSelection"; import { @@ -123,6 +120,9 @@ import { import { resolveNativeMarkdownTypography } from "../../lib/appearancePreferences"; import { useAppearancePreferences } from "../settings/appearance/AppearancePreferencesProvider"; import { PierreEntryIcon } from "../../components/PierreEntryIcon"; +import { markdownFileIconSource } from "@t3tools/mobile-markdown-text/file-icons"; +import { enrichedContextLinkPresentation } from "../../lib/enrichedLinkPresentation"; +import { useMarkdownImageSource } from "../../native/useMarkdownImageSource"; import { normalizeNativeMarkdownUrl, resolveMarkdownLinkPresentation, @@ -153,12 +153,7 @@ import { } from "./thread-work-log"; import { appendPendingThreadMessages, type PendingThreadFeedEntry } from "./pending-thread-feed"; import type { QueuedThreadMessage } from "../../state/thread-outbox-model"; -import { - assetEnvironment, - useAssetUrl, - useAssetUrlState, - useRefreshAssetUrl, -} from "../../state/assets"; +import { assetEnvironment, useAssetUrl, useRefreshAssetUrl } from "../../state/assets"; import { useAtomQueryRunner } from "../../state/use-atom-query-runner"; import { usePreparedConnection } from "../../state/session"; import { useThreadSelection } from "../../state/use-thread-selection"; @@ -537,7 +532,6 @@ function MessageAttachmentUnknown(props: { readonly name: string }) { ); } -const ThreadMediaVisibleContext = createContext(false); // LegendList only computes hook visibility when the list has a viewability config. const THREAD_MEDIA_VIEWABILITY_CONFIG = { itemVisiblePercentThreshold: 0 }; @@ -549,37 +543,6 @@ function ThreadMediaVisibility(props: { readonly children: ReactNode }) { return {props.children}; } -function ThreadMarkdownVideo(props: { readonly source: MediaVideoPreviewSource }) { - const { source } = props; - const visible = useContext(ThreadMediaVisibleContext); - const thumbnailKey = mediaVideoThumbnailKey(source); - const asset = useAssetUrlState( - "environmentId" in source ? source.environmentId : null, - "resource" in source ? source.resource : null, - ); - const refreshAssetUrl = useRefreshAssetUrl( - "environmentId" in source ? source.environmentId : null, - "resource" in source ? source.resource : null, - ); - const uri = mediaVideoPreviewUri(source, asset._tag === "Success" ? asset.url : null); - return ( - mediaVideoPreviewUri(source, await refreshAssetUrl()) - : undefined - } - name={source.name} - thumbnailKey={thumbnailKey} - thumbnailVisible={visible} - unavailable={"resource" in source && asset._tag === "Failure"} - actionsSource={source.actionsSource} - /> - ); -} - interface MarkdownStyleSets { readonly user: MarkdownStyleSet; readonly assistant: MarkdownStyleSet; @@ -651,9 +614,12 @@ function ArtifactTemplateCard(props: { /** Tap opens a link; long-press on a native file chip shows its menu. Built once per feed. */ interface MarkdownLinkHandlers { + readonly resolveImageSource?: MarkdownImageSourceResolver; + readonly onImagePress?: (href: string) => void; readonly onLinkPress: (href: string) => void; readonly fileContextMenu: (href: string) => MarkdownFileContextMenu | undefined; readonly onFileContextMenuAction: (href: string, actionId: string) => void; + readonly linkCustomization?: (href: string) => MarkdownLinkCustomization | undefined; } const AssistantMarkdownContent = memo(function AssistantMarkdownContent(props: { @@ -1266,7 +1232,55 @@ function UserMessageContent(props: UserMessageContentProps) { { + const reference = parseComposerContextHref(href); + if (!reference) return props.linkHandlers.fileContextMenu(href); + const record = props.context?.records.find( + (item) => item.contextId === reference.contextId, + ); + return { + title: record?.label ?? "Context unavailable", + actions: [ + { id: "open-context", title: "Open context" }, + { id: "copy-context", title: "Copy context", disabled: !record }, + ], + }; + }, + onFileContextMenuAction: (href, actionId) => { + const reference = parseComposerContextHref(href); + if (!reference) return props.linkHandlers.onFileContextMenuAction(href, actionId); + if (actionId === "open-context") return onLinkPress(href); + const record = props.context?.records.find( + (item) => item.contextId === reference.contextId, + ); + if (actionId === "copy-context" && record) { + void writeComposerContextClipboard( + formatComposerContextReference({ + ...reference, + label: record.label, + }), + { + version: 1, + source: { environmentId: props.environmentId }, + records: [record], + }, + ) + .then(() => Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success)) + .catch(() => { + Alert.alert("Could not copy context", "Try copying this context again."); + }); + } + }, + linkCustomization: (href) => { + const presentation = enrichedContextLinkPresentation(href, props.context?.records); + return presentation + ? { color: presentation.color, icon: markdownFileIconSource(presentation.icon) } + : props.linkHandlers.linkCustomization?.(href); + }, + }} /> {selected ? ( { + const media = resolveMarkdownMediaPreview(href, { + environmentId: props.environmentId, + threadId: props.threadId, + workspaceRoot: props.workspaceRoot, + }); + if (media?.kind === "image") setExpandedFile(media.source); + else if (media?.kind === "video") setExpandedVideo(media.source); + else onMarkdownLinkPress(href); + }, + [onMarkdownLinkPress, props.environmentId, props.threadId, props.workspaceRoot], + ); const markdownLinkHandlers = useMemo( () => ({ onLinkPress: onMarkdownLinkPress, + onImagePress: onMarkdownImagePress, + resolveImageSource, fileContextMenu: (href) => { const target = resolveFileChipTarget(href, props.workspaceRoot); return target ? fileChipMenu(target) : undefined; @@ -1606,7 +1640,13 @@ export const ThreadFeed = memo(function ThreadFeed(props: ThreadFeedProps) { } }, }), - [onMarkdownLinkPress, props.workspaceRoot, shareFileChip], + [ + onMarkdownLinkPress, + onMarkdownImagePress, + props.workspaceRoot, + resolveImageSource, + shareFileChip, + ], ); const renderMarkdownImage = useCallback( (image) => { @@ -1629,6 +1669,11 @@ export const ThreadFeed = memo(function ThreadFeed(props: ThreadFeedProps) { return ( void; }) { @@ -126,6 +130,7 @@ export function ThreadMarkdownImageView(props: { setFailedUri(props.uri)} /> @@ -147,22 +152,34 @@ function ThreadMarkdownImageRequest(props: { readonly uri: string; readonly onLoad: (sourceSize: { width: number; height: number }) => void; readonly onError: () => void; + readonly format?: "svg"; }) { const [loaded, setLoaded] = useState(false); return ( <> - { - setLoaded(true); - props.onLoad(event.nativeEvent.source); - }} - onError={props.onError} - style={{ width: "100%", height: "100%", opacity: loaded ? 1 : 0 }} - /> + {props.format === "svg" ? ( + { + setLoaded(true); + if (size) props.onLoad(size); + }} + onError={props.onError} + /> + ) : ( + { + setLoaded(true); + props.onLoad(event.nativeEvent.source); + }} + onError={props.onError} + style={{ width: "100%", height: "100%", opacity: loaded ? 1 : 0 }} + /> + )} {loaded ? null : ( void; + readonly onError: () => void; +}) { + const [ast, setAst] = useState(null); + const onLoad = useEffectEvent(props.onLoad); + const onError = useEffectEvent(props.onError); + useEffect(() => { + const controller = new AbortController(); + const load = async () => { + if (props.uri.startsWith("data:image/svg+xml")) { + const comma = props.uri.indexOf(","); + if (comma < 0) throw new Error("SVG data URI has no content"); + const content = decodeURIComponent(props.uri.slice(comma + 1)); + return props.uri.slice(0, comma).includes(";base64") + ? new TextDecoder().decode( + Uint8Array.from(atob(content), (character) => character.charCodeAt(0)), + ) + : content; + } + const response = await fetch(props.uri, { signal: controller.signal }); + if (!response.ok && !(response.status === 0 && props.uri.startsWith("file://"))) + throw new Error(`SVG request failed: ${response.status}`); + return response.text(); + }; + void load() + .then((xml) => { + const parsed = parse(xml); + if (!parsed) throw new Error("SVG has no root element"); + if (controller.signal.aborted) return; + setAst(parsed); + onLoad(resolveSvgImageSize(parsed.props)); + }) + .catch(() => { + if (!controller.signal.aborted) onError(); + }); + return () => controller.abort(); + }, [props.uri]); + return ; +} + /** Environment-hosted image that loads through a signed asset URL. */ export function ThreadMarkdownImage(props: { readonly environmentId: EnvironmentId; - readonly resource: Extract; + readonly resource: Extract< + AssetResource, + { readonly _tag: "attachment" | "media-file" | "draft-workspace-file" } + >; readonly alt: string | null; readonly srcFragment?: string; readonly actionsSource?: MediaActionsSource; @@ -196,6 +258,12 @@ export function ThreadMarkdownImage(props: { } unavailable={assetUrl._tag === "Failure"} knownSize={assetUrl._tag === "Success" ? assetUrl.imageDimensions : undefined} + format={ + (props.resource._tag === "media-file" || props.resource._tag === "draft-workspace-file") && + /\.svg$/i.test(props.resource.path) + ? "svg" + : undefined + } alt={props.alt} actionsSource={props.actionsSource} onPressPreview={props.onPressPreview} diff --git a/apps/mobile/src/features/threads/ThreadMarkdownVideo.tsx b/apps/mobile/src/features/threads/ThreadMarkdownVideo.tsx new file mode 100644 index 000000000000..e01f6ae3b2aa --- /dev/null +++ b/apps/mobile/src/features/threads/ThreadMarkdownVideo.tsx @@ -0,0 +1,45 @@ +import { createContext, useContext } from "react"; +import { MediaVideoPlayer } from "../../components/MediaVideoPlayer"; +import { useAssetUrlState, useRefreshAssetUrl } from "../../state/assets"; +import { + mediaVideoPreviewUri, + mediaVideoThumbnailKey, + type MediaVideoPreviewSource, +} from "../../lib/videoPreviewSource"; + +export const ThreadMediaVisibleContext = createContext(false); + +export function ThreadMarkdownVideo(props: { + readonly source: MediaVideoPreviewSource; + readonly thumbnailVisible?: boolean; +}) { + const { source } = props; + const feedVisible = useContext(ThreadMediaVisibleContext); + const visible = props.thumbnailVisible ?? feedVisible; + const thumbnailKey = mediaVideoThumbnailKey(source); + const asset = useAssetUrlState( + "environmentId" in source ? source.environmentId : null, + "resource" in source ? source.resource : null, + ); + const refreshAssetUrl = useRefreshAssetUrl( + "environmentId" in source ? source.environmentId : null, + "resource" in source ? source.resource : null, + ); + const uri = mediaVideoPreviewUri(source, asset._tag === "Success" ? asset.url : null); + return ( + mediaVideoPreviewUri(source, await refreshAssetUrl()) + : undefined + } + name={source.name} + thumbnailKey={thumbnailKey} + thumbnailVisible={visible} + unavailable={"resource" in source && asset._tag === "Failure"} + actionsSource={source.actionsSource} + /> + ); +} diff --git a/apps/mobile/src/features/threads/markdownImageSize.test.ts b/apps/mobile/src/features/threads/markdownImageSize.test.ts index 76170890d519..614640cc3f8a 100644 --- a/apps/mobile/src/features/threads/markdownImageSize.test.ts +++ b/apps/mobile/src/features/threads/markdownImageSize.test.ts @@ -4,6 +4,7 @@ import { MARKDOWN_IMAGE_MAX_HEIGHT, MARKDOWN_IMAGE_MAX_WIDTH, resolveMarkdownImageDisplaySize, + resolveSvgImageSize, } from "./markdownImageSize"; describe("resolveMarkdownImageDisplaySize", () => { @@ -60,3 +61,20 @@ describe("resolveMarkdownImageDisplaySize", () => { ).toBeNull(); }); }); + +describe("resolveSvgImageSize", () => { + it("uses pixel dimensions before the viewBox", () => { + expect(resolveSvgImageSize({ width: "32px", height: "48", viewBox: "0 0 100 100" })).toEqual({ + width: 32, + height: 48, + }); + }); + + it("uses the viewBox for responsive SVGs", () => { + expect( + resolveSvgImageSize({ width: "100%", height: "100%", viewBox: "-10, -20, 120, 240" }), + ).toEqual({ width: 120, height: 240 }); + expect(resolveSvgImageSize({ viewBox: "0 0 100 NaN" })).toBeNull(); + expect(resolveSvgImageSize({ viewBox: "0 0 0 100" })).toBeNull(); + }); +}); diff --git a/apps/mobile/src/features/threads/markdownImageSize.ts b/apps/mobile/src/features/threads/markdownImageSize.ts index 0fb6f8fbcc6d..b5b3c8402b25 100644 --- a/apps/mobile/src/features/threads/markdownImageSize.ts +++ b/apps/mobile/src/features/threads/markdownImageSize.ts @@ -6,6 +6,34 @@ export interface MarkdownImageDisplaySize { readonly height: number; } +/** SVG percentages need a viewport; use the intrinsic viewBox in that case. */ +export function resolveSvgImageSize(props: Readonly>) { + const dimension = (value: unknown) => { + if (typeof value === "number") return value; + if (typeof value !== "string" || !/^\s*\d+(?:\.\d+)?(?:px)?\s*$/.test(value)) return NaN; + return Number.parseFloat(value); + }; + const width = dimension(props.width); + const height = dimension(props.height); + if (Number.isFinite(width) && Number.isFinite(height) && width > 0 && height > 0) + return { width, height }; + const viewBox = + typeof props.viewBox === "string" + ? props.viewBox + .trim() + .split(/[\s,]+/) + .map(Number) + : []; + if ( + viewBox.length !== 4 || + !viewBox.every(Number.isFinite) || + viewBox[2]! <= 0 || + viewBox[3]! <= 0 + ) + return null; + return { width: viewBox[2]!, height: viewBox[3]! }; +} + /** Keeps small images intrinsic while fitting larger images inside the chat viewport. */ export function resolveMarkdownImageDisplaySize(input: { readonly sourceWidth: number; diff --git a/apps/mobile/src/lib/enrichedLinkPresentation.test.ts b/apps/mobile/src/lib/enrichedLinkPresentation.test.ts new file mode 100644 index 000000000000..b067365dd3ec --- /dev/null +++ b/apps/mobile/src/lib/enrichedLinkPresentation.test.ts @@ -0,0 +1,98 @@ +import { describe, expect, it } from "vite-plus/test"; +import type { ComposerContextId, ReviewCommentContextRecord } from "@t3tools/contracts"; +import { + enrichedContextLinkPresentation, + enrichedLinkVariantPattern, + enrichedSkillLinkRegex, + ENRICHED_INLINE_FILE_LINK_REGEX, +} from "./enrichedLinkPresentation"; + +describe("Enriched link presentation", () => { + it("recognizes file-shaped code without turning commands or URLs into links", () => { + for (const path of [ + "src/app.tsx", + "./README.md", + "/tmp/report.md", + "C:\\repo\\app.tsx", + "app.tsx:12:3", + ]) { + expect(ENRICHED_INLINE_FILE_LINK_REGEX.test(path), path).toBe(true); + } + for (const text of [ + "npm run dev", + "port:3000", + "TODO:12", + "example.com", + "https://example.com/app.tsx", + "x + y", + "README.md", + "/app/settings", + ]) { + expect(ENRICHED_INLINE_FILE_LINK_REGEX.test(text), text).toBe(false); + } + }); + + it("only recognizes complete known skill names and escapes their punctuation", () => { + const regex = enrichedSkillLinkRegex([{ name: "check" }, { name: "check.mobile" }]); + expect(regex?.exec("Try $check.mobile next")?.[0]).toBe("$check.mobile"); + expect(regex?.exec("Try $check-mobile next")).toBeNull(); + expect(regex?.exec("Try $checkXmobile next")).toBeNull(); + expect(regex?.exec("prefix$check next")).toBeNull(); + expect(enrichedSkillLinkRegex([])).toBeNull(); + }); + it("matches only the complete URL, including literal regex metacharacters", () => { + const url = "file:///workspace/app[1].tsx?line=3+4"; + const pattern = new RegExp(enrichedLinkVariantPattern(url)); + expect(pattern.test(url)).toBe(true); + expect(pattern.test(`${url}/child`)).toBe(false); + expect(pattern.test("file:///workspace/app1Xtsx?line=34")).toBe(false); + }); + + it("uses context identity for PR status even when labels are identical", () => { + const record: ReviewCommentContextRecord = { + version: 1, + contextId: "review_1" as ComposerContextId, + kind: "review-comment", + label: "Review", + sectionId: "pull-request:7", + sectionTitle: "Review", + filePath: "app.tsx", + startIndex: 0, + endIndex: 1, + rangeLabel: "line 1", + text: "Comment", + diff: "", + pullRequest: { + number: 7, + title: "Review", + url: "https://github.com/example/repo/pull/7", + headBranch: "feature", + baseBranch: "main", + state: "merged", + isDraft: false, + }, + }; + expect( + enrichedContextLinkPresentation("t3-context://v1/review-comment/review_1", [record]), + ).toEqual({ color: "#8a70dd", icon: "git" }); + expect( + enrichedContextLinkPresentation("t3-context://v1/review-comment/review_2", [record]), + ).toEqual({ color: "#8a70dd", icon: "markdown" }); + }); + + it("retains recognizable presentation for unavailable and future context kinds", () => { + expect(enrichedContextLinkPresentation("t3-context://v1/terminal/missing")).toEqual({ + color: "#009f6e", + icon: "bash", + }); + expect(enrichedContextLinkPresentation("t3-context://v1/skill/missing")).toEqual({ + color: "#b261be", + icon: "mcp", + }); + expect(enrichedContextLinkPresentation("t3-context://v1/future/missing")).toEqual({ + color: "#0090cd", + icon: "default", + }); + expect(enrichedContextLinkPresentation("https://example.com/terminal/missing")).toBeUndefined(); + }); +}); diff --git a/apps/mobile/src/lib/enrichedLinkPresentation.ts b/apps/mobile/src/lib/enrichedLinkPresentation.ts new file mode 100644 index 000000000000..5dd3cae68492 --- /dev/null +++ b/apps/mobile/src/lib/enrichedLinkPresentation.ts @@ -0,0 +1,58 @@ +import type { ComposerContextRecord } from "@t3tools/contracts"; +import { contextChipPresentation } from "@t3tools/mobile-markdown-text/markdown"; +import type { MarkdownFileIcon } from "@t3tools/mobile-markdown-text/links"; +import type { SelectableMarkdownSkill } from "@t3tools/mobile-markdown-text/types"; +import { parseComposerContextHref } from "@t3tools/shared/composerContextReferences"; + +const CONTEXT_ICONS: Readonly> = { + photo: "image", + "play.rectangle": "video", + terminal: "bash", + "cursorarrow.click": "react", + "text.bubble": "markdown", + "git-pull-request": "git", + cube: "mcp", + doc: "default", +}; + +/** Context identity comes from the URL, even when different chips share a label. */ +export function enrichedContextLinkPresentation( + href: string, + records?: ReadonlyArray, +) { + const reference = parseComposerContextHref(href); + if (!reference) return undefined; + const record = records?.find((candidate) => candidate.contextId === reference.contextId); + const presentation = contextChipPresentation(reference.kind, record); + return { + color: presentation.accent, + icon: CONTEXT_ICONS[presentation.symbol] ?? "default", + }; +} + +export function enrichedLinkVariantPattern(url: string) { + return `^${url.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`; +} + +/** Conservative recognition for Enriched's whole-span inline-code link hook. */ +export const ENRICHED_INLINE_FILE_LINK_REGEX = + /^(?!\S*:\/\/)(?:(?:\.{1,2}[\\/]|~[\\/]|\/(?:Users|home|tmp|var|etc|opt|mnt|Volumes|private|root|usr|bin|sbin|lib|lib64|srv|dev|proc|sys|run|boot|media|workspace|workspaces)\/|[A-Za-z]:[\\/])[^\s`]+|(?:[A-Za-z0-9._-]+[\\/])+[A-Za-z0-9._-]+\.[A-Za-z0-9_-]+(?::\d+){0,2}|[A-Za-z0-9._-]+\.[A-Za-z0-9_-]+:\d+(?::\d+)?)$/; + +export function enrichedSkillLinkRegex(skills?: ReadonlyArray) { + const names = [...new Set(skills?.map((skill) => skill.name) ?? [])].filter(Boolean); + if (names.length === 0) return null; + names.sort((a, b) => b.length - a.length); + const alternatives = names.map((name) => name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")); + return new RegExp(`(? word.charAt(0).toUpperCase() + word.slice(1)) + .join(" ") + ); +} diff --git a/apps/mobile/src/lib/markdownMediaSource.test.ts b/apps/mobile/src/lib/markdownMediaSource.test.ts new file mode 100644 index 000000000000..faa44e76af50 --- /dev/null +++ b/apps/mobile/src/lib/markdownMediaSource.test.ts @@ -0,0 +1,41 @@ +import { ThreadId } from "@t3tools/contracts"; +import { describe, expect, it } from "vite-plus/test"; +import { resolveMobileMarkdownMediaSource } from "./markdownMediaSource"; + +describe("mobile Markdown draft media", () => { + it("authorizes relative images and videos against the draft directory", () => { + for (const name of ["diagram.svg", "clip.mp4"]) { + expect( + resolveMobileMarkdownMediaSource(`./${name}`, { + threadId: undefined, + workspaceRoot: "/project/docs", + imageEmbed: true, + }), + ).toMatchObject({ + access: "environment", + resource: { + _tag: "draft-workspace-file", + cwd: "/project/docs", + path: `/project/docs/./${name}`, + }, + }); + } + }); + + it("keeps thread authorization when a thread exists", () => { + const threadId = ThreadId.make("markdown-thread"); + expect( + resolveMobileMarkdownMediaSource("image.png", { threadId, workspaceRoot: "/project" }), + ).toMatchObject({ resource: { _tag: "media-file", threadId, path: "/project/image.png" } }); + }); + + it("keeps direct URLs direct and rejects unresolvable or blocked references", () => { + const input = { threadId: undefined, workspaceRoot: "/project" }; + expect(resolveMobileMarkdownMediaSource("https://example.com/image.png", input)).toMatchObject({ + access: "direct", + uri: "https://example.com/image.png", + }); + expect(resolveMobileMarkdownMediaSource("javascript:alert(1)", input)).toBeNull(); + expect(resolveMobileMarkdownMediaSource("image.png", { threadId: undefined })).toBeNull(); + }); +}); diff --git a/apps/mobile/src/lib/markdownMediaSource.ts b/apps/mobile/src/lib/markdownMediaSource.ts new file mode 100644 index 000000000000..f2538f495b20 --- /dev/null +++ b/apps/mobile/src/lib/markdownMediaSource.ts @@ -0,0 +1,22 @@ +import { classifyMarkdownImageSource } from "@t3tools/client-runtime/markdown-images"; +import { + resolveMediaSource, + type ResolveMediaSourceInput, +} from "@t3tools/client-runtime/media-source"; + +/** A project draft names its workspace explicitly because it has no thread. */ +export function resolveMobileMarkdownMediaSource(href: string, input: ResolveMediaSourceInput) { + const media = resolveMediaSource(href, input); + if (media?.access !== "unavailable" || !input.workspaceRoot) return media; + const source = classifyMarkdownImageSource(href, input.workspaceRoot); + if (source._tag !== "WorkspaceFile") return media; + return { + ...media, + access: "environment" as const, + resource: { + _tag: "draft-workspace-file" as const, + cwd: input.workspaceRoot, + path: source.path, + }, + }; +} diff --git a/apps/mobile/src/native/EnrichedMarkdownText.tsx b/apps/mobile/src/native/EnrichedMarkdownText.tsx index 9b46d65222e1..d087d3b33400 100644 --- a/apps/mobile/src/native/EnrichedMarkdownText.tsx +++ b/apps/mobile/src/native/EnrichedMarkdownText.tsx @@ -1,9 +1,21 @@ -import { useMemo } from "react"; -import { Platform, View } from "react-native"; -import { EnrichedMarkdownText, type MarkdownStyle } from "react-native-enriched-markdown"; +import { useCallback, useMemo, useState } from "react"; +import { ActionSheetIOS, Platform, View } from "react-native"; +import { + EnrichedMarkdownText, + type DocumentAssetsEvent, + type MarkdownStyle, + type MarkdownMediaAsset, +} from "react-native-enriched-markdown"; import type { SelectableMarkdownTextProps } from "@t3tools/mobile-markdown-text/types"; import { useAppearancePreferences } from "../features/settings/appearance/AppearancePreferencesProvider"; +import { AndroidAnchoredMenu } from "../components/AndroidAnchoredMenu"; +import { useEnrichedLinkVariants } from "./useEnrichedLinkVariants"; +import { copyTextWithHaptic } from "../lib/copyTextWithHaptic"; +import { + ENRICHED_INLINE_FILE_LINK_REGEX, + enrichedSkillLinkRegex, +} from "../lib/enrichedLinkPresentation"; function enrichedStyle( style: SelectableMarkdownTextProps["textStyle"], @@ -112,41 +124,153 @@ function enrichedStyle( }; } -// The Enriched-only spike leaves attachment renderers and chip decorations to -// future app integrations; every Markdown block goes through this native view. export function MobileEnrichedMarkdownText(props: SelectableMarkdownTextProps) { + const { renderImage, resolveImageSource } = props; const { themeAppearance } = useAppearancePreferences(); + const [documentAssets, setDocumentAssets] = useState([]); + const onDocumentAssets = useCallback(({ assets }: DocumentAssetsEvent) => { + setDocumentAssets((previous) => + previous.length === assets.length && + previous.every((asset, index) => { + const next = assets[index]!; + return ( + asset.id === next.id && + asset.kind === next.kind && + asset.url === next.url && + asset.altText === next.altText && + asset.title === next.title && + asset.placement === next.placement && + asset.eligible === next.eligible + ); + }) + ? previous + : assets, + ); + }, []); + const linkVariants = useEnrichedLinkVariants(documentAssets, props); + const skillLinkRegex = useMemo(() => enrichedSkillLinkRegex(props.skills), [props.skills]); + const [activeMenu, setActiveMenu] = useState<{ + url: string; + menu: NonNullable>>; + } | null>(null); const markdownStyle = useMemo( - () => enrichedStyle(props.textStyle, themeAppearance === "dark"), - [props.textStyle, themeAppearance], + () => ({ ...enrichedStyle(props.textStyle, themeAppearance === "dark"), linkVariants }), + [props.textStyle, themeAppearance, linkVariants], ); + const renderMedia = useCallback( + (asset: MarkdownMediaAsset) => + renderImage?.({ + href: asset.url, + alt: asset.altText || null, + title: asset.title || null, + }) ?? null, + [renderImage], + ); + const resolveNativeImageSource = useCallback( + (asset: MarkdownMediaAsset) => + resolveImageSource?.({ + href: asset.url, + alt: asset.altText || null, + title: asset.title || null, + }) ?? null, + [resolveImageSource], + ); + const renderMarkdown = (openAndroidMenu?: () => void) => { + const onLinkLongPress = props.fileContextMenu + ? ({ url }: { url: string }) => { + const menu = props.fileContextMenu?.(url) ?? { + title: url, + actions: [ + { id: "enriched-open-link", title: "Open link" }, + { id: "enriched-copy-link", title: "Copy link" }, + ], + }; + const actions = menu.actions; + if (Platform.OS === "ios") { + ActionSheetIOS.showActionSheetWithOptions( + { + title: menu.title, + options: [...actions.map((action) => action.title), "Cancel"], + cancelButtonIndex: actions.length, + disabledButtonIndices: actions.flatMap((action, index) => + action.disabled ? [index] : [], + ), + }, + (index) => { + const action = actions[index]; + if (action && !action.disabled) performMenuAction(url, action.id); + }, + ); + } else { + setActiveMenu({ url, menu }); + openAndroidMenu?.(); + } + } + : undefined; - return ( - + (props.onImagePress ?? props.onLinkPress)?.(url) + : undefined + } + linkRegex={skillLinkRegex} + inlineCodeLinkRegex={ENRICHED_INLINE_FILE_LINK_REGEX} + containerStyle={{ flexShrink: 1, minWidth: 0 }} + flavor="github" + selectable + selectionColor={props.textStyle.selectionColor} + selectionHandleColor={props.textStyle.selectionHandleColor} + md4cFlags={{ + latexMath: false, + hardSoftBreaks: props.preserveSoftBreaks ?? false, + admonitions: false, + }} + enableTaskListItemToggle={false} + spoilerOverlay="solid" + onLinkPress={props.onLinkPress ? ({ url }) => props.onLinkPress?.(url) : undefined} + onLinkLongPress={onLinkLongPress} + /> + + ); + }; + const performMenuAction = (url: string, actionId: string) => { + if (actionId === "enriched-open-link") props.onLinkPress?.(url); + else if (actionId === "enriched-copy-link") copyTextWithHaptic(url); + else props.onFileContextMenuAction?.(url, actionId); + }; + return Platform.OS === "android" && props.fileContextMenu ? ( + ({ + id: action.id, + title: action.title, + attributes: { disabled: action.disabled }, + })) ?? [] + } + onPressAction={({ nativeEvent }) => { + if (activeMenu) performMenuAction(activeMenu.url, nativeEvent.event); }} + style={{ flexShrink: 1, minWidth: 0 }} > - props.onLinkPress?.(url) : undefined} - /> - + {renderMarkdown} + + ) : ( + renderMarkdown() ); } diff --git a/apps/mobile/src/native/SelectableMarkdownText.tsx b/apps/mobile/src/native/SelectableMarkdownText.tsx index 73e629ad1fd1..daf840ceb4cc 100644 --- a/apps/mobile/src/native/SelectableMarkdownText.tsx +++ b/apps/mobile/src/native/SelectableMarkdownText.tsx @@ -11,6 +11,8 @@ export type { MarkdownFileContextMenuAction, MarkdownImageRenderer, MarkdownImageRequest, + MarkdownImageSourceResolver, + MarkdownLinkCustomization, NativeMarkdownTextStyle, SelectableMarkdownSkill, } from "@t3tools/mobile-markdown-text/types"; diff --git a/apps/mobile/src/native/useEnrichedLinkVariants.ts b/apps/mobile/src/native/useEnrichedLinkVariants.ts new file mode 100644 index 000000000000..acb2a844e042 --- /dev/null +++ b/apps/mobile/src/native/useEnrichedLinkVariants.ts @@ -0,0 +1,154 @@ +import { Asset } from "expo-asset"; +import { useEffect, useMemo, useState } from "react"; +import type { ImageSourcePropType } from "react-native"; +import type { MarkdownDocumentAsset, MarkdownStyle } from "react-native-enriched-markdown"; +import { markdownFileIconSource } from "@t3tools/mobile-markdown-text/file-icons"; +import { markdownLinkIconSource } from "@t3tools/mobile-markdown-text/link-icons"; +import { + resolveMarkdownLinkIcon, + resolveMarkdownLinkPresentation, +} from "@t3tools/mobile-markdown-text/links"; +import type { SelectableMarkdownTextProps } from "@t3tools/mobile-markdown-text/types"; + +import { + enrichedContextLinkPresentation, + enrichedLinkVariantPattern, + enrichedSkillDisplayName, +} from "../lib/enrichedLinkPresentation"; +import { themeColorWithAlpha } from "../lib/mobileTheme"; + +// Native pill drawing accepts local image URIs. Expo resolves bundled PNGs once, +// including Metro's HTTP asset sources during development. +const localIconUris = new Map(); +const iconDownloads = new Map>(); + +function localIconUri(source: number) { + const cached = localIconUris.get(source); + if (cached) return Promise.resolve(cached); + const existing = iconDownloads.get(source); + if (existing) return existing; + const download = Asset.fromModule(source) + .downloadAsync() + .then((asset) => { + if (asset.localUri) localIconUris.set(source, asset.localUri); + return asset.localUri; + }) + .catch(() => { + iconDownloads.delete(source); + return null; + }); + iconDownloads.set(source, download); + return download; +} + +function presentation( + url: string, + props: Pick, +) { + const custom = props.linkCustomization?.(url); + if (custom) return custom; + const context = enrichedContextLinkPresentation(url); + if (context) return { color: context.color, icon: markdownFileIconSource(context.icon) }; + const skill = url.startsWith("$") + ? props.skills?.find((candidate) => `$${candidate.name}` === url) + : undefined; + if (skill) + return { + color: props.textStyle.skillTextColor, + label: enrichedSkillDisplayName(skill), + icon: markdownFileIconSource("mcp"), + }; + const link = resolveMarkdownLinkPresentation(url); + if (link.kind === "file") + return { + color: props.textStyle.fileTextColor, + label: link.label, + icon: markdownFileIconSource(link.icon), + }; + const icon = link.kind === "external" ? resolveMarkdownLinkIcon(link.host) : null; + return icon + ? { + color: props.textStyle.linkColor, + icon: markdownLinkIconSource(icon), + iconTintColor: props.textStyle.linkColor, + } + : undefined; +} + +function iconUri(source: ImageSourcePropType | undefined, downloaded: ReadonlyMap) { + if (typeof source === "number") return downloaded.get(source); + if (source && !Array.isArray(source) && "uri" in source && source.uri?.startsWith("file://")) { + return source.uri; + } + return undefined; +} + +export function useEnrichedLinkVariants( + assets: ReadonlyArray, + props: SelectableMarkdownTextProps, +): MarkdownStyle["linkVariants"] { + const { linkCustomization, skills, textStyle } = props; + const links = useMemo(() => { + const byUrl = new Map>>(); + for (const asset of assets) { + if (asset.kind !== "link" || byUrl.has(asset.url)) continue; + const value = presentation(asset.url, { linkCustomization, skills, textStyle }); + if (value) byUrl.set(asset.url, value); + } + return byUrl; + }, [assets, linkCustomization, skills, textStyle]); + const sourceKey = [ + ...new Set( + [...links.values()].flatMap((link) => (typeof link.icon === "number" ? [link.icon] : [])), + ), + ] + .sort((a, b) => a - b) + .join(","); + const [downloaded, setDownloaded] = useState(() => new Map(localIconUris)); + useEffect(() => { + let cancelled = false; + const sources = sourceKey ? sourceKey.split(",").map(Number) : []; + const missing = sources.filter((source) => !localIconUris.has(source)); + if (sources.length === 0) return; + void Promise.all(missing.map(localIconUri)).then(() => { + if (!cancelled) + setDownloaded((previous) => + sources.every((source) => previous.get(source) === localIconUris.get(source)) + ? previous + : new Map(localIconUris), + ); + }); + return () => { + cancelled = true; + }; + }, [sourceKey]); + + return useMemo( + () => + Object.fromEntries( + [...links].map(([url, link]) => { + const color = link.color ?? props.textStyle.fileTextColor; + return [ + enrichedLinkVariantPattern(url), + { + pill: true, + label: link.label, + iconUri: iconUri(link.icon, downloaded), + iconTintColor: link.iconTintColor, + fontFamily: props.textStyle.fontFamily, + color, + underline: false, + backgroundColor: themeColorWithAlpha(color, 0.08), + borderColor: + props.textStyle.contextChipBorderColor ?? themeColorWithAlpha(color, 0.2), + borderWidth: 0.5, + borderRadius: 6, + paddingHorizontal: 5, + paddingVertical: 2, + }, + ]; + }), + ), + [links, downloaded, props.textStyle], + ); +} diff --git a/apps/mobile/src/native/useMarkdownImageSource.ts b/apps/mobile/src/native/useMarkdownImageSource.ts new file mode 100644 index 000000000000..052060ba48f4 --- /dev/null +++ b/apps/mobile/src/native/useMarkdownImageSource.ts @@ -0,0 +1,52 @@ +import { resolveMobileMarkdownMediaSource } from "../lib/markdownMediaSource"; +import { resolveAssetUrl } from "@t3tools/client-runtime/state/assets"; +import type { EnvironmentId, ThreadId } from "@t3tools/contracts"; +import type { MarkdownImageSourceResolver } from "@t3tools/mobile-markdown-text/types"; +import { normalizeNativeMarkdownUrl } from "@t3tools/mobile-markdown-text/links"; +import { useCallback } from "react"; +import * as Option from "effect/Option"; + +import { assetEnvironment, useAssetConnectionPhase } from "../state/assets"; +import { usePreparedConnection } from "../state/session"; +import { useAtomQueryRunner } from "../state/use-atom-query-runner"; + +/** Native nested images use the same signed asset queries as app-owned media. */ +export function useMarkdownImageSource(props: { + readonly environmentId: EnvironmentId; + readonly threadId: ThreadId | null; + readonly workspaceRoot: string | null; + readonly captured?: boolean; +}): MarkdownImageSourceResolver { + const { environmentId, threadId, workspaceRoot, captured } = props; + const connection = usePreparedConnection(environmentId); + const connectionPhase = useAssetConnectionPhase(environmentId); + const httpBaseUrl = Option.isSome(connection) ? connection.value.httpBaseUrl : null; + const createUrl = useAtomQueryRunner(assetEnvironment.createUrl, { reportFailure: false }); + return useCallback( + async (image) => { + const media = resolveMobileMarkdownMediaSource(image.href, { + threadId: threadId ?? undefined, + workspaceRoot, + imageEmbed: true, + }); + if (media?.access === "direct") return { uri: normalizeNativeMarkdownUrl(media.uri) }; + if ( + captured || + media === null || + media.access === "unavailable" || + httpBaseUrl === null || + connectionPhase === "offline" || + connectionPhase === "error" || + connectionPhase === "unsupported" || + connectionPhase === "reconnecting" + ) + throw new Error("Markdown image is unavailable"); + const result = await createUrl({ environmentId, input: { resource: media.resource } }); + if (result._tag !== "Success") throw new Error("Could not authorize Markdown image"); + const uri = resolveAssetUrl(httpBaseUrl, result.value.relativeUrl); + if (uri === null) throw new Error("Markdown image URL is invalid"); + return { uri }; + }, + [captured, connectionPhase, createUrl, environmentId, httpBaseUrl, threadId, workspaceRoot], + ); +} diff --git a/apps/mobile/src/state/assets.ts b/apps/mobile/src/state/assets.ts index 15cbd1d9a89f..11f201a486ed 100644 --- a/apps/mobile/src/state/assets.ts +++ b/apps/mobile/src/state/assets.ts @@ -35,7 +35,9 @@ const EMPTY_CONNECTION_STATE_ATOM = Atom.make(AsyncResult.initial( Atom.withLabel("mobile-asset-connection-state:empty"), ); -function useConnectionPhase(environmentId: EnvironmentId | null): EnvironmentConnectionPhase { +export function useAssetConnectionPhase( + environmentId: EnvironmentId | null, +): EnvironmentConnectionPhase { const state = useAtomValue( environmentId === null ? EMPTY_CONNECTION_STATE_ATOM @@ -50,7 +52,7 @@ export function useAssetUrlState( resource: AssetResource | null, ): AssetUrlState { const preparedConnection = usePreparedConnection(environmentId); - const connectionPhase = useConnectionPhase(environmentId); + const connectionPhase = useAssetConnectionPhase(environmentId); const result = useAtomValue( environmentId === null || resource === null ? EMPTY_ASSET_URL_ATOM diff --git a/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch b/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch index 4a28c34870c8..c2102028d845 100644 --- a/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch +++ b/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch @@ -1,3 +1,3479 @@ +diff --git a/ReactNativeEnrichedMarkdown.podspec b/ReactNativeEnrichedMarkdown.podspec +index aa878306fd3e5a295297c75a3704bdc3cc97c52f..f872de8240e1f95d6d54a543c04c8ef4a640dbc7 100644 +--- a/ReactNativeEnrichedMarkdown.podspec ++++ b/ReactNativeEnrichedMarkdown.podspec +@@ -101,6 +101,8 @@ Pod::Spec.new do |s| + # sources. Both compile into this pod's module only when math is enabled. + exclude += ["ios/math/**/*.swift", "ios/vendor/*.swift"] unless enable_math + s.exclude_files = exclude ++ # Bounded decoding of native pill icons. ++ s.frameworks = "ImageIO" + + # Video playback (AVKit, built into iOS — no external framework or vendored asset). + # Default on: consumers opt out via "enriched-markdown".enableVideo = false in package.json. +diff --git a/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java b/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +index 4f647a69aec3692c3e6c79813555c25ca27be607..0149b9310bcf06881aa8b2c03f8978dcc9d10f5f 100644 +--- a/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java ++++ b/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +@@ -26,6 +26,39 @@ public class EnrichedMarkdownManagerDelegate extends ViewManagerWithGeneratedInterface { ++ void setEnableImageSourceResolution(T view, boolean value); ++ void setImageSourcesRevision(T view, int value); ++ void setImageSourcesContinuityStart(T view, int value); ++ void setImageSources(T view, @Nullable ReadableArray value); ++ void setDocumentRevision(T view, int value); ++ void setEnableDocumentAssets(T view, boolean value); ++ void setEnableMediaSlots(T view, boolean value); ++ void setMediaOverridesRevision(T view, int value); ++ void setMediaOverrides(T view, @Nullable ReadableArray value); ++ void setLinkRegex(T view, @Nullable ReadableMap value); ++ void setInlineCodeLinkRegex(T view, @Nullable ReadableMap value); + void setMarkdown(T view, @Nullable String value); + void setMarkdownStyle(T view, @Nullable ReadableMap value); + void setEnableImagePress(T view, boolean value); +diff --git a/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java b/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +index 8bcb475fc2b7edbfd8407e49ad2a045aa9939419..ce923d6a17c82cbafaf11dd802b88c67cbcbdc79 100644 +--- a/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java ++++ b/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +@@ -26,6 +26,12 @@ public class EnrichedMarkdownTextManagerDelegate extends ViewManagerWithGeneratedInterface { ++ void setLinkRegex(T view, @Nullable ReadableMap value); ++ void setInlineCodeLinkRegex(T view, @Nullable ReadableMap value); + void setMarkdown(T view, @Nullable String value); + void setMarkdownStyle(T view, @Nullable ReadableMap value); + void setEnableImagePress(T view, boolean value); +diff --git a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +index 1b1b96234e8313e1e1fb2f033a19df84434255f0..e854371ae92d15228fb65133108ce2f4bd4c234d 100644 +--- a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp ++++ b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +@@ -13,6 +13,55 @@ + + namespace facebook::react { + ++void EnrichedMarkdownEventEmitter::onDocumentAssets(OnDocumentAssets event) const { ++ dispatchEvent("documentAssets", [event=std::move(event)](jsi::Runtime &runtime) { ++ auto payload = jsi::Object(runtime); ++ payload.setProperty(runtime, "revision", event.revision); ++ ++ auto assets = jsi::Array(runtime, event.assets.size()); ++ size_t assetsIndex = 0; ++ for (auto assetsValue : event.assets) { ++ auto assetsObject = jsi::Object(runtime); ++ assetsObject.setProperty(runtime, "anchor", assetsValue.anchor); ++assetsObject.setProperty(runtime, "id", assetsValue.id); ++assetsObject.setProperty(runtime, "kind", assetsValue.kind); ++assetsObject.setProperty(runtime, "url", assetsValue.url); ++assetsObject.setProperty(runtime, "altText", assetsValue.altText); ++assetsObject.setProperty(runtime, "title", assetsValue.title); ++assetsObject.setProperty(runtime, "placement", assetsValue.placement); ++assetsObject.setProperty(runtime, "eligible", assetsValue.eligible); ++ assets.setValueAtIndex(runtime, assetsIndex++, assetsObject); ++ } ++ payload.setProperty(runtime, "assets", assets); ++ ++ return payload; ++ }); ++} ++ ++ ++void EnrichedMarkdownEventEmitter::onMediaLayout(OnMediaLayout event) const { ++ dispatchEvent("mediaLayout", [event=std::move(event)](jsi::Runtime &runtime) { ++ auto payload = jsi::Object(runtime); ++ payload.setProperty(runtime, "revision", event.revision); ++ ++ auto frames = jsi::Array(runtime, event.frames.size()); ++ size_t framesIndex = 0; ++ for (auto framesValue : event.frames) { ++ auto framesObject = jsi::Object(runtime); ++ framesObject.setProperty(runtime, "id", framesValue.id); ++framesObject.setProperty(runtime, "x", framesValue.x); ++framesObject.setProperty(runtime, "y", framesValue.y); ++framesObject.setProperty(runtime, "width", framesValue.width); ++framesObject.setProperty(runtime, "height", framesValue.height); ++ frames.setValueAtIndex(runtime, framesIndex++, framesObject); ++ } ++ payload.setProperty(runtime, "frames", frames); ++ ++ return payload; ++ }); ++} ++ ++ + void EnrichedMarkdownEventEmitter::onLinkPress(OnLinkPress event) const { + dispatchEvent("linkPress", [event=std::move(event)](jsi::Runtime &runtime) { + auto payload = jsi::Object(runtime); +diff --git a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +index 3fda20ba6e4d253545401f9a4d76fabdebe4126f..0aa908394302b7753305f324d8165aaea3b24d08 100644 +--- a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h ++++ b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +@@ -17,6 +17,35 @@ class EnrichedMarkdownEventEmitter : public ViewEventEmitter { + public: + using ViewEventEmitter::ViewEventEmitter; + ++ struct OnDocumentAssetsAssets { ++ std::string anchor; ++ std::string id; ++ std::string kind; ++ std::string url; ++ std::string altText; ++ std::string title; ++ std::string placement; ++ bool eligible; ++ }; ++ ++ struct OnDocumentAssets { ++ int revision; ++ std::vector assets; ++ }; ++ ++ struct OnMediaLayoutFrames { ++ std::string id; ++ Float x; ++ Float y; ++ Float width; ++ Float height; ++ }; ++ ++ struct OnMediaLayout { ++ int revision; ++ std::vector frames; ++ }; ++ + struct OnLinkPress { + std::string url; + }; +@@ -58,6 +87,10 @@ class EnrichedMarkdownEventEmitter : public ViewEventEmitter { + int selectionStart; + int selectionEnd; + }; ++ void onDocumentAssets(OnDocumentAssets value) const; ++ ++ void onMediaLayout(OnMediaLayout value) const; ++ + void onLinkPress(OnLinkPress value) const; + + void onLinkLongPress(OnLinkLongPress value) const; +diff --git a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +index fe3cfc5c95ceafbdbf32ea2fbbf1cba8989157e8..5bc5b43908ad3ce0b80f061d491a75058a59872f 100644 +--- a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp ++++ b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +@@ -19,6 +19,17 @@ EnrichedMarkdownProps::EnrichedMarkdownProps( + const EnrichedMarkdownProps &sourceProps, + const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), + ++ enableImageSourceResolution(convertRawProp(context, rawProps, "enableImageSourceResolution", sourceProps.enableImageSourceResolution, {false})), ++ imageSourcesRevision(convertRawProp(context, rawProps, "imageSourcesRevision", sourceProps.imageSourcesRevision, {-1})), ++ imageSourcesContinuityStart(convertRawProp(context, rawProps, "imageSourcesContinuityStart", sourceProps.imageSourcesContinuityStart, {1})), ++ imageSources(convertRawProp(context, rawProps, "imageSources", sourceProps.imageSources, {})), ++ documentRevision(convertRawProp(context, rawProps, "documentRevision", sourceProps.documentRevision, {0})), ++ enableDocumentAssets(convertRawProp(context, rawProps, "enableDocumentAssets", sourceProps.enableDocumentAssets, {false})), ++ enableMediaSlots(convertRawProp(context, rawProps, "enableMediaSlots", sourceProps.enableMediaSlots, {false})), ++ mediaOverridesRevision(convertRawProp(context, rawProps, "mediaOverridesRevision", sourceProps.mediaOverridesRevision, {-1})), ++ mediaOverrides(convertRawProp(context, rawProps, "mediaOverrides", sourceProps.mediaOverrides, {})), ++ linkRegex(convertRawProp(context, rawProps, "linkRegex", sourceProps.linkRegex, {})), ++ inlineCodeLinkRegex(convertRawProp(context, rawProps, "inlineCodeLinkRegex", sourceProps.inlineCodeLinkRegex, {})), + markdown(convertRawProp(context, rawProps, "markdown", sourceProps.markdown, {})), + markdownStyle(convertRawProp(context, rawProps, "markdownStyle", sourceProps.markdownStyle, {})), + enableImagePress(convertRawProp(context, rawProps, "enableImagePress", sourceProps.enableImagePress, {false})), +@@ -63,6 +74,50 @@ folly::dynamic EnrichedMarkdownProps::getDiffProps( + } + folly::dynamic result = HostPlatformViewProps::getDiffProps(prevProps); + ++ if (enableImageSourceResolution != oldProps->enableImageSourceResolution) { ++ result["enableImageSourceResolution"] = enableImageSourceResolution; ++ } ++ ++ if (imageSourcesRevision != oldProps->imageSourcesRevision) { ++ result["imageSourcesRevision"] = imageSourcesRevision; ++ } ++ ++ if (imageSourcesContinuityStart != oldProps->imageSourcesContinuityStart) { ++ result["imageSourcesContinuityStart"] = imageSourcesContinuityStart; ++ } ++ ++ if (imageSources != oldProps->imageSources) { ++ result["imageSources"] = toDynamic(imageSources); ++ } ++ ++ if (documentRevision != oldProps->documentRevision) { ++ result["documentRevision"] = documentRevision; ++ } ++ ++ if (enableDocumentAssets != oldProps->enableDocumentAssets) { ++ result["enableDocumentAssets"] = enableDocumentAssets; ++ } ++ ++ if (enableMediaSlots != oldProps->enableMediaSlots) { ++ result["enableMediaSlots"] = enableMediaSlots; ++ } ++ ++ if (mediaOverridesRevision != oldProps->mediaOverridesRevision) { ++ result["mediaOverridesRevision"] = mediaOverridesRevision; ++ } ++ ++ if (mediaOverrides != oldProps->mediaOverrides) { ++ result["mediaOverrides"] = toDynamic(mediaOverrides); ++ } ++ ++ if (linkRegex != oldProps->linkRegex) { ++ result["linkRegex"] = toDynamic(linkRegex); ++ } ++ ++ if (inlineCodeLinkRegex != oldProps->inlineCodeLinkRegex) { ++ result["inlineCodeLinkRegex"] = toDynamic(inlineCodeLinkRegex); ++ } ++ + if (markdown != oldProps->markdown) { + result["markdown"] = markdown; + } +@@ -317,6 +372,8 @@ EnrichedMarkdownTextProps::EnrichedMarkdownTextProps( + const EnrichedMarkdownTextProps &sourceProps, + const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), + ++ linkRegex(convertRawProp(context, rawProps, "linkRegex", sourceProps.linkRegex, {})), ++ inlineCodeLinkRegex(convertRawProp(context, rawProps, "inlineCodeLinkRegex", sourceProps.inlineCodeLinkRegex, {})), + markdown(convertRawProp(context, rawProps, "markdown", sourceProps.markdown, {})), + markdownStyle(convertRawProp(context, rawProps, "markdownStyle", sourceProps.markdownStyle, {})), + enableImagePress(convertRawProp(context, rawProps, "enableImagePress", sourceProps.enableImagePress, {false})), +@@ -361,6 +418,14 @@ folly::dynamic EnrichedMarkdownTextProps::getDiffProps( + } + folly::dynamic result = HostPlatformViewProps::getDiffProps(prevProps); + ++ if (linkRegex != oldProps->linkRegex) { ++ result["linkRegex"] = toDynamic(linkRegex); ++ } ++ ++ if (inlineCodeLinkRegex != oldProps->inlineCodeLinkRegex) { ++ result["inlineCodeLinkRegex"] = toDynamic(inlineCodeLinkRegex); ++ } ++ + if (markdown != oldProps->markdown) { + result["markdown"] = markdown; + } +diff --git a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +index ed3b4bf2507500ee012b6412e85b48f11214b364..9c8f8139bbbbff277c0b10eb541723e366fb6015 100644 +--- a/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h ++++ b/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +@@ -18,6 +18,320 @@ + + namespace facebook::react { + ++struct EnrichedMarkdownImageSourcesHeadersStruct { ++ std::string name{}; ++ std::string value{}; ++ ++ ++#ifdef RN_SERIALIZABLE_STATE ++ bool operator==(const EnrichedMarkdownImageSourcesHeadersStruct&) const = default; ++ ++ folly::dynamic toDynamic() const { ++ folly::dynamic result = folly::dynamic::object(); ++ result["name"] = name; ++ result["value"] = value; ++ return result; ++ } ++#endif ++}; ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownImageSourcesHeadersStruct &result) { ++ auto map = (std::unordered_map)value; ++ ++ auto tmp_name = map.find("name"); ++ if (tmp_name != map.end()) { ++ fromRawValue(context, tmp_name->second, result.name); ++ } ++ auto tmp_value = map.find("value"); ++ if (tmp_value != map.end()) { ++ fromRawValue(context, tmp_value->second, result.value); ++ } ++} ++ ++static inline std::string toString(const EnrichedMarkdownImageSourcesHeadersStruct &value) { ++ return "[Object EnrichedMarkdownImageSourcesHeadersStruct]"; ++} ++ ++#ifdef RN_SERIALIZABLE_STATE ++static inline folly::dynamic toDynamic(const EnrichedMarkdownImageSourcesHeadersStruct &value) { ++ return value.toDynamic(); ++} ++#endif ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, std::vector &result) { ++ auto items = (std::vector)value; ++ for (const auto &item : items) { ++ EnrichedMarkdownImageSourcesHeadersStruct newItem; ++ fromRawValue(context, item, newItem); ++ result.emplace_back(newItem); ++ } ++} ++ ++ ++struct EnrichedMarkdownImageSourcesStruct { ++ std::string id{}; ++ std::string url{}; ++ std::string anchor{}; ++ std::string uri{}; ++ std::vector headers{}; ++ bool useDefault{false}; ++ ++ ++#ifdef RN_SERIALIZABLE_STATE ++ bool operator==(const EnrichedMarkdownImageSourcesStruct&) const = default; ++ ++ folly::dynamic toDynamic() const { ++ folly::dynamic result = folly::dynamic::object(); ++ result["id"] = id; ++ result["url"] = url; ++ result["anchor"] = anchor; ++ result["uri"] = uri; ++ result["headers"] = ::facebook::react::toDynamic(headers); ++ result["useDefault"] = useDefault; ++ return result; ++ } ++#endif ++}; ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownImageSourcesStruct &result) { ++ auto map = (std::unordered_map)value; ++ ++ auto tmp_id = map.find("id"); ++ if (tmp_id != map.end()) { ++ fromRawValue(context, tmp_id->second, result.id); ++ } ++ auto tmp_url = map.find("url"); ++ if (tmp_url != map.end()) { ++ fromRawValue(context, tmp_url->second, result.url); ++ } ++ auto tmp_anchor = map.find("anchor"); ++ if (tmp_anchor != map.end()) { ++ fromRawValue(context, tmp_anchor->second, result.anchor); ++ } ++ auto tmp_uri = map.find("uri"); ++ if (tmp_uri != map.end()) { ++ fromRawValue(context, tmp_uri->second, result.uri); ++ } ++ auto tmp_headers = map.find("headers"); ++ if (tmp_headers != map.end()) { ++ fromRawValue(context, tmp_headers->second, result.headers); ++ } ++ auto tmp_useDefault = map.find("useDefault"); ++ if (tmp_useDefault != map.end()) { ++ fromRawValue(context, tmp_useDefault->second, result.useDefault); ++ } ++} ++ ++static inline std::string toString(const EnrichedMarkdownImageSourcesStruct &value) { ++ return "[Object EnrichedMarkdownImageSourcesStruct]"; ++} ++ ++#ifdef RN_SERIALIZABLE_STATE ++static inline folly::dynamic toDynamic(const EnrichedMarkdownImageSourcesStruct &value) { ++ return value.toDynamic(); ++} ++#endif ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, std::vector &result) { ++ auto items = (std::vector)value; ++ for (const auto &item : items) { ++ EnrichedMarkdownImageSourcesStruct newItem; ++ fromRawValue(context, item, newItem); ++ result.emplace_back(newItem); ++ } ++} ++ ++ ++struct EnrichedMarkdownMediaOverridesStruct { ++ std::string url{}; ++ std::string kind{}; ++ std::string anchor{}; ++ std::string id{}; ++ Float height{0.0}; ++ Float width{0.0}; ++ ++ ++#ifdef RN_SERIALIZABLE_STATE ++ bool operator==(const EnrichedMarkdownMediaOverridesStruct&) const = default; ++ ++ folly::dynamic toDynamic() const { ++ folly::dynamic result = folly::dynamic::object(); ++ result["url"] = url; ++ result["kind"] = kind; ++ result["anchor"] = anchor; ++ result["id"] = id; ++ result["height"] = height; ++ result["width"] = width; ++ return result; ++ } ++#endif ++}; ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownMediaOverridesStruct &result) { ++ auto map = (std::unordered_map)value; ++ ++ auto tmp_url = map.find("url"); ++ if (tmp_url != map.end()) { ++ fromRawValue(context, tmp_url->second, result.url); ++ } ++ auto tmp_kind = map.find("kind"); ++ if (tmp_kind != map.end()) { ++ fromRawValue(context, tmp_kind->second, result.kind); ++ } ++ auto tmp_anchor = map.find("anchor"); ++ if (tmp_anchor != map.end()) { ++ fromRawValue(context, tmp_anchor->second, result.anchor); ++ } ++ auto tmp_id = map.find("id"); ++ if (tmp_id != map.end()) { ++ fromRawValue(context, tmp_id->second, result.id); ++ } ++ auto tmp_height = map.find("height"); ++ if (tmp_height != map.end()) { ++ fromRawValue(context, tmp_height->second, result.height); ++ } ++ auto tmp_width = map.find("width"); ++ if (tmp_width != map.end()) { ++ fromRawValue(context, tmp_width->second, result.width); ++ } ++} ++ ++static inline std::string toString(const EnrichedMarkdownMediaOverridesStruct &value) { ++ return "[Object EnrichedMarkdownMediaOverridesStruct]"; ++} ++ ++#ifdef RN_SERIALIZABLE_STATE ++static inline folly::dynamic toDynamic(const EnrichedMarkdownMediaOverridesStruct &value) { ++ return value.toDynamic(); ++} ++#endif ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, std::vector &result) { ++ auto items = (std::vector)value; ++ for (const auto &item : items) { ++ EnrichedMarkdownMediaOverridesStruct newItem; ++ fromRawValue(context, item, newItem); ++ result.emplace_back(newItem); ++ } ++} ++ ++ ++struct EnrichedMarkdownLinkRegexStruct { ++ std::string pattern{}; ++ bool caseInsensitive{false}; ++ bool dotAll{false}; ++ bool isDisabled{false}; ++ bool isDefault{false}; ++ ++ ++#ifdef RN_SERIALIZABLE_STATE ++ bool operator==(const EnrichedMarkdownLinkRegexStruct&) const = default; ++ ++ folly::dynamic toDynamic() const { ++ folly::dynamic result = folly::dynamic::object(); ++ result["pattern"] = pattern; ++ result["caseInsensitive"] = caseInsensitive; ++ result["dotAll"] = dotAll; ++ result["isDisabled"] = isDisabled; ++ result["isDefault"] = isDefault; ++ return result; ++ } ++#endif ++}; ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownLinkRegexStruct &result) { ++ auto map = (std::unordered_map)value; ++ ++ auto tmp_pattern = map.find("pattern"); ++ if (tmp_pattern != map.end()) { ++ fromRawValue(context, tmp_pattern->second, result.pattern); ++ } ++ auto tmp_caseInsensitive = map.find("caseInsensitive"); ++ if (tmp_caseInsensitive != map.end()) { ++ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); ++ } ++ auto tmp_dotAll = map.find("dotAll"); ++ if (tmp_dotAll != map.end()) { ++ fromRawValue(context, tmp_dotAll->second, result.dotAll); ++ } ++ auto tmp_isDisabled = map.find("isDisabled"); ++ if (tmp_isDisabled != map.end()) { ++ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); ++ } ++ auto tmp_isDefault = map.find("isDefault"); ++ if (tmp_isDefault != map.end()) { ++ fromRawValue(context, tmp_isDefault->second, result.isDefault); ++ } ++} ++ ++static inline std::string toString(const EnrichedMarkdownLinkRegexStruct &value) { ++ return "[Object EnrichedMarkdownLinkRegexStruct]"; ++} ++ ++#ifdef RN_SERIALIZABLE_STATE ++static inline folly::dynamic toDynamic(const EnrichedMarkdownLinkRegexStruct &value) { ++ return value.toDynamic(); ++} ++#endif ++ ++struct EnrichedMarkdownInlineCodeLinkRegexStruct { ++ std::string pattern{}; ++ bool caseInsensitive{false}; ++ bool dotAll{false}; ++ bool isDisabled{false}; ++ bool isDefault{false}; ++ ++ ++#ifdef RN_SERIALIZABLE_STATE ++ bool operator==(const EnrichedMarkdownInlineCodeLinkRegexStruct&) const = default; ++ ++ folly::dynamic toDynamic() const { ++ folly::dynamic result = folly::dynamic::object(); ++ result["pattern"] = pattern; ++ result["caseInsensitive"] = caseInsensitive; ++ result["dotAll"] = dotAll; ++ result["isDisabled"] = isDisabled; ++ result["isDefault"] = isDefault; ++ return result; ++ } ++#endif ++}; ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownInlineCodeLinkRegexStruct &result) { ++ auto map = (std::unordered_map)value; ++ ++ auto tmp_pattern = map.find("pattern"); ++ if (tmp_pattern != map.end()) { ++ fromRawValue(context, tmp_pattern->second, result.pattern); ++ } ++ auto tmp_caseInsensitive = map.find("caseInsensitive"); ++ if (tmp_caseInsensitive != map.end()) { ++ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); ++ } ++ auto tmp_dotAll = map.find("dotAll"); ++ if (tmp_dotAll != map.end()) { ++ fromRawValue(context, tmp_dotAll->second, result.dotAll); ++ } ++ auto tmp_isDisabled = map.find("isDisabled"); ++ if (tmp_isDisabled != map.end()) { ++ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); ++ } ++ auto tmp_isDefault = map.find("isDefault"); ++ if (tmp_isDefault != map.end()) { ++ fromRawValue(context, tmp_isDefault->second, result.isDefault); ++ } ++} ++ ++static inline std::string toString(const EnrichedMarkdownInlineCodeLinkRegexStruct &value) { ++ return "[Object EnrichedMarkdownInlineCodeLinkRegexStruct]"; ++} ++ ++#ifdef RN_SERIALIZABLE_STATE ++static inline folly::dynamic toDynamic(const EnrichedMarkdownInlineCodeLinkRegexStruct &value) { ++ return value.toDynamic(); ++} ++#endif ++ + struct EnrichedMarkdownMarkdownStyleParagraphStruct { + Float fontSize{0.0}; + std::string fontFamily{}; +@@ -1313,6 +1627,17 @@ struct EnrichedMarkdownMarkdownStyleLinkVariantsStruct { + SharedColor color{}; + bool underline{false}; + SharedColor backgroundColor{}; ++ std::string fontFamily{}; ++ bool pill{false}; ++ std::string label{}; ++ std::string iconUri{}; ++ SharedColor iconTintColor{}; ++ Float borderRadius{0.0}; ++ Float paddingHorizontal{0.0}; ++ Float paddingVertical{0.0}; ++ Float borderWidth{0.0}; ++ SharedColor borderColor{}; ++ Float maxWidth{0.0}; + + + #ifdef RN_SERIALIZABLE_STATE +@@ -1324,6 +1649,17 @@ struct EnrichedMarkdownMarkdownStyleLinkVariantsStruct { + result["color"] = ::facebook::react::toDynamic(color); + result["underline"] = underline; + result["backgroundColor"] = ::facebook::react::toDynamic(backgroundColor); ++ result["fontFamily"] = fontFamily; ++ result["pill"] = pill; ++ result["label"] = label; ++ result["iconUri"] = iconUri; ++ result["iconTintColor"] = ::facebook::react::toDynamic(iconTintColor); ++ result["borderRadius"] = borderRadius; ++ result["paddingHorizontal"] = paddingHorizontal; ++ result["paddingVertical"] = paddingVertical; ++ result["borderWidth"] = borderWidth; ++ result["borderColor"] = ::facebook::react::toDynamic(borderColor); ++ result["maxWidth"] = maxWidth; + return result; + } + #endif +@@ -1348,6 +1684,50 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu + if (tmp_backgroundColor != map.end()) { + fromRawValue(context, tmp_backgroundColor->second, result.backgroundColor); + } ++ auto tmp_fontFamily = map.find("fontFamily"); ++ if (tmp_fontFamily != map.end()) { ++ fromRawValue(context, tmp_fontFamily->second, result.fontFamily); ++ } ++ auto tmp_pill = map.find("pill"); ++ if (tmp_pill != map.end()) { ++ fromRawValue(context, tmp_pill->second, result.pill); ++ } ++ auto tmp_label = map.find("label"); ++ if (tmp_label != map.end()) { ++ fromRawValue(context, tmp_label->second, result.label); ++ } ++ auto tmp_iconUri = map.find("iconUri"); ++ if (tmp_iconUri != map.end()) { ++ fromRawValue(context, tmp_iconUri->second, result.iconUri); ++ } ++ auto tmp_iconTintColor = map.find("iconTintColor"); ++ if (tmp_iconTintColor != map.end()) { ++ fromRawValue(context, tmp_iconTintColor->second, result.iconTintColor); ++ } ++ auto tmp_borderRadius = map.find("borderRadius"); ++ if (tmp_borderRadius != map.end()) { ++ fromRawValue(context, tmp_borderRadius->second, result.borderRadius); ++ } ++ auto tmp_paddingHorizontal = map.find("paddingHorizontal"); ++ if (tmp_paddingHorizontal != map.end()) { ++ fromRawValue(context, tmp_paddingHorizontal->second, result.paddingHorizontal); ++ } ++ auto tmp_paddingVertical = map.find("paddingVertical"); ++ if (tmp_paddingVertical != map.end()) { ++ fromRawValue(context, tmp_paddingVertical->second, result.paddingVertical); ++ } ++ auto tmp_borderWidth = map.find("borderWidth"); ++ if (tmp_borderWidth != map.end()) { ++ fromRawValue(context, tmp_borderWidth->second, result.borderWidth); ++ } ++ auto tmp_borderColor = map.find("borderColor"); ++ if (tmp_borderColor != map.end()) { ++ fromRawValue(context, tmp_borderColor->second, result.borderColor); ++ } ++ auto tmp_maxWidth = map.find("maxWidth"); ++ if (tmp_maxWidth != map.end()) { ++ fromRawValue(context, tmp_maxWidth->second, result.maxWidth); ++ } + } + + static inline std::string toString(const EnrichedMarkdownMarkdownStyleLinkVariantsStruct &value) { +@@ -3116,6 +3496,17 @@ class EnrichedMarkdownProps final : public ViewProps { + + #pragma mark - Props + ++ bool enableImageSourceResolution{false}; ++ int imageSourcesRevision{-1}; ++ int imageSourcesContinuityStart{1}; ++ std::vector imageSources{}; ++ int documentRevision{0}; ++ bool enableDocumentAssets{false}; ++ bool enableMediaSlots{false}; ++ int mediaOverridesRevision{-1}; ++ std::vector mediaOverrides{}; ++ EnrichedMarkdownLinkRegexStruct linkRegex{}; ++ EnrichedMarkdownInlineCodeLinkRegexStruct inlineCodeLinkRegex{}; + std::string markdown{}; + EnrichedMarkdownMarkdownStyleStruct markdownStyle{}; + bool enableImagePress{false}; +@@ -4078,6 +4469,122 @@ class EnrichedMarkdownTextInputProps final : public ViewProps { + + }; + ++struct EnrichedMarkdownTextLinkRegexStruct { ++ std::string pattern{}; ++ bool caseInsensitive{false}; ++ bool dotAll{false}; ++ bool isDisabled{false}; ++ bool isDefault{false}; ++ ++ ++#ifdef RN_SERIALIZABLE_STATE ++ bool operator==(const EnrichedMarkdownTextLinkRegexStruct&) const = default; ++ ++ folly::dynamic toDynamic() const { ++ folly::dynamic result = folly::dynamic::object(); ++ result["pattern"] = pattern; ++ result["caseInsensitive"] = caseInsensitive; ++ result["dotAll"] = dotAll; ++ result["isDisabled"] = isDisabled; ++ result["isDefault"] = isDefault; ++ return result; ++ } ++#endif ++}; ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownTextLinkRegexStruct &result) { ++ auto map = (std::unordered_map)value; ++ ++ auto tmp_pattern = map.find("pattern"); ++ if (tmp_pattern != map.end()) { ++ fromRawValue(context, tmp_pattern->second, result.pattern); ++ } ++ auto tmp_caseInsensitive = map.find("caseInsensitive"); ++ if (tmp_caseInsensitive != map.end()) { ++ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); ++ } ++ auto tmp_dotAll = map.find("dotAll"); ++ if (tmp_dotAll != map.end()) { ++ fromRawValue(context, tmp_dotAll->second, result.dotAll); ++ } ++ auto tmp_isDisabled = map.find("isDisabled"); ++ if (tmp_isDisabled != map.end()) { ++ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); ++ } ++ auto tmp_isDefault = map.find("isDefault"); ++ if (tmp_isDefault != map.end()) { ++ fromRawValue(context, tmp_isDefault->second, result.isDefault); ++ } ++} ++ ++static inline std::string toString(const EnrichedMarkdownTextLinkRegexStruct &value) { ++ return "[Object EnrichedMarkdownTextLinkRegexStruct]"; ++} ++ ++#ifdef RN_SERIALIZABLE_STATE ++static inline folly::dynamic toDynamic(const EnrichedMarkdownTextLinkRegexStruct &value) { ++ return value.toDynamic(); ++} ++#endif ++ ++struct EnrichedMarkdownTextInlineCodeLinkRegexStruct { ++ std::string pattern{}; ++ bool caseInsensitive{false}; ++ bool dotAll{false}; ++ bool isDisabled{false}; ++ bool isDefault{false}; ++ ++ ++#ifdef RN_SERIALIZABLE_STATE ++ bool operator==(const EnrichedMarkdownTextInlineCodeLinkRegexStruct&) const = default; ++ ++ folly::dynamic toDynamic() const { ++ folly::dynamic result = folly::dynamic::object(); ++ result["pattern"] = pattern; ++ result["caseInsensitive"] = caseInsensitive; ++ result["dotAll"] = dotAll; ++ result["isDisabled"] = isDisabled; ++ result["isDefault"] = isDefault; ++ return result; ++ } ++#endif ++}; ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownTextInlineCodeLinkRegexStruct &result) { ++ auto map = (std::unordered_map)value; ++ ++ auto tmp_pattern = map.find("pattern"); ++ if (tmp_pattern != map.end()) { ++ fromRawValue(context, tmp_pattern->second, result.pattern); ++ } ++ auto tmp_caseInsensitive = map.find("caseInsensitive"); ++ if (tmp_caseInsensitive != map.end()) { ++ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); ++ } ++ auto tmp_dotAll = map.find("dotAll"); ++ if (tmp_dotAll != map.end()) { ++ fromRawValue(context, tmp_dotAll->second, result.dotAll); ++ } ++ auto tmp_isDisabled = map.find("isDisabled"); ++ if (tmp_isDisabled != map.end()) { ++ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); ++ } ++ auto tmp_isDefault = map.find("isDefault"); ++ if (tmp_isDefault != map.end()) { ++ fromRawValue(context, tmp_isDefault->second, result.isDefault); ++ } ++} ++ ++static inline std::string toString(const EnrichedMarkdownTextInlineCodeLinkRegexStruct &value) { ++ return "[Object EnrichedMarkdownTextInlineCodeLinkRegexStruct]"; ++} ++ ++#ifdef RN_SERIALIZABLE_STATE ++static inline folly::dynamic toDynamic(const EnrichedMarkdownTextInlineCodeLinkRegexStruct &value) { ++ return value.toDynamic(); ++} ++#endif ++ + struct EnrichedMarkdownTextMarkdownStyleParagraphStruct { + Float fontSize{0.0}; + std::string fontFamily{}; +@@ -5373,6 +5880,17 @@ struct EnrichedMarkdownTextMarkdownStyleLinkVariantsStruct { + SharedColor color{}; + bool underline{false}; + SharedColor backgroundColor{}; ++ std::string fontFamily{}; ++ bool pill{false}; ++ std::string label{}; ++ std::string iconUri{}; ++ SharedColor iconTintColor{}; ++ Float borderRadius{0.0}; ++ Float paddingHorizontal{0.0}; ++ Float paddingVertical{0.0}; ++ Float borderWidth{0.0}; ++ SharedColor borderColor{}; ++ Float maxWidth{0.0}; + + + #ifdef RN_SERIALIZABLE_STATE +@@ -5384,6 +5902,17 @@ struct EnrichedMarkdownTextMarkdownStyleLinkVariantsStruct { + result["color"] = ::facebook::react::toDynamic(color); + result["underline"] = underline; + result["backgroundColor"] = ::facebook::react::toDynamic(backgroundColor); ++ result["fontFamily"] = fontFamily; ++ result["pill"] = pill; ++ result["label"] = label; ++ result["iconUri"] = iconUri; ++ result["iconTintColor"] = ::facebook::react::toDynamic(iconTintColor); ++ result["borderRadius"] = borderRadius; ++ result["paddingHorizontal"] = paddingHorizontal; ++ result["paddingVertical"] = paddingVertical; ++ result["borderWidth"] = borderWidth; ++ result["borderColor"] = ::facebook::react::toDynamic(borderColor); ++ result["maxWidth"] = maxWidth; + return result; + } + #endif +@@ -5408,6 +5937,50 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu + if (tmp_backgroundColor != map.end()) { + fromRawValue(context, tmp_backgroundColor->second, result.backgroundColor); + } ++ auto tmp_fontFamily = map.find("fontFamily"); ++ if (tmp_fontFamily != map.end()) { ++ fromRawValue(context, tmp_fontFamily->second, result.fontFamily); ++ } ++ auto tmp_pill = map.find("pill"); ++ if (tmp_pill != map.end()) { ++ fromRawValue(context, tmp_pill->second, result.pill); ++ } ++ auto tmp_label = map.find("label"); ++ if (tmp_label != map.end()) { ++ fromRawValue(context, tmp_label->second, result.label); ++ } ++ auto tmp_iconUri = map.find("iconUri"); ++ if (tmp_iconUri != map.end()) { ++ fromRawValue(context, tmp_iconUri->second, result.iconUri); ++ } ++ auto tmp_iconTintColor = map.find("iconTintColor"); ++ if (tmp_iconTintColor != map.end()) { ++ fromRawValue(context, tmp_iconTintColor->second, result.iconTintColor); ++ } ++ auto tmp_borderRadius = map.find("borderRadius"); ++ if (tmp_borderRadius != map.end()) { ++ fromRawValue(context, tmp_borderRadius->second, result.borderRadius); ++ } ++ auto tmp_paddingHorizontal = map.find("paddingHorizontal"); ++ if (tmp_paddingHorizontal != map.end()) { ++ fromRawValue(context, tmp_paddingHorizontal->second, result.paddingHorizontal); ++ } ++ auto tmp_paddingVertical = map.find("paddingVertical"); ++ if (tmp_paddingVertical != map.end()) { ++ fromRawValue(context, tmp_paddingVertical->second, result.paddingVertical); ++ } ++ auto tmp_borderWidth = map.find("borderWidth"); ++ if (tmp_borderWidth != map.end()) { ++ fromRawValue(context, tmp_borderWidth->second, result.borderWidth); ++ } ++ auto tmp_borderColor = map.find("borderColor"); ++ if (tmp_borderColor != map.end()) { ++ fromRawValue(context, tmp_borderColor->second, result.borderColor); ++ } ++ auto tmp_maxWidth = map.find("maxWidth"); ++ if (tmp_maxWidth != map.end()) { ++ fromRawValue(context, tmp_maxWidth->second, result.maxWidth); ++ } + } + + static inline std::string toString(const EnrichedMarkdownTextMarkdownStyleLinkVariantsStruct &value) { +@@ -7176,6 +7749,8 @@ class EnrichedMarkdownTextProps final : public ViewProps { + + #pragma mark - Props + ++ EnrichedMarkdownTextLinkRegexStruct linkRegex{}; ++ EnrichedMarkdownTextInlineCodeLinkRegexStruct inlineCodeLinkRegex{}; + std::string markdown{}; + EnrichedMarkdownTextMarkdownStyleStruct markdownStyle{}; + bool enableImagePress{false}; +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +index b6b38b4cc1a37eacf53f48f940608ed7ead26f93..5031b3b10dc9675b54b9f36701aadc3ae074bc70 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +@@ -9,9 +9,20 @@ import android.util.Log + import android.view.View + import com.facebook.react.bridge.Arguments + import com.facebook.react.bridge.ReadableMap ++import com.facebook.react.uimanager.PixelUtil + import com.facebook.react.uimanager.StateWrapper + import com.swmansion.enriched.markdown.accessibility.AccessibilityLabels ++import com.swmansion.enriched.markdown.input.autolink.LinkRegexConfig + import com.swmansion.enriched.markdown.math.LatexErrorReporter ++import com.swmansion.enriched.markdown.media.DocumentAsset ++import com.swmansion.enriched.markdown.media.DocumentAssets ++import com.swmansion.enriched.markdown.media.ImageSourceDecision ++import com.swmansion.enriched.markdown.media.MediaOverride ++import com.swmansion.enriched.markdown.media.MediaSlotView ++import com.swmansion.enriched.markdown.media.documentAssetsEventData ++import com.swmansion.enriched.markdown.media.emitMediaEvent ++import com.swmansion.enriched.markdown.media.mediaSlotsForDocument ++import com.swmansion.enriched.markdown.media.withImageSources + import com.swmansion.enriched.markdown.parser.Md4cFlags + import com.swmansion.enriched.markdown.parser.Parser + import com.swmansion.enriched.markdown.segments.BlockquoteContainerView +@@ -57,6 +68,87 @@ class EnrichedMarkdown( + private val videoContainerClass: Class<*>? by lazy { SegmentViewCreators.videoContainerClass() } + + private var currentRenderId = 0L ++ private var enableImageSourceResolution = false ++ private var imageSourcesRevision = -1 ++ private var imageSourcesContinuityStart = 1 ++ private var imageSources = emptyList() ++ private var documentRevision = 0 ++ private var mediaOverridesRevision = -1 ++ private var enableDocumentAssets = false ++ private var enableMediaSlots = false ++ private var mediaOverrides = emptyList() ++ private var acceptedRevision = -1 ++ private var acceptedAssets = emptyList() ++ private var lastAssetManifest: Pair>? = null ++ private var lastMediaFrames: String? = null ++ ++ fun setEnableImageSourceResolution(value: Boolean) { ++ if (enableImageSourceResolution == value) return ++ enableImageSourceResolution = value ++ dirtyFlags += DirtyFlag.RECREATE_SEGMENTS ++ dirtyFlags += DirtyFlag.FORCE_HEIGHT ++ renderPending = true ++ } ++ ++ fun setImageSourcesRevision(value: Int) { ++ if (imageSourcesRevision == value) return ++ imageSourcesRevision = value ++ dirtyFlags += DirtyFlag.RECREATE_SEGMENTS ++ dirtyFlags += DirtyFlag.FORCE_HEIGHT ++ renderPending = true ++ } ++ ++ fun setImageSourcesContinuityStart(value: Int) { ++ if (imageSourcesContinuityStart == value) return ++ imageSourcesContinuityStart = value ++ dirtyFlags += DirtyFlag.RECREATE_SEGMENTS ++ dirtyFlags += DirtyFlag.FORCE_HEIGHT ++ renderPending = true ++ } ++ ++ fun setImageSources(value: List) { ++ if (imageSources == value) return ++ imageSources = value ++ dirtyFlags += DirtyFlag.RECREATE_SEGMENTS ++ dirtyFlags += DirtyFlag.FORCE_HEIGHT ++ renderPending = true ++ } ++ ++ fun setDocumentRevision(value: Int) { ++ if (documentRevision == value) return ++ documentRevision = value ++ ++currentRenderId ++ renderPending = true ++ } ++ ++ fun setMediaOverridesRevision(value: Int) { ++ if (mediaOverridesRevision == value) return ++ mediaOverridesRevision = value ++ dirtyFlags += DirtyFlag.FORCE_HEIGHT ++ renderPending = true ++ } ++ ++ fun setEnableDocumentAssets(value: Boolean) { ++ if (enableDocumentAssets == value) return ++ enableDocumentAssets = value ++ lastAssetManifest = null ++ renderPending = true ++ } ++ ++ fun setEnableMediaSlots(value: Boolean) { ++ if (enableMediaSlots == value) return ++ enableMediaSlots = value ++ dirtyFlags += DirtyFlag.FORCE_HEIGHT ++ renderPending = true ++ } ++ ++ fun setMediaOverrides(value: List) { ++ if (mediaOverrides == value) return ++ mediaOverrides = value ++ dirtyFlags += DirtyFlag.FORCE_HEIGHT ++ renderPending = true ++ } ++ + private val dirtyFlags = EnumSet.noneOf(DirtyFlag::class.java) + var streamingAnimation: Boolean = false + +@@ -79,6 +171,8 @@ class EnrichedMarkdown( + + var md4cFlags: Md4cFlags = Md4cFlags.DEFAULT + private set ++ private var linkRegex: LinkRegexConfig? = null ++ private var inlineCodeLinkRegex: LinkRegexConfig? = null + private var isGFM: Boolean = true + private var allowFontScaling: Boolean = true + private var maxFontSizeMultiplier: Float = 0f +@@ -143,6 +237,7 @@ class EnrichedMarkdown( + fun setMarkdownContent(markdown: String) { + if (currentMarkdown == markdown) return + currentMarkdown = markdown ++ ++currentRenderId + renderPending = true + } + +@@ -188,6 +283,18 @@ class EnrichedMarkdown( + } + } + ++ fun setLinkRegex(config: LinkRegexConfig?) { ++ if (linkRegex == config) return ++ linkRegex = config ++ renderPending = true ++ } ++ ++ fun setInlineCodeLinkRegex(config: LinkRegexConfig?) { ++ if (inlineCodeLinkRegex == config) return ++ inlineCodeLinkRegex = config ++ renderPending = true ++ } ++ + fun setMd4cFlags(flags: Md4cFlags) { + if (md4cFlags == flags) return + md4cFlags = flags +@@ -362,7 +469,11 @@ class EnrichedMarkdown( + } + + private fun scheduleRenderIfNeeded() { +- if (currentMarkdown.isNotEmpty()) scheduleRender() ++ if (currentMarkdown.isNotEmpty()) { ++ scheduleRender() ++ } else { ++ applyEmptyDocument(documentRevision) ++ } + } + + private fun scheduleRender() { +@@ -372,6 +483,19 @@ class EnrichedMarkdown( + val tableMode = tableStreamingMode + val codeBlockMode = codeBlockStreamingMode + ++ val sourcesEnabled = enableImageSourceResolution && isGFM ++ val sourcesRevision = imageSourcesRevision ++ val sourcesContinuityStart = imageSourcesContinuityStart ++ val sources = imageSources ++ val revision = documentRevision ++ val assetEventsEnabled = enableDocumentAssets ++ val slotsEnabled = enableMediaSlots ++ val overrideRevision = mediaOverridesRevision ++ val overrides = mediaOverrides ++ val flags = md4cFlags ++ val gfm = isGFM ++ val textLinkRegex = linkRegex ++ val codeLinkRegex = inlineCodeLinkRegex + val renderId = ++currentRenderId + + executor.execute { +@@ -386,17 +510,20 @@ class EnrichedMarkdown( + val hasPendingCodeBlock = filtered?.endsInsideOpenCodeFence ?: false + + if (renderableMarkdown.isEmpty()) { +- postToMain(renderId) { applyRenderedSegments(emptyList(), false) } ++ postToMain(renderId) { applyEmptyDocument(revision) } + return@execute + } + + val ast = +- parser.parseMarkdown(renderableMarkdown, md4cFlags, isGFM) ?: run { +- postToMain(renderId) { applyRenderedSegments(emptyList(), false) } ++ parser.parseMarkdown(renderableMarkdown, flags, gfm, textLinkRegex, codeLinkRegex) ?: run { ++ postToMain(renderId) { applyEmptyDocument(revision) } + return@execute + } + +- val segments = splitASTIntoSegments(ast) ++ val sourceAST = withImageSources(ast, sourcesEnabled, revision, sourcesRevision, sourcesContinuityStart, sources) ++ val assets = DocumentAssets.collect(sourceAST) ++ val mediaSlots = mediaSlotsForDocument(assets, slotsEnabled, revision, overrideRevision, overrides) ++ val segments = splitASTIntoSegments(sourceAST, mediaSlots, assets) + val renderedSegments = + MarkdownSegmentRenderer.render( + segments, +@@ -407,10 +534,19 @@ class EnrichedMarkdown( + onLatexError = latexErrorReporter, + ) + +- postToMain(renderId) { applyRenderedSegments(renderedSegments, hasPendingCodeBlock) } ++ postToMain(renderId) { ++ if (revision != documentRevision) return@postToMain ++ acceptedRevision = revision ++ acceptedAssets = assets.assets ++ val forceHeight = DirtyFlag.FORCE_HEIGHT in dirtyFlags ++ applyRenderedSegments(renderedSegments, hasPendingCodeBlock) ++ if (assetEventsEnabled) publishAssets(revision, assets.assets) ++ publishMediaFrames() ++ if (forceHeight) onImageLayoutChanged() ++ } + } catch (e: Exception) { + Log.e(TAG, "Render failed", e) +- postToMain(renderId) { applyRenderedSegments(emptyList(), false) } ++ postToMain(renderId) { applyEmptyDocument(revision) } + } + } + } +@@ -493,7 +629,7 @@ class EnrichedMarkdown( + is RenderedSegment.Math -> isMathContainerView(view) + is RenderedSegment.CodeBlock -> view is CodeBlockContainerView + is RenderedSegment.Blockquote -> view is BlockquoteContainerView +- is RenderedSegment.Video -> isVideoContainerView(view) ++ is RenderedSegment.Video -> if (segment.mediaSlot != null) view is MediaSlotView else isVideoContainerView(view) + } + + override fun createView(segment: RenderedSegment): View { +@@ -563,7 +699,7 @@ class EnrichedMarkdown( + } + + is RenderedSegment.Blockquote -> { +- (view as BlockquoteContainerView).applyBlockquoteNode(segment.node) ++ (view as BlockquoteContainerView).applyBlockquoteNode(segment.node, segment.mediaSlots, segment.assets) + } + + is RenderedSegment.Video -> { +@@ -628,6 +764,8 @@ class EnrichedMarkdown( + b: Int, + ) { + layoutSegments() ++ if (acceptedRevision == documentRevision) publishAssets(acceptedRevision, acceptedAssets) ++ publishMediaFrames() + } + + fun onImageLayoutChanged() { +@@ -642,7 +780,60 @@ class EnrichedMarkdown( + wrapper.updateState(state) + } + ++ private fun applyEmptyDocument(revision: Int) { ++ if (revision != documentRevision) return ++ acceptedRevision = revision ++ acceptedAssets = emptyList() ++ applyRenderedSegments(emptyList(), false) ++ publishAssets(revision, emptyList()) ++ publishMediaFrames() ++ onImageLayoutChanged() ++ } ++ ++ private fun publishAssets( ++ revision: Int, ++ assets: List, ++ ) { ++ if (!enableDocumentAssets) return ++ val manifest = revision to assets ++ if (lastAssetManifest == manifest) return ++ if (emitMediaEvent(this, "onDocumentAssets", documentAssetsEventData(revision, assets))) { ++ lastAssetManifest = manifest ++ } ++ } ++ ++ private fun publishMediaFrames() { ++ if (acceptedRevision != documentRevision || width <= 0) return ++ val slots = mediaSlotFrames() ++ val key = ++ "$acceptedRevision:" + ++ slots.joinToString(";") { ++ "${it.id},${it.x},${it.y},${it.width},${it.height}" ++ } ++ if (lastMediaFrames == key) return ++ val frames = Arguments.createArray() ++ slots.forEach { view -> ++ frames.pushMap( ++ Arguments.createMap().apply { ++ putString("id", view.id) ++ putDouble("x", PixelUtil.toDIPFromPixel(view.x.toFloat()).toDouble()) ++ putDouble("y", PixelUtil.toDIPFromPixel(view.y.toFloat()).toDouble()) ++ putDouble("width", PixelUtil.toDIPFromPixel(view.width.toFloat()).toDouble()) ++ putDouble("height", PixelUtil.toDIPFromPixel(view.height.toFloat()).toDouble()) ++ }, ++ ) ++ } ++ val data = ++ Arguments.createMap().apply { ++ putInt("revision", acceptedRevision) ++ putArray("frames", frames) ++ } ++ if (emitMediaEvent(this, "onMediaLayout", data)) lastMediaFrames = key ++ } ++ + fun cleanup() { ++ ++currentRenderId ++ mainHandler.removeCallbacksAndMessages(null) + executor.shutdownNow() + } + +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +index 61eed4b3119e1a802b5f99eb36a5ee815b8269b6..93fffcd9fcc2e5373b3928a6621403f2863e8103 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +@@ -13,6 +13,9 @@ import com.facebook.react.uimanager.annotations.ReactProp + import com.facebook.react.viewmanagers.EnrichedMarkdownManagerDelegate + import com.facebook.react.viewmanagers.EnrichedMarkdownManagerInterface + import com.facebook.yoga.YogaMeasureMode ++import com.swmansion.enriched.markdown.media.parseImageSources ++import com.swmansion.enriched.markdown.media.parseMediaOverrides ++import com.swmansion.enriched.markdown.parser.parseTextLinkRegex + import com.swmansion.enriched.markdown.spoiler.SpoilerOverlay + import com.swmansion.enriched.markdown.utils.common.CodeBlockStreamingMode + import com.swmansion.enriched.markdown.utils.common.TableStreamingMode +@@ -112,7 +115,83 @@ class EnrichedMarkdownManager : + MeasurementStore.clearFontScalingSettings(view.id) + } + +- override fun getExportedCustomDirectEventTypeConstants(): MutableMap = markdownEventTypeConstants() ++ override fun getExportedCustomDirectEventTypeConstants(): MutableMap = ++ markdownEventTypeConstants().apply { ++ put("onDocumentAssets", mapOf("registrationName" to "onDocumentAssets")) ++ put("onMediaLayout", mapOf("registrationName" to "onMediaLayout")) ++ } ++ ++ @ReactProp(name = "enableImageSourceResolution", defaultBoolean = false) ++ override fun setEnableImageSourceResolution( ++ view: EnrichedMarkdown?, ++ value: Boolean, ++ ) { ++ view?.setEnableImageSourceResolution(value) ++ } ++ ++ @ReactProp(name = "imageSourcesRevision", defaultInt = -1) ++ override fun setImageSourcesRevision( ++ view: EnrichedMarkdown?, ++ value: Int, ++ ) { ++ view?.setImageSourcesRevision(value) ++ } ++ ++ @ReactProp(name = "imageSourcesContinuityStart", defaultInt = 1) ++ override fun setImageSourcesContinuityStart( ++ view: EnrichedMarkdown?, ++ value: Int, ++ ) { ++ view?.setImageSourcesContinuityStart(value) ++ } ++ ++ @ReactProp(name = "imageSources") ++ override fun setImageSources( ++ view: EnrichedMarkdown?, ++ value: ReadableArray?, ++ ) { ++ view?.setImageSources(parseImageSources(value)) ++ } ++ ++ @ReactProp(name = "documentRevision", defaultInt = 0) ++ override fun setDocumentRevision( ++ view: EnrichedMarkdown?, ++ value: Int, ++ ) { ++ view?.setDocumentRevision(value) ++ } ++ ++ @ReactProp(name = "mediaOverridesRevision", defaultInt = -1) ++ override fun setMediaOverridesRevision( ++ view: EnrichedMarkdown?, ++ value: Int, ++ ) { ++ view?.setMediaOverridesRevision(value) ++ } ++ ++ @ReactProp(name = "enableDocumentAssets", defaultBoolean = false) ++ override fun setEnableDocumentAssets( ++ view: EnrichedMarkdown?, ++ value: Boolean, ++ ) { ++ view?.setEnableDocumentAssets(value) ++ } ++ ++ @ReactProp(name = "enableMediaSlots", defaultBoolean = false) ++ override fun setEnableMediaSlots( ++ view: EnrichedMarkdown?, ++ value: Boolean, ++ ) { ++ view?.setEnableMediaSlots(value) ++ } ++ ++ @ReactProp(name = "mediaOverrides") ++ override fun setMediaOverrides( ++ view: EnrichedMarkdown?, ++ value: ReadableArray?, ++ ) { ++ view?.setMediaOverrides(parseMediaOverrides(value)) ++ } + + @ReactProp(name = "markdown") + override fun setMarkdown( +@@ -152,6 +231,22 @@ class EnrichedMarkdownManager : + view?.setSelectionHandleColor(value) + } + ++ @ReactProp(name = "linkRegex") ++ override fun setLinkRegex( ++ view: EnrichedMarkdown?, ++ value: ReadableMap?, ++ ) { ++ view?.setLinkRegex(parseTextLinkRegex(value)) ++ } ++ ++ @ReactProp(name = "inlineCodeLinkRegex") ++ override fun setInlineCodeLinkRegex( ++ view: EnrichedMarkdown?, ++ value: ReadableMap?, ++ ) { ++ view?.setInlineCodeLinkRegex(parseTextLinkRegex(value)) ++ } ++ + @ReactProp(name = "md4cFlags") + override fun setMd4cFlags( + view: EnrichedMarkdown?, +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +index f3bb9122d27d80746b9b8ed07ca5247f080a25d0..90b6e38cc0c8429d0702bfb33c7115bd1e68e551 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +@@ -20,6 +20,7 @@ import com.facebook.react.uimanager.StateWrapper + import com.facebook.react.uimanager.style.LogicalEdge + import com.swmansion.enriched.markdown.accessibility.AccessibilityLabels + import com.swmansion.enriched.markdown.accessibility.AccessibleMarkdownTextView ++import com.swmansion.enriched.markdown.input.autolink.LinkRegexConfig + import com.swmansion.enriched.markdown.math.LatexErrorReporter + import com.swmansion.enriched.markdown.parser.Md4cFlags + import com.swmansion.enriched.markdown.parser.Parser +@@ -102,6 +103,8 @@ class EnrichedMarkdownText + + var md4cFlags: Md4cFlags = Md4cFlags.DEFAULT + private set ++ private var linkRegex: LinkRegexConfig? = null ++ private var inlineCodeLinkRegex: LinkRegexConfig? = null + private var isGFM: Boolean = false + + private var lastKnownFontScale: Float = context.resources.configuration.fontScale +@@ -185,6 +188,18 @@ class EnrichedMarkdownText + } + } + ++ fun setLinkRegex(config: LinkRegexConfig?) { ++ if (linkRegex == config) return ++ linkRegex = config ++ scheduleRenderIfNeeded() ++ } ++ ++ fun setInlineCodeLinkRegex(config: LinkRegexConfig?) { ++ if (inlineCodeLinkRegex == config) return ++ inlineCodeLinkRegex = config ++ scheduleRenderIfNeeded() ++ } ++ + fun setMd4cFlags(flags: Md4cFlags) { + if (md4cFlags == flags) return + md4cFlags = flags +@@ -271,12 +286,14 @@ class EnrichedMarkdownText + val markdown = currentMarkdown + if (markdown.isEmpty()) return + ++ val textLinkRegex = linkRegex ++ val codeLinkRegex = inlineCodeLinkRegex + val renderId = ++currentRenderId + + executor.execute { + try { + val ast = +- parser.parseMarkdown(markdown, md4cFlags, isGFM) ?: run { ++ parser.parseMarkdown(markdown, md4cFlags, isGFM, textLinkRegex, codeLinkRegex) ?: run { + mainHandler.post { if (renderId == currentRenderId && isAttachedToWindow) text = "" } + return@execute + } +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +index 442567d5f006966204f48f37f061f304b39592df..5ad3d1fcc3819d4dda610f863757c1f2cdadfb77 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +@@ -13,6 +13,7 @@ import com.facebook.react.uimanager.annotations.ReactProp + import com.facebook.react.viewmanagers.EnrichedMarkdownTextManagerDelegate + import com.facebook.react.viewmanagers.EnrichedMarkdownTextManagerInterface + import com.facebook.yoga.YogaMeasureMode ++import com.swmansion.enriched.markdown.parser.parseTextLinkRegex + import com.swmansion.enriched.markdown.spoiler.SpoilerOverlay + import com.swmansion.enriched.markdown.utils.common.applyReactBorderProps + import com.swmansion.enriched.markdown.utils.common.emitContextMenuItemPress +@@ -149,6 +150,22 @@ class EnrichedMarkdownTextManager : + view?.setSelectionHandleColor(value) + } + ++ @ReactProp(name = "linkRegex") ++ override fun setLinkRegex( ++ view: EnrichedMarkdownText?, ++ value: ReadableMap?, ++ ) { ++ view?.setLinkRegex(parseTextLinkRegex(value)) ++ } ++ ++ @ReactProp(name = "inlineCodeLinkRegex") ++ override fun setInlineCodeLinkRegex( ++ view: EnrichedMarkdownText?, ++ value: ReadableMap?, ++ ) { ++ view?.setInlineCodeLinkRegex(parseTextLinkRegex(value)) ++ } ++ + @ReactProp(name = "md4cFlags") + override fun setMd4cFlags( + view: EnrichedMarkdownText?, +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt b/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +index 160cc710dd7857bc517249857f0b6f71b5ec70b8..20a29bde47280a4fa0cd1681140c045195d41b5a 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +@@ -13,8 +13,16 @@ import com.facebook.react.bridge.ReadableMap + import com.facebook.react.uimanager.PixelUtil + import com.facebook.yoga.YogaMeasureMode + import com.facebook.yoga.YogaMeasureOutput ++import com.swmansion.enriched.markdown.input.autolink.LinkRegexConfig ++import com.swmansion.enriched.markdown.media.DocumentAssets ++import com.swmansion.enriched.markdown.media.MediaSlotView ++import com.swmansion.enriched.markdown.media.mediaSlotsForDocument ++import com.swmansion.enriched.markdown.media.parseImageSources ++import com.swmansion.enriched.markdown.media.parseMediaOverrides ++import com.swmansion.enriched.markdown.media.withImageSources + import com.swmansion.enriched.markdown.parser.Md4cFlags + import com.swmansion.enriched.markdown.parser.Parser ++import com.swmansion.enriched.markdown.parser.parseTextLinkRegex + import com.swmansion.enriched.markdown.renderer.Renderer + import com.swmansion.enriched.markdown.segments.BlockquoteContainerView + import com.swmansion.enriched.markdown.segments.CodeBlockContainerView +@@ -328,6 +336,8 @@ object MeasurementStore { + var result = markdown.hashCode() + result = 31 * result + (styleMap?.hashCode() ?: 0) + result = 31 * result + (md4cFlagsMap?.hashCode() ?: 0) ++ result = 31 * result + (parseTextLinkRegex(props.getMapOrNull("linkRegex"))?.hashCode() ?: 0) ++ result = 31 * result + (parseTextLinkRegex(props.getMapOrNull("inlineCodeLinkRegex"))?.hashCode() ?: 0) + result = 31 * result + fontScale.toBits() + result = 31 * result + allowFontScaling.hashCode() + result = 31 * result + maxFontSizeMultiplier.toBits() +@@ -335,6 +345,14 @@ object MeasurementStore { + result = 31 * result + imageRequestHeaders.hashCode() + result = 31 * result + props.getIntOrDefault("numberOfLines", 0) + result = 31 * result + props.getStringOrDefault("ellipsizeMode", EllipsizeUtils.DEFAULT_MODE).hashCode() ++ result = 31 * result + props.getBooleanOrDefault("enableImageSourceResolution", false).hashCode() ++ result = 31 * result + props.getIntOrDefault("imageSourcesRevision", -1) ++ result = 31 * result + props.getIntOrDefault("imageSourcesContinuityStart", 1) ++ result = 31 * result + parseImageSources(props.getArrayOrNull("imageSources")).hashCode() ++ result = 31 * result + props.getIntOrDefault("documentRevision", 0) ++ result = 31 * result + props.getIntOrDefault("mediaOverridesRevision", -1) ++ result = 31 * result + props.getBooleanOrDefault("enableMediaSlots", false).hashCode() ++ result = 31 * result + parseMediaOverrides(props.getArrayOrNull("mediaOverrides")).hashCode() + return result + } + +@@ -405,6 +423,8 @@ object MeasurementStore { + allowFontScaling, + maxFontSizeMultiplier, + imageRequestHeaders, ++ parseTextLinkRegex(props.getMapOrNull("linkRegex")), ++ parseTextLinkRegex(props.getMapOrNull("inlineCodeLinkRegex")), + ) + spannable?.replaceMathSpansWithPlaceholders(context) + val textToMeasure = spannable ?: markdown +@@ -497,12 +517,36 @@ object MeasurementStore { + + return try { + val ast = +- Parser.shared.parseMarkdown(markdown, md4cFlags, isGFM) ++ Parser.shared.parseMarkdown( ++ markdown, ++ md4cFlags, ++ isGFM, ++ parseTextLinkRegex(props.getMapOrNull("linkRegex")), ++ parseTextLinkRegex(props.getMapOrNull("inlineCodeLinkRegex")), ++ ) + ?: return YogaMeasureOutput.make(PixelUtil.toDIPFromPixel(width), 0f) + + val style = StyleConfig(styleMap, context, allowFontScaling, maxFontSizeMultiplier) + style.imageRequestHeaders = parseImageRequestHeaders(props.getArrayOrNull("imageRequestHeaders")) +- val segments = splitASTIntoSegments(ast) ++ val sourceAST = ++ withImageSources( ++ ast, ++ isGFM && props.getBooleanOrDefault("enableImageSourceResolution", false), ++ props.getIntOrDefault("documentRevision", 0), ++ props.getIntOrDefault("imageSourcesRevision", -1), ++ props.getIntOrDefault("imageSourcesContinuityStart", 1), ++ parseImageSources(props.getArrayOrNull("imageSources")), ++ ) ++ val assets = DocumentAssets.collect(sourceAST) ++ val mediaSlots = ++ mediaSlotsForDocument( ++ assets, ++ props.getBooleanOrDefault("enableMediaSlots", false), ++ props.getIntOrDefault("documentRevision", 0), ++ props.getIntOrDefault("mediaOverridesRevision", -1), ++ parseMediaOverrides(props.getArrayOrNull("mediaOverrides")), ++ ) ++ val segments = splitASTIntoSegments(sourceAST, mediaSlots, assets) + val renderedSegments = MarkdownSegmentRenderer.render(segments, style, context, null, null) + + val mathHeightByIndex = HashMap() +@@ -582,7 +626,15 @@ object MeasurementStore { + + is RenderedSegment.Blockquote -> { + totalHeightPx += style.blockquoteStyle.marginTop +- totalHeightPx += BlockquoteContainerView.measureBlockquoteNodeHeight(segment.node, style, context, width) ++ totalHeightPx += ++ BlockquoteContainerView.measureBlockquoteNodeHeight( ++ segment.node, ++ style, ++ context, ++ width, ++ segment.mediaSlots, ++ segment.assets, ++ ) + maxContentWidthPx = width + if (includeBottomMargin) { + totalHeightPx += style.blockquoteStyle.marginBottom +@@ -590,11 +642,12 @@ object MeasurementStore { + } + + is RenderedSegment.Video -> { +- totalHeightPx += style.videoStyle.marginTop +- totalHeightPx += width / style.videoStyle.resolvedAspectRatio ++ totalHeightPx += segment.mediaSlot?.let { MediaSlotView.marginTop(it, style) } ?: style.videoStyle.marginTop ++ totalHeightPx += ++ segment.mediaSlot?.let { MediaSlotView.heightPx(it, style, width) } ?: (width / style.videoStyle.resolvedAspectRatio) + maxContentWidthPx = width + if (includeBottomMargin) { +- totalHeightPx += style.videoStyle.marginBottom ++ totalHeightPx += segment.mediaSlot?.let { MediaSlotView.marginBottom(it, style) } ?: style.videoStyle.marginBottom + } + } + } +@@ -618,6 +671,8 @@ object MeasurementStore { + text: CharSequence?, + widthPx: Int, + ) { ++ com.swmansion.enriched.markdown.spans.LinkPillSpan ++ .prepareForMeasurement(text, widthPx) + // widthPx == 1 is the coerceAtLeast(1) fallback for a not-yet-measured view + if (widthPx <= 1) return + val spanned = text as? android.text.Spanned ?: return +@@ -658,11 +713,13 @@ object MeasurementStore { + allowFontScaling: Boolean, + maxFontSizeMultiplier: Float, + imageRequestHeaders: Map = emptyMap(), ++ linkRegex: LinkRegexConfig? = null, ++ inlineCodeLinkRegex: LinkRegexConfig? = null, + ): SpannableString? { + if (styleMap == null) return null + + return try { +- val ast = Parser.shared.parseMarkdown(markdown, md4cFlags, isGFM) ?: return null ++ val ast = Parser.shared.parseMarkdown(markdown, md4cFlags, isGFM, linkRegex, inlineCodeLinkRegex) ?: return null + val style = StyleConfig(styleMap, context, allowFontScaling, maxFontSizeMultiplier) + style.imageRequestHeaders = imageRequestHeaders + measureRenderer.configure(style, context) +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/accessibility/AccessibleMarkdownTextView.kt b/android/src/main/java/com/swmansion/enriched/markdown/accessibility/AccessibleMarkdownTextView.kt +index 9de3bedd2226f67127eacc690cf6d37e241e85f3..49dfb95b8e0e727b137d45b6e1fade9f761c519f 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/accessibility/AccessibleMarkdownTextView.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/accessibility/AccessibleMarkdownTextView.kt +@@ -17,6 +17,23 @@ abstract class AccessibleMarkdownTextView + ) : AppCompatTextView(context, attrs, defStyleAttr) { + val accessibilityHelper = MarkdownAccessibilityHelper(this) + ++ override fun onMeasure( ++ widthMeasureSpec: Int, ++ heightMeasureSpec: Int, ++ ) { ++ if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED) { ++ val width = (MeasureSpec.getSize(widthMeasureSpec) - compoundPaddingLeft - compoundPaddingRight).coerceAtLeast(1) ++ if (com.swmansion.enriched.markdown.spans.LinkPillSpan ++ .prepareForMeasurement(text, width) ++ ) { ++ // TextView can reuse a layout at the same width after a style or label change. ++ val current = text ++ text = current ++ } ++ } ++ super.onMeasure(widthMeasureSpec, heightMeasureSpec) ++ } ++ + override fun dispatchHoverEvent(event: MotionEvent): Boolean = + accessibilityHelper.dispatchHoverEvent(event) || super.dispatchHoverEvent(event) + +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/media/DocumentAssets.kt b/android/src/main/java/com/swmansion/enriched/markdown/media/DocumentAssets.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..18eeaec07394b35df85aae90b459ac3e22c08373 +--- /dev/null ++++ b/android/src/main/java/com/swmansion/enriched/markdown/media/DocumentAssets.kt +@@ -0,0 +1,156 @@ ++package com.swmansion.enriched.markdown.media ++ ++import com.swmansion.enriched.markdown.parser.MarkdownASTNode ++import java.util.IdentityHashMap ++import kotlin.math.abs ++ ++/** Descriptors come from the accepted native AST, including occurrences we cannot override. */ ++data class DocumentAsset( ++ val id: String, ++ val kind: String, ++ val url: String, ++ val altText: String, ++ val title: String, ++ val placement: String, ++ val eligible: Boolean, ++ val anchor: String, ++) ++ ++class DocumentAssets private constructor( ++ val assets: List, ++ private val byNode: IdentityHashMap, ++) { ++ fun assetForNode(node: MarkdownASTNode): DocumentAsset? = byNode[node] ++ ++ companion object { ++ fun collect(root: MarkdownASTNode): DocumentAssets { ++ val assets = mutableListOf() ++ val byNode = IdentityHashMap() ++ ++ fun text(node: MarkdownASTNode): String = node.content + node.children.joinToString("") { text(it) } ++ ++ fun visit( ++ node: MarkdownASTNode, ++ parent: MarkdownASTNode?, ++ placement: String, ++ path: String, ++ parentPath: String, ++ parentIsSegmentContainer: Boolean, ++ parentIsSegmentParagraph: Boolean, ++ ) { ++ val nestedPlacement = ++ when (node.type) { ++ MarkdownASTNode.NodeType.Table -> "table" ++ ++ MarkdownASTNode.NodeType.UnorderedList, ++ MarkdownASTNode.NodeType.OrderedList, ++ -> "list" ++ ++ MarkdownASTNode.NodeType.Blockquote, ++ MarkdownASTNode.NodeType.Admonition, ++ -> "blockquote" ++ ++ else -> placement ++ } ++ val isSegmentContainer = ++ node === root || ++ ( ++ parentIsSegmentContainer && ++ (node.type == MarkdownASTNode.NodeType.Blockquote || node.type == MarkdownASTNode.NodeType.Admonition) ++ ) ++ val kind = ++ when (node.type) { ++ MarkdownASTNode.NodeType.Image -> "image" ++ MarkdownASTNode.NodeType.Video -> "video" ++ MarkdownASTNode.NodeType.Link -> "link" ++ else -> null ++ } ++ if (kind != null) { ++ val standaloneImage = ++ kind == "image" && parent?.type == MarkdownASTNode.NodeType.Paragraph && ++ parent.children.size == 1 && parentIsSegmentParagraph ++ val eligible = standaloneImage || (kind == "video" && parentIsSegmentContainer) ++ val asset = ++ DocumentAsset( ++ id = "asset-${assets.size}", ++ kind = kind, ++ url = node.getAttribute("url") ?: "", ++ altText = text(node).trim(), ++ title = node.getAttribute("title") ?: "", ++ placement = ++ if (eligible && nestedPlacement == "block") { ++ "block" ++ } else if (nestedPlacement == "block") { ++ "inline" ++ } else { ++ nestedPlacement ++ }, ++ eligible = eligible, ++ anchor = if (standaloneImage) parentPath else path, ++ ) ++ assets.add(asset) ++ byNode[node] = asset ++ } ++ node.children.forEachIndexed { index, child -> ++ visit( ++ child, ++ node, ++ nestedPlacement, ++ "$path.$index", ++ path, ++ isSegmentContainer, ++ node.type == MarkdownASTNode.NodeType.Paragraph && parentIsSegmentContainer, ++ ) ++ } ++ } ++ visit(root, null, "block", "0", "", false, false) ++ return DocumentAssets(assets, byNode) ++ } ++ } ++} ++ ++/** Values are DIP. A zero width denotes a provisional height, valid at any width. */ ++data class MediaOverride( ++ val id: String, ++ val height: Float, ++ val width: Float, ++ val url: String, ++ val kind: String, ++ val anchor: String, ++) { ++ fun matches(asset: DocumentAsset): Boolean = ++ asset.eligible && id == asset.id && url == asset.url && kind == asset.kind && anchor == asset.anchor ++} ++ ++data class MediaSlot( ++ val asset: DocumentAsset, ++ val measuredOverride: MediaOverride?, ++) { ++ fun heightForWidth( ++ width: Float, ++ fallback: Float, ++ ): Float { ++ val value = measuredOverride ?: return fallback ++ return if (value.height.isFinite() && value.height >= 0 && ++ (value.width == 0f || abs(value.width - width) < 0.5f) ++ ) { ++ value.height ++ } else { ++ fallback ++ } ++ } ++} ++ ++fun mediaSlotsForDocument( ++ assets: DocumentAssets, ++ enabled: Boolean, ++ revision: Int, ++ overridesRevision: Int, ++ overrides: List, ++): Map { ++ if (!enabled) return emptyMap() ++ val decisions = overrides.associateBy { it.id } ++ return assets.assets ++ .filter { it.eligible && (overridesRevision != revision || decisions.containsKey(it.id)) } ++ .associate { asset -> asset.id to MediaSlot(asset, decisions[asset.id]?.takeIf { it.matches(asset) }) } ++} +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/media/ImageSourceBridge.kt b/android/src/main/java/com/swmansion/enriched/markdown/media/ImageSourceBridge.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..073c6f343df872ef2e20ad94964f7ba1e9b52718 +--- /dev/null ++++ b/android/src/main/java/com/swmansion/enriched/markdown/media/ImageSourceBridge.kt +@@ -0,0 +1,20 @@ ++package com.swmansion.enriched.markdown.media ++ ++import com.facebook.react.bridge.ReadableArray ++import com.swmansion.enriched.markdown.utils.common.parseImageRequestHeaders ++ ++fun parseImageSources(value: ReadableArray?): List = ++ (0 until (value?.size() ?: 0)).mapNotNull { index -> ++ val entry = value?.getMap(index) ?: return@mapNotNull null ++ val id = entry.getString("id") ?: return@mapNotNull null ++ val url = entry.getString("url") ?: return@mapNotNull null ++ val anchor = entry.getString("anchor") ?: return@mapNotNull null ++ ImageSourceDecision( ++ id, ++ url, ++ anchor, ++ entry.getString("uri") ?: "", ++ parseImageRequestHeaders(entry.getArray("headers")), ++ entry.getBoolean("useDefault"), ++ ) ++ } +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/media/ImageSources.kt b/android/src/main/java/com/swmansion/enriched/markdown/media/ImageSources.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..0da0be7746c1af9ea07e04b2a2d5a09260cedfef +--- /dev/null ++++ b/android/src/main/java/com/swmansion/enriched/markdown/media/ImageSources.kt +@@ -0,0 +1,66 @@ ++package com.swmansion.enriched.markdown.media ++ ++import com.swmansion.enriched.markdown.parser.MarkdownASTNode ++import java.util.Locale ++ ++/** Download transport only. A null URI holds the normal native placeholder. */ ++data class ImageSourceTransport( ++ val uri: String?, ++ val headers: Map = emptyMap(), ++) ++ ++data class ImageSourceDecision( ++ val id: String, ++ val url: String, ++ val anchor: String, ++ val uri: String, ++ val headers: Map, ++ val useDefault: Boolean, ++) { ++ fun matches(asset: DocumentAsset): Boolean = asset.kind == "image" && id == asset.id && url == asset.url && anchor == asset.anchor ++} ++ ++/** Copies accepted AST nodes without changing any semantic attributes or cached parser trees. */ ++fun withImageSources( ++ root: MarkdownASTNode, ++ enabled: Boolean, ++ documentRevision: Int, ++ sourcesRevision: Int, ++ continuityStart: Int, ++ decisions: List, ++): MarkdownASTNode { ++ if (!enabled) return root ++ val assets = DocumentAssets.collect(root) ++ val acceptedDecisions = ++ if (sourcesRevision >= continuityStart && sourcesRevision <= documentRevision) { ++ decisions.associateBy { it.id } ++ } else { ++ emptyMap() ++ } ++ ++ fun visit(node: MarkdownASTNode): MarkdownASTNode { ++ val children = node.children.map { visit(it) } ++ if (node.type != MarkdownASTNode.NodeType.Image) return node.copy(children = children) ++ val asset = assets.assetForNode(node) ++ val decision = asset?.let { acceptedDecisions[it.id]?.takeIf { source -> source.matches(it) } } ++ val transport = ++ when { ++ decision == null -> ImageSourceTransport(null) ++ decision.useDefault -> null ++ decision.uri.isBlank() -> ImageSourceTransport(null) ++ else -> ImageSourceTransport(decision.uri, decision.headers) ++ } ++ return node.copy(children = children, imageSource = transport) ++ } ++ return visit(root) ++} ++ ++/** HTTP field names are case-insensitive. Per-source values replace document values. */ ++fun mergeImageRequestHeaders( ++ document: Map, ++ source: Map, ++): Map = ++ buildMap { ++ document.forEach { (name, value) -> put(name.lowercase(Locale.ROOT), value) } ++ source.forEach { (name, value) -> put(name.lowercase(Locale.ROOT), value) } ++ } +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotBridge.kt b/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotBridge.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..682ae9341e8500fffc07d5f8a0651ad77859c030 +--- /dev/null ++++ b/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotBridge.kt +@@ -0,0 +1,70 @@ ++package com.swmansion.enriched.markdown.media ++ ++import android.view.View ++import com.facebook.react.bridge.Arguments ++import com.facebook.react.bridge.ReactContext ++import com.facebook.react.bridge.ReadableArray ++import com.facebook.react.bridge.WritableMap ++import com.facebook.react.uimanager.UIManagerHelper ++import com.facebook.react.uimanager.events.Event ++ ++fun parseMediaOverrides(value: ReadableArray?): List = ++ (0 until (value?.size() ?: 0)).mapNotNull { index -> ++ val entry = value?.getMap(index) ?: return@mapNotNull null ++ val id = entry.getString("id") ?: return@mapNotNull null ++ val url = entry.getString("url") ?: return@mapNotNull null ++ val kind = entry.getString("kind") ?: return@mapNotNull null ++ val anchor = entry.getString("anchor") ?: return@mapNotNull null ++ val height = entry.getDouble("height").toFloat() ++ val width = entry.getDouble("width").toFloat() ++ if (!height.isFinite() || height < 0 || !width.isFinite() || width < 0) null else MediaOverride(id, height, width, url, kind, anchor) ++ } ++ ++fun emitMediaEvent( ++ view: View, ++ name: String, ++ data: WritableMap, ++): Boolean { ++ val context = view.context as ReactContext ++ val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id) ?: return false ++ dispatcher.dispatchEvent(MediaEvent(UIManagerHelper.getSurfaceId(context), view.id, name, data)) ++ return true ++} ++ ++fun documentAssetsEventData( ++ revision: Int, ++ assets: List, ++): WritableMap { ++ val entries = Arguments.createArray() ++ assets.forEach { asset -> ++ entries.pushMap( ++ Arguments.createMap().apply { ++ putString("id", asset.id) ++ putString("kind", asset.kind) ++ putString("url", asset.url) ++ putString("altText", asset.altText) ++ putString("title", asset.title) ++ putString("placement", asset.placement) ++ putBoolean("eligible", asset.eligible) ++ putString("anchor", asset.anchor) ++ }, ++ ) ++ } ++ return Arguments.createMap().apply { ++ putInt("revision", revision) ++ putArray("assets", entries) ++ } ++} ++ ++private class MediaEvent( ++ surfaceId: Int, ++ viewId: Int, ++ private val name: String, ++ private val data: WritableMap, ++) : Event(surfaceId, viewId) { ++ override fun getEventName(): String = name ++ ++ override fun getEventData(): WritableMap = data ++ ++ override fun canCoalesce(): Boolean = false ++} +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotFrame.kt b/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotFrame.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..3bd8794a92575c32e4d5698ab0b8049ad51d3637 +--- /dev/null ++++ b/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotFrame.kt +@@ -0,0 +1,15 @@ ++package com.swmansion.enriched.markdown.media ++ ++/** Native pixels; conversion to DIP happens once at the root event boundary. */ ++data class MediaSlotFrame( ++ val id: String, ++ val x: Int, ++ val y: Int, ++ val width: Int, ++ val height: Int, ++) { ++ fun translated( ++ offsetX: Int, ++ offsetY: Int, ++ ): MediaSlotFrame = copy(x = x + offsetX, y = y + offsetY) ++} +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotView.kt b/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotView.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..6d0ffd950300cabc4204930a6b3b0b7db8aac8c2 +--- /dev/null ++++ b/android/src/main/java/com/swmansion/enriched/markdown/media/MediaSlotView.kt +@@ -0,0 +1,71 @@ ++package com.swmansion.enriched.markdown.media ++ ++import android.content.Context ++import android.view.View ++import com.facebook.react.uimanager.PixelUtil ++import com.swmansion.enriched.markdown.segments.BlockSegmentView ++import com.swmansion.enriched.markdown.styles.StyleConfig ++import kotlin.math.ceil ++ ++/** A measured, inaccessible native box. React owns its visual and interactive content. */ ++class MediaSlotView( ++ context: Context, ++ private val style: StyleConfig, ++ slot: MediaSlot, ++) : View(context), ++ BlockSegmentView { ++ var slot: MediaSlot = slot ++ set(value) { ++ if (field == value) return ++ field = value ++ requestLayout() ++ } ++ ++ init { ++ importantForAccessibility = IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS ++ isFocusable = false ++ } ++ ++ override val segmentMarginTop: Int get() = ceil(marginTop(slot, style)).toInt() ++ override val segmentMarginBottom: Int get() = ceil(marginBottom(slot, style)).toInt() ++ ++ override fun onMeasure( ++ widthMeasureSpec: Int, ++ heightMeasureSpec: Int, ++ ) { ++ val width = MeasureSpec.getSize(widthMeasureSpec) ++ setMeasuredDimension(width, ceil(heightPx(slot, style, width.toFloat())).toInt()) ++ } ++ ++ companion object { ++ fun marginTop( ++ slot: MediaSlot, ++ style: StyleConfig, ++ ): Float = ceil(if (slot.asset.kind == "video") style.videoStyle.marginTop else style.imageStyle.marginTop) ++ ++ fun marginBottom( ++ slot: MediaSlot, ++ style: StyleConfig, ++ ): Float = ceil(if (slot.asset.kind == "video") style.videoStyle.marginBottom else style.imageStyle.marginBottom) ++ ++ fun heightPx( ++ slot: MediaSlot, ++ style: StyleConfig, ++ width: Float, ++ ): Float { ++ val fallback = ++ if (slot.asset.kind == "video") { ++ width / style.videoStyle.resolvedAspectRatio ++ } else { ++ val image = style.imageStyle ++ val value = if (image.aspectRatio > 0) width / image.aspectRatio else image.height ++ if (image.maxHeight > 0) value.coerceAtMost(image.maxHeight) else value ++ } ++ return ceil( ++ PixelUtil.toPixelFromDIP( ++ slot.heightForWidth(PixelUtil.toDIPFromPixel(width), PixelUtil.toDIPFromPixel(fallback)), ++ ), ++ ) ++ } ++ } ++} +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt b/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +index 8b8bce9d71d5a07e659d587c3efd75ee50277f55..4ce6880723db777ff5eeb0300b7dafe9e0246610 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +@@ -1,50 +1,55 @@ + package com.swmansion.enriched.markdown.parser + +-data class MarkdownASTNode( +- val type: NodeType, +- val content: String = "", +- val attributes: Map = emptyMap(), +- val children: List = emptyList(), +-) { +- enum class NodeType { +- Document, +- Paragraph, +- Text, +- Link, +- Heading, +- LineBreak, +- Strong, +- Emphasis, +- Strikethrough, +- Underline, +- Code, +- Image, +- Blockquote, +- UnorderedList, +- OrderedList, +- ListItem, +- CodeBlock, +- ThematicBreak, +- Table, +- TableHead, +- TableBody, +- TableRow, +- TableHeaderCell, +- TableCell, +- LatexMathInline, +- LatexMathDisplay, +- Spoiler, +- Superscript, +- Subscript, +- Highlight, +- SoftBreak, +- BlankLine, +- Admonition, +- Video, +- } ++import com.swmansion.enriched.markdown.media.ImageSourceTransport ++ ++data class MarkdownASTNode ++ @JvmOverloads ++ constructor( ++ val type: NodeType, ++ val content: String = "", ++ val attributes: Map = emptyMap(), ++ val children: List = emptyList(), ++ val imageSource: ImageSourceTransport? = null, ++ ) { ++ enum class NodeType { ++ Document, ++ Paragraph, ++ Text, ++ Link, ++ Heading, ++ LineBreak, ++ Strong, ++ Emphasis, ++ Strikethrough, ++ Underline, ++ Code, ++ Image, ++ Blockquote, ++ UnorderedList, ++ OrderedList, ++ ListItem, ++ CodeBlock, ++ ThematicBreak, ++ Table, ++ TableHead, ++ TableBody, ++ TableRow, ++ TableHeaderCell, ++ TableCell, ++ LatexMathInline, ++ LatexMathDisplay, ++ Spoiler, ++ Superscript, ++ Subscript, ++ Highlight, ++ SoftBreak, ++ BlankLine, ++ Admonition, ++ Video, ++ } + +- fun getAttribute(key: String): String? = attributes[key] +-} ++ fun getAttribute(key: String): String? = attributes[key] ++ } + + // A node type that md4c emits as a standalone block stacked vertically, as opposed to an inline span. + internal fun MarkdownASTNode.NodeType.isTopLevelBlock(): Boolean = +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt b/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +index 217d46473a8cf6f1f6c6439bf0b802c328531b83..1fd34d2a4675fc786a1b48349bfef967b6cb5c68 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +@@ -1,6 +1,7 @@ + package com.swmansion.enriched.markdown.parser + + import android.util.Log ++import com.swmansion.enriched.markdown.input.autolink.LinkRegexConfig + import com.swmansion.enriched.markdown.utils.common.FeatureFlags + + data class Md4cFlags( +@@ -51,6 +52,8 @@ class Parser { + markdown: String, + flags: Md4cFlags = Md4cFlags.DEFAULT, + isGFM: Boolean = true, ++ linkRegex: LinkRegexConfig? = null, ++ inlineCodeLinkRegex: LinkRegexConfig? = null, + ): MarkdownASTNode? { + if (markdown.isBlank()) { + return null +@@ -60,7 +63,7 @@ class Parser { + val ast = nativeParseMarkdown(markdown, flags, isGFM) + + if (ast != null) { +- return ast ++ return TextLinkRecognizer.recognize(ast, linkRegex, inlineCodeLinkRegex) + } else { + Log.w("MarkdownParser", "Native parser returned null") + return null +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/parser/TextLinkRecognizer.kt b/android/src/main/java/com/swmansion/enriched/markdown/parser/TextLinkRecognizer.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..6d8b5faa65bd315ec67911dbe0300a26b9cbcd81 +--- /dev/null ++++ b/android/src/main/java/com/swmansion/enriched/markdown/parser/TextLinkRecognizer.kt +@@ -0,0 +1,89 @@ ++package com.swmansion.enriched.markdown.parser ++ ++import com.swmansion.enriched.markdown.input.autolink.LinkRegexConfig ++import com.swmansion.enriched.markdown.parser.MarkdownASTNode.NodeType ++import java.util.regex.Pattern ++import java.util.regex.PatternSyntaxException ++ ++/** Native regex parity with iOS ENRMTextLinkRecognizer, applied before AST consumers. */ ++object TextLinkRecognizer { ++ fun recognize( ++ ast: MarkdownASTNode, ++ linkRegex: LinkRegexConfig? = null, ++ inlineCodeLinkRegex: LinkRegexConfig? = null, ++ ): MarkdownASTNode { ++ val textPattern = compile(linkRegex) ++ val codePattern = compile(inlineCodeLinkRegex, wholeSpan = true) ++ if (textPattern == null && codePattern == null) return ast ++ ++ fun link( ++ child: MarkdownASTNode, ++ url: String, ++ ): MarkdownASTNode = ++ MarkdownASTNode( ++ NodeType.Link, ++ attributes = mapOf("url" to url, "recognizedLink" to "true"), ++ children = listOf(child), ++ ) ++ ++ fun transform(node: MarkdownASTNode): List { ++ when (node.type) { ++ NodeType.Link, NodeType.CodeBlock, NodeType.Image, NodeType.Video, ++ NodeType.LatexMathInline, NodeType.LatexMathDisplay, ++ -> { ++ return listOf(node) ++ } ++ ++ NodeType.Code -> { ++ // Code renderers concatenate the parser's text children verbatim. ++ val content = node.children.joinToString("") { it.content } ++ val matcher = codePattern?.matcher(content) ++ if (content.isNotEmpty() && matcher != null && matcher.find() && matcher.start() == 0 && matcher.end() == content.length) { ++ return listOf(link(node, content)) ++ } ++ return listOf(node) ++ } ++ ++ NodeType.Text -> { ++ val matcher = textPattern?.matcher(node.content) ?: return listOf(node) ++ val result = mutableListOf() ++ var offset = 0 ++ while (matcher.find()) { ++ val start = matcher.start() ++ val end = matcher.end() ++ if (start == end) continue ++ if (start > offset) result.add(node.copy(content = node.content.substring(offset, start))) ++ val matched = node.content.substring(start, end) ++ result.add(link(node.copy(content = matched), matched)) ++ offset = end ++ } ++ if (offset == 0) return listOf(node) ++ if (offset < node.content.length) result.add(node.copy(content = node.content.substring(offset))) ++ return result ++ } ++ ++ else -> { ++ return listOf(node.copy(children = node.children.flatMap { transform(it) })) ++ } ++ } ++ } ++ ++ // Documents are containers, so recognition never changes their root type. ++ return ast.copy(children = ast.children.flatMap { transform(it) }) ++ } ++ ++ private fun compile( ++ config: LinkRegexConfig?, ++ wholeSpan: Boolean = false, ++ ): Pattern? { ++ if (config == null || config.isDisabled || config.isDefault || config.pattern.isEmpty()) return null ++ var flags = 0 ++ if (config.caseInsensitive) flags = flags or Pattern.CASE_INSENSITIVE ++ if (config.dotAll) flags = flags or Pattern.DOTALL ++ return try { ++ Pattern.compile(if (wholeSpan) "\\A(?:${config.pattern})\\z" else config.pattern, flags) ++ } catch (_: PatternSyntaxException) { ++ null ++ } ++ } ++} +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/parser/TextLinkRegexProps.kt b/android/src/main/java/com/swmansion/enriched/markdown/parser/TextLinkRegexProps.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..32e1219561fbd9c741d8711c75a763cc19181521 +--- /dev/null ++++ b/android/src/main/java/com/swmansion/enriched/markdown/parser/TextLinkRegexProps.kt +@@ -0,0 +1,15 @@ ++package com.swmansion.enriched.markdown.parser ++ ++import com.facebook.react.bridge.ReadableMap ++import com.swmansion.enriched.markdown.input.autolink.LinkRegexConfig ++ ++internal fun parseTextLinkRegex(map: ReadableMap?): LinkRegexConfig? { ++ if (map == null) return null ++ return LinkRegexConfig( ++ pattern = if (map.hasKey("pattern")) map.getString("pattern") ?: "" else "", ++ caseInsensitive = map.hasKey("caseInsensitive") && map.getBoolean("caseInsensitive"), ++ dotAll = map.hasKey("dotAll") && map.getBoolean("dotAll"), ++ isDisabled = !map.hasKey("isDisabled") || map.getBoolean("isDisabled"), ++ isDefault = map.hasKey("isDefault") && map.getBoolean("isDefault"), ++ ) ++} +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/renderer/ImageRenderer.kt b/android/src/main/java/com/swmansion/enriched/markdown/renderer/ImageRenderer.kt +index 0047361a70d925ec1d5cf8f34aed814e036e277c..5cd48d60bd70f97eaa3de58bdbe853cf11b213ee 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/renderer/ImageRenderer.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/renderer/ImageRenderer.kt +@@ -29,6 +29,7 @@ class ImageRenderer : NodeRenderer { + imageUrl = imageUrl, + isInline = isInline, + altText = altText, ++ imageSource = node.imageSource, + ) + + builder.setSpan( +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt b/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt +index 7beb976e1daa8eeee864edca6da33cd2e358ba7f..e49a12080732653cfe7416294b3eb8fef21e0a79 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt +@@ -1,8 +1,11 @@ + package com.swmansion.enriched.markdown.renderer + + import android.text.SpannableStringBuilder ++import android.text.TextPaint + import com.swmansion.enriched.markdown.parser.MarkdownASTNode ++import com.swmansion.enriched.markdown.spans.LinkPillSpan + import com.swmansion.enriched.markdown.spans.LinkSpan ++import com.swmansion.enriched.markdown.utils.text.extensions.applyBlockStyleFont + import com.swmansion.enriched.markdown.utils.text.span.SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE + + class LinkRenderer( +@@ -16,10 +19,35 @@ class LinkRenderer( + factory: RendererFactory, + ) { + val url = node.getAttribute("url") ?: return ++ val recognizedLink = node.getAttribute("recognizedLink") == "true" + + factory.renderWithSpan(builder, { factory.renderChildren(node, builder, onLinkPress, onLinkLongPress) }) { start, end, blockStyle -> ++ val variant = factory.styleCache.resolvedVariantForUrl(url) ++ if (variant?.pill == true && builder.getSpans(start, end, android.text.style.ReplacementSpan::class.java).isEmpty()) { ++ val fontFamily = variant.fontFamily.ifEmpty { factory.styleCache.linkFontFamily }.ifEmpty { blockStyle.fontFamily } ++ val font = TextPaint().apply { applyBlockStyleFont(blockStyle.copy(fontFamily = fontFamily), factory.context) } ++ factory.registerDeferredSpan( ++ LinkPillSpan( ++ variant, ++ font.typeface, ++ blockStyle.fontSize, ++ builder.subSequence(start, end).toString(), ++ ), ++ start, ++ end, ++ ) ++ } + builder.setSpan( +- LinkSpan(url, onLinkPress, onLinkLongPress, factory.styleCache, blockStyle, factory.context), ++ LinkSpan( ++ url, ++ onLinkPress, ++ onLinkLongPress, ++ factory.styleCache, ++ blockStyle, ++ factory.context, ++ preserveCodeFont = recognizedLink && node.children.any { it.type == MarkdownASTNode.NodeType.Code }, ++ recognizedLink = recognizedLink, ++ ), + start, + end, + SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE, +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt b/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +index a0f37cdafe25dcadb0dcbbc8a63494acbd148070..f3dd36f771e5d366f5880e823951dcc83fab71b1 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +@@ -4,6 +4,7 @@ import android.content.Context + import android.text.SpannableStringBuilder + import android.text.style.MetricAffectingSpan + import com.swmansion.enriched.markdown.math.LatexErrorReporter ++import com.swmansion.enriched.markdown.media.ImageSourceTransport + import com.swmansion.enriched.markdown.parser.MarkdownASTNode + import com.swmansion.enriched.markdown.spans.ImageSpan + import com.swmansion.enriched.markdown.styles.StyleConfig +@@ -71,6 +72,7 @@ class RendererFactory( + imageUrl: String, + isInline: Boolean, + altText: String, ++ imageSource: ImageSourceTransport? = null, + ): ImageSpan = + ImageSpan( + context = context, +@@ -78,6 +80,7 @@ class RendererFactory( + styleConfig = config.style, + isInline = isInline, + altText = altText, ++ imageSource = imageSource, + ) + + private val textRenderer = TextRenderer() +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/BlockquoteContainerView.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/BlockquoteContainerView.kt +index 8027e6054946a9402a0db1711d7475a14b98c490..54c1eaec45701d1a31ecc1af9937852bb3ae34c7 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/segments/BlockquoteContainerView.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/BlockquoteContainerView.kt +@@ -14,6 +14,9 @@ import androidx.core.graphics.withSave + import com.facebook.react.common.ReactConstants + import com.facebook.react.views.text.ReactTypefaceUtils.applyStyles + import com.swmansion.enriched.markdown.EnrichedMarkdownInternalText ++import com.swmansion.enriched.markdown.media.DocumentAssets ++import com.swmansion.enriched.markdown.media.MediaSlot ++import com.swmansion.enriched.markdown.media.MediaSlotView + import com.swmansion.enriched.markdown.parser.MarkdownASTNode + import com.swmansion.enriched.markdown.styles.BlockquoteStyle + import com.swmansion.enriched.markdown.styles.StyleConfig +@@ -115,7 +118,11 @@ class BlockquoteContainerView( + setOnLongClickListener { view -> showContextMenu(view) } + } + +- fun applyBlockquoteNode(node: MarkdownASTNode) { ++ fun applyBlockquoteNode( ++ node: MarkdownASTNode, ++ mediaSlots: Map = emptyMap(), ++ assets: DocumentAssets? = null, ++ ) { + admonitionType = + if (node.type == MarkdownASTNode.NodeType.Admonition) { + node.getAttribute("admonitionType")?.takeIf { it.isNotEmpty() } ?: "note" +@@ -128,7 +135,7 @@ class BlockquoteContainerView( + cachedMarkdown = MarkdownASTSerializer.serializeBlockquote(node) + cachedPlainText = MarkdownASTSerializer.plainText(node) + +- val segments = splitASTIntoSegments(node) ++ val segments = splitASTIntoSegments(node, mediaSlots, assets) + val rendered = + MarkdownSegmentRenderer.render( + segments, +@@ -276,12 +283,35 @@ class BlockquoteContainerView( + segment: RenderedSegment, + ): Boolean = + when (segment) { +- is RenderedSegment.Text -> view is EnrichedMarkdownInternalText +- is RenderedSegment.Table -> view is TableContainerView +- is RenderedSegment.Math -> SegmentViewCreators.isMathContainerView(view) +- is RenderedSegment.CodeBlock -> view is CodeBlockContainerView +- is RenderedSegment.Blockquote -> view is BlockquoteContainerView +- is RenderedSegment.Video -> SegmentViewCreators.isVideoContainerView(view) ++ is RenderedSegment.Text -> { ++ view is EnrichedMarkdownInternalText ++ } ++ ++ is RenderedSegment.Table -> { ++ view is TableContainerView ++ } ++ ++ is RenderedSegment.Math -> { ++ SegmentViewCreators.isMathContainerView(view) ++ } ++ ++ is RenderedSegment.CodeBlock -> { ++ view is CodeBlockContainerView ++ } ++ ++ is RenderedSegment.Blockquote -> { ++ view is BlockquoteContainerView ++ } ++ ++ is RenderedSegment.Video -> { ++ if (segment.mediaSlot != ++ null ++ ) { ++ view is MediaSlotView ++ } else { ++ SegmentViewCreators.isVideoContainerView(view) ++ } ++ } + } + + override fun createView(segment: RenderedSegment): View = +@@ -316,12 +346,33 @@ class BlockquoteContainerView( + segment: RenderedSegment, + ) { + when (segment) { +- is RenderedSegment.Text -> SegmentViewCreators.updateTextView(view as EnrichedMarkdownInternalText, segment) +- is RenderedSegment.Table -> (view as TableContainerView).applyTableNode(segment.node) +- is RenderedSegment.Math -> SegmentViewCreators.updateMathView(view, segment) +- is RenderedSegment.CodeBlock -> (view as CodeBlockContainerView).applyCodeBlockNode(segment.node) +- is RenderedSegment.Blockquote -> (view as BlockquoteContainerView).applyBlockquoteNode(segment.node) +- is RenderedSegment.Video -> SegmentViewCreators.updateVideoView(view, segment) ++ is RenderedSegment.Text -> { ++ SegmentViewCreators.updateTextView(view as EnrichedMarkdownInternalText, segment) ++ } ++ ++ is RenderedSegment.Table -> { ++ (view as TableContainerView).applyTableNode(segment.node) ++ } ++ ++ is RenderedSegment.Math -> { ++ SegmentViewCreators.updateMathView(view, segment) ++ } ++ ++ is RenderedSegment.CodeBlock -> { ++ (view as CodeBlockContainerView).applyCodeBlockNode(segment.node) ++ } ++ ++ is RenderedSegment.Blockquote -> { ++ (view as BlockquoteContainerView).applyBlockquoteNode( ++ segment.node, ++ segment.mediaSlots, ++ segment.assets, ++ ) ++ } ++ ++ is RenderedSegment.Video -> { ++ SegmentViewCreators.updateVideoView(view, segment) ++ } + } + } + +@@ -359,6 +410,8 @@ class BlockquoteContainerView( + config: StyleConfig, + context: Context, + width: Float, ++ mediaSlots: Map = emptyMap(), ++ assets: DocumentAssets? = null, + ): Float { + val style = config.blockquoteStyle + val leftInset = ceil(style.borderWidth + style.gapWidth + style.padding).toInt() +@@ -370,9 +423,9 @@ class BlockquoteContainerView( + } else { + 0f + } +- val innerWidth = (width - leftInset - rightInset).coerceAtLeast(1f) ++ val innerWidth = (ceil(width) - leftInset - rightInset).coerceAtLeast(1f) + +- val segments = splitASTIntoSegments(node) ++ val segments = splitASTIntoSegments(node, mediaSlots, assets) + val rendered = MarkdownSegmentRenderer.render(segments, config, context, null, null, style) + + val fontSize = style.fontSize +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/ContainerNodeView.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/ContainerNodeView.kt +index 016d11dd349dcbc8bd2c14e6c67543612cc98def..859b7f0780fcfe5a71c82ab84bcd46ee8c93342c 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/segments/ContainerNodeView.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/ContainerNodeView.kt +@@ -3,6 +3,8 @@ package com.swmansion.enriched.markdown.segments + import android.content.Context + import android.view.View + import android.widget.FrameLayout ++import com.swmansion.enriched.markdown.media.MediaSlotFrame ++import com.swmansion.enriched.markdown.media.MediaSlotView + import kotlin.math.ceil + import kotlin.math.max + +@@ -80,6 +82,20 @@ open class ContainerNodeView( + return result.viewsToAttach.isNotEmpty() || result.viewsToRemove.isNotEmpty() + } + ++ /** Slot rectangles include every quote inset and header, in this container's coordinates. */ ++ fun mediaSlotFrames(): List { ++ // A zero-width nested quote leaves its descendants' prior frames intact. ++ // Stop at that ancestor rather than publishing stale positive-width slots. ++ if (width - paddingLeft - paddingRight <= 0) return emptyList() ++ return segmentViews.flatMap { view -> ++ when (view) { ++ is MediaSlotView -> listOf(MediaSlotFrame(view.slot.asset.id, view.left, view.top, view.width, view.height)) ++ is ContainerNodeView -> view.mediaSlotFrames().map { it.translated(view.left, view.top) } ++ else -> emptyList() ++ } ++ } ++ } ++ + protected fun layoutSegments() { + val containerWidth = width + if (containerWidth <= 0) return +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/MarkdownSegment.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/MarkdownSegment.kt +index c203527cc55c9293b9ecb7ff46f8eecead50ed1c..b4a8499cdf92f52c307d906ecb150420bbe3e95f 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/segments/MarkdownSegment.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/MarkdownSegment.kt +@@ -1,5 +1,7 @@ + package com.swmansion.enriched.markdown.segments + ++import com.swmansion.enriched.markdown.media.DocumentAssets ++import com.swmansion.enriched.markdown.media.MediaSlot + import com.swmansion.enriched.markdown.parser.MarkdownASTNode + + sealed interface MarkdownSegment { +@@ -22,14 +24,21 @@ sealed interface MarkdownSegment { + + data class Blockquote( + val node: MarkdownASTNode, ++ val mediaSlots: Map = emptyMap(), ++ val assets: DocumentAssets? = null, + ) : MarkdownSegment + + data class Video( + val node: MarkdownASTNode, ++ val mediaSlot: MediaSlot? = null, + ) : MarkdownSegment + } + +-fun splitASTIntoSegments(root: MarkdownASTNode): List { ++fun splitASTIntoSegments( ++ root: MarkdownASTNode, ++ mediaSlots: Map = emptyMap(), ++ assets: DocumentAssets? = null, ++): List { + val segments = mutableListOf() + val currentTextNodes = mutableListOf() + +@@ -41,6 +50,14 @@ fun splitASTIntoSegments(root: MarkdownASTNode): List { + } + + for (child in root.children) { ++ val mediaNode = ++ if (child.type == MarkdownASTNode.NodeType.Paragraph && child.children.size == 1) child.children.first() else child ++ val slot = assets?.assetForNode(mediaNode)?.let { mediaSlots[it.id] } ++ if (slot != null) { ++ flushTextNodes() ++ segments.add(MarkdownSegment.Video(mediaNode, slot)) ++ continue ++ } + when (child.type) { + MarkdownASTNode.NodeType.Table -> { + flushTextNodes() +@@ -67,7 +84,7 @@ fun splitASTIntoSegments(root: MarkdownASTNode): List { + MarkdownASTNode.NodeType.Admonition, + -> { + flushTextNodes() +- segments.add(MarkdownSegment.Blockquote(child)) ++ segments.add(MarkdownSegment.Blockquote(child, mediaSlots, assets)) + } + + MarkdownASTNode.NodeType.Video -> { +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/RenderedSegment.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/RenderedSegment.kt +index 6377d91e80b6d236f0a1d94ab315986796274b20..aa72b8463f8f35d2a03a4b2ff57bcec00cdc7261 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/segments/RenderedSegment.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/RenderedSegment.kt +@@ -3,6 +3,8 @@ package com.swmansion.enriched.markdown.segments + import android.content.Context + import android.text.SpannableString + import com.swmansion.enriched.markdown.math.LatexErrorReporter ++import com.swmansion.enriched.markdown.media.DocumentAssets ++import com.swmansion.enriched.markdown.media.MediaSlot + import com.swmansion.enriched.markdown.parser.MarkdownASTNode + import com.swmansion.enriched.markdown.renderer.BlockquoteTextRenderer + import com.swmansion.enriched.markdown.renderer.Renderer +@@ -39,11 +41,14 @@ sealed interface RenderedSegment { + data class Blockquote( + val node: MarkdownASTNode, + override val signature: Long, ++ val mediaSlots: Map = emptyMap(), ++ val assets: DocumentAssets? = null, + ) : RenderedSegment + + data class Video( + val node: MarkdownASTNode, + override val signature: Long, ++ val mediaSlot: MediaSlot? = null, + ) : RenderedSegment + } + +@@ -80,13 +85,15 @@ object MarkdownSegmentRenderer { + } + + is MarkdownSegment.Blockquote -> { +- val signature = SegmentSignature.signatureForNode(segment.node) xor SegmentSignature.BLOCKQUOTE_KIND_SALT +- RenderedSegment.Blockquote(segment.node, signature) ++ val signature = ++ SegmentSignature.signatureForNode(segment.node) xor SegmentSignature.BLOCKQUOTE_KIND_SALT xor ++ segment.mediaSlots.hashCode().toLong() ++ RenderedSegment.Blockquote(segment.node, signature, segment.mediaSlots, segment.assets) + } + + is MarkdownSegment.Video -> { + val signature = SegmentSignature.signatureForNode(segment.node) xor SegmentSignature.VIDEO_KIND_SALT +- RenderedSegment.Video(segment.node, signature) ++ RenderedSegment.Video(segment.node, signature xor (segment.mediaSlot?.hashCode()?.toLong() ?: 0L), segment.mediaSlot) + } + } + } +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentHeightMeasurer.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentHeightMeasurer.kt +index 58f34e97d390b9277b81c14b8c7c2699cf854ff4..592e9321cec4017797241ba52dd7b4f13ed98ea8 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentHeightMeasurer.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentHeightMeasurer.kt +@@ -78,14 +78,40 @@ object SegmentHeightMeasurer { + // A quote encountered here is always nested inside another quote, so it + // carries no vertical margin (only the outermost quote does, added by + // MeasurementStore); this mirrors BlockquoteContainerView.nested. +- totalHeightPx += BlockquoteContainerView.measureBlockquoteNodeHeight(segment.node, style, context, contentWidthPx) ++ totalHeightPx += ++ BlockquoteContainerView.measureBlockquoteNodeHeight( ++ segment.node, ++ style, ++ context, ++ contentWidthPx, ++ segment.mediaSlots, ++ segment.assets, ++ ) + } + + is RenderedSegment.Video -> { +- totalHeightPx += style.videoStyle.marginTop +- totalHeightPx += contentWidthPx / style.videoStyle.resolvedAspectRatio ++ totalHeightPx += ++ segment.mediaSlot?.let { ++ com.swmansion.enriched.markdown.media.MediaSlotView ++ .marginTop(it, style) ++ .let { margin -> ceil(margin) } ++ } ++ ?: style.videoStyle.marginTop ++ totalHeightPx += ++ segment.mediaSlot?.let { ++ com.swmansion.enriched.markdown.media.MediaSlotView ++ .heightPx(it, style, widthPx.toFloat()) ++ .let { height -> ceil(height) } ++ } ++ ?: (contentWidthPx / style.videoStyle.resolvedAspectRatio) + if (includeBottomMargin) { +- totalHeightPx += style.videoStyle.marginBottom ++ totalHeightPx += ++ segment.mediaSlot?.let { ++ com.swmansion.enriched.markdown.media.MediaSlotView ++ .marginBottom(it, style) ++ .let { margin -> ceil(margin) } ++ } ++ ?: style.videoStyle.marginBottom + } + } + } +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentSignature.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentSignature.kt +index d1c9346326bab2dc3eb675bcdc2d3385866a992a..648dcbf62407c33422624ac6de4cd9707e488d9a 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentSignature.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentSignature.kt +@@ -1,5 +1,6 @@ + package com.swmansion.enriched.markdown.segments + ++import com.swmansion.enriched.markdown.media.mergeImageRequestHeaders + import com.swmansion.enriched.markdown.parser.MarkdownASTNode + + /** FNV-1a 64-bit hashing. Constants match the iOS implementation for cross-platform parity. */ +@@ -64,6 +65,16 @@ object SegmentSignature { + } + } + ++ node.imageSource?.let { source -> ++ hash = fnvMixString(hash, "image-source") ++ hash = fnvMixLong(hash, source.uri?.length?.toLong() ?: -1) ++ hash = fnvMixString(hash, source.uri) ++ for ((name, value) in mergeImageRequestHeaders(emptyMap(), source.headers).toSortedMap()) { ++ hash = fnvMixString(hash, name) ++ hash = fnvMixString(hash, value) ++ } ++ } ++ + for (child in node.children) { + hash = fnvMixLong(hash, signatureForNode(child)) + } +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentViewCreators.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentViewCreators.kt +index c9644d15d11cb32bce9ac370d6283ab66aa6dd57..4dcaf4d1c1812f6e4f3335659f5e557271ba34c1 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentViewCreators.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/SegmentViewCreators.kt +@@ -9,6 +9,7 @@ import android.view.View + import com.swmansion.enriched.markdown.EnrichedMarkdownInternalText + import com.swmansion.enriched.markdown.accessibility.AccessibilityLabels + import com.swmansion.enriched.markdown.math.LatexErrorReporter ++import com.swmansion.enriched.markdown.media.MediaSlotView + import com.swmansion.enriched.markdown.parser.MarkdownASTNode + import com.swmansion.enriched.markdown.styles.StyleConfig + import com.swmansion.enriched.markdown.utils.common.BreakStrategyUtils +@@ -208,7 +209,7 @@ object SegmentViewCreators { + segment: RenderedSegment.Blockquote, + config: SegmentViewConfig, + ) = BlockquoteContainerView(config.context, config).apply { +- applyBlockquoteNode(segment.node) ++ applyBlockquoteNode(segment.node, segment.mediaSlots, segment.assets) + } + + private val cachedVideoContainerClass: Class<*>? by lazy { +@@ -227,6 +228,7 @@ object SegmentViewCreators { + segment: RenderedSegment.Video, + config: SegmentViewConfig, + ): View { ++ segment.mediaSlot?.let { return MediaSlotView(config.context, config.style, it) } + val resolvedClass = videoContainerClass() + if (!FeatureFlags.IS_VIDEO_ENABLED || resolvedClass == null) return View(config.context) + return try { +@@ -251,6 +253,10 @@ object SegmentViewCreators { + view: View, + segment: RenderedSegment.Video, + ) { ++ if (view is MediaSlotView) { ++ segment.mediaSlot?.let { view.slot = it } ++ return ++ } + videoContainerClass() + ?.getMethod("applyVideoNode", MarkdownASTNode::class.java) + ?.invoke(view, segment.node) +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/segments/TableContainerView.kt b/android/src/main/java/com/swmansion/enriched/markdown/segments/TableContainerView.kt +index 40c959ba4dc7fa85cf0648d75e797bcd5bdecc7a..dde664899bee811b213a6db13f1bfa49c810aa56 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/segments/TableContainerView.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/segments/TableContainerView.kt +@@ -446,6 +446,8 @@ class TableContainerView( + text: CharSequence, + widthPx: Int, + ) { ++ com.swmansion.enriched.markdown.spans.LinkPillSpan ++ .prepareForMeasurement(text, widthPx) + if (widthPx <= 1) return + val spanned = text as? Spanned ?: return + spanned +@@ -476,6 +478,8 @@ class TableContainerView( + val columnWidths = FloatArray(texts.maxOfOrNull { it.size } ?: 0) + texts.forEach { row -> + row.forEachIndexed { colIndex, cellText -> ++ com.swmansion.enriched.markdown.spans.LinkPillSpan ++ .prepareForMeasurement(cellText, maxColumnWidth.toInt()) + val layout = + StaticLayout.Builder + .obtain(cellText, 0, cellText.length, paint, maxColumnWidth.toInt()) +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt b/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +index cbda855f33ae7e7dd25fd7b36f9805be6a1ebd56..c5e209803f96e2d9e17de343e414752c8862751a 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +@@ -53,24 +53,49 @@ class CodeBackgroundSpan( + val spanEnd = text.getSpanEnd(this) + if (spanStart !in 0 until spanEnd) return + +- // 1. Determine relative positioning +- val isFirst = spanStart >= start +- val isLast = spanEnd <= end +- +- // 2. Calculate coordinates +- val finalBottom = adjustBottomForMargin(text, end, bottom) +- val leadingMargin = leadingMarginAt(text, start) +- val startX = if (isFirst) getHorizontalOffset(text, start, end, spanStart, p, leadingMargin) + left else left.toFloat() + leadingMargin +- val endX = if (isLast) getHorizontalOffset(text, start, end, spanEnd, p, leadingMargin) + left else right.toFloat() +- +- rect.set(min(startX, endX), top.toFloat(), max(startX, endX), finalBottom.toFloat()) +- +- // 3. Apply Style +- val codeStyle = styleConfig.codeStyle +- sharedBackgroundPaint.color = codeStyle.backgroundColor +- sharedBorderPaint.color = codeStyle.borderColor ++ // Keep CodeSpan and this background span intact for semantic extraction. Draw only ++ // portions outside replacement pills, including code surrounding a partially covered run. ++ fun drawUncoveredRange( ++ rangeStart: Int, ++ rangeEnd: Int, ++ ) { ++ if (max(rangeStart, start) >= min(rangeEnd, end)) return ++ // 1. Determine relative positioning ++ val isFirst = rangeStart >= start ++ val isLast = rangeEnd <= end ++ ++ // 2. Calculate coordinates ++ val finalBottom = adjustBottomForMargin(text, end, bottom) ++ val leadingMargin = leadingMarginAt(text, start) ++ val startX = ++ if (isFirst) { ++ getHorizontalOffset(text, start, end, rangeStart, p, leadingMargin) + left ++ } else { ++ left.toFloat() + ++ leadingMargin ++ } ++ val endX = if (isLast) getHorizontalOffset(text, start, end, rangeEnd, p, leadingMargin) + left else right.toFloat() ++ ++ rect.set(min(startX, endX), top.toFloat(), max(startX, endX), finalBottom.toFloat()) ++ ++ // 3. Apply Style ++ val codeStyle = styleConfig.codeStyle ++ sharedBackgroundPaint.color = codeStyle.backgroundColor ++ sharedBorderPaint.color = codeStyle.borderColor ++ ++ drawShapes(canvas, isFirst, isLast) ++ } + +- drawShapes(canvas, isFirst, isLast) ++ var cursor = spanStart ++ val pills = text.getSpans(spanStart, spanEnd, LinkPillSpan::class.java).sortedBy { text.getSpanStart(it) } ++ for (pill in pills) { ++ val coveredStart = max(spanStart, text.getSpanStart(pill)) ++ val coveredEnd = min(spanEnd, text.getSpanEnd(pill)) ++ if (coveredStart >= coveredEnd) continue ++ if (cursor < coveredStart) drawUncoveredRange(cursor, coveredStart) ++ cursor = max(cursor, coveredEnd) ++ } ++ drawUncoveredRange(cursor, spanEnd) + } + + /** +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt b/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +index 56951af974e5d29d2398c136701b0aec63953ff1..2cdabe149c754d18ec5dbf875f269e06a1aee8ae 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +@@ -19,6 +19,8 @@ import androidx.core.graphics.drawable.toDrawable + import androidx.core.graphics.withClip + import androidx.core.graphics.withSave + import com.swmansion.enriched.markdown.EnrichedMarkdownText ++import com.swmansion.enriched.markdown.media.ImageSourceTransport ++import com.swmansion.enriched.markdown.media.mergeImageRequestHeaders + import com.swmansion.enriched.markdown.styles.StyleConfig + import com.swmansion.enriched.markdown.utils.common.findEnrichedMarkdownAncestor + import com.swmansion.enriched.markdown.utils.text.ImageCache +@@ -35,6 +37,7 @@ class ImageSpan( + styleConfig: StyleConfig, + val isInline: Boolean = false, + val altText: String = "", ++ imageSource: ImageSourceTransport? = null, + ) : AndroidImageSpan( + Color.TRANSPARENT.toDrawable(), + imageUrl, +@@ -61,8 +64,10 @@ class ImageSpan( + else -> height + } + +- private val requestHeaders: Map = styleConfig.imageRequestHeaders +- private val requestKey: String = ImageCache.requestKey(imageUrl, requestHeaders) ++ private val transportUri: String? = if (imageSource == null) imageUrl else imageSource.uri ++ private val requestHeaders: Map = ++ mergeImageRequestHeaders(styleConfig.imageRequestHeaders, imageSource?.headers.orEmpty()) ++ private val requestKey: String? = transportUri?.let { ImageCache.requestKey(it, requestHeaders) } + + private var cachedWidth: Int = 0 + private var viewRef: WeakReference? = null +@@ -71,7 +76,7 @@ class ImageSpan( + + private fun intrinsicImageSize(): Pair { + sourceDrawable?.let { return it.intrinsicWidth to it.intrinsicHeight } +- val cached = ImageCache.getOriginal(imageUrl) ?: return 0 to 0 ++ val cached = requestKey?.let { ImageCache.getOriginal(it) } ?: return 0 to 0 + return cached.width to cached.height + } + +@@ -107,19 +112,21 @@ class ImageSpan( + } + + private fun loadImage() { +- val scheme = Uri.parse(imageUrl).scheme?.lowercase() ++ val uri = transportUri ?: return ++ val key = requestKey ?: return ++ val scheme = Uri.parse(uri).scheme?.lowercase() + if (scheme == "http" || scheme == "https") { +- ImageDownloader.download(context, imageUrl, requestHeaders) { bitmap -> ++ ImageDownloader.download(context, uri, requestHeaders) { bitmap -> + if (bitmap != null) { + sourceDrawable = bitmap.toDrawable(context.resources) + wrapAndAssignDrawable() + } + } + } else { +- val cached = ImageCache.getOriginal(imageUrl) +- val bitmap = cached ?: LocalImageLoader.load(context, imageUrl) ++ val cached = ImageCache.getOriginal(key) ++ val bitmap = cached ?: LocalImageLoader.load(context, uri) + if (bitmap != null) { +- if (cached == null) ImageCache.putOriginal(imageUrl, bitmap) ++ if (cached == null) ImageCache.putOriginal(key, bitmap) + sourceDrawable = bitmap.toDrawable(context.resources) + wrapAndAssignDrawable() + } +@@ -138,7 +145,8 @@ class ImageSpan( + + boxHeight = resolveBoxHeight(targetWidth) + +- val cachedBitmap = ImageCache.getProcessed(requestKey, targetWidth, boxHeight, borderRadiusPx, resizeMode) ++ val key = requestKey ?: return ++ val cachedBitmap = ImageCache.getProcessed(key, targetWidth, boxHeight, borderRadiusPx, resizeMode) + + if (cachedBitmap != null) { + loadedDrawable = +@@ -155,7 +163,7 @@ class ImageSpan( + isBlockImage = !isInline, + resizeMode = resizeMode, + legacySizing = legacySizing, +- cacheKey = CacheKey(requestKey, targetWidth, boxHeight, borderRadiusPx, resizeMode), ++ cacheKey = CacheKey(key, targetWidth, boxHeight, borderRadiusPx, resizeMode), + ) + } + requestReflow() +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkPillIconCache.kt b/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkPillIconCache.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..bddad2494e82d73f1e22e47cbd0012941e5de611 +--- /dev/null ++++ b/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkPillIconCache.kt +@@ -0,0 +1,53 @@ ++package com.swmansion.enriched.markdown.spans ++ ++import android.graphics.Bitmap ++import android.graphics.BitmapFactory ++import android.net.Uri ++import java.io.File ++import kotlin.math.max ++ ++/** Original-color local icons, shared by measurement and rendering across reparses. */ ++internal object LinkPillIconCache { ++ private const val MAX_ENTRIES = 64 ++ private const val MAX_BYTES = 8 * 1024 * 1024 ++ private const val MAX_DIMENSION = 512 ++ ++ private data class Key( ++ val path: String, ++ val modified: Long, ++ val size: Long, ++ ) ++ ++ private val images = LinkedHashMap(16, 0.75f, true) ++ private var bytes = 0 ++ ++ @Synchronized ++ fun load(iconUri: String): Bitmap? = ++ runCatching { ++ val uri = Uri.parse(iconUri) ++ if (uri.scheme != "file") return@runCatching null ++ val file = File(uri.path ?: return@runCatching null).canonicalFile ++ if (!file.isFile) return@runCatching null ++ val key = Key(file.path, file.lastModified(), file.length()) ++ images[key]?.let { return@runCatching it } ++ val bounds = BitmapFactory.Options().apply { inJustDecodeBounds = true } ++ BitmapFactory.decodeFile(file.path, bounds) ++ if (bounds.outWidth <= 0 || bounds.outHeight <= 0) return@runCatching null ++ val options = BitmapFactory.Options().apply { inSampleSize = 1 } ++ while (max(bounds.outWidth, bounds.outHeight) / options.inSampleSize > MAX_DIMENSION) { ++ options.inSampleSize *= 2 ++ } ++ val bitmap = BitmapFactory.decodeFile(file.path, options) ?: return@runCatching null ++ val cost = bitmap.allocationByteCount ++ if (cost > MAX_BYTES) return@runCatching bitmap ++ images[key] = bitmap ++ bytes += cost ++ while (images.size > MAX_ENTRIES || bytes > MAX_BYTES) { ++ val oldest = images.entries.iterator() ++ bytes -= oldest.next().value.allocationByteCount ++ oldest.remove() ++ // Do not recycle: existing spans can still own the evicted bitmap. ++ } ++ bitmap ++ }.getOrNull() ++} +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkPillSpan.kt b/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkPillSpan.kt +new file mode 100644 +index 0000000000000000000000000000000000000000..7dc8be3d3e9a0af60bff269617751db4bbd3dda0 +--- /dev/null ++++ b/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkPillSpan.kt +@@ -0,0 +1,142 @@ ++package com.swmansion.enriched.markdown.spans ++ ++import android.graphics.Canvas ++import android.graphics.Paint ++import android.graphics.PorterDuff ++import android.graphics.PorterDuffColorFilter ++import android.graphics.RectF ++import android.os.Build ++import android.text.Spanned ++import android.text.TextPaint ++import android.text.TextUtils ++import android.text.style.ReplacementSpan ++import com.swmansion.enriched.markdown.styles.LinkVariantEntry ++import kotlin.math.ceil ++import kotlin.math.max ++import kotlin.math.min ++ ++/** Draws an atomic visual over the original link text, without changing stored characters. */ ++class LinkPillSpan( ++ private val variant: LinkVariantEntry, ++ private val typeface: android.graphics.Typeface, ++ private val fontSize: Float, ++ originalLabel: String, ++) : ReplacementSpan() { ++ private val label = (variant.label.ifEmpty { originalLabel }).replace('\n', ' ').replace('\r', ' ') ++ private var availableWidth = Float.MAX_VALUE ++ private val icon = LinkPillIconCache.load(variant.iconUri) ++ private val iconPaint = ++ Paint(Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG).apply { ++ variant.iconTintColor?.let { colorFilter = PorterDuffColorFilter(it, PorterDuff.Mode.SRC_IN) } ++ } ++ ++ init { ++ // TalkBack reads original semantics even when the visual label differs. ++ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) contentDescription = originalLabel ++ } ++ ++ fun prepareForMeasurement(width: Int): Boolean { ++ val next = width.coerceAtLeast(1).toFloat() ++ if (availableWidth == next) return false ++ availableWidth = next ++ return true ++ } ++ ++ private fun textPaint(paint: Paint) = ++ TextPaint(paint).apply { ++ typeface = this@LinkPillSpan.typeface ++ textSize = fontSize ++ color = variant.color ++ bgColor = 0 ++ isUnderlineText = variant.underline ++ isStrikeThruText = false ++ } ++ ++ private fun width(paint: Paint): Float { ++ val iconWidth = if (icon == null) 0f else fontSize + fontSize * 0.25f ++ val natural = paint.measureText(label) + iconWidth + 2 * (variant.paddingHorizontal + variant.borderWidth) ++ val limit = if (variant.maxWidth > 0) min(availableWidth, variant.maxWidth) else availableWidth ++ return min(ceil(natural), limit).coerceAtLeast(1f) ++ } ++ ++ override fun getSize( ++ paint: Paint, ++ text: CharSequence, ++ start: Int, ++ end: Int, ++ fm: Paint.FontMetricsInt?, ++ ): Int { ++ val labelPaint = textPaint(paint) ++ val metrics = labelPaint.fontMetricsInt ++ val inset = ceil(variant.paddingVertical + variant.borderWidth).toInt() ++ fm?.let { ++ it.ascent = min(it.ascent, metrics.ascent - inset) ++ it.descent = max(it.descent, metrics.descent + inset) ++ it.top = min(it.top, it.ascent) ++ it.bottom = max(it.bottom, it.descent) ++ } ++ return ceil(width(labelPaint)).toInt() ++ } ++ ++ override fun draw( ++ canvas: Canvas, ++ text: CharSequence, ++ start: Int, ++ end: Int, ++ x: Float, ++ top: Int, ++ y: Int, ++ bottom: Int, ++ paint: Paint, ++ ) { ++ val labelPaint = textPaint(paint) ++ val metrics = labelPaint.fontMetrics ++ val inset = variant.paddingVertical + variant.borderWidth ++ val rect = RectF(x, y + metrics.ascent - inset, x + width(labelPaint), y + metrics.descent + inset) ++ val fill = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = variant.backgroundColor } ++ canvas.drawRoundRect(rect, variant.borderRadius, variant.borderRadius, fill) ++ if (variant.borderWidth > 0) { ++ fill.color = variant.borderColor ++ fill.style = Paint.Style.STROKE ++ fill.strokeWidth = variant.borderWidth ++ val border = RectF(rect).apply { inset(variant.borderWidth / 2, variant.borderWidth / 2) } ++ canvas.drawRoundRect(border, variant.borderRadius, variant.borderRadius, fill) ++ } ++ val save = canvas.save() ++ canvas.clipRect(rect) ++ var left = x + variant.paddingHorizontal + variant.borderWidth ++ val right = rect.right - variant.paddingHorizontal - variant.borderWidth ++ if (icon != null && right - left >= fontSize) { ++ val iconTop = y + (metrics.ascent + metrics.descent - fontSize) / 2 ++ val scale = fontSize / max(icon.width, icon.height) ++ val destination = RectF(left, iconTop, left + icon.width * scale, iconTop + icon.height * scale) ++ destination.offset((fontSize - destination.width()) / 2, (fontSize - destination.height()) / 2) ++ canvas.drawBitmap(icon, null, destination, iconPaint) ++ left += fontSize + fontSize * 0.25f ++ } ++ val displayed = TextUtils.ellipsize(label, labelPaint, max(0f, right - left), TextUtils.TruncateAt.END) ++ canvas.drawText(displayed.toString(), left, y.toFloat(), labelPaint) ++ canvas.restoreToCount(save) ++ } ++ ++ companion object { ++ /** Called before both Fabric measurement and visible TextView layout, including table cells. */ ++ fun prepareForMeasurement( ++ text: CharSequence?, ++ width: Int, ++ ): Boolean { ++ val spanned = text as? Spanned ?: return false ++ var changed = false ++ spanned.getSpans(0, spanned.length, LinkPillSpan::class.java).forEach { pill -> ++ val start = spanned.getSpanStart(pill) ++ val end = spanned.getSpanEnd(pill) ++ val margin = ++ spanned ++ .getSpans(start, end, android.text.style.LeadingMarginSpan::class.java) ++ .sumOf { max(it.getLeadingMargin(true), it.getLeadingMargin(false)) } ++ changed = pill.prepareForMeasurement(width - margin) || changed ++ } ++ return changed ++ } ++ } ++} +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt b/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt +index 2cef891852a55b5050de339481e195e588c7393d..f699342b3cc0ff12405c6a0ca1f8d2e9d35c8ec7 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt +@@ -17,6 +17,8 @@ class LinkSpan( + private val styleCache: SpanStyleCache, + private val blockStyle: BlockStyle, + private val context: Context, ++ private val preserveCodeFont: Boolean = false, ++ val recognizedLink: Boolean = false, + ) : ClickableSpan() { + @Volatile + private var longPressTriggered = false +@@ -43,16 +45,18 @@ class LinkSpan( + override fun updateDrawState(textPaint: TextPaint) { + super.updateDrawState(textPaint) + +- textPaint.textSize = blockStyle.fontSize ++ if (!preserveCodeFont) textPaint.textSize = blockStyle.fontSize + + val variant = styleCache.resolvedVariantForUrl(url) + +- val fontFamily = styleCache.linkFontFamily +- if (fontFamily.isNotEmpty()) { +- val overriddenBlockStyle = blockStyle.copy(fontFamily = fontFamily) +- textPaint.applyBlockStyleFont(overriddenBlockStyle, context) +- } else { +- textPaint.applyBlockStyleFont(blockStyle, context) ++ val fontFamily = variant?.fontFamily?.takeIf { it.isNotEmpty() } ?: styleCache.linkFontFamily ++ if (!preserveCodeFont) { ++ if (fontFamily.isNotEmpty()) { ++ val overriddenBlockStyle = blockStyle.copy(fontFamily = fontFamily) ++ textPaint.applyBlockStyleFont(overriddenBlockStyle, context) ++ } else { ++ textPaint.applyBlockStyleFont(blockStyle, context) ++ } + } + + textPaint.color = variant?.color ?: styleCache.linkColor +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkVariantEntry.kt b/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkVariantEntry.kt +index e502ae1671c24c3fea1d2087412b8c48cd6cbc6e..c0f2ad3ab16ad03dfc8fd6c33384ca07a21013e1 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkVariantEntry.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkVariantEntry.kt +@@ -13,6 +13,17 @@ data class LinkVariantEntry( + val color: Int, + val underline: Boolean, + val backgroundColor: Int, ++ val fontFamily: String = "", ++ val pill: Boolean = false, ++ val label: String = "", ++ val iconUri: String = "", ++ val iconTintColor: Int? = null, ++ val borderRadius: Float = 8f, ++ val paddingHorizontal: Float = 6f, ++ val paddingVertical: Float = 2f, ++ val borderWidth: Float = 0f, ++ val borderColor: Int = android.graphics.Color.TRANSPARENT, ++ val maxWidth: Float = 0f, + ) { + companion object { + fun fromReadableMap( +@@ -24,6 +35,17 @@ data class LinkVariantEntry( + color = parser.parseColor(map, "color"), + underline = parser.parseBoolean(map, "underline"), + backgroundColor = parser.parseColor(map, "backgroundColor"), ++ fontFamily = parser.parseString(map, "fontFamily"), ++ pill = parser.parseBoolean(map, "pill"), ++ label = parser.parseString(map, "label"), ++ iconUri = parser.parseString(map, "iconUri"), ++ iconTintColor = parser.parseOptionalColor(map, "iconTintColor"), ++ borderRadius = parser.toPixelFromDIP(parser.parseOptionalDouble(map, "borderRadius", 8.0).toFloat()), ++ paddingHorizontal = parser.toPixelFromDIP(parser.parseOptionalDouble(map, "paddingHorizontal", 6.0).toFloat()), ++ paddingVertical = parser.toPixelFromDIP(parser.parseOptionalDouble(map, "paddingVertical", 2.0).toFloat()), ++ borderWidth = parser.toPixelFromDIP(parser.parseOptionalDouble(map, "borderWidth").toFloat()), ++ borderColor = parser.parseOptionalColor(map, "borderColor") ?: android.graphics.Color.TRANSPARENT, ++ maxWidth = parser.toPixelFromDIP(parser.parseOptionalDouble(map, "maxWidth").toFloat()), + ) + } + } +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt b/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +index 705176702a715092c79cd3d2aaded6fc0513054f..7e156aa9b7644fb43fbc16b7c4d8efb92c4a0f5e 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +@@ -298,6 +298,10 @@ object MarkdownASTSerializer { + } + + NodeType.Link -> { ++ if (node.getAttribute("recognizedLink") == "true") { ++ appendChildren(node, buffer) ++ return ++ } + val url = node.getAttribute("url") ?: "" + buffer.append("[") + appendChildren(node, buffer) +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt b/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +index b96bac1b663db52f4c3ac766371b0fb0512f42a9..9702d30908f3585b4799afee2566278810f856d0 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +@@ -3,6 +3,7 @@ package com.swmansion.enriched.markdown.utils.text + import android.graphics.Bitmap + import android.util.LruCache + import java.security.MessageDigest ++import java.util.Locale + + object ImageCache { + private const val ORIGINAL_CACHE_SIZE = 20 * 1024 * 1024 +@@ -23,7 +24,9 @@ object ImageCache { + ): String { + if (headers.isEmpty()) return url + val joined = +- headers.entries ++ headers ++ .mapKeys { it.key.lowercase(Locale.ROOT) } ++ .entries + .sortedBy { it.key } + .joinToString(separator = "\n") { "${it.key}:${it.value}" } + val digest = MessageDigest.getInstance("SHA-256").digest(joined.toByteArray()) +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt b/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +index 7a2071e4d8aefe3e4106436d5affd48f197d88a6..582b70d22237ceebaf4d99ce0b8fe8a5fc0c2b47 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +@@ -7,6 +7,7 @@ import android.os.Handler + import android.os.Looper + import android.util.Log + import okhttp3.Cache ++import okhttp3.CacheControl + import okhttp3.Call + import okhttp3.Callback + import okhttp3.OkHttpClient +@@ -69,12 +70,7 @@ object ImageDownloader { + inFlight[requestKey] = mutableListOf(callback) + } + +- val request = +- Request +- .Builder() +- .url(url) +- .apply { headers.forEach { (name, value) -> addHeader(name, value) } } +- .build() ++ val request = requestForImage(url, headers) + getClient(context).newCall(request).enqueue( + object : Callback { + override fun onResponse( +@@ -110,6 +106,27 @@ object ImageDownloader { + ) + } + ++ internal fun requestForImage( ++ url: String, ++ headers: Map, ++ ): Request = ++ Request ++ .Builder() ++ .url(url) ++ .apply { ++ headers.forEach { (name, value) -> addHeader(name, value) } ++ // The HTTP cache uses URL + server Vary, which may omit source header identity. ++ if (headers.isNotEmpty()) { ++ cacheControl( ++ CacheControl ++ .Builder() ++ .noCache() ++ .noStore() ++ .build(), ++ ) ++ } ++ }.build() ++ + private fun decodeDownsampled( + bytes: ByteArray, + targetWidth: Int, +diff --git a/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/MarkdownExtractor.kt b/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/MarkdownExtractor.kt +index 2957f98ceb399397359c14481d0d0a3e628258e8..ec5a0347a7c62f6c8d893b189c95d099173ea911 100644 +--- a/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/MarkdownExtractor.kt ++++ b/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/MarkdownExtractor.kt +@@ -300,7 +300,7 @@ object MarkdownExtractor { + val baselineShiftSpans = spannable.getSpans(start, end, BaselineShiftSpan::class.java) + val hasSuperscript = baselineShiftSpans.any { it.spanType == BaselineShiftSpan.SpanType.SUPERSCRIPT } + val hasSubscript = baselineShiftSpans.any { it.spanType == BaselineShiftSpan.SpanType.SUBSCRIPT } +- val linkSpans = spannable.getSpans(start, end, LinkSpan::class.java) ++ val linkSpans = spannable.getSpans(start, end, LinkSpan::class.java).filterNot { it.recognizedLink } + val hasHighlight = spannable.getSpans(start, end, HighlightSpan::class.java).isNotEmpty() + + var result = text +diff --git a/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h b/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +index dea8bb2e79987d70aa8b01bffffcc5d079d077c4..43a423af43b267d84be94bdd005fde2a5983e9e3 100644 +--- a/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h ++++ b/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +@@ -20,6 +20,17 @@ public: + MarkdownContainerShadowNode(ShadowNode const &sourceShadowNode, ShadowNodeFragment const &fragment) + : ConcreteViewShadowNode(sourceShadowNode, fragment) { + dirtyLayoutIfNeeded(); ++ const auto &previousProps = static_cast(sourceShadowNode).getConcreteProps(); ++ const auto &props = getConcreteProps(); ++ if (previousProps.enableImageSourceResolution != props.enableImageSourceResolution || ++ previousProps.imageSourcesRevision != props.imageSourcesRevision || ++ previousProps.imageSourcesContinuityStart != props.imageSourcesContinuityStart || ++ previousProps.imageSources != props.imageSources || previousProps.documentRevision != props.documentRevision || ++ previousProps.enableMediaSlots != props.enableMediaSlots || ++ previousProps.mediaOverridesRevision != props.mediaOverridesRevision || ++ previousProps.mediaOverrides != props.mediaOverrides) { ++ dirtyLayout(); ++ } + } + + static ShadowNodeTraits BaseTraits() { +diff --git a/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h b/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +index 1c8ea11951050ff54f122728764c8ea5749dc2e3..d8fadfbdbb795e0753255e0e45681ddb6e76eb7e 100644 +--- a/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h ++++ b/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +@@ -38,6 +38,29 @@ inline folly::dynamic toDynamic(const EnrichedMarkdownProps &props) { + serializedProps["allowTrailingMargin"] = props.allowTrailingMargin; + serializedProps["streamingAnimation"] = props.streamingAnimation; + ++ serializedProps["enableImageSourceResolution"] = props.enableImageSourceResolution; ++ serializedProps["imageSourcesRevision"] = props.imageSourcesRevision; ++ serializedProps["imageSourcesContinuityStart"] = props.imageSourcesContinuityStart; ++ folly::dynamic imageSources = folly::dynamic::array(); ++ for (const auto &source : props.imageSources) { ++ folly::dynamic headers = folly::dynamic::array(); ++ for (const auto &header : source.headers) { ++ headers.push_back(folly::dynamic::object("name", header.name)("value", header.value)); ++ } ++ imageSources.push_back(folly::dynamic::object("id", source.id)("url", source.url)("anchor", source.anchor)( ++ "uri", source.uri)("headers", std::move(headers))("useDefault", source.useDefault)); ++ } ++ serializedProps["imageSources"] = std::move(imageSources); ++ serializedProps["documentRevision"] = props.documentRevision; ++ serializedProps["mediaOverridesRevision"] = props.mediaOverridesRevision; ++ serializedProps["enableMediaSlots"] = props.enableMediaSlots; ++ folly::dynamic mediaOverrides = folly::dynamic::array(); ++ for (const auto &slot : props.mediaOverrides) { ++ mediaOverrides.push_back(folly::dynamic::object("id", slot.id)("height", slot.height)("width", slot.width)( ++ "url", slot.url)("kind", slot.kind)("anchor", slot.anchor)); ++ } ++ serializedProps["mediaOverrides"] = std::move(mediaOverrides); ++ + folly::dynamic imageRequestHeaders = folly::dynamic::array(); + for (const auto &header : props.imageRequestHeaders) { + imageRequestHeaders.push_back(toDynamic(header)); diff --git a/cpp/md4c/md4c.h b/cpp/md4c/md4c.h index cf965d8cc17cb2724c8d194f5cbd5784298f1e5c..d42080a9262b13a808b50c29794802c473fe1911 100644 --- a/cpp/md4c/md4c.h @@ -9,34 +3485,2381 @@ index cf965d8cc17cb2724c8d194f5cbd5784298f1e5c..d42080a9262b13a808b50c29794802c4 +/* Isolate the embedded parser from other libraries linking their own MD4C. */ +#define md_parse enrm_md_parse + - #ifdef __cplusplus - extern "C" { - #endif -diff --git a/ios/input/ENRMInputParser.mm b/ios/input/ENRMInputParser.mm -index f82e72b3b838e40d886cf1eb5037b0a406730afe..ca3ae2df35e0e6bbdf2bc57cee0db2a89fbefff9 100644 ---- a/ios/input/ENRMInputParser.mm -+++ b/ios/input/ENRMInputParser.mm -@@ -1,7 +1,7 @@ - #import "ENRMInputParser.h" - #import "ENRMFormattingRange.h" - #import "ENRMInputRemend.h" --#include "md4c.h" -+#include "../../cpp/md4c/md4c.h" - #include - #include - #include + #ifdef __cplusplus + extern "C" { + #endif +diff --git a/ios/EnrichedMarkdown.mm b/ios/EnrichedMarkdown.mm +index 5a22a30affaeda8431e439390962a9c5242f5608..c46857768d36ad107cc9660ffc1612103c5bcabf 100644 +--- a/ios/EnrichedMarkdown.mm ++++ b/ios/EnrichedMarkdown.mm +@@ -3,11 +3,14 @@ + #import "ENRMAccessibilityLabels.h" + #import "ENRMAsyncRenderCoordinator.h" + #import "ENRMAtomicSize.h" ++#import "ENRMDocumentAssets.h" + #import "ENRMImageAttachment.h" + #import "ENRMLatexErrorCoordinator.h" + #import "ENRMMarkdownParser.h" ++#import "ENRMMediaSlotView.h" + #import "ENRMTailFadeInAnimator.h" + #import "ENRMTextInteractionUtils.h" ++#import "ENRMTextLinkRecognizer.h" + #import "ENRMTextRenderer.h" + #import "ENRMTextViewSetup.h" + #import "ENRMUIKit.h" +@@ -78,6 +81,8 @@ static char kENRMSegmentFadeAnimatorKey; + + @interface EnrichedMarkdown () + + (ENRMMd4cFlags *)flagsFromProps:(const EnrichedMarkdownMd4cFlagsStruct &)props; ++- (void)emitDocumentAssets; ++- (void)emitMediaLayout:(NSArray *)frames; + - (void)emitLinkPress:(NSString *)url; + - (void)emitLinkLongPress:(NSString *)url; + - (void)emitImagePress:(NSString *)url altText:(NSString *)altText; +@@ -95,6 +100,8 @@ static char kENRMSegmentFadeAnimatorKey; + StyleConfig *_config; + ENRMMd4cFlags *_md4cFlags; + BOOL _isGFM; ++ ENRMLinkRegexConfig *_linkRegex; ++ ENRMLinkRegexConfig *_inlineCodeLinkRegex; + NSString *_cachedMarkdown; + NSString *_renderedMarkdown; + ENRMLatexErrorCoordinator *_latexErrorCoordinator; +@@ -141,6 +148,20 @@ static char kENRMSegmentFadeAnimatorKey; + NSWritingDirection _resolvedLayoutDirection; + + ENRMAtomicSize _lastCommittedSize; ++ NSInteger _documentRevision; ++ NSInteger _renderedDocumentRevision; ++ BOOL _enableDocumentAssets; ++ BOOL _enableMediaSlots; ++ BOOL _enableImageSourceResolution; ++ NSInteger _imageSourcesRevision; ++ NSInteger _imageSourcesContinuityStart; ++ NSDictionary *_imageSources; ++ NSInteger _mediaOverridesRevision; ++ NSDictionary *_mediaOverrides; ++ NSArray *_documentAssets; ++ NSArray *_lastMediaFrames; ++ NSArray *_lastEmittedAssets; ++ NSInteger _lastEmittedAssetsRevision; + } + + + (ComponentDescriptorProvider)componentDescriptorProvider +@@ -172,6 +193,15 @@ static char kENRMSegmentFadeAnimatorKey; + _parser = [[ENRMMarkdownParser alloc] init]; + _md4cFlags = [EnrichedMarkdown flagsFromProps:defaultProps->md4cFlags]; + _isGFM = defaultProps->isGFM; ++ _imageSourcesRevision = -1; ++ _imageSourcesContinuityStart = 1; ++ _imageSources = @{}; ++ _mediaOverridesRevision = -1; ++ _renderedDocumentRevision = -1; ++ _lastEmittedAssetsRevision = -1; ++ _mediaOverrides = @{}; ++ _linkRegex = ENRMTextLinkRegexConfigFromProps(defaultProps->linkRegex); ++ _inlineCodeLinkRegex = ENRMTextLinkRegexConfigFromProps(defaultProps->inlineCodeLinkRegex); + _segmentViews = [NSMutableArray array]; + _segmentSignatures = [NSMutableArray array]; + __weak __typeof(self) weakLatexSelf = self; +@@ -368,6 +398,18 @@ static char kENRMSegmentFadeAnimatorKey; + }]]; + #endif + ++ [handlers addObject:[ENRMSegmentViewHandler handlerWithKind:ENRMSegmentKindMediaSlot ++ matchesView:^BOOL(RCTUIView *view, ENRMRenderedSegment *segment) { ++ return [view isKindOfClass:[ENRMMediaSlotView class]]; ++ } ++ createView:^RCTUIView *(ENRMRenderedSegment *segment) { ++ ENRMMediaSlotView *view = [[ENRMMediaSlotView alloc] init]; ++ view.mediaNode = segment.mediaSlotNode; ++ return view; ++ } ++ updateView:^(RCTUIView *view, ENRMRenderedSegment *segment) { ++ ((ENRMMediaSlotView *)view).mediaNode = segment.mediaSlotNode; ++ }]]; + _segmentViewRegistry = [[ENRMSegmentViewRegistry alloc] initWithHandlers:handlers]; + } + +@@ -432,6 +474,7 @@ static char kENRMSegmentFadeAnimatorKey; + #endif + } + ++ NSMutableArray *mediaFrames = [NSMutableArray array]; + __block CGFloat yOffset = 0.0; + __block CGFloat maxContentWidth = 0.0; + const NSUInteger lastIndex = _segmentViews.count - 1; +@@ -443,7 +486,13 @@ static char kENRMSegmentFadeAnimatorKey; + CGFloat segmentHeight = 0; + const BOOL isTable = [segment isKindOfClass:[TableContainerView class]]; + +- if ([segment isKindOfClass:[EnrichedMarkdownInternalText class]]) { ++ if ([segment isKindOfClass:[ENRMMediaSlotView class]]) { ++ MarkdownASTNode *node = ((ENRMMediaSlotView *)segment).mediaNode; ++ BOOL video = [node.attributes[@"_enrmMediaKind"] isEqualToString:@"video"]; ++ yOffset += video ? _config.videoMarginTop : _config.imageMarginTop; ++ segmentHeight = ENRMMediaSlotHeight(node, width, _config); ++ maxContentWidth = width; ++ } else if ([segment isKindOfClass:[EnrichedMarkdownInternalText class]]) { + EnrichedMarkdownInternalText *textView = (EnrichedMarkdownInternalText *)segment; + textView.allowTrailingMargin = shouldAddBottomMargin; + CGSize textSize = [textView measureSize:width]; +@@ -504,7 +553,11 @@ static char kENRMSegmentFadeAnimatorKey; + + yOffset += segmentHeight; + +- if ([segment isKindOfClass:[TableContainerView class]] && shouldAddBottomMargin) { ++ if ([segment isKindOfClass:[ENRMMediaSlotView class]] && shouldAddBottomMargin) { ++ MarkdownASTNode *node = ((ENRMMediaSlotView *)segment).mediaNode; ++ yOffset += [node.attributes[@"_enrmMediaKind"] isEqualToString:@"video"] ? _config.videoMarginBottom ++ : _config.imageMarginBottom; ++ } else if ([segment isKindOfClass:[TableContainerView class]] && shouldAddBottomMargin) { + yOffset += _config.tableMarginBottom; + } + #if ENRICHED_MARKDOWN_MATH +@@ -524,6 +577,28 @@ static char kENRMSegmentFadeAnimatorKey; + #endif + }]; + ++ if (applyFrames && _enableMediaSlots && _renderedDocumentRevision == _documentRevision) { ++ for (RCTUIView *view in _segmentViews) { ++ if ([view isKindOfClass:[ENRMMediaSlotView class]]) { ++ MarkdownASTNode *node = ((ENRMMediaSlotView *)view).mediaNode; ++ CGRect rect = [self convertRect:view.bounds fromView:view]; ++ [mediaFrames addObject:@{ ++ @"id" : node.attributes[@"_enrmMediaSlot"], ++ @"x" : @(rect.origin.x), ++ @"y" : @(rect.origin.y), ++ @"width" : @(rect.size.width), ++ @"height" : @(rect.size.height) ++ }]; ++ } else if ([view isKindOfClass:[ENRMContainerNodeView class]]) { ++ [(ENRMContainerNodeView *)view appendMediaFrames:mediaFrames relativeToView:self]; ++ } ++ } ++ } ++ if (applyFrames && _enableMediaSlots && _renderedDocumentRevision == _documentRevision && ++ ![_lastMediaFrames isEqualToArray:mediaFrames]) { ++ _lastMediaFrames = [mediaFrames copy]; ++ [self emitMediaLayout:mediaFrames]; ++ } + return CGSizeMake(maxContentWidth, yOffset); + } + +@@ -669,6 +744,8 @@ static char kENRMSegmentFadeAnimatorKey; + ENRMMarkdownParser *parser = _parser; + ENRMMd4cFlags *md4cFlags = [_md4cFlags copy]; + BOOL isGFM = _isGFM; ++ ENRMLinkRegexConfig *linkRegex = _linkRegex; ++ ENRMLinkRegexConfig *inlineCodeLinkRegex = _inlineCodeLinkRegex; + + BOOL allowFontScaling = _fontScaleObserver.allowFontScaling; + CGFloat maxFontSizeMultiplier = _maxFontSizeMultiplier; +@@ -680,6 +757,16 @@ static char kENRMSegmentFadeAnimatorKey; + ENRMWritingDirectionMode writingDirectionMode = _writingDirectionMode; + NSWritingDirection resolvedLayoutDirection = _resolvedLayoutDirection; + ++ NSInteger revision = _documentRevision; ++ BOOL enableMediaSlots = _enableMediaSlots; ++ BOOL enableDocumentAssets = _enableDocumentAssets; ++ BOOL decisionsAccepted = _mediaOverridesRevision == revision; ++ NSDictionary *mediaOverrides = [_mediaOverrides copy]; ++ BOOL enableImageSourceResolution = _enableImageSourceResolution && isGFM; ++ BOOL imageSourcesAccepted = ++ _imageSourcesRevision >= _imageSourcesContinuityStart && _imageSourcesRevision <= revision; ++ NSDictionary *imageSources = [_imageSources copy]; ++ __block NSArray *documentAssets = @[]; + __block NSArray *renderedSegments = nil; + __block NSString *renderableMarkdown = nil; + __block BOOL endsInsideOpenCodeFence = NO; +@@ -696,10 +783,17 @@ static char kENRMSegmentFadeAnimatorKey; + return YES; + } + +- MarkdownASTNode *ast = [parser parseMarkdown:renderableMarkdown flags:md4cFlags isGFM:isGFM]; ++ MarkdownASTNode *ast = [parser parseMarkdown:renderableMarkdown ++ flags:md4cFlags ++ isGFM:isGFM ++ linkRegex:linkRegex ++ inlineCodeLinkRegex:inlineCodeLinkRegex]; + if (!ast) + return NO; + ++ if (enableDocumentAssets || enableMediaSlots || enableImageSourceResolution) ++ documentAssets = ENRMPrepareDocumentAssets(ast, enableMediaSlots, decisionsAccepted, mediaOverrides); ++ ENRMPrepareImageSources(ast, documentAssets, enableImageSourceResolution, imageSourcesAccepted, imageSources); + renderedSegments = ENRMRenderSegmentsFromAST(ast, config, allowTrailingMargin, allowFontScaling, + maxFontSizeMultiplier, lineBreakStrategy, + /*blockquoteContent*/ NO); +@@ -712,6 +806,12 @@ static char kENRMSegmentFadeAnimatorKey; + return YES; + } + apply:^{ ++ if (revision != self->_documentRevision) ++ return; ++ self->_renderedDocumentRevision = revision; ++ self->_documentAssets = documentAssets; ++ self->_lastMediaFrames = nil; ++ [self emitDocumentAssets]; + self->_renderedStyleFingerprint = self->_pendingStyleFingerprint; + [self applyRenderedSegments:renderedSegments + renderedMarkdown:renderableMarkdown +@@ -721,11 +821,23 @@ static char kENRMSegmentFadeAnimatorKey; + + - (NSArray *)parseAndRenderSegments:(NSString *)markdownString + { +- MarkdownASTNode *ast = [_parser parseMarkdown:markdownString flags:_md4cFlags isGFM:_isGFM]; ++ MarkdownASTNode *ast = [_parser parseMarkdown:markdownString ++ flags:_md4cFlags ++ isGFM:_isGFM ++ linkRegex:_linkRegex ++ inlineCodeLinkRegex:_inlineCodeLinkRegex]; + if (!ast) { + return nil; + } + ++ if (_enableDocumentAssets || _enableMediaSlots || (_enableImageSourceResolution && _isGFM)) ++ _documentAssets = ENRMPrepareDocumentAssets(ast, _enableMediaSlots, _mediaOverridesRevision == _documentRevision, ++ _mediaOverrides); ++ ENRMPrepareImageSources(ast, _documentAssets, _enableImageSourceResolution && _isGFM, ++ _imageSourcesRevision >= _imageSourcesContinuityStart && ++ _imageSourcesRevision <= _documentRevision, ++ _imageSources); ++ _renderedDocumentRevision = _documentRevision; + NSArray *segments = + ENRMRenderSegmentsFromAST(ast, _config, _allowTrailingMargin, _fontScaleObserver.allowFontScaling, + _maxFontSizeMultiplier, _lineBreakStrategy, /*blockquoteContent*/ NO); +@@ -1025,6 +1137,34 @@ static char kENRMSegmentFadeAnimatorKey; + _dirtyFlags |= ENRMDirtyRender; + } + ++ NSDictionary *mediaOverrides = ENRMMediaOverridesFromProps(newViewProps); ++ if (_documentRevision != newViewProps.documentRevision || _enableMediaSlots != newViewProps.enableMediaSlots || ++ _enableDocumentAssets != newViewProps.enableDocumentAssets || ++ _mediaOverridesRevision != newViewProps.mediaOverridesRevision || ++ ![_mediaOverrides isEqualToDictionary:mediaOverrides]) { ++ _documentRevision = newViewProps.documentRevision; ++ _enableMediaSlots = newViewProps.enableMediaSlots; ++ if (_enableDocumentAssets != newViewProps.enableDocumentAssets) ++ _lastEmittedAssets = nil; ++ _enableDocumentAssets = newViewProps.enableDocumentAssets; ++ _mediaOverridesRevision = newViewProps.mediaOverridesRevision; ++ _mediaOverrides = mediaOverrides; ++ _lastMediaFrames = nil; ++ _dirtyFlags |= ENRMDirtyForceHeight | ENRMDirtyRender; ++ } ++ ++ NSDictionary *imageSources = ENRMImageSourcesFromProps(newViewProps); ++ if (_enableImageSourceResolution != newViewProps.enableImageSourceResolution || ++ _imageSourcesRevision != newViewProps.imageSourcesRevision || ++ _imageSourcesContinuityStart != newViewProps.imageSourcesContinuityStart || ++ ![_imageSources isEqualToDictionary:imageSources]) { ++ _enableImageSourceResolution = newViewProps.enableImageSourceResolution; ++ _imageSourcesRevision = newViewProps.imageSourcesRevision; ++ _imageSourcesContinuityStart = newViewProps.imageSourcesContinuityStart; ++ _imageSources = imageSources; ++ _dirtyFlags |= ENRMDirtyRecreateSegments | ENRMDirtyForceHeight | ENRMDirtyRender; ++ } ++ + if (_config == nil) { + _config = [[StyleConfig alloc] init]; + [_config setFontScaleMultiplier:_fontScaleObserver.effectiveFontScale]; +@@ -1039,10 +1179,7 @@ static char kENRMSegmentFadeAnimatorKey; + + if (ENRMImageRequestHeadersChanged(oldViewProps.imageRequestHeaders, newViewProps.imageRequestHeaders)) { + [_config setImageRequestHeaders:ENRMImageRequestHeadersFromProps(newViewProps.imageRequestHeaders)]; +- _dirtyFlags |= ENRMDirtyRender; +- if (!markdownChanged) { +- _dirtyFlags |= ENRMDirtyRecreateSegments; +- } ++ _dirtyFlags |= ENRMDirtyRecreateSegments | ENRMDirtyForceHeight | ENRMDirtyRender; + } + + _selectable = newViewProps.selectable; +@@ -1077,6 +1214,19 @@ static char kENRMSegmentFadeAnimatorKey; + _dirtyFlags |= ENRMDirtyRecreateSegments | ENRMDirtyForceHeight | ENRMDirtyRender; + } + ++ ENRMLinkRegexConfig *linkRegex = ENRMTextLinkRegexConfigFromProps(newViewProps.linkRegex); ++ ENRMLinkRegexConfig *inlineCodeLinkRegex = ENRMTextLinkRegexConfigFromProps(newViewProps.inlineCodeLinkRegex); ++ if ((_linkRegex || linkRegex) && ![_linkRegex isEqualToConfig:linkRegex]) { ++ _linkRegex = linkRegex; ++ _dirtyFlags |= ENRMDirtyRender; ++ _dirtyFlags |= ENRMDirtyForceHeight; ++ } ++ if ((_inlineCodeLinkRegex || inlineCodeLinkRegex) && ![_inlineCodeLinkRegex isEqualToConfig:inlineCodeLinkRegex]) { ++ _inlineCodeLinkRegex = inlineCodeLinkRegex; ++ _dirtyFlags |= ENRMDirtyRender; ++ _dirtyFlags |= ENRMDirtyForceHeight; ++ } ++ + if (newViewProps.md4cFlags.underline != oldViewProps.md4cFlags.underline || + newViewProps.md4cFlags.superscript != oldViewProps.md4cFlags.superscript || + newViewProps.md4cFlags.subscript != oldViewProps.md4cFlags.subscript || +@@ -1258,9 +1408,25 @@ static char kENRMSegmentFadeAnimatorKey; + + _cachedMarkdown = nil; + _renderedMarkdown = nil; ++ _documentAssets = nil; ++ _lastEmittedAssets = nil; ++ _lastEmittedAssetsRevision = -1; ++ _lastMediaFrames = nil; ++ _mediaOverrides = nil; ++ _imageSources = nil; ++ _imageSourcesRevision = -1; ++ _imageSourcesContinuityStart = 1; ++ _enableImageSourceResolution = NO; ++ _documentRevision = 0; ++ _renderedDocumentRevision = -1; ++ _mediaOverridesRevision = -1; ++ _enableDocumentAssets = NO; ++ _enableMediaSlots = NO; + _config = nil; + _md4cFlags = [EnrichedMarkdown flagsFromProps:resetProps->md4cFlags]; + _isGFM = resetProps->isGFM; ++ _linkRegex = ENRMTextLinkRegexConfigFromProps(resetProps->linkRegex); ++ _inlineCodeLinkRegex = ENRMTextLinkRegexConfigFromProps(resetProps->inlineCodeLinkRegex); + _maxFontSizeMultiplier = 0; + _allowTrailingMargin = NO; + _streamingAnimation = NO; +@@ -1357,6 +1523,52 @@ Class EnrichedMarkdownCls(void) + } + #endif + ++- (void)emitDocumentAssets ++{ ++ if (!_enableDocumentAssets || _renderedDocumentRevision != _documentRevision || ++ (_lastEmittedAssetsRevision == _renderedDocumentRevision && [_lastEmittedAssets isEqualToArray:_documentAssets])) ++ return; ++ auto emitter = std::static_pointer_cast(_eventEmitter); ++ if (!emitter) ++ return; ++ EnrichedMarkdownEventEmitter::OnDocumentAssets event{}; ++ event.revision = (int)_renderedDocumentRevision; ++ for (NSDictionary *asset in _documentAssets) { ++ decltype(event.assets)::value_type item{}; ++ item.id = std::string([asset[@"id"] UTF8String]); ++ item.anchor = std::string([asset[@"anchor"] UTF8String]); ++ item.kind = std::string([asset[@"kind"] UTF8String]); ++ item.url = std::string([asset[@"url"] UTF8String]); ++ item.altText = std::string([asset[@"altText"] UTF8String]); ++ item.title = std::string([asset[@"title"] UTF8String]); ++ item.placement = std::string([asset[@"placement"] UTF8String]); ++ item.eligible = [asset[@"eligible"] boolValue]; ++ event.assets.push_back(item); ++ } ++ _lastEmittedAssetsRevision = _renderedDocumentRevision; ++ _lastEmittedAssets = [_documentAssets copy]; ++ emitter->onDocumentAssets(event); ++} ++ ++- (void)emitMediaLayout:(NSArray *)frames ++{ ++ auto emitter = std::static_pointer_cast(_eventEmitter); ++ if (!emitter) ++ return; ++ EnrichedMarkdownEventEmitter::OnMediaLayout event{}; ++ event.revision = (int)_renderedDocumentRevision; ++ for (NSDictionary *frame in frames) { ++ decltype(event.frames)::value_type item{}; ++ item.id = std::string([frame[@"id"] UTF8String]); ++ item.x = [frame[@"x"] floatValue]; ++ item.y = [frame[@"y"] floatValue]; ++ item.width = [frame[@"width"] floatValue]; ++ item.height = [frame[@"height"] floatValue]; ++ event.frames.push_back(item); ++ } ++ emitter->onMediaLayout(event); ++} ++ + - (void)emitLinkPress:(NSString *)url + { + auto emitter = std::static_pointer_cast(_eventEmitter); +@@ -1418,8 +1630,14 @@ Class EnrichedMarkdownCls(void) + + - (void)updateEventEmitter:(const facebook::react::EventEmitter::Shared &)eventEmitter + { ++ BOOL firstAttachment = !_eventEmitter && eventEmitter; + [super updateEventEmitter:eventEmitter]; + [_latexErrorCoordinator flushPending]; ++ [self emitDocumentAssets]; ++ if (firstAttachment) { ++ _lastMediaFrames = nil; ++ [self setNeedsLayout]; ++ } + } + + - (void)textTapped:(ENRMTapRecognizer *)recognizer +@@ -1510,7 +1728,12 @@ Class EnrichedMarkdownCls(void) + + - (NSArray *)accessibilityElements + { +- return _segmentViews; ++ NSMutableArray *elements = [NSMutableArray array]; ++ for (RCTUIView *segment in _segmentViews) { ++ if (![segment isKindOfClass:[ENRMMediaSlotView class]]) ++ [elements addObject:segment]; ++ } ++ return elements; + } + + - (NSInteger)accessibilityElementCount +diff --git a/ios/EnrichedMarkdownText.mm b/ios/EnrichedMarkdownText.mm +index 0bfa5d353bb1f99dc4d94277c0982f6fcd5046f2..20d3749ddf19742e3791efd1699c30f9f9a7b053 100644 +--- a/ios/EnrichedMarkdownText.mm ++++ b/ios/EnrichedMarkdownText.mm +@@ -12,6 +12,7 @@ + #import "ENRMSpoilerTapUtils.h" + #import "ENRMTailFadeInAnimator.h" + #import "ENRMTextInteractionUtils.h" ++#import "ENRMTextLinkRecognizer.h" + #import "ENRMTextRenderer.h" + #import "ENRMTextViewSetup.h" + #import "ENRMUIKit.h" +@@ -75,6 +76,8 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { + StyleConfig *_config; + ENRMMd4cFlags *_md4cFlags; + BOOL _isGFM; ++ ENRMLinkRegexConfig *_linkRegex; ++ ENRMLinkRegexConfig *_inlineCodeLinkRegex; + + ENRMAsyncRenderCoordinator *_renderCoordinator; + +@@ -243,6 +246,8 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { + _parser = [[ENRMMarkdownParser alloc] init]; + _md4cFlags = [EnrichedMarkdownText flagsFromProps:defaultProps->md4cFlags]; + _isGFM = defaultProps->isGFM; ++ _linkRegex = ENRMTextLinkRegexConfigFromProps(defaultProps->linkRegex); ++ _inlineCodeLinkRegex = ENRMTextLinkRegexConfigFromProps(defaultProps->inlineCodeLinkRegex); + + _renderCoordinator = + [[ENRMAsyncRenderCoordinator alloc] initWithQueueLabel:"com.swmansion.enriched.markdown.render"]; +@@ -303,7 +308,7 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { + - (void)setupTextView + { + #if !TARGET_OS_OSX +- _textView = [[ENRMPlatformTextView alloc] init]; ++ _textView = ENRMCreateMarkdownTextView(); + _textView.text = @""; + #else + _textView = [[ENRMContextMenuTextView alloc] init]; +@@ -375,6 +380,8 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { + ENRMMarkdownParser *parser = _parser; + ENRMMd4cFlags *md4cFlags = [_md4cFlags copy]; + BOOL isGFM = _isGFM; ++ ENRMLinkRegexConfig *linkRegex = _linkRegex; ++ ENRMLinkRegexConfig *inlineCodeLinkRegex = _inlineCodeLinkRegex; + + BOOL allowFontScaling = _fontScaleObserver.allowFontScaling; + CGFloat maxFontSizeMultiplier = _maxFontSizeMultiplier; +@@ -387,7 +394,11 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { + + [_renderCoordinator + scheduleRender:^BOOL { +- MarkdownASTNode *ast = [parser parseMarkdown:markdownString flags:md4cFlags isGFM:isGFM]; ++ MarkdownASTNode *ast = [parser parseMarkdown:markdownString ++ flags:md4cFlags ++ isGFM:isGFM ++ linkRegex:linkRegex ++ inlineCodeLinkRegex:inlineCodeLinkRegex]; + if (!ast) + return NO; + +@@ -407,7 +418,11 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { + + - (NSMutableAttributedString *)parseAndRenderMarkdown:(NSString *)markdownString + { +- MarkdownASTNode *ast = [_parser parseMarkdown:markdownString flags:_md4cFlags isGFM:_isGFM]; ++ MarkdownASTNode *ast = [_parser parseMarkdown:markdownString ++ flags:_md4cFlags ++ isGFM:_isGFM ++ linkRegex:_linkRegex ++ inlineCodeLinkRegex:_inlineCodeLinkRegex]; + if (!ast) { + return nil; + } +@@ -618,6 +633,19 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { + _dirtyFlags |= ENRMDirtyRender; + } + ++ ENRMLinkRegexConfig *linkRegex = ENRMTextLinkRegexConfigFromProps(newViewProps.linkRegex); ++ ENRMLinkRegexConfig *inlineCodeLinkRegex = ENRMTextLinkRegexConfigFromProps(newViewProps.inlineCodeLinkRegex); ++ if ((_linkRegex || linkRegex) && ![_linkRegex isEqualToConfig:linkRegex]) { ++ _linkRegex = linkRegex; ++ _dirtyFlags |= ENRMDirtyRender; ++ _forceHeightUpdateOnNextRender = YES; ++ } ++ if ((_inlineCodeLinkRegex || inlineCodeLinkRegex) && ![_inlineCodeLinkRegex isEqualToConfig:inlineCodeLinkRegex]) { ++ _inlineCodeLinkRegex = inlineCodeLinkRegex; ++ _dirtyFlags |= ENRMDirtyRender; ++ _forceHeightUpdateOnNextRender = YES; ++ } ++ + if (newViewProps.md4cFlags.underline != oldViewProps.md4cFlags.underline || + newViewProps.md4cFlags.superscript != oldViewProps.md4cFlags.superscript || + newViewProps.md4cFlags.subscript != oldViewProps.md4cFlags.subscript || +@@ -769,6 +797,8 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) { + _config = nil; + _md4cFlags = [EnrichedMarkdownText flagsFromProps:resetProps->md4cFlags]; + _isGFM = resetProps->isGFM; ++ _linkRegex = ENRMTextLinkRegexConfigFromProps(resetProps->linkRegex); ++ _inlineCodeLinkRegex = ENRMTextLinkRegexConfigFromProps(resetProps->inlineCodeLinkRegex); + _maxFontSizeMultiplier = 0; + _lastElementMarginBottom = 0; + _allowTrailingMargin = NO; +diff --git a/ios/attachments/ENRMImageAttachment.h b/ios/attachments/ENRMImageAttachment.h +index b0247d7cb0c570b63b64f6cf969f2d9bdbee43d3..677295bdbf10e2666a3ce4763e0a1aa1154c750e 100644 +--- a/ios/attachments/ENRMImageAttachment.h ++++ b/ios/attachments/ENRMImageAttachment.h +@@ -43,6 +43,13 @@ NS_ASSUME_NONNULL_BEGIN + + + (instancetype)attachmentForURL:(NSString *)imageURL config:(StyleConfig *)config isInline:(BOOL)isInline; + ++// A nil transportURI holds the normal placeholder without starting a request. +++ (instancetype)attachmentForURL:(NSString *)imageURL ++ config:(StyleConfig *)config ++ isInline:(BOOL)isInline ++ transportURI:(nullable NSString *)transportURI ++ requestHeaders:(nullable NSDictionary *)requestHeaders; ++ + + (NSCache *)originalImageCache; + + (NSCache *)processedImageCache; + +diff --git a/ios/attachments/ENRMImageAttachment.m b/ios/attachments/ENRMImageAttachment.m +index f17cfb0274d9e5bdcbece40efcf5c4ca4629e445..37d5bb80481d4e639874a2f63607d989fd4ff049 100644 +--- a/ios/attachments/ENRMImageAttachment.m ++++ b/ios/attachments/ENRMImageAttachment.m +@@ -34,6 +34,7 @@ static NSCache *_processedImageCache; + @interface ENRMImageAttachment () + + @property (nonatomic, copy) NSString *imageURL; ++@property (nonatomic, copy, nullable) NSString *transportURI; + @property (nonatomic, copy, nullable) NSDictionary *requestHeaders; + @property (nonatomic, copy) NSString *cacheKey; + @property (nonatomic, assign) BOOL isInline; +@@ -81,16 +82,38 @@ static NSCache *_processedImageCache; + // the same image URL at a different width than a copy outside the table, and a shared + // NSTextAttachment would thrash its single last-processed width into a redraw loop. The + // image caches keep fresh instances cheap (no re-fetch or re-scale). +- return [[self alloc] initWithImageURL:imageURL config:config isInline:isInline]; ++ return [self attachmentForURL:imageURL ++ config:config ++ isInline:isInline ++ transportURI:imageURL ++ requestHeaders:config.imageRequestHeaders]; + } + +-- (instancetype)initWithImageURL:(NSString *)imageURL config:(StyleConfig *)config isInline:(BOOL)isInline +++ (instancetype)attachmentForURL:(NSString *)imageURL ++ config:(StyleConfig *)config ++ isInline:(BOOL)isInline ++ transportURI:(NSString *)transportURI ++ requestHeaders:(NSDictionary *)requestHeaders ++{ ++ return [[self alloc] initWithImageURL:imageURL ++ config:config ++ isInline:isInline ++ transportURI:transportURI ++ requestHeaders:requestHeaders]; ++} ++ ++- (instancetype)initWithImageURL:(NSString *)imageURL ++ config:(StyleConfig *)config ++ isInline:(BOOL)isInline ++ transportURI:(NSString *)transportURI ++ requestHeaders:(NSDictionary *)requestHeaders + { + self = [super init]; + if (self) { + _imageURL = imageURL; +- _requestHeaders = [[config imageRequestHeaders] copy]; +- _cacheKey = ENRMImageCacheKey(imageURL, _requestHeaders); ++ _transportURI = [transportURI copy]; ++ _requestHeaders = [requestHeaders copy]; ++ _cacheKey = transportURI ? ENRMImageCacheKey(transportURI, _requestHeaders) : @""; + _isInline = isInline; + + _cachedHeight = isInline ? [config inlineImageSize] : [config imageHeight]; +@@ -320,11 +343,11 @@ static NSCache *_processedImageCache; + + - (void)startDownloadingImage + { +- if (self.imageURL.length == 0) ++ if (self.transportURI.length == 0) + return; + + __weak typeof(self) weakSelf = self; +- [[ENRMImageDownloader shared] downloadURL:self.imageURL ++ [[ENRMImageDownloader shared] downloadURL:self.transportURI + headers:self.requestHeaders + completion:^(RCTUIImage *image) { [weakSelf handleLoadedImage:image]; }]; + } +diff --git a/ios/attachments/ENRMLinkPillAttachment.h b/ios/attachments/ENRMLinkPillAttachment.h +new file mode 100644 +index 0000000000000000000000000000000000000000..344ee92b158abc55e2b3db6b70e34e20d161bb13 +--- /dev/null ++++ b/ios/attachments/ENRMLinkPillAttachment.h +@@ -0,0 +1,20 @@ ++#pragma once ++#import "ENRMUIKit.h" ++ ++#if !TARGET_OS_OSX ++@class LinkVariantConfig; ++ ++/// Presentation over the original link characters. Text storage never receives U+FFFC. ++@interface ENRMLinkPillAttachment : NSTextAttachment ++@property (nonatomic, readonly) CGFloat boxHeight; ++- (instancetype)initWithLabel:(NSString *)originalLabel variant:(LinkVariantConfig *)variant font:(UIFont *)font; ++@end ++ ++/// Stateless and shared by visible, table, and view-free TextKit stacks. ++@interface ENRMLinkPillLayoutDelegate : NSObject +++ (instancetype)shared; ++@end ++ ++FOUNDATION_EXPORT CGRect ENRMLinkPillTextBounds(NSAttributedString *text, CGFloat width); ++FOUNDATION_EXPORT void ENRMDrawLinkPillText(NSAttributedString *text, CGRect rect); ++#endif +diff --git a/ios/attachments/ENRMLinkPillAttachment.m b/ios/attachments/ENRMLinkPillAttachment.m +new file mode 100644 +index 0000000000000000000000000000000000000000..9e1a6ccca25b049c7db2a9006663fdc5d28213a4 +--- /dev/null ++++ b/ios/attachments/ENRMLinkPillAttachment.m +@@ -0,0 +1,241 @@ ++#import "ENRMLinkPillAttachment.h" ++#import "ENRMLinkPillIconCache.h" ++#import "ENRMLinkPillTextStorage.h" ++#import "StyleConfig.h" ++ ++#if !TARGET_OS_OSX ++ ++@implementation ENRMLinkPillAttachment { ++ NSString *_label; ++ LinkVariantConfig *_variant; ++ UIFont *_font; ++ UIImage *_icon; ++} ++ ++- (instancetype)initWithLabel:(NSString *)originalLabel variant:(LinkVariantConfig *)variant font:(UIFont *)font ++{ ++ self = [super initWithData:nil ofType:nil]; ++ if (self) { ++ _variant = variant; ++ _font = font ?: [UIFont systemFontOfSize:16]; ++ NSString *label = variant.label.length > 0 ? variant.label : originalLabel; ++ _label = [[label stringByReplacingOccurrencesOfString:@"\n" ++ withString:@" "] stringByReplacingOccurrencesOfString:@"\r" ++ withString:@" "]; ++ _icon = ENRMLoadLinkPillIcon(variant.iconUri); ++ } ++ return self; ++} ++ ++- (CGFloat)boxHeight ++{ ++ return ceil(_font.ascender - _font.descender + 2 * (_variant.paddingVertical + _variant.borderWidth)); ++} ++ ++- (CGFloat)widthForLimit:(CGFloat)available ++{ ++ CGFloat iconWidth = _icon ? _font.pointSize * 1.25 : 0; ++ CGFloat natural = ceil([_label sizeWithAttributes:@{NSFontAttributeName : _font}].width + iconWidth + ++ 2 * (_variant.paddingHorizontal + _variant.borderWidth)); ++ CGFloat limit = _variant.maxWidth > 0 ? MIN(available, _variant.maxWidth) : available; ++ return MAX(1, MIN(natural, limit)); ++} ++ ++- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)container ++ proposedLineFragment:(CGRect)lineFragment ++ glyphPosition:(CGPoint)position ++ characterIndex:(NSUInteger)characterIndex ++{ ++ // Use the full container width, not the remainder of the current line. TextKit then moves ++ // the whole attachment to the next line if it doesn't fit the remainder. ++ NSParagraphStyle *paragraph = [container.layoutManager.textStorage attribute:NSParagraphStyleAttributeName ++ atIndex:characterIndex ++ effectiveRange:NULL]; ++ CGFloat indent = MAX(paragraph.firstLineHeadIndent, paragraph.headIndent); ++ CGFloat tailInset = paragraph.tailIndent < 0 ? -paragraph.tailIndent : 0; ++ CGFloat available = MAX(1, container.size.width - 2 * container.lineFragmentPadding - indent - tailInset); ++ CGFloat inset = _variant.paddingVertical + _variant.borderWidth; ++ return CGRectMake(0, _font.descender - inset, [self widthForLimit:available], self.boxHeight); ++} ++ ++- (UIImage *)imageForBounds:(CGRect)bounds textContainer:(NSTextContainer *)container characterIndex:(NSUInteger)index ++{ ++ CGSize size = bounds.size; ++ UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat preferredFormat]; ++ format.opaque = NO; ++ UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size format:format]; ++ return [renderer imageWithActions:^(UIGraphicsImageRendererContext *context) { ++ CGRect rect = (CGRect){CGPointZero, size}; ++ UIBezierPath *background = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:_variant.borderRadius]; ++ [_variant.backgroundColor ?: UIColor.clearColor setFill]; ++ [background fill]; ++ if (_variant.borderWidth > 0) { ++ UIBezierPath *border = ++ [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, _variant.borderWidth / 2, _variant.borderWidth / 2) ++ cornerRadius:_variant.borderRadius]; ++ border.lineWidth = _variant.borderWidth; ++ [_variant.borderColor setStroke]; ++ [border stroke]; ++ } ++ [background addClip]; ++ CGFloat left = _variant.paddingHorizontal + _variant.borderWidth; ++ CGFloat right = size.width - left; ++ if (_icon && right - left >= _font.pointSize) { ++ CGFloat side = _font.pointSize; ++ CGFloat scale = side / MAX(_icon.size.width, _icon.size.height); ++ CGSize iconSize = CGSizeMake(_icon.size.width * scale, _icon.size.height * scale); ++ CGRect iconRect = CGRectMake(left + (side - iconSize.width) / 2, (size.height - iconSize.height) / 2, ++ iconSize.width, iconSize.height); ++ UIImage *presentedIcon = _variant.iconTintColor ? [_icon imageWithTintColor:_variant.iconTintColor ++ renderingMode:UIImageRenderingModeAlwaysOriginal] ++ : _icon; ++ [presentedIcon drawInRect:iconRect]; ++ left += side * 1.25; ++ } ++ NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init]; ++ paragraph.lineBreakMode = NSLineBreakByTruncatingTail; ++ NSDictionary *attributes = @{ ++ NSFontAttributeName : _font, ++ NSForegroundColorAttributeName : _variant.color, ++ NSUnderlineStyleAttributeName : @(_variant.underline ? NSUnderlineStyleSingle : NSUnderlineStyleNone), ++ NSParagraphStyleAttributeName : paragraph, ++ }; ++ [_label drawInRect:CGRectMake(left, _variant.paddingVertical + _variant.borderWidth, MAX(0, right - left), ++ size.height) ++ withAttributes:attributes]; ++ }]; ++} ++@end ++ ++@implementation ENRMLinkPillLayoutDelegate +++ (instancetype)shared ++{ ++ static ENRMLinkPillLayoutDelegate *delegate; ++ static dispatch_once_t once; ++ dispatch_once(&once, ^{ delegate = [[self alloc] init]; }); ++ return delegate; ++} ++ ++- (NSUInteger)layoutManager:(NSLayoutManager *)manager ++ shouldGenerateGlyphs:(const CGGlyph *)glyphs ++ properties:(const NSGlyphProperty *)properties ++ characterIndexes:(const NSUInteger *)indexes ++ font:(UIFont *)font ++ forGlyphRange:(NSRange)glyphRange ++{ ++ NSUInteger count = glyphRange.length; ++ NSMutableData *glyphData = [NSMutableData dataWithBytes:glyphs length:count * sizeof(CGGlyph)]; ++ NSMutableData *propertyData = [NSMutableData dataWithBytes:properties length:count * sizeof(NSGlyphProperty)]; ++ CGGlyph *replacement = glyphData.mutableBytes; ++ NSGlyphProperty *replacementProperties = propertyData.mutableBytes; ++ BOOL changed = NO; ++ for (NSUInteger i = 0; i < count; i++) { ++ NSRange range; ++ // Attribute runs may split at every source character after UIKit fixes fonts/colors. ++ // The pill starts at the longest range of the attachment alone, not the current run. ++ id attachment = [manager.textStorage attribute:NSAttachmentAttributeName ++ atIndex:indexes[i] ++ longestEffectiveRange:&range ++ inRange:NSMakeRange(0, manager.textStorage.length)]; ++ if (![attachment isKindOfClass:ENRMLinkPillAttachment.class]) ++ continue; ++ changed = YES; ++ // A character can have multiple glyphs, even across font/callback boundaries. ++ // The preceding glyph is outside this callback's range and is already generated. ++ BOOL startsAttachment = indexes[i] == range.location; ++ BOOL continuesCharacter = ++ startsAttachment && (i > 0 ? indexes[i - 1] == indexes[i] ++ : glyphRange.location > 0 && ++ [manager characterIndexForGlyphAtIndex:glyphRange.location - 1] == indexes[i]); ++ if (startsAttachment && !continuesCharacter) { ++ // TextKit's attachment glyph exists only in the glyph buffer, never in text storage. ++ replacement[i] = 0xFFFC; ++ replacementProperties[i] = 0; ++ } else { ++ replacement[i] = 0; ++ replacementProperties[i] = NSGlyphPropertyNull; ++ } ++ } ++ if (!changed) ++ return 0; ++ [manager setGlyphs:replacement ++ properties:replacementProperties ++ characterIndexes:indexes ++ font:font ++ forGlyphRange:glyphRange]; ++ return count; ++} ++ ++- (BOOL)layoutManager:(NSLayoutManager *)manager shouldBreakLineByWordBeforeCharacterAtIndex:(NSUInteger)index ++{ ++ if (index >= manager.textStorage.length) ++ return YES; ++ NSRange range; ++ id attachment = [manager.textStorage attribute:NSAttachmentAttributeName ++ atIndex:index ++ longestEffectiveRange:&range ++ inRange:NSMakeRange(0, manager.textStorage.length)]; ++ return ![attachment isKindOfClass:ENRMLinkPillAttachment.class] || index == range.location; ++} ++@end ++ ++static NSLayoutManager *ENRMPillLayout(NSAttributedString *text, CGSize size, NSTextStorage **storageOut, ++ NSTextContainer **containerOut) ++{ ++ NSTextStorage *storage = [[ENRMLinkPillTextStorage alloc] initWithAttributedString:text]; ++ NSLayoutManager *manager = [[NSLayoutManager alloc] init]; ++ manager.delegate = ENRMLinkPillLayoutDelegate.shared; ++ manager.allowsNonContiguousLayout = NO; ++ NSTextContainer *container = [[NSTextContainer alloc] initWithSize:size]; ++ container.lineFragmentPadding = 0; ++ [storage addLayoutManager:manager]; ++ [manager addTextContainer:container]; ++ [manager ensureLayoutForTextContainer:container]; ++ *storageOut = storage; ++ *containerOut = container; ++ return manager; ++} ++ ++static BOOL ENRMHasLinkPill(NSAttributedString *text) ++{ ++ __block BOOL found = NO; ++ [text enumerateAttribute:NSAttachmentAttributeName ++ inRange:NSMakeRange(0, text.length) ++ options:0 ++ usingBlock:^(id value, NSRange range, BOOL *stop) { ++ if ([value isKindOfClass:ENRMLinkPillAttachment.class]) { ++ found = YES; ++ *stop = YES; ++ } ++ }]; ++ return found; ++} ++ ++CGRect ENRMLinkPillTextBounds(NSAttributedString *text, CGFloat width) ++{ ++ if (!ENRMHasLinkPill(text)) ++ return [text boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) ++ options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading ++ context:nil]; ++ // NSLayoutManager does not own its storage. Keep it alive through measurement/drawing under ARC. ++ __attribute__((objc_precise_lifetime)) NSTextStorage *storage; ++ NSTextContainer *container; ++ NSLayoutManager *manager = ENRMPillLayout(text, CGSizeMake(width, CGFLOAT_MAX), &storage, &container); ++ return [manager usedRectForTextContainer:container]; ++} ++ ++void ENRMDrawLinkPillText(NSAttributedString *text, CGRect rect) ++{ ++ if (!ENRMHasLinkPill(text)) { ++ [text drawWithRect:rect options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil]; ++ return; ++ } ++ // NSLayoutManager does not own its storage. Keep it alive through measurement/drawing under ARC. ++ __attribute__((objc_precise_lifetime)) NSTextStorage *storage; ++ NSTextContainer *container; ++ NSLayoutManager *manager = ENRMPillLayout(text, rect.size, &storage, &container); ++ NSRange glyphs = [manager glyphRangeForTextContainer:container]; ++ [manager drawBackgroundForGlyphRange:glyphs atPoint:rect.origin]; ++ [manager drawGlyphsForGlyphRange:glyphs atPoint:rect.origin]; ++} ++#endif +diff --git a/ios/attachments/ENRMLinkPillIconCache.h b/ios/attachments/ENRMLinkPillIconCache.h +new file mode 100644 +index 0000000000000000000000000000000000000000..ab708fbe0a1882278c684849a759295e81704fb5 +--- /dev/null ++++ b/ios/attachments/ENRMLinkPillIconCache.h +@@ -0,0 +1,7 @@ ++#pragma once ++#import "ENRMUIKit.h" ++ ++#if !TARGET_OS_OSX ++/** Original-color local icons; bounded shared cache, tint remains presentation-specific. */ ++FOUNDATION_EXPORT UIImage *_Nullable ENRMLoadLinkPillIcon(NSString *_Nullable iconUri); ++#endif +diff --git a/ios/attachments/ENRMLinkPillIconCache.m b/ios/attachments/ENRMLinkPillIconCache.m +new file mode 100644 +index 0000000000000000000000000000000000000000..0bece83dac6608ff78e8458c40095d7279ef87bc +--- /dev/null ++++ b/ios/attachments/ENRMLinkPillIconCache.m +@@ -0,0 +1,63 @@ ++#import "ENRMLinkPillIconCache.h" ++#if !TARGET_OS_OSX ++#import ++ ++UIImage *ENRMLoadLinkPillIcon(NSString *iconUri) ++{ ++ NSURL *uri = iconUri.length > 0 ? [NSURL URLWithString:iconUri] : nil; ++ if (!uri.isFileURL) ++ return nil; ++ NSString *path = uri.URLByResolvingSymlinksInPath.path; ++ NSDictionary *attributes = [NSFileManager.defaultManager attributesOfItemAtPath:path error:nil]; ++ if (!attributes || ![attributes[NSFileType] isEqual:NSFileTypeRegular]) ++ return nil; ++ NSString *key = ++ [NSString stringWithFormat:@"%@|%.9f|%@", path, [attributes[NSFileModificationDate] timeIntervalSince1970], ++ attributes[NSFileSize]]; ++ static NSMutableDictionary *images; ++ static NSMutableArray *order; ++ static NSUInteger bytes; ++ static dispatch_once_t once; ++ dispatch_once(&once, ^{ ++ images = [NSMutableDictionary new]; ++ order = [NSMutableArray new]; ++ }); ++ @synchronized(images) { ++ UIImage *cached = images[key]; ++ if (cached) { ++ [order removeObject:key]; ++ [order addObject:key]; ++ return cached; ++ } ++ CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)[NSURL fileURLWithPath:path], NULL); ++ if (!source) ++ return nil; ++ NSDictionary *options = @{ ++ (__bridge NSString *)kCGImageSourceCreateThumbnailFromImageAlways : @YES, ++ (__bridge NSString *)kCGImageSourceCreateThumbnailWithTransform : @YES, ++ (__bridge NSString *)kCGImageSourceShouldCacheImmediately : @YES, ++ (__bridge NSString *)kCGImageSourceThumbnailMaxPixelSize : @512, ++ }; ++ CGImageRef decoded = CGImageSourceCreateThumbnailAtIndex(source, 0, (__bridge CFDictionaryRef)options); ++ CFRelease(source); ++ if (!decoded) ++ return nil; ++ NSUInteger cost = CGImageGetBytesPerRow(decoded) * CGImageGetHeight(decoded); ++ UIImage *image = [UIImage imageWithCGImage:decoded]; ++ CGImageRelease(decoded); ++ if (cost > 8 * 1024 * 1024) ++ return image; ++ images[key] = image; ++ [order addObject:key]; ++ bytes += cost; ++ while (order.count > 64 || bytes > 8 * 1024 * 1024) { ++ NSString *oldest = order.firstObject; ++ CGImageRef previous = images[oldest].CGImage; ++ bytes -= CGImageGetBytesPerRow(previous) * CGImageGetHeight(previous); ++ [images removeObjectForKey:oldest]; ++ [order removeObjectAtIndex:0]; ++ } ++ return image; ++ } ++} ++#endif +diff --git a/ios/attachments/ENRMLinkPillTextStorage.h b/ios/attachments/ENRMLinkPillTextStorage.h +new file mode 100644 +index 0000000000000000000000000000000000000000..a2479abd1dcf31de33d74a74d2396f8eeb0dd579 +--- /dev/null ++++ b/ios/attachments/ENRMLinkPillTextStorage.h +@@ -0,0 +1,11 @@ ++#pragma once ++#import "ENRMUIKit.h" ++ ++#if !TARGET_OS_OSX ++/// Keeps presentation attachments over original link characters through TextKit attribute fixing. ++@interface ENRMLinkPillTextStorage : NSTextStorage ++@end ++ ++/// An explicit TextKit 1 stack using the same storage as view-free and table layout. ++FOUNDATION_EXPORT UITextView *ENRMCreateMarkdownTextView(void); ++#endif +diff --git a/ios/attachments/ENRMLinkPillTextStorage.m b/ios/attachments/ENRMLinkPillTextStorage.m +new file mode 100644 +index 0000000000000000000000000000000000000000..a70cb6898e6c48bab54435bfb9470ef0a1073565 +--- /dev/null ++++ b/ios/attachments/ENRMLinkPillTextStorage.m +@@ -0,0 +1,80 @@ ++#import "ENRMLinkPillTextStorage.h" ++#import "ENRMLinkPillAttachment.h" ++ ++#if !TARGET_OS_OSX ++@implementation ENRMLinkPillTextStorage { ++ NSMutableAttributedString *_backing; ++} ++ ++- (instancetype)init ++{ ++ self = [super init]; ++ if (self) ++ _backing = [[NSMutableAttributedString alloc] init]; ++ return self; ++} ++ ++- (instancetype)initWithAttributedString:(NSAttributedString *)text ++{ ++ self = [self init]; ++ if (self) ++ [self setAttributedString:text]; ++ return self; ++} ++ ++- (NSString *)string ++{ ++ return _backing.string; ++} ++ ++- (NSDictionary *)attributesAtIndex:(NSUInteger)index effectiveRange:(NSRangePointer)range ++{ ++ return [_backing attributesAtIndex:index effectiveRange:range]; ++} ++ ++- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)text ++{ ++ [_backing replaceCharactersInRange:range withString:text]; ++ [self edited:NSTextStorageEditedCharacters ++ range:range ++ changeInLength:(NSInteger)text.length - (NSInteger)range.length]; ++} ++ ++- (void)setAttributes:(NSDictionary *)attributes range:(NSRange)range ++{ ++ [_backing setAttributes:attributes range:range]; ++ [self edited:NSTextStorageEditedAttributes range:range changeInLength:0]; ++} ++ ++- (void)fixAttributesInRange:(NSRange)range ++{ ++ // Foundation removes NSAttachmentAttributeName unless the source character is U+FFFC. ++ // A pill deliberately leaves source characters intact; preserve only these attachments. ++ // Standard fixing can extend to the complete paragraph, including pills outside the edit. ++ NSRange fixingRange = [_backing.string paragraphRangeForRange:range]; ++ NSMutableArray *pills = [NSMutableArray new]; ++ [_backing enumerateAttribute:NSAttachmentAttributeName ++ inRange:fixingRange ++ options:0 ++ usingBlock:^(id value, NSRange subrange, BOOL *stop) { ++ if ([value isKindOfClass:ENRMLinkPillAttachment.class]) ++ [pills addObject:@{@"attachment" : value, @"range" : [NSValue valueWithRange:subrange]}]; ++ }]; ++ [_backing fixAttributesInRange:range]; ++ for (NSDictionary *pill in pills) ++ [_backing addAttribute:NSAttachmentAttributeName value:pill[@"attachment"] range:[pill[@"range"] rangeValue]]; ++ // Fixing belongs to the existing edit notification. Direct backing restoration avoids recursive edits. ++} ++@end ++ ++UITextView *ENRMCreateMarkdownTextView(void) ++{ ++ ENRMLinkPillTextStorage *storage = [[ENRMLinkPillTextStorage alloc] init]; ++ NSLayoutManager *manager = [[NSLayoutManager alloc] init]; ++ manager.delegate = ENRMLinkPillLayoutDelegate.shared; ++ [storage addLayoutManager:manager]; ++ NSTextContainer *container = [[NSTextContainer alloc] initWithSize:CGSizeMake(0, CGFLOAT_MAX)]; ++ [manager addTextContainer:container]; ++ return [[UITextView alloc] initWithFrame:CGRectZero textContainer:container]; ++} ++#endif +diff --git a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +index 1b1b96234e8313e1e1fb2f033a19df84434255f0..e854371ae92d15228fb65133108ce2f4bd4c234d 100644 +--- a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp ++++ b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +@@ -13,6 +13,55 @@ + + namespace facebook::react { + ++void EnrichedMarkdownEventEmitter::onDocumentAssets(OnDocumentAssets event) const { ++ dispatchEvent("documentAssets", [event=std::move(event)](jsi::Runtime &runtime) { ++ auto payload = jsi::Object(runtime); ++ payload.setProperty(runtime, "revision", event.revision); ++ ++ auto assets = jsi::Array(runtime, event.assets.size()); ++ size_t assetsIndex = 0; ++ for (auto assetsValue : event.assets) { ++ auto assetsObject = jsi::Object(runtime); ++ assetsObject.setProperty(runtime, "anchor", assetsValue.anchor); ++assetsObject.setProperty(runtime, "id", assetsValue.id); ++assetsObject.setProperty(runtime, "kind", assetsValue.kind); ++assetsObject.setProperty(runtime, "url", assetsValue.url); ++assetsObject.setProperty(runtime, "altText", assetsValue.altText); ++assetsObject.setProperty(runtime, "title", assetsValue.title); ++assetsObject.setProperty(runtime, "placement", assetsValue.placement); ++assetsObject.setProperty(runtime, "eligible", assetsValue.eligible); ++ assets.setValueAtIndex(runtime, assetsIndex++, assetsObject); ++ } ++ payload.setProperty(runtime, "assets", assets); ++ ++ return payload; ++ }); ++} ++ ++ ++void EnrichedMarkdownEventEmitter::onMediaLayout(OnMediaLayout event) const { ++ dispatchEvent("mediaLayout", [event=std::move(event)](jsi::Runtime &runtime) { ++ auto payload = jsi::Object(runtime); ++ payload.setProperty(runtime, "revision", event.revision); ++ ++ auto frames = jsi::Array(runtime, event.frames.size()); ++ size_t framesIndex = 0; ++ for (auto framesValue : event.frames) { ++ auto framesObject = jsi::Object(runtime); ++ framesObject.setProperty(runtime, "id", framesValue.id); ++framesObject.setProperty(runtime, "x", framesValue.x); ++framesObject.setProperty(runtime, "y", framesValue.y); ++framesObject.setProperty(runtime, "width", framesValue.width); ++framesObject.setProperty(runtime, "height", framesValue.height); ++ frames.setValueAtIndex(runtime, framesIndex++, framesObject); ++ } ++ payload.setProperty(runtime, "frames", frames); ++ ++ return payload; ++ }); ++} ++ ++ + void EnrichedMarkdownEventEmitter::onLinkPress(OnLinkPress event) const { + dispatchEvent("linkPress", [event=std::move(event)](jsi::Runtime &runtime) { + auto payload = jsi::Object(runtime); +diff --git a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +index 3fda20ba6e4d253545401f9a4d76fabdebe4126f..0aa908394302b7753305f324d8165aaea3b24d08 100644 +--- a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h ++++ b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +@@ -17,6 +17,35 @@ class EnrichedMarkdownEventEmitter : public ViewEventEmitter { + public: + using ViewEventEmitter::ViewEventEmitter; + ++ struct OnDocumentAssetsAssets { ++ std::string anchor; ++ std::string id; ++ std::string kind; ++ std::string url; ++ std::string altText; ++ std::string title; ++ std::string placement; ++ bool eligible; ++ }; ++ ++ struct OnDocumentAssets { ++ int revision; ++ std::vector assets; ++ }; ++ ++ struct OnMediaLayoutFrames { ++ std::string id; ++ Float x; ++ Float y; ++ Float width; ++ Float height; ++ }; ++ ++ struct OnMediaLayout { ++ int revision; ++ std::vector frames; ++ }; ++ + struct OnLinkPress { + std::string url; + }; +@@ -58,6 +87,10 @@ class EnrichedMarkdownEventEmitter : public ViewEventEmitter { + int selectionStart; + int selectionEnd; + }; ++ void onDocumentAssets(OnDocumentAssets value) const; ++ ++ void onMediaLayout(OnMediaLayout value) const; ++ + void onLinkPress(OnLinkPress value) const; + + void onLinkLongPress(OnLinkLongPress value) const; +diff --git a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +index fe3cfc5c95ceafbdbf32ea2fbbf1cba8989157e8..5bc5b43908ad3ce0b80f061d491a75058a59872f 100644 +--- a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp ++++ b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +@@ -19,6 +19,17 @@ EnrichedMarkdownProps::EnrichedMarkdownProps( + const EnrichedMarkdownProps &sourceProps, + const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), + ++ enableImageSourceResolution(convertRawProp(context, rawProps, "enableImageSourceResolution", sourceProps.enableImageSourceResolution, {false})), ++ imageSourcesRevision(convertRawProp(context, rawProps, "imageSourcesRevision", sourceProps.imageSourcesRevision, {-1})), ++ imageSourcesContinuityStart(convertRawProp(context, rawProps, "imageSourcesContinuityStart", sourceProps.imageSourcesContinuityStart, {1})), ++ imageSources(convertRawProp(context, rawProps, "imageSources", sourceProps.imageSources, {})), ++ documentRevision(convertRawProp(context, rawProps, "documentRevision", sourceProps.documentRevision, {0})), ++ enableDocumentAssets(convertRawProp(context, rawProps, "enableDocumentAssets", sourceProps.enableDocumentAssets, {false})), ++ enableMediaSlots(convertRawProp(context, rawProps, "enableMediaSlots", sourceProps.enableMediaSlots, {false})), ++ mediaOverridesRevision(convertRawProp(context, rawProps, "mediaOverridesRevision", sourceProps.mediaOverridesRevision, {-1})), ++ mediaOverrides(convertRawProp(context, rawProps, "mediaOverrides", sourceProps.mediaOverrides, {})), ++ linkRegex(convertRawProp(context, rawProps, "linkRegex", sourceProps.linkRegex, {})), ++ inlineCodeLinkRegex(convertRawProp(context, rawProps, "inlineCodeLinkRegex", sourceProps.inlineCodeLinkRegex, {})), + markdown(convertRawProp(context, rawProps, "markdown", sourceProps.markdown, {})), + markdownStyle(convertRawProp(context, rawProps, "markdownStyle", sourceProps.markdownStyle, {})), + enableImagePress(convertRawProp(context, rawProps, "enableImagePress", sourceProps.enableImagePress, {false})), +@@ -63,6 +74,50 @@ folly::dynamic EnrichedMarkdownProps::getDiffProps( + } + folly::dynamic result = HostPlatformViewProps::getDiffProps(prevProps); + ++ if (enableImageSourceResolution != oldProps->enableImageSourceResolution) { ++ result["enableImageSourceResolution"] = enableImageSourceResolution; ++ } ++ ++ if (imageSourcesRevision != oldProps->imageSourcesRevision) { ++ result["imageSourcesRevision"] = imageSourcesRevision; ++ } ++ ++ if (imageSourcesContinuityStart != oldProps->imageSourcesContinuityStart) { ++ result["imageSourcesContinuityStart"] = imageSourcesContinuityStart; ++ } ++ ++ if (imageSources != oldProps->imageSources) { ++ result["imageSources"] = toDynamic(imageSources); ++ } ++ ++ if (documentRevision != oldProps->documentRevision) { ++ result["documentRevision"] = documentRevision; ++ } ++ ++ if (enableDocumentAssets != oldProps->enableDocumentAssets) { ++ result["enableDocumentAssets"] = enableDocumentAssets; ++ } ++ ++ if (enableMediaSlots != oldProps->enableMediaSlots) { ++ result["enableMediaSlots"] = enableMediaSlots; ++ } ++ ++ if (mediaOverridesRevision != oldProps->mediaOverridesRevision) { ++ result["mediaOverridesRevision"] = mediaOverridesRevision; ++ } ++ ++ if (mediaOverrides != oldProps->mediaOverrides) { ++ result["mediaOverrides"] = toDynamic(mediaOverrides); ++ } ++ ++ if (linkRegex != oldProps->linkRegex) { ++ result["linkRegex"] = toDynamic(linkRegex); ++ } ++ ++ if (inlineCodeLinkRegex != oldProps->inlineCodeLinkRegex) { ++ result["inlineCodeLinkRegex"] = toDynamic(inlineCodeLinkRegex); ++ } ++ + if (markdown != oldProps->markdown) { + result["markdown"] = markdown; + } +@@ -317,6 +372,8 @@ EnrichedMarkdownTextProps::EnrichedMarkdownTextProps( + const EnrichedMarkdownTextProps &sourceProps, + const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), + ++ linkRegex(convertRawProp(context, rawProps, "linkRegex", sourceProps.linkRegex, {})), ++ inlineCodeLinkRegex(convertRawProp(context, rawProps, "inlineCodeLinkRegex", sourceProps.inlineCodeLinkRegex, {})), + markdown(convertRawProp(context, rawProps, "markdown", sourceProps.markdown, {})), + markdownStyle(convertRawProp(context, rawProps, "markdownStyle", sourceProps.markdownStyle, {})), + enableImagePress(convertRawProp(context, rawProps, "enableImagePress", sourceProps.enableImagePress, {false})), +@@ -361,6 +418,14 @@ folly::dynamic EnrichedMarkdownTextProps::getDiffProps( + } + folly::dynamic result = HostPlatformViewProps::getDiffProps(prevProps); + ++ if (linkRegex != oldProps->linkRegex) { ++ result["linkRegex"] = toDynamic(linkRegex); ++ } ++ ++ if (inlineCodeLinkRegex != oldProps->inlineCodeLinkRegex) { ++ result["inlineCodeLinkRegex"] = toDynamic(inlineCodeLinkRegex); ++ } ++ + if (markdown != oldProps->markdown) { + result["markdown"] = markdown; + } +diff --git a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +index ed3b4bf2507500ee012b6412e85b48f11214b364..9c8f8139bbbbff277c0b10eb541723e366fb6015 100644 +--- a/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h ++++ b/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +@@ -18,6 +18,320 @@ + + namespace facebook::react { + ++struct EnrichedMarkdownImageSourcesHeadersStruct { ++ std::string name{}; ++ std::string value{}; ++ ++ ++#ifdef RN_SERIALIZABLE_STATE ++ bool operator==(const EnrichedMarkdownImageSourcesHeadersStruct&) const = default; ++ ++ folly::dynamic toDynamic() const { ++ folly::dynamic result = folly::dynamic::object(); ++ result["name"] = name; ++ result["value"] = value; ++ return result; ++ } ++#endif ++}; ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownImageSourcesHeadersStruct &result) { ++ auto map = (std::unordered_map)value; ++ ++ auto tmp_name = map.find("name"); ++ if (tmp_name != map.end()) { ++ fromRawValue(context, tmp_name->second, result.name); ++ } ++ auto tmp_value = map.find("value"); ++ if (tmp_value != map.end()) { ++ fromRawValue(context, tmp_value->second, result.value); ++ } ++} ++ ++static inline std::string toString(const EnrichedMarkdownImageSourcesHeadersStruct &value) { ++ return "[Object EnrichedMarkdownImageSourcesHeadersStruct]"; ++} ++ ++#ifdef RN_SERIALIZABLE_STATE ++static inline folly::dynamic toDynamic(const EnrichedMarkdownImageSourcesHeadersStruct &value) { ++ return value.toDynamic(); ++} ++#endif ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, std::vector &result) { ++ auto items = (std::vector)value; ++ for (const auto &item : items) { ++ EnrichedMarkdownImageSourcesHeadersStruct newItem; ++ fromRawValue(context, item, newItem); ++ result.emplace_back(newItem); ++ } ++} ++ ++ ++struct EnrichedMarkdownImageSourcesStruct { ++ std::string id{}; ++ std::string url{}; ++ std::string anchor{}; ++ std::string uri{}; ++ std::vector headers{}; ++ bool useDefault{false}; ++ ++ ++#ifdef RN_SERIALIZABLE_STATE ++ bool operator==(const EnrichedMarkdownImageSourcesStruct&) const = default; ++ ++ folly::dynamic toDynamic() const { ++ folly::dynamic result = folly::dynamic::object(); ++ result["id"] = id; ++ result["url"] = url; ++ result["anchor"] = anchor; ++ result["uri"] = uri; ++ result["headers"] = ::facebook::react::toDynamic(headers); ++ result["useDefault"] = useDefault; ++ return result; ++ } ++#endif ++}; ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownImageSourcesStruct &result) { ++ auto map = (std::unordered_map)value; ++ ++ auto tmp_id = map.find("id"); ++ if (tmp_id != map.end()) { ++ fromRawValue(context, tmp_id->second, result.id); ++ } ++ auto tmp_url = map.find("url"); ++ if (tmp_url != map.end()) { ++ fromRawValue(context, tmp_url->second, result.url); ++ } ++ auto tmp_anchor = map.find("anchor"); ++ if (tmp_anchor != map.end()) { ++ fromRawValue(context, tmp_anchor->second, result.anchor); ++ } ++ auto tmp_uri = map.find("uri"); ++ if (tmp_uri != map.end()) { ++ fromRawValue(context, tmp_uri->second, result.uri); ++ } ++ auto tmp_headers = map.find("headers"); ++ if (tmp_headers != map.end()) { ++ fromRawValue(context, tmp_headers->second, result.headers); ++ } ++ auto tmp_useDefault = map.find("useDefault"); ++ if (tmp_useDefault != map.end()) { ++ fromRawValue(context, tmp_useDefault->second, result.useDefault); ++ } ++} ++ ++static inline std::string toString(const EnrichedMarkdownImageSourcesStruct &value) { ++ return "[Object EnrichedMarkdownImageSourcesStruct]"; ++} ++ ++#ifdef RN_SERIALIZABLE_STATE ++static inline folly::dynamic toDynamic(const EnrichedMarkdownImageSourcesStruct &value) { ++ return value.toDynamic(); ++} ++#endif ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, std::vector &result) { ++ auto items = (std::vector)value; ++ for (const auto &item : items) { ++ EnrichedMarkdownImageSourcesStruct newItem; ++ fromRawValue(context, item, newItem); ++ result.emplace_back(newItem); ++ } ++} ++ ++ ++struct EnrichedMarkdownMediaOverridesStruct { ++ std::string url{}; ++ std::string kind{}; ++ std::string anchor{}; ++ std::string id{}; ++ Float height{0.0}; ++ Float width{0.0}; ++ ++ ++#ifdef RN_SERIALIZABLE_STATE ++ bool operator==(const EnrichedMarkdownMediaOverridesStruct&) const = default; ++ ++ folly::dynamic toDynamic() const { ++ folly::dynamic result = folly::dynamic::object(); ++ result["url"] = url; ++ result["kind"] = kind; ++ result["anchor"] = anchor; ++ result["id"] = id; ++ result["height"] = height; ++ result["width"] = width; ++ return result; ++ } ++#endif ++}; ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownMediaOverridesStruct &result) { ++ auto map = (std::unordered_map)value; ++ ++ auto tmp_url = map.find("url"); ++ if (tmp_url != map.end()) { ++ fromRawValue(context, tmp_url->second, result.url); ++ } ++ auto tmp_kind = map.find("kind"); ++ if (tmp_kind != map.end()) { ++ fromRawValue(context, tmp_kind->second, result.kind); ++ } ++ auto tmp_anchor = map.find("anchor"); ++ if (tmp_anchor != map.end()) { ++ fromRawValue(context, tmp_anchor->second, result.anchor); ++ } ++ auto tmp_id = map.find("id"); ++ if (tmp_id != map.end()) { ++ fromRawValue(context, tmp_id->second, result.id); ++ } ++ auto tmp_height = map.find("height"); ++ if (tmp_height != map.end()) { ++ fromRawValue(context, tmp_height->second, result.height); ++ } ++ auto tmp_width = map.find("width"); ++ if (tmp_width != map.end()) { ++ fromRawValue(context, tmp_width->second, result.width); ++ } ++} ++ ++static inline std::string toString(const EnrichedMarkdownMediaOverridesStruct &value) { ++ return "[Object EnrichedMarkdownMediaOverridesStruct]"; ++} ++ ++#ifdef RN_SERIALIZABLE_STATE ++static inline folly::dynamic toDynamic(const EnrichedMarkdownMediaOverridesStruct &value) { ++ return value.toDynamic(); ++} ++#endif ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, std::vector &result) { ++ auto items = (std::vector)value; ++ for (const auto &item : items) { ++ EnrichedMarkdownMediaOverridesStruct newItem; ++ fromRawValue(context, item, newItem); ++ result.emplace_back(newItem); ++ } ++} ++ ++ ++struct EnrichedMarkdownLinkRegexStruct { ++ std::string pattern{}; ++ bool caseInsensitive{false}; ++ bool dotAll{false}; ++ bool isDisabled{false}; ++ bool isDefault{false}; ++ ++ ++#ifdef RN_SERIALIZABLE_STATE ++ bool operator==(const EnrichedMarkdownLinkRegexStruct&) const = default; ++ ++ folly::dynamic toDynamic() const { ++ folly::dynamic result = folly::dynamic::object(); ++ result["pattern"] = pattern; ++ result["caseInsensitive"] = caseInsensitive; ++ result["dotAll"] = dotAll; ++ result["isDisabled"] = isDisabled; ++ result["isDefault"] = isDefault; ++ return result; ++ } ++#endif ++}; ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownLinkRegexStruct &result) { ++ auto map = (std::unordered_map)value; ++ ++ auto tmp_pattern = map.find("pattern"); ++ if (tmp_pattern != map.end()) { ++ fromRawValue(context, tmp_pattern->second, result.pattern); ++ } ++ auto tmp_caseInsensitive = map.find("caseInsensitive"); ++ if (tmp_caseInsensitive != map.end()) { ++ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); ++ } ++ auto tmp_dotAll = map.find("dotAll"); ++ if (tmp_dotAll != map.end()) { ++ fromRawValue(context, tmp_dotAll->second, result.dotAll); ++ } ++ auto tmp_isDisabled = map.find("isDisabled"); ++ if (tmp_isDisabled != map.end()) { ++ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); ++ } ++ auto tmp_isDefault = map.find("isDefault"); ++ if (tmp_isDefault != map.end()) { ++ fromRawValue(context, tmp_isDefault->second, result.isDefault); ++ } ++} ++ ++static inline std::string toString(const EnrichedMarkdownLinkRegexStruct &value) { ++ return "[Object EnrichedMarkdownLinkRegexStruct]"; ++} ++ ++#ifdef RN_SERIALIZABLE_STATE ++static inline folly::dynamic toDynamic(const EnrichedMarkdownLinkRegexStruct &value) { ++ return value.toDynamic(); ++} ++#endif ++ ++struct EnrichedMarkdownInlineCodeLinkRegexStruct { ++ std::string pattern{}; ++ bool caseInsensitive{false}; ++ bool dotAll{false}; ++ bool isDisabled{false}; ++ bool isDefault{false}; ++ ++ ++#ifdef RN_SERIALIZABLE_STATE ++ bool operator==(const EnrichedMarkdownInlineCodeLinkRegexStruct&) const = default; ++ ++ folly::dynamic toDynamic() const { ++ folly::dynamic result = folly::dynamic::object(); ++ result["pattern"] = pattern; ++ result["caseInsensitive"] = caseInsensitive; ++ result["dotAll"] = dotAll; ++ result["isDisabled"] = isDisabled; ++ result["isDefault"] = isDefault; ++ return result; ++ } ++#endif ++}; ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownInlineCodeLinkRegexStruct &result) { ++ auto map = (std::unordered_map)value; ++ ++ auto tmp_pattern = map.find("pattern"); ++ if (tmp_pattern != map.end()) { ++ fromRawValue(context, tmp_pattern->second, result.pattern); ++ } ++ auto tmp_caseInsensitive = map.find("caseInsensitive"); ++ if (tmp_caseInsensitive != map.end()) { ++ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); ++ } ++ auto tmp_dotAll = map.find("dotAll"); ++ if (tmp_dotAll != map.end()) { ++ fromRawValue(context, tmp_dotAll->second, result.dotAll); ++ } ++ auto tmp_isDisabled = map.find("isDisabled"); ++ if (tmp_isDisabled != map.end()) { ++ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); ++ } ++ auto tmp_isDefault = map.find("isDefault"); ++ if (tmp_isDefault != map.end()) { ++ fromRawValue(context, tmp_isDefault->second, result.isDefault); ++ } ++} ++ ++static inline std::string toString(const EnrichedMarkdownInlineCodeLinkRegexStruct &value) { ++ return "[Object EnrichedMarkdownInlineCodeLinkRegexStruct]"; ++} ++ ++#ifdef RN_SERIALIZABLE_STATE ++static inline folly::dynamic toDynamic(const EnrichedMarkdownInlineCodeLinkRegexStruct &value) { ++ return value.toDynamic(); ++} ++#endif ++ + struct EnrichedMarkdownMarkdownStyleParagraphStruct { + Float fontSize{0.0}; + std::string fontFamily{}; +@@ -1313,6 +1627,17 @@ struct EnrichedMarkdownMarkdownStyleLinkVariantsStruct { + SharedColor color{}; + bool underline{false}; + SharedColor backgroundColor{}; ++ std::string fontFamily{}; ++ bool pill{false}; ++ std::string label{}; ++ std::string iconUri{}; ++ SharedColor iconTintColor{}; ++ Float borderRadius{0.0}; ++ Float paddingHorizontal{0.0}; ++ Float paddingVertical{0.0}; ++ Float borderWidth{0.0}; ++ SharedColor borderColor{}; ++ Float maxWidth{0.0}; + + + #ifdef RN_SERIALIZABLE_STATE +@@ -1324,6 +1649,17 @@ struct EnrichedMarkdownMarkdownStyleLinkVariantsStruct { + result["color"] = ::facebook::react::toDynamic(color); + result["underline"] = underline; + result["backgroundColor"] = ::facebook::react::toDynamic(backgroundColor); ++ result["fontFamily"] = fontFamily; ++ result["pill"] = pill; ++ result["label"] = label; ++ result["iconUri"] = iconUri; ++ result["iconTintColor"] = ::facebook::react::toDynamic(iconTintColor); ++ result["borderRadius"] = borderRadius; ++ result["paddingHorizontal"] = paddingHorizontal; ++ result["paddingVertical"] = paddingVertical; ++ result["borderWidth"] = borderWidth; ++ result["borderColor"] = ::facebook::react::toDynamic(borderColor); ++ result["maxWidth"] = maxWidth; + return result; + } + #endif +@@ -1348,6 +1684,50 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu + if (tmp_backgroundColor != map.end()) { + fromRawValue(context, tmp_backgroundColor->second, result.backgroundColor); + } ++ auto tmp_fontFamily = map.find("fontFamily"); ++ if (tmp_fontFamily != map.end()) { ++ fromRawValue(context, tmp_fontFamily->second, result.fontFamily); ++ } ++ auto tmp_pill = map.find("pill"); ++ if (tmp_pill != map.end()) { ++ fromRawValue(context, tmp_pill->second, result.pill); ++ } ++ auto tmp_label = map.find("label"); ++ if (tmp_label != map.end()) { ++ fromRawValue(context, tmp_label->second, result.label); ++ } ++ auto tmp_iconUri = map.find("iconUri"); ++ if (tmp_iconUri != map.end()) { ++ fromRawValue(context, tmp_iconUri->second, result.iconUri); ++ } ++ auto tmp_iconTintColor = map.find("iconTintColor"); ++ if (tmp_iconTintColor != map.end()) { ++ fromRawValue(context, tmp_iconTintColor->second, result.iconTintColor); ++ } ++ auto tmp_borderRadius = map.find("borderRadius"); ++ if (tmp_borderRadius != map.end()) { ++ fromRawValue(context, tmp_borderRadius->second, result.borderRadius); ++ } ++ auto tmp_paddingHorizontal = map.find("paddingHorizontal"); ++ if (tmp_paddingHorizontal != map.end()) { ++ fromRawValue(context, tmp_paddingHorizontal->second, result.paddingHorizontal); ++ } ++ auto tmp_paddingVertical = map.find("paddingVertical"); ++ if (tmp_paddingVertical != map.end()) { ++ fromRawValue(context, tmp_paddingVertical->second, result.paddingVertical); ++ } ++ auto tmp_borderWidth = map.find("borderWidth"); ++ if (tmp_borderWidth != map.end()) { ++ fromRawValue(context, tmp_borderWidth->second, result.borderWidth); ++ } ++ auto tmp_borderColor = map.find("borderColor"); ++ if (tmp_borderColor != map.end()) { ++ fromRawValue(context, tmp_borderColor->second, result.borderColor); ++ } ++ auto tmp_maxWidth = map.find("maxWidth"); ++ if (tmp_maxWidth != map.end()) { ++ fromRawValue(context, tmp_maxWidth->second, result.maxWidth); ++ } + } + + static inline std::string toString(const EnrichedMarkdownMarkdownStyleLinkVariantsStruct &value) { +@@ -3116,6 +3496,17 @@ class EnrichedMarkdownProps final : public ViewProps { + + #pragma mark - Props + ++ bool enableImageSourceResolution{false}; ++ int imageSourcesRevision{-1}; ++ int imageSourcesContinuityStart{1}; ++ std::vector imageSources{}; ++ int documentRevision{0}; ++ bool enableDocumentAssets{false}; ++ bool enableMediaSlots{false}; ++ int mediaOverridesRevision{-1}; ++ std::vector mediaOverrides{}; ++ EnrichedMarkdownLinkRegexStruct linkRegex{}; ++ EnrichedMarkdownInlineCodeLinkRegexStruct inlineCodeLinkRegex{}; + std::string markdown{}; + EnrichedMarkdownMarkdownStyleStruct markdownStyle{}; + bool enableImagePress{false}; +@@ -4078,6 +4469,122 @@ class EnrichedMarkdownTextInputProps final : public ViewProps { + + }; + ++struct EnrichedMarkdownTextLinkRegexStruct { ++ std::string pattern{}; ++ bool caseInsensitive{false}; ++ bool dotAll{false}; ++ bool isDisabled{false}; ++ bool isDefault{false}; ++ ++ ++#ifdef RN_SERIALIZABLE_STATE ++ bool operator==(const EnrichedMarkdownTextLinkRegexStruct&) const = default; ++ ++ folly::dynamic toDynamic() const { ++ folly::dynamic result = folly::dynamic::object(); ++ result["pattern"] = pattern; ++ result["caseInsensitive"] = caseInsensitive; ++ result["dotAll"] = dotAll; ++ result["isDisabled"] = isDisabled; ++ result["isDefault"] = isDefault; ++ return result; ++ } ++#endif ++}; ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownTextLinkRegexStruct &result) { ++ auto map = (std::unordered_map)value; ++ ++ auto tmp_pattern = map.find("pattern"); ++ if (tmp_pattern != map.end()) { ++ fromRawValue(context, tmp_pattern->second, result.pattern); ++ } ++ auto tmp_caseInsensitive = map.find("caseInsensitive"); ++ if (tmp_caseInsensitive != map.end()) { ++ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); ++ } ++ auto tmp_dotAll = map.find("dotAll"); ++ if (tmp_dotAll != map.end()) { ++ fromRawValue(context, tmp_dotAll->second, result.dotAll); ++ } ++ auto tmp_isDisabled = map.find("isDisabled"); ++ if (tmp_isDisabled != map.end()) { ++ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); ++ } ++ auto tmp_isDefault = map.find("isDefault"); ++ if (tmp_isDefault != map.end()) { ++ fromRawValue(context, tmp_isDefault->second, result.isDefault); ++ } ++} ++ ++static inline std::string toString(const EnrichedMarkdownTextLinkRegexStruct &value) { ++ return "[Object EnrichedMarkdownTextLinkRegexStruct]"; ++} ++ ++#ifdef RN_SERIALIZABLE_STATE ++static inline folly::dynamic toDynamic(const EnrichedMarkdownTextLinkRegexStruct &value) { ++ return value.toDynamic(); ++} ++#endif ++ ++struct EnrichedMarkdownTextInlineCodeLinkRegexStruct { ++ std::string pattern{}; ++ bool caseInsensitive{false}; ++ bool dotAll{false}; ++ bool isDisabled{false}; ++ bool isDefault{false}; ++ ++ ++#ifdef RN_SERIALIZABLE_STATE ++ bool operator==(const EnrichedMarkdownTextInlineCodeLinkRegexStruct&) const = default; ++ ++ folly::dynamic toDynamic() const { ++ folly::dynamic result = folly::dynamic::object(); ++ result["pattern"] = pattern; ++ result["caseInsensitive"] = caseInsensitive; ++ result["dotAll"] = dotAll; ++ result["isDisabled"] = isDisabled; ++ result["isDefault"] = isDefault; ++ return result; ++ } ++#endif ++}; ++ ++static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, EnrichedMarkdownTextInlineCodeLinkRegexStruct &result) { ++ auto map = (std::unordered_map)value; ++ ++ auto tmp_pattern = map.find("pattern"); ++ if (tmp_pattern != map.end()) { ++ fromRawValue(context, tmp_pattern->second, result.pattern); ++ } ++ auto tmp_caseInsensitive = map.find("caseInsensitive"); ++ if (tmp_caseInsensitive != map.end()) { ++ fromRawValue(context, tmp_caseInsensitive->second, result.caseInsensitive); ++ } ++ auto tmp_dotAll = map.find("dotAll"); ++ if (tmp_dotAll != map.end()) { ++ fromRawValue(context, tmp_dotAll->second, result.dotAll); ++ } ++ auto tmp_isDisabled = map.find("isDisabled"); ++ if (tmp_isDisabled != map.end()) { ++ fromRawValue(context, tmp_isDisabled->second, result.isDisabled); ++ } ++ auto tmp_isDefault = map.find("isDefault"); ++ if (tmp_isDefault != map.end()) { ++ fromRawValue(context, tmp_isDefault->second, result.isDefault); ++ } ++} ++ ++static inline std::string toString(const EnrichedMarkdownTextInlineCodeLinkRegexStruct &value) { ++ return "[Object EnrichedMarkdownTextInlineCodeLinkRegexStruct]"; ++} ++ ++#ifdef RN_SERIALIZABLE_STATE ++static inline folly::dynamic toDynamic(const EnrichedMarkdownTextInlineCodeLinkRegexStruct &value) { ++ return value.toDynamic(); ++} ++#endif ++ + struct EnrichedMarkdownTextMarkdownStyleParagraphStruct { + Float fontSize{0.0}; + std::string fontFamily{}; +@@ -5373,6 +5880,17 @@ struct EnrichedMarkdownTextMarkdownStyleLinkVariantsStruct { + SharedColor color{}; + bool underline{false}; + SharedColor backgroundColor{}; ++ std::string fontFamily{}; ++ bool pill{false}; ++ std::string label{}; ++ std::string iconUri{}; ++ SharedColor iconTintColor{}; ++ Float borderRadius{0.0}; ++ Float paddingHorizontal{0.0}; ++ Float paddingVertical{0.0}; ++ Float borderWidth{0.0}; ++ SharedColor borderColor{}; ++ Float maxWidth{0.0}; + + + #ifdef RN_SERIALIZABLE_STATE +@@ -5384,6 +5902,17 @@ struct EnrichedMarkdownTextMarkdownStyleLinkVariantsStruct { + result["color"] = ::facebook::react::toDynamic(color); + result["underline"] = underline; + result["backgroundColor"] = ::facebook::react::toDynamic(backgroundColor); ++ result["fontFamily"] = fontFamily; ++ result["pill"] = pill; ++ result["label"] = label; ++ result["iconUri"] = iconUri; ++ result["iconTintColor"] = ::facebook::react::toDynamic(iconTintColor); ++ result["borderRadius"] = borderRadius; ++ result["paddingHorizontal"] = paddingHorizontal; ++ result["paddingVertical"] = paddingVertical; ++ result["borderWidth"] = borderWidth; ++ result["borderColor"] = ::facebook::react::toDynamic(borderColor); ++ result["maxWidth"] = maxWidth; + return result; + } + #endif +@@ -5408,6 +5937,50 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu + if (tmp_backgroundColor != map.end()) { + fromRawValue(context, tmp_backgroundColor->second, result.backgroundColor); + } ++ auto tmp_fontFamily = map.find("fontFamily"); ++ if (tmp_fontFamily != map.end()) { ++ fromRawValue(context, tmp_fontFamily->second, result.fontFamily); ++ } ++ auto tmp_pill = map.find("pill"); ++ if (tmp_pill != map.end()) { ++ fromRawValue(context, tmp_pill->second, result.pill); ++ } ++ auto tmp_label = map.find("label"); ++ if (tmp_label != map.end()) { ++ fromRawValue(context, tmp_label->second, result.label); ++ } ++ auto tmp_iconUri = map.find("iconUri"); ++ if (tmp_iconUri != map.end()) { ++ fromRawValue(context, tmp_iconUri->second, result.iconUri); ++ } ++ auto tmp_iconTintColor = map.find("iconTintColor"); ++ if (tmp_iconTintColor != map.end()) { ++ fromRawValue(context, tmp_iconTintColor->second, result.iconTintColor); ++ } ++ auto tmp_borderRadius = map.find("borderRadius"); ++ if (tmp_borderRadius != map.end()) { ++ fromRawValue(context, tmp_borderRadius->second, result.borderRadius); ++ } ++ auto tmp_paddingHorizontal = map.find("paddingHorizontal"); ++ if (tmp_paddingHorizontal != map.end()) { ++ fromRawValue(context, tmp_paddingHorizontal->second, result.paddingHorizontal); ++ } ++ auto tmp_paddingVertical = map.find("paddingVertical"); ++ if (tmp_paddingVertical != map.end()) { ++ fromRawValue(context, tmp_paddingVertical->second, result.paddingVertical); ++ } ++ auto tmp_borderWidth = map.find("borderWidth"); ++ if (tmp_borderWidth != map.end()) { ++ fromRawValue(context, tmp_borderWidth->second, result.borderWidth); ++ } ++ auto tmp_borderColor = map.find("borderColor"); ++ if (tmp_borderColor != map.end()) { ++ fromRawValue(context, tmp_borderColor->second, result.borderColor); ++ } ++ auto tmp_maxWidth = map.find("maxWidth"); ++ if (tmp_maxWidth != map.end()) { ++ fromRawValue(context, tmp_maxWidth->second, result.maxWidth); ++ } + } + + static inline std::string toString(const EnrichedMarkdownTextMarkdownStyleLinkVariantsStruct &value) { +@@ -7176,6 +7749,8 @@ class EnrichedMarkdownTextProps final : public ViewProps { + + #pragma mark - Props + ++ EnrichedMarkdownTextLinkRegexStruct linkRegex{}; ++ EnrichedMarkdownTextInlineCodeLinkRegexStruct inlineCodeLinkRegex{}; + std::string markdown{}; + EnrichedMarkdownTextMarkdownStyleStruct markdownStyle{}; + bool enableImagePress{false}; +diff --git a/ios/input/ENRMInputParser.mm b/ios/input/ENRMInputParser.mm +index f82e72b3b838e40d886cf1eb5037b0a406730afe..79c53c0eeea362902c5a62f1d6be3e730715ab6f 100644 +--- a/ios/input/ENRMInputParser.mm ++++ b/ios/input/ENRMInputParser.mm +@@ -1,7 +1,7 @@ + #import "ENRMInputParser.h" ++#include "../../cpp/md4c/md4c.h" + #import "ENRMFormattingRange.h" + #import "ENRMInputRemend.h" +-#include "md4c.h" + #include + #include + #include +diff --git a/ios/internals/ENRMViewFreeMeasurement.h b/ios/internals/ENRMViewFreeMeasurement.h +index 8f7b44006ef080ff62976be02520c08c5b6463f2..c15350c28c65eb4386844612f69dfd9bd9e9a661 100644 +--- a/ios/internals/ENRMViewFreeMeasurement.h ++++ b/ios/internals/ENRMViewFreeMeasurement.h +@@ -2,8 +2,10 @@ + + #import "ENRMBlockquoteContainerView.h" + #import "ENRMCodeBlockContainerView.h" ++#import "ENRMDocumentAssets.h" + #import "ENRMFeatureFlags.h" + #import "ENRMMarkdownParser.h" ++#import "ENRMTextLinkRecognizer.h" + #import "ENRMTextRenderer.h" + #import "ENRMTextViewSetup.h" + #import "ImageRequestHeaderUtils.h" +@@ -147,10 +149,17 @@ static inline CGSize ENRMMeasureAttributedTextViewFree(NSAttributedString *text, + textContainer.lineBreakMode = lineBreakMode; + } + NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; ++#if !TARGET_OS_OSX ++ layoutManager.delegate = ENRMLinkPillLayoutDelegate.shared; ++#endif + layoutManager.allowsNonContiguousLayout = NO; + layoutManager.usesFontLeading = NO; + [layoutManager addTextContainer:textContainer]; ++#if !TARGET_OS_OSX ++ NSTextStorage *textStorage = [[ENRMLinkPillTextStorage alloc] initWithAttributedString:text]; ++#else + NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:text]; ++#endif + [textStorage addLayoutManager:layoutManager]; + + [layoutManager ensureLayoutForTextContainer:textContainer]; +@@ -184,7 +193,11 @@ static inline CGSize ENRMMeasureMarkdownViewFree(const PropsT &typedProps, CGFlo + + ENRMMd4cFlags *flags = ENRMMd4cFlagsFromProps(typedProps.md4cFlags); + ENRMMarkdownParser *parser = [[ENRMMarkdownParser alloc] init]; +- MarkdownASTNode *ast = [parser parseMarkdown:markdown flags:flags isGFM:typedProps.isGFM]; ++ MarkdownASTNode *ast = [parser parseMarkdown:markdown ++ flags:flags ++ isGFM:typedProps.isGFM ++ linkRegex:ENRMTextLinkRegexConfigFromProps(typedProps.linkRegex) ++ inlineCodeLinkRegex:ENRMTextLinkRegexConfigFromProps(typedProps.inlineCodeLinkRegex)]; + if (!ast) { + return fallback; + } +@@ -262,7 +275,11 @@ static inline CGSize ENRMMeasureSegmentedMarkdownViewFree(const PropsT &typedPro + + ENRMMd4cFlags *flags = ENRMMd4cFlagsFromProps(typedProps.md4cFlags); + ENRMMarkdownParser *parser = [[ENRMMarkdownParser alloc] init]; +- MarkdownASTNode *ast = [parser parseMarkdown:markdown flags:flags isGFM:typedProps.isGFM]; ++ MarkdownASTNode *ast = [parser parseMarkdown:markdown ++ flags:flags ++ isGFM:typedProps.isGFM ++ linkRegex:ENRMTextLinkRegexConfigFromProps(typedProps.linkRegex) ++ inlineCodeLinkRegex:ENRMTextLinkRegexConfigFromProps(typedProps.inlineCodeLinkRegex)]; + if (!ast) { + return fallback; + } +@@ -272,6 +289,15 @@ static inline CGSize ENRMMeasureSegmentedMarkdownViewFree(const PropsT &typedPro + ENRMWritingDirectionMode writingDirectionMode = + ENRMResolveWritingDirectionMode([[NSString alloc] initWithUTF8String:typedProps.writingDirection.c_str()]); + ++ BOOL resolveSources = typedProps.enableImageSourceResolution && typedProps.isGFM; ++ NSArray *assets = @[]; ++ if (typedProps.enableMediaSlots || resolveSources) { ++ assets = ENRMPrepareDocumentAssets(ast, typedProps.enableMediaSlots, ++ typedProps.mediaOverridesRevision == typedProps.documentRevision, ++ ENRMMediaOverridesFromProps(typedProps)); ++ } ++ ENRMPrepareImageSources(ast, assets, resolveSources, ENRMImageSourcesAccepted(typedProps), ++ ENRMImageSourcesFromProps(typedProps)); + NSArray *segments = + ENRMRenderSegmentsFromAST(ast, config, typedProps.allowTrailingMargin, typedProps.allowFontScaling, + typedProps.maxFontSizeMultiplier, lineBreakStrategy, /*blockquoteContent*/ NO); +@@ -294,7 +320,14 @@ static inline CGSize ENRMMeasureSegmentedMarkdownViewFree(const PropsT &typedPro + const BOOL isLast = (i == lastIndex); + const BOOL shouldAddBottomMargin = (!isLast || typedProps.allowTrailingMargin); + +- if (segment.kind == ENRMSegmentKindText && segment.textResult) { ++ if (segment.kind == ENRMSegmentKindMediaSlot && segment.mediaSlotNode) { ++ BOOL video = [segment.mediaSlotNode.attributes[@"_enrmMediaKind"] isEqualToString:@"video"]; ++ yOffset += video ? config.videoMarginTop : config.imageMarginTop; ++ yOffset += ENRMMediaSlotHeight(segment.mediaSlotNode, maxWidth, config); ++ maxContentWidth = maxWidth; ++ if (shouldAddBottomMargin) ++ yOffset += video ? config.videoMarginBottom : config.imageMarginBottom; ++ } else if (segment.kind == ENRMSegmentKindText && segment.textResult) { + CGSize textSize = ENRMMeasureAttributedTextViewFree( + segment.textResult.attributedText, maxWidth, config, shouldAddBottomMargin, + segment.textResult.lastElementMarginBottom, pointScaleFactor, 0, NSLineBreakByWordWrapping); +diff --git a/ios/internals/EnrichedMarkdownShadowNode.mm b/ios/internals/EnrichedMarkdownShadowNode.mm +index 056225f54a2ae249b6178c2e48c87685042389a1..2eab8469c16a5c50b90749505f00839d584e1f84 100644 +--- a/ios/internals/EnrichedMarkdownShadowNode.mm ++++ b/ios/internals/EnrichedMarkdownShadowNode.mm +@@ -31,6 +31,10 @@ EnrichedMarkdownShadowNode::EnrichedMarkdownShadowNode(const ShadowNode &sourceS + lastExactMeasurementCounter_ = -1; + } + ++ if (ENRMMediaPropsFingerprint(oldProps) != ENRMMediaPropsFingerprint(newProps)) { ++ lastExactMeasurementCounter_ = -1; ++ YGNodeMarkDirty(&yogaNode_); ++ } + dirtyLayoutIfNeeded(); + } + +diff --git a/ios/internals/MeasurementCache.h b/ios/internals/MeasurementCache.h +index 64604a3ac7e8788c06701ca6074badc3b852bcb9..12934e3c88dfbf940a954898ac41af4adfbe47e4 100644 +--- a/ios/internals/MeasurementCache.h ++++ b/ios/internals/MeasurementCache.h +@@ -1,5 +1,6 @@ + #pragma once + ++#import "ENRMDocumentAssets.h" + #include + #include + #include +@@ -50,6 +51,8 @@ struct MeasurementCacheKey { + std::string writingDirection; + int numberOfLines; + std::string ellipsizeMode; ++ std::string linkRegexKey; ++ std::string inlineCodeLinkRegexKey; + + bool operator==(const MeasurementCacheKey &other) const + { +@@ -57,13 +60,14 @@ struct MeasurementCacheKey { + md4cFlagsUnderline, md4cFlagsSuperscript, md4cFlagsSubscript, md4cFlagsHighlight, + md4cFlagsLatexMath, md4cFlagsHardSoftBreaks, md4cFlagsPreserveBlankLines, md4cFlagsAdmonitions, + styleFingerprint, fontScale, flavor, lineBreakStrategyIOS, writingDirection, numberOfLines, +- ellipsizeMode) == ++ ellipsizeMode, linkRegexKey, inlineCodeLinkRegexKey) == + std::tie(other.markdown, other.maxWidth, other.allowTrailingMargin, other.allowFontScaling, + other.maxFontSizeMultiplier, other.md4cFlagsUnderline, other.md4cFlagsSuperscript, + other.md4cFlagsSubscript, other.md4cFlagsHighlight, other.md4cFlagsLatexMath, + other.md4cFlagsHardSoftBreaks, other.md4cFlagsPreserveBlankLines, other.md4cFlagsAdmonitions, + other.styleFingerprint, other.fontScale, other.flavor, other.lineBreakStrategyIOS, +- other.writingDirection, other.numberOfLines, other.ellipsizeMode); ++ other.writingDirection, other.numberOfLines, other.ellipsizeMode, other.linkRegexKey, ++ other.inlineCodeLinkRegexKey); + } + }; + +@@ -91,6 +95,8 @@ struct MeasurementCacheKeyHash { + HashUtils::hash_one(h, key.writingDirection); + HashUtils::hash_one(h, key.numberOfLines); + HashUtils::hash_one(h, key.ellipsizeMode); ++ HashUtils::hash_one(h, key.linkRegexKey); ++ HashUtils::hash_one(h, key.inlineCodeLinkRegexKey); + return h; + } + }; +@@ -157,6 +163,17 @@ template inline size_t computeStyleFingerprint(const Styl + return h; + } + ++template inline std::string buildLinkRecognitionCacheKey(const RegexProps &props) ++{ ++ // Fixed-width flag prefix keeps key equality exact, including pattern changes. ++ std::string key; ++ key += props.caseInsensitive ? '1' : '0'; ++ key += props.dotAll ? '1' : '0'; ++ key += props.isDisabled ? '1' : '0'; ++ key += props.isDefault ? '1' : '0'; ++ return key + props.pattern; ++} ++ + template + inline MeasurementCacheKey buildMeasurementCacheKey(const PropsType &props, CGFloat maxWidth, CGFloat fontScale, + MarkdownFlavor flavor) +@@ -175,13 +192,15 @@ inline MeasurementCacheKey buildMeasurementCacheKey(const PropsType &props, CGFl + .md4cFlagsHardSoftBreaks = props.md4cFlags.hardSoftBreaks, + .md4cFlagsPreserveBlankLines = props.md4cFlags.preserveBlankLines, + .md4cFlagsAdmonitions = props.md4cFlags.admonitions, +- .styleFingerprint = computeStyleFingerprint(props.markdownStyle), ++ .styleFingerprint = computeStyleFingerprint(props.markdownStyle) ^ ENRMMediaPropsFingerprint(props), + .fontScale = fontScale, + .flavor = flavor, + .lineBreakStrategyIOS = props.lineBreakStrategyIOS, + .writingDirection = props.writingDirection, + .numberOfLines = props.numberOfLines, + .ellipsizeMode = props.ellipsizeMode, ++ .linkRegexKey = buildLinkRecognitionCacheKey(props.linkRegex), ++ .inlineCodeLinkRegexKey = buildLinkRecognitionCacheKey(props.inlineCodeLinkRegex), + }; + } + +diff --git a/ios/internals/ShadowMeasurementUtils.h b/ios/internals/ShadowMeasurementUtils.h +index 6cee54b0c814462aa3479d3c080537404775b1cb..3122de09d937a3bee13275911cabe1ed1a499f4d 100644 +--- a/ios/internals/ShadowMeasurementUtils.h ++++ b/ios/internals/ShadowMeasurementUtils.h +@@ -59,7 +59,8 @@ static inline Size ENRMClampMeasuredSize(CGSize size, const LayoutConstraints &l + template + static inline bool ENRMPropsNeedExactStreamingMeasurement(const PropsT &oldProps, const PropsT &newProps) + { +- return oldProps.streamingAnimation != newProps.streamingAnimation || ++ return ENRMMediaPropsFingerprint(oldProps) != ENRMMediaPropsFingerprint(newProps) || ++ oldProps.streamingAnimation != newProps.streamingAnimation || + oldProps.allowFontScaling != newProps.allowFontScaling || + oldProps.maxFontSizeMultiplier != newProps.maxFontSizeMultiplier || + oldProps.allowTrailingMargin != newProps.allowTrailingMargin || +@@ -70,8 +71,7 @@ static inline bool ENRMPropsNeedExactStreamingMeasurement(const PropsT &oldProps + oldProps.md4cFlags.highlight != newProps.md4cFlags.highlight || + oldProps.md4cFlags.hardSoftBreaks != newProps.md4cFlags.hardSoftBreaks || + oldProps.md4cFlags.preserveBlankLines != newProps.md4cFlags.preserveBlankLines || +- oldProps.isGFM != newProps.isGFM || +- oldProps.md4cFlags.admonitions != newProps.md4cFlags.admonitions || ++ oldProps.isGFM != newProps.isGFM || oldProps.md4cFlags.admonitions != newProps.md4cFlags.admonitions || + computeStyleFingerprint(oldProps.markdownStyle) != computeStyleFingerprint(newProps.markdownStyle); + } + +@@ -104,7 +104,8 @@ ENRMMeasureMarkdownContent(const PropsT &typedProps, const std::shared_ptr + // bumps lastExactMeasurementCounter, the rest land here. Return the freshly + // measured size, not the view's mailbox — mid-pass the frame isn't committed, + // so the mailbox is a generation stale and would freeze the height. +- if (typedProps.streamingAnimation && view && receivedCounter <= lastExactMeasurementCounter) { ++ if (typedProps.streamingAnimation && !ENRMMediaSlotsEnabled(typedProps) && view && ++ receivedCounter <= lastExactMeasurementCounter) { + if (lastExactMeasurementSize.width > 0 && lastExactMeasurementSize.height > 0) { + return ENRMClampMeasuredSize(lastExactMeasurementSize, layoutConstraints); + } +diff --git a/ios/parser/ENRMMarkdownParser.h b/ios/parser/ENRMMarkdownParser.h +index 7bcba9f8c131e3ec81e1ed94ea851f00ef9a324d..0c792b53b3a63b67f3839174cec4bcb61149bdd9 100644 +--- a/ios/parser/ENRMMarkdownParser.h ++++ b/ios/parser/ENRMMarkdownParser.h +@@ -16,10 +16,18 @@ + + @end + ++@class ENRMLinkRegexConfig; ++ + @interface ENRMMarkdownParser : NSObject + + - (MarkdownASTNode *)parseMarkdown:(NSString *)markdown; + - (MarkdownASTNode *)parseMarkdown:(NSString *)markdown flags:(ENRMMd4cFlags *)flags; + - (MarkdownASTNode *)parseMarkdown:(NSString *)markdown flags:(ENRMMd4cFlags *)flags isGFM:(BOOL)isGFM; ++// Recognition runs before returning the AST to rendering or document assets. ++- (MarkdownASTNode *)parseMarkdown:(NSString *)markdown ++ flags:(ENRMMd4cFlags *)flags ++ isGFM:(BOOL)isGFM ++ linkRegex:(ENRMLinkRegexConfig *)linkRegex ++ inlineCodeLinkRegex:(ENRMLinkRegexConfig *)inlineCodeLinkRegex; + + @end +diff --git a/ios/parser/ENRMMarkdownParser.mm b/ios/parser/ENRMMarkdownParser.mm +index a4a0022b73edeb53924a4ca067f68c5e6d2bd58a..2515b424dd51a3c6631e5ae697f86200e1b4e6df 100644 +--- a/ios/parser/ENRMMarkdownParser.mm ++++ b/ios/parser/ENRMMarkdownParser.mm +@@ -1,4 +1,5 @@ + #import "ENRMMarkdownParser.h" ++#import "ENRMTextLinkRecognizer.h" + #import "MarkdownASTNode.h" + + extern MarkdownASTNode *parseMarkdownWithCppParser(NSString *markdown, ENRMMd4cFlags *flags, BOOL isGFM); +@@ -58,4 +59,15 @@ extern MarkdownASTNode *parseMarkdownWithCppParser(NSString *markdown, ENRMMd4cF + return parseMarkdownWithCppParser(markdown, flags, isGFM); + } + ++- (MarkdownASTNode *)parseMarkdown:(NSString *)markdown ++ flags:(ENRMMd4cFlags *)flags ++ isGFM:(BOOL)isGFM ++ linkRegex:(ENRMLinkRegexConfig *)linkRegex ++ inlineCodeLinkRegex:(ENRMLinkRegexConfig *)inlineCodeLinkRegex ++{ ++ MarkdownASTNode *ast = [self parseMarkdown:markdown flags:flags isGFM:isGFM]; ++ ENRMRecognizeTextLinks(ast, linkRegex, inlineCodeLinkRegex); ++ return ast; ++} ++ + @end +diff --git a/ios/parser/ENRMTextLinkAttributes.h b/ios/parser/ENRMTextLinkAttributes.h +new file mode 100644 +index 0000000000000000000000000000000000000000..9d36943d00d9ef57c7f7405a279b25c48a77e04c +--- /dev/null ++++ b/ios/parser/ENRMTextLinkAttributes.h +@@ -0,0 +1,7 @@ ++#pragma once ++ ++#import ++ ++// Rendering metadata only. Copy reconstruction retains the source semantics. ++static NSString *const ENRMRecognizedLinkAttributeName = @"ENRMRecognizedLink"; ++static NSString *const ENRMRecognizedLinkOriginalUnderlineAttributeName = @"ENRMRecognizedLinkOriginalUnderline"; +diff --git a/ios/parser/ENRMTextLinkRecognizer.h b/ios/parser/ENRMTextLinkRecognizer.h +new file mode 100644 +index 0000000000000000000000000000000000000000..b83648d603bf9cd03eacf07deadafde6ffccfab9 +--- /dev/null ++++ b/ios/parser/ENRMTextLinkRecognizer.h +@@ -0,0 +1,31 @@ ++#pragma once ++ ++#import "ENRMLinkRegexConfig.h" ++#import "MarkdownASTNode.h" ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++// Mutates only the freshly parsed AST. Existing links and block code are opaque. ++void ENRMRecognizeTextLinks(MarkdownASTNode *ast, ENRMLinkRegexConfig *linkRegex, ++ ENRMLinkRegexConfig *inlineCodeLinkRegex); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#ifdef __cplusplus ++// Props share EnrichedMarkdownTextInput's native regex transport. ++template ++static inline ENRMLinkRegexConfig *ENRMTextLinkRegexConfigFromProps(const RegexProps &props) ++{ ++ if (props.isDisabled || props.isDefault || props.pattern.empty()) ++ return nil; ++ return [[ENRMLinkRegexConfig alloc] initWithPattern:[NSString stringWithUTF8String:props.pattern.c_str()] ++ caseInsensitive:props.caseInsensitive ++ dotAll:props.dotAll ++ isDisabled:props.isDisabled ++ isDefault:props.isDefault]; ++} ++#endif +diff --git a/ios/parser/ENRMTextLinkRecognizer.m b/ios/parser/ENRMTextLinkRecognizer.m +new file mode 100644 +index 0000000000000000000000000000000000000000..797354e5dc05a5b7a7baa5a9dc4dcee0aca404d3 +--- /dev/null ++++ b/ios/parser/ENRMTextLinkRecognizer.m +@@ -0,0 +1,98 @@ ++#import "ENRMTextLinkRecognizer.h" ++ ++static MarkdownASTNode *ENRMRecognizedLink(MarkdownASTNode *child, NSString *url) ++{ ++ MarkdownASTNode *link = [[MarkdownASTNode alloc] initWithType:MarkdownNodeTypeLink]; ++ [link setAttribute:@"url" value:url]; ++ [link setAttribute:@"recognizedLink" value:@"true"]; ++ [link addChild:child]; ++ return link; ++} ++ ++static MarkdownASTNode *ENRMTextSlice(MarkdownASTNode *node, NSString *content) ++{ ++ MarkdownASTNode *text = [[MarkdownASTNode alloc] initWithType:MarkdownNodeTypeText]; ++ text.content = content; ++ text.attributes = [node.attributes mutableCopy]; ++ return text; ++} ++ ++static NSArray *ENRMRecognizeNode(MarkdownASTNode *node, NSRegularExpression *textRegex, ++ NSRegularExpression *codeRegex) ++{ ++ switch (node.type) { ++ case MarkdownNodeTypeLink: ++ case MarkdownNodeTypeCodeBlock: ++ case MarkdownNodeTypeImage: ++ case MarkdownNodeTypeVideo: ++ case MarkdownNodeTypeLatexMathInline: ++ case MarkdownNodeTypeLatexMathDisplay: ++ return @[ node ]; ++ ++ case MarkdownNodeTypeCode: { ++ NSMutableString *content = [NSMutableString string]; ++ for (MarkdownASTNode *child in node.children) { ++ [content appendString:child.content ?: @""]; ++ } ++ NSRange range = NSMakeRange(0, content.length); ++ NSTextCheckingResult *match = [codeRegex firstMatchInString:content options:0 range:range]; ++ if (content.length > 0 && match && NSEqualRanges(match.range, range)) { ++ return @[ ENRMRecognizedLink(node, content) ]; ++ } ++ return @[ node ]; ++ } ++ ++ case MarkdownNodeTypeText: { ++ if (!textRegex) ++ return @[ node ]; ++ NSString *content = node.content ?: @""; ++ NSMutableArray *result = [NSMutableArray array]; ++ NSUInteger offset = 0; ++ for (NSTextCheckingResult *match in [textRegex matchesInString:content ++ options:0 ++ range:NSMakeRange(0, content.length)]) { ++ if (match.range.length == 0) ++ continue; ++ if (match.range.location > offset) { ++ [result addObject:ENRMTextSlice( ++ node, [content substringWithRange:NSMakeRange(offset, match.range.location - offset)])]; ++ } ++ NSString *matched = [content substringWithRange:match.range]; ++ [result addObject:ENRMRecognizedLink(ENRMTextSlice(node, matched), matched)]; ++ offset = NSMaxRange(match.range); ++ } ++ if (offset == 0) ++ return @[ node ]; ++ if (offset < content.length) { ++ [result addObject:ENRMTextSlice(node, [content substringFromIndex:offset])]; ++ } ++ return result; ++ } ++ ++ default: { ++ NSMutableArray *children = [NSMutableArray array]; ++ for (MarkdownASTNode *child in node.children) { ++ [children addObjectsFromArray:ENRMRecognizeNode(child, textRegex, codeRegex)]; ++ } ++ node.children = children; ++ return @[ node ]; ++ } ++ } ++} ++ ++void ENRMRecognizeTextLinks(MarkdownASTNode *ast, ENRMLinkRegexConfig *linkRegex, ++ ENRMLinkRegexConfig *inlineCodeLinkRegex) ++{ ++ NSRegularExpression *textRegex = (!linkRegex.isDefault && !linkRegex.isDisabled) ? linkRegex.parsedRegex : nil; ++ NSRegularExpression *codeRegex = nil; ++ if (!inlineCodeLinkRegex.isDefault && !inlineCodeLinkRegex.isDisabled && inlineCodeLinkRegex.parsedRegex) { ++ // Full-span matching, including alternatives that first match a shorter prefix. ++ codeRegex = [NSRegularExpression ++ regularExpressionWithPattern:[NSString stringWithFormat:@"\\A(?:%@)\\z", inlineCodeLinkRegex.pattern] ++ options:inlineCodeLinkRegex.parsedRegex.options ++ error:nil]; ++ } ++ if (ast && (textRegex || codeRegex)) { ++ ENRMRecognizeNode(ast, textRegex, codeRegex); ++ } ++} diff --git a/ios/parser/MarkdownParserBridge.mm b/ios/parser/MarkdownParserBridge.mm -index e700fcee063a5def59cf0a966f69221d627e24fe..9ad621a13b79951fc9f206bf5f2d33544dafc89c 100644 +index e700fcee063a5def59cf0a966f69221d627e24fe..07d862c5dc253b7f4302162b8bb3946f0430647b 100644 --- a/ios/parser/MarkdownParserBridge.mm +++ b/ios/parser/MarkdownParserBridge.mm -@@ -1,5 +1,6 @@ +@@ -1,7 +1,7 @@ ++#include "../../cpp/parser/MD4CParser.hpp" ++#include "../../cpp/parser/MarkdownASTNode.hpp" #import "ENRMMarkdownParser.h" -#include "MD4CParser.hpp" -+// Resolve our core explicitly; CocoaPods header maps can contain other MD4C parsers. -+#include "../../cpp/parser/MD4CParser.hpp" #import "MarkdownASTNode.h" - #include "MarkdownASTNode.hpp" +-#include "MarkdownASTNode.hpp" #import + + // Convert C++ AST node to Objective-C AST node diff --git a/ios/renderer/BaselineShiftTextAttributes.h b/ios/renderer/BaselineShiftTextAttributes.h index e862a564c4af827fa4ec85ee09a3657e7496d568..b56208c4311e57b3ec7fb1e7a4eda2fe196906cb 100644 --- a/ios/renderer/BaselineShiftTextAttributes.h @@ -61,6 +5884,114 @@ index da1d4b40332e83a1f88935632eb835be8876702b..c9d44b48fbd544c963bd7168d4e627a8 void ENRMApplyBaselineShift(NSMutableAttributedString *output, NSRange range, CGFloat fontScale, CGFloat baselineOffsetScale) { +diff --git a/ios/renderer/ENRMImageRenderer.m b/ios/renderer/ENRMImageRenderer.m +index 32edfcce882d4a9cb6133f938b7354c26e259f03..4253d82229fd34691ca204b9bc9bed6a54e10636 100644 +--- a/ios/renderer/ENRMImageRenderer.m ++++ b/ios/renderer/ENRMImageRenderer.m +@@ -1,5 +1,6 @@ + #import "ENRMImageRenderer.h" + #import "ENRMImageAttachment.h" ++#import "ENRMImageSources.h" + #import "MarkdownASTNode.h" + #import "RenderContext.h" + #import "RendererFactory.h" +@@ -20,7 +21,15 @@ static const unichar kZeroWidthSpace = 0x200B; + } + + BOOL isInline = [self isInlineImageInOutput:output]; +- ENRMImageAttachment *attachment = [ENRMImageAttachment attachmentForURL:imageURL config:_config isInline:isInline]; ++ NSDictionary *source = ENRMImageSourceDecisionForNode(node); ++ NSString *transportURI = [source[@"pending"] boolValue] ? nil : (source[@"uri"] ?: imageURL); ++ NSDictionary *headers = source ? ENRMMergeImageRequestHeaders(_config.imageRequestHeaders, source[@"headers"]) ++ : _config.imageRequestHeaders; ++ ENRMImageAttachment *attachment = [ENRMImageAttachment attachmentForURL:imageURL ++ config:_config ++ isInline:isInline ++ transportURI:transportURI ++ requestHeaders:headers]; + + NSUInteger startIndex = output.length; + +diff --git a/ios/renderer/LinkRenderer.m b/ios/renderer/LinkRenderer.m +index 5fdc4a78b464e58f36ecb8d5b7728eca125dff49..c9b54328b88b2765254acbd91d3a2e331c46862d 100644 +--- a/ios/renderer/LinkRenderer.m ++++ b/ios/renderer/LinkRenderer.m +@@ -1,4 +1,7 @@ + #import "LinkRenderer.h" ++#import "ENRMLinkPillAttachment.h" ++#import "CodeBackground.h" ++#import "ENRMTextLinkAttributes.h" + #import "FontUtils.h" + #import "RenderContext.h" + #import "RendererFactory.h" +@@ -13,6 +16,7 @@ + into:(NSMutableAttributedString *)output + context:(RenderContext *)context + { ++ BOOL recognizedLink = [node.attributes[@"recognizedLink"] isEqualToString:@"true"]; + NSUInteger start = output.length; + + // 1. Render children first to establish base attributes +@@ -28,7 +32,7 @@ + + RCTUIColor *linkColor = variant.color ?: [_config linkColor]; + BOOL linkUnderline = variant ? variant.underline : [_config linkUnderline]; +- NSString *linkFontFamily = [_config linkFontFamily]; ++ NSString *linkFontFamily = variant.fontFamily.length > 0 ? variant.fontFamily : [_config linkFontFamily]; + RCTUIColor *backgroundColor = variant ? variant.backgroundColor : [_config linkBackgroundColor]; + + NSNumber *underlineStyle = @(linkUnderline ? NSUnderlineStyleSingle : NSUnderlineStyleNone); +@@ -41,6 +45,11 @@ + options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired + usingBlock:^(NSDictionary *attrs, NSRange subrange, BOOL *stop) { + NSMutableDictionary *newAttributes = [NSMutableDictionary dictionary]; ++ if (recognizedLink) { ++ newAttributes[ENRMRecognizedLinkAttributeName] = @YES; ++ newAttributes[ENRMRecognizedLinkOriginalUnderlineAttributeName] = ++ attrs[NSUnderlineStyleAttributeName] ?: @0; ++ } + + // Only apply link color if the subrange isn't already colored by the link style + if (linkColor && ![attrs[NSForegroundColorAttributeName] isEqual:linkColor]) { +@@ -53,7 +62,7 @@ + newAttributes[NSUnderlineStyleAttributeName] = underlineStyle; + } + +- if (linkFontFamily.length > 0) { ++ if (linkFontFamily.length > 0 && (!recognizedLink || !attrs[CodeAttributeName])) { + UIFont *currentFont = attrs[NSFontAttributeName]; + if (currentFont) { + UIFont *linkFont = [RCTFont updateFont:currentFont +@@ -78,6 +87,29 @@ + [output addAttribute:NSBackgroundColorAttributeName value:backgroundColor range:range]; + } + ++#if !TARGET_OS_OSX ++ if (variant.pill) { ++ __block BOOL hasAttachment = NO; ++ [output enumerateAttribute:NSAttachmentAttributeName ++ inRange:range ++ options:0 ++ usingBlock:^(id value, NSRange subrange, BOOL *stop) { ++ if (value) { ++ hasAttachment = YES; ++ *stop = YES; ++ } ++ }]; ++ if (!hasAttachment) { ++ UIFont *font = [output attribute:NSFontAttributeName atIndex:range.location effectiveRange:NULL]; ++ ENRMLinkPillAttachment *pill = ++ [[ENRMLinkPillAttachment alloc] initWithLabel:[output.string substringWithRange:range] ++ variant:variant ++ font:font ?: [context getBlockStyle].cachedFont]; ++ [output removeAttribute:NSBackgroundColorAttributeName range:range]; ++ [output addAttribute:NSAttachmentAttributeName value:pill range:range]; ++ } ++ } ++#endif + [context registerLinkRange:range url:url]; + } + diff --git a/ios/renderer/SubscriptRenderer.m b/ios/renderer/SubscriptRenderer.m index f697216589db39e72cef5ed5f3f85ad2d5e009a1..d88f5e15ed79440ace831efe531f47e00d0cbfb2 100644 --- a/ios/renderer/SubscriptRenderer.m @@ -85,19 +6016,997 @@ index edba7364733ea7bb312176893387b7906c34353c..308b8de0ecfec3ce5a0b5961bbeafc3b ENRMApplyBaselineShift(output, range, _config.superscriptFontScale, _config.superscriptBaselineOffsetScale); } +diff --git a/ios/renderer/UnderlineRenderer.m b/ios/renderer/UnderlineRenderer.m +index e772e4ba509a05163dfd19bf4315d1fe543b56d2..007fe7bb76e41cdaf17f493dab0e7f7234be5496 100644 +--- a/ios/renderer/UnderlineRenderer.m ++++ b/ios/renderer/UnderlineRenderer.m +@@ -1,4 +1,5 @@ + #import "UnderlineRenderer.h" ++#import "ENRMTextLinkAttributes.h" + #import "MarkdownASTNode.h" + #import "RenderContext.h" + #import "RendererFactory.h" +@@ -20,6 +21,7 @@ + return; + + [output addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:range]; ++ [output addAttribute:ENRMRecognizedLinkOriginalUnderlineAttributeName value:@(NSUnderlineStyleSingle) range:range]; + + RCTUIColor *underlineColor = [_config underlineColor]; + +diff --git a/ios/segments/ENRMBlockquoteContainerView.mm b/ios/segments/ENRMBlockquoteContainerView.mm +index b2f2eb57aa12963b88255150d505977c33464aa8..42fe66e2fefb60b1297a948413df156000e06d3b 100644 +--- a/ios/segments/ENRMBlockquoteContainerView.mm ++++ b/ios/segments/ENRMBlockquoteContainerView.mm +@@ -2,6 +2,7 @@ + #import "ENRMAdmonitionIcons.h" + #import "ENRMCodeBlockContainerView.h" + #import "ENRMFeatureFlags.h" ++#import "ENRMMediaSlotView.h" + #import "ENRMSegmentHeightMeasurer.h" + #import "ENRMTextInteractionUtils.h" + #import "ENRMTextRenderer.h" +@@ -312,6 +313,18 @@ static UIEdgeInsets ENRMBlockquoteContentInsets(StyleConfig *config) + }]]; + #endif + ++ [handlers addObject:[ENRMSegmentViewHandler handlerWithKind:ENRMSegmentKindMediaSlot ++ matchesView:^BOOL(RCTUIView *view, ENRMRenderedSegment *segment) { ++ return [view isKindOfClass:[ENRMMediaSlotView class]]; ++ } ++ createView:^RCTUIView *(ENRMRenderedSegment *segment) { ++ ENRMMediaSlotView *view = [[ENRMMediaSlotView alloc] init]; ++ view.mediaNode = segment.mediaSlotNode; ++ return view; ++ } ++ updateView:^(RCTUIView *view, ENRMRenderedSegment *segment) { ++ ((ENRMMediaSlotView *)view).mediaNode = segment.mediaSlotNode; ++ }]]; + return [[ENRMSegmentViewRegistry alloc] initWithHandlers:handlers]; + } + +diff --git a/ios/segments/ENRMContainerNodeView.h b/ios/segments/ENRMContainerNodeView.h +index 41e522d05e47f398c989389be1afc74419458053..849a4eaafcbb42988873a65cce740641bae1e137 100644 +--- a/ios/segments/ENRMContainerNodeView.h ++++ b/ios/segments/ENRMContainerNodeView.h +@@ -47,6 +47,9 @@ NS_ASSUME_NONNULL_BEGIN + // i.e. bounds width minus horizontal insets), including the vertical insets. + - (CGFloat)computeContentHeightForWidth:(CGFloat)contentWidth; + ++// Lays out nested children and appends accepted slot rectangles in root space. ++- (void)appendMediaFrames:(NSMutableArray *)frames relativeToView:(RCTUIView *)rootView; ++ + @end + + NS_ASSUME_NONNULL_END +diff --git a/ios/segments/ENRMContainerNodeView.mm b/ios/segments/ENRMContainerNodeView.mm +index 448840013e73e2abd483cfec94441831082ff889..d26f3b390d564d73062e20bf0f15f12239e7d417 100644 +--- a/ios/segments/ENRMContainerNodeView.mm ++++ b/ios/segments/ENRMContainerNodeView.mm +@@ -1,7 +1,9 @@ + #import "ENRMContainerNodeView.h" + #import "ENRMBlockquoteContainerView.h" + #import "ENRMCodeBlockContainerView.h" ++#import "ENRMDocumentAssets.h" + #import "ENRMFeatureFlags.h" ++#import "ENRMMediaSlotView.h" + #import "EnrichedMarkdownInternalText.h" + #import "SegmentReconciler.h" + #import "TableContainerView.h" +@@ -66,6 +68,11 @@ + + - (CGFloat)marginTopForView:(RCTUIView *)view + { ++ if ([view isKindOfClass:[ENRMMediaSlotView class]]) { ++ MarkdownASTNode *node = ((ENRMMediaSlotView *)view).mediaNode; ++ return [node.attributes[@"_enrmMediaKind"] isEqualToString:@"video"] ? _config.videoMarginTop ++ : _config.imageMarginTop; ++ } + if ([view isKindOfClass:[TableContainerView class]]) { + return _config.tableMarginTop; + } +@@ -92,6 +99,11 @@ + + - (CGFloat)marginBottomForView:(RCTUIView *)view + { ++ if ([view isKindOfClass:[ENRMMediaSlotView class]]) { ++ MarkdownASTNode *node = ((ENRMMediaSlotView *)view).mediaNode; ++ return [node.attributes[@"_enrmMediaKind"] isEqualToString:@"video"] ? _config.videoMarginBottom ++ : _config.imageMarginBottom; ++ } + if ([view isKindOfClass:[TableContainerView class]]) { + return _config.tableMarginBottom; + } +@@ -116,6 +128,8 @@ + + - (CGFloat)heightForView:(RCTUIView *)view atWidth:(CGFloat)width shouldAddBottomMargin:(BOOL)shouldAddBottomMargin + { ++ if ([view isKindOfClass:[ENRMMediaSlotView class]]) ++ return ENRMMediaSlotHeight(((ENRMMediaSlotView *)view).mediaNode, width, _config); + if ([view isKindOfClass:[EnrichedMarkdownInternalText class]]) { + EnrichedMarkdownInternalText *textView = (EnrichedMarkdownInternalText *)view; + textView.allowTrailingMargin = shouldAddBottomMargin; +@@ -178,6 +192,32 @@ + return CGSizeMake(outerWidth, yOffset); + } + ++- (void)appendMediaFrames:(NSMutableArray *)frames relativeToView:(RCTUIView *)rootView ++{ ++ // The layout helper leaves child frames untouched when no inner width exists. ++ // Never publish those rectangles from the previous positive-width layout. ++ if (self.bounds.size.width - _contentInsets.left - _contentInsets.right <= 0) ++ return; ++ // Apply nested frames now rather than relying on UIKit's later subview pass: ++ // the root publishes this batch immediately after its own segment layout. ++ [self layoutChildrenForOuterWidth:self.bounds.size.width applyFrames:YES]; ++ for (RCTUIView *view in _segmentViews) { ++ if ([view isKindOfClass:[ENRMMediaSlotView class]]) { ++ MarkdownASTNode *node = ((ENRMMediaSlotView *)view).mediaNode; ++ CGRect rect = [rootView convertRect:view.bounds fromView:view]; ++ [frames addObject:@{ ++ @"id" : node.attributes[@"_enrmMediaSlot"], ++ @"x" : @(rect.origin.x), ++ @"y" : @(rect.origin.y), ++ @"width" : @(rect.size.width), ++ @"height" : @(rect.size.height) ++ }]; ++ } else if ([view isKindOfClass:[ENRMContainerNodeView class]]) { ++ [(ENRMContainerNodeView *)view appendMediaFrames:frames relativeToView:rootView]; ++ } ++ } ++} ++ + - (CGFloat)computeContentHeightForWidth:(CGFloat)contentWidth + { + return [self layoutChildrenForOuterWidth:contentWidth + _contentInsets.left + _contentInsets.right applyFrames:NO] +diff --git a/ios/segments/ENRMMediaSlotView.h b/ios/segments/ENRMMediaSlotView.h +new file mode 100644 +index 0000000000000000000000000000000000000000..b89cde54e2365d6e20567d4922115f71ccc6c13e +--- /dev/null ++++ b/ios/segments/ENRMMediaSlotView.h +@@ -0,0 +1,6 @@ ++#pragma once ++#import "ENRMUIKit.h" ++@class MarkdownASTNode; ++@interface ENRMMediaSlotView : RCTUIView ++@property (nonatomic, strong) MarkdownASTNode *mediaNode; ++@end +diff --git a/ios/segments/ENRMMediaSlotView.m b/ios/segments/ENRMMediaSlotView.m +new file mode 100644 +index 0000000000000000000000000000000000000000..ef5a16547e58f15074599142962737f84efbdff4 +--- /dev/null ++++ b/ios/segments/ENRMMediaSlotView.m +@@ -0,0 +1,14 @@ ++#import "ENRMMediaSlotView.h" ++@implementation ENRMMediaSlotView ++- (instancetype)initWithFrame:(CGRect)frame ++{ ++ if ((self = [super initWithFrame:frame])) { ++#if !TARGET_OS_OSX ++ self.isAccessibilityElement = NO; ++ self.accessibilityElementsHidden = YES; ++ self.userInteractionEnabled = NO; ++#endif ++ } ++ return self; ++} ++@end +diff --git a/ios/segments/ENRMSegmentHeightMeasurer.mm b/ios/segments/ENRMSegmentHeightMeasurer.mm +index 0f4eeb1e6adf3ab21c6713846b972ffce425a329..30a3a5598a2610273259bc0be4f9bc1de6d3653e 100644 +--- a/ios/segments/ENRMSegmentHeightMeasurer.mm ++++ b/ios/segments/ENRMSegmentHeightMeasurer.mm +@@ -1,6 +1,7 @@ + #import "ENRMSegmentHeightMeasurer.h" + #import "ENRMBlockquoteContainerView.h" + #import "ENRMCodeBlockContainerView.h" ++#import "ENRMDocumentAssets.h" + #import "ENRMFeatureFlags.h" + #import "ENRMTextRenderer.h" + #import "ENRMViewFreeMeasurement.h" +@@ -30,7 +31,13 @@ CGFloat ENRMMeasureSegmentsHeightViewFree(NSArray *segmen + const BOOL isLast = (i == lastIndex); + const BOOL shouldAddBottomMargin = (!isLast || allowTrailingMargin); + +- if (segment.kind == ENRMSegmentKindText && segment.textResult) { ++ if (segment.kind == ENRMSegmentKindMediaSlot && segment.mediaSlotNode) { ++ BOOL video = [segment.mediaSlotNode.attributes[@"_enrmMediaKind"] isEqualToString:@"video"]; ++ totalHeight += video ? config.videoMarginTop : config.imageMarginTop; ++ totalHeight += ENRMMediaSlotHeight(segment.mediaSlotNode, contentWidth, config); ++ if (shouldAddBottomMargin) ++ totalHeight += video ? config.videoMarginBottom : config.imageMarginBottom; ++ } else if (segment.kind == ENRMSegmentKindText && segment.textResult) { + // GFM segments are never line-clamped (numberOfLines is a no-op for GFM). + CGSize textSize = ENRMMeasureAttributedTextViewFree( + segment.textResult.attributedText, contentWidth, config, shouldAddBottomMargin, +diff --git a/ios/segments/ENRMTableIOSGridView.m b/ios/segments/ENRMTableIOSGridView.m +index 138435033005771ce0bb194f273316a5328e3057..b4cdf7a13292366c21951749e7a496dbea7a097d 100644 +--- a/ios/segments/ENRMTableIOSGridView.m ++++ b/ios/segments/ENRMTableIOSGridView.m +@@ -1,4 +1,6 @@ + #import "ENRMTableIOSGridView.h" ++#import "ENRMLinkPillAttachment.h" ++#import "ENRMLinkPillTextStorage.h" + + #if !TARGET_OS_OSX + +@@ -97,9 +99,7 @@ + if (text.length > 0) { + CGRect textRect = CGRectMake(xOffset + _horizontalCellPadding, yOffset + _verticalCellPadding, + columnWidth - _horizontalCellPadding * 2, rowHeight - _verticalCellPadding * 2); +- [text drawWithRect:textRect +- options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading +- context:nil]; ++ ENRMDrawLinkPillText(text, textRect); + } + + xOffset += columnWidth; +@@ -149,8 +149,9 @@ static NSString *linkInAttributedString(NSAttributedString *text, CGRect textRec + if (text.length == 0) + return nil; + +- NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:text]; ++ NSTextStorage *textStorage = [[ENRMLinkPillTextStorage alloc] initWithAttributedString:text]; + NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; ++ layoutManager.delegate = ENRMLinkPillLayoutDelegate.shared; + NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:textRect.size]; + textContainer.lineFragmentPadding = 0; + [layoutManager addTextContainer:textContainer]; +diff --git a/ios/segments/RenderedMarkdownSegment.h b/ios/segments/RenderedMarkdownSegment.h +index 4a0e3c797d789536cfcacd8899714e50074be9bf..1e548df87da6cb8205ba5da08604245d00a5698a 100644 +--- a/ios/segments/RenderedMarkdownSegment.h ++++ b/ios/segments/RenderedMarkdownSegment.h +@@ -13,7 +13,8 @@ typedef NS_ENUM(NSInteger, ENRMSegmentKind) { + ENRMSegmentKindMath, + ENRMSegmentKindCodeBlock, + ENRMSegmentKindBlockquote, +- ENRMSegmentKindVideo ++ ENRMSegmentKindVideo, ++ ENRMSegmentKindMediaSlot + }; + + @interface ENRMTextSegment : NSObject +@@ -49,6 +50,7 @@ typedef NS_ENUM(NSInteger, ENRMSegmentKind) { + @interface ENRMRenderedSegment : NSObject + @property (nonatomic, assign) ENRMSegmentKind kind; + @property (nonatomic, assign) uint64_t signature; ++@property (nonatomic, strong, nullable) MarkdownASTNode *mediaSlotNode; + @property (nonatomic, strong, nullable) ENRMRenderResult *textResult; + @property (nonatomic, strong, nullable) ENRMTableSegment *tableSegment; + @property (nonatomic, strong, nullable) ENRMMathSegment *mathSegment; +diff --git a/ios/segments/SegmentRenderer.m b/ios/segments/SegmentRenderer.m +index 1cbe7fd0a50e5302f08a299cad468eab736a012d..b5e225ddab2c4fe829d3673b0956404d8532673d 100644 +--- a/ios/segments/SegmentRenderer.m ++++ b/ios/segments/SegmentRenderer.m +@@ -1,5 +1,6 @@ + #import "SegmentRenderer.h" + #import "ENRMFeatureFlags.h" ++#import "ENRMImageSources.h" + #import "ENRMTextRenderer.h" + #import "MarkdownASTNode.h" + #import "ParagraphStyleUtils.h" +@@ -11,7 +12,13 @@ static NSArray *ENRMSplitASTIntoSegments(MarkdownASTNode *root) + NSMutableArray *currentTextNodes = [NSMutableArray array]; + + for (MarkdownASTNode *child in root.children) { +- if (child.type == MarkdownNodeTypeTable) { ++ if (child.attributes[@"_enrmMediaSlot"]) { ++ if (currentTextNodes.count > 0) { ++ [segments addObject:[ENRMTextSegment segmentWithNodes:[currentTextNodes copy]]]; ++ [currentTextNodes removeAllObjects]; ++ } ++ [segments addObject:child]; ++ } else if (child.type == MarkdownNodeTypeTable) { + if (currentTextNodes.count > 0) { + [segments addObject:[ENRMTextSegment segmentWithNodes:[currentTextNodes copy]]]; + [currentTextNodes removeAllObjects]; +@@ -83,18 +90,26 @@ NSArray *ENRMRenderSegmentsFromAST(MarkdownASTNode *ast, + static const uint64_t kVideoKindSalt = 0x7669646F00000000ULL; // "vido" + + for (id segment in segments) { +- if ([segment isKindOfClass:[ENRMTextSegment class]]) { ++ if ([segment isKindOfClass:[MarkdownASTNode class]]) { ++ ENRMRenderedSegment *rendered = [[ENRMRenderedSegment alloc] init]; ++ rendered.kind = ENRMSegmentKindMediaSlot; ++ rendered.mediaSlotNode = segment; ++ rendered.signature = ENRMSignatureForNode(segment); ++ [renderedSegments addObject:rendered]; ++ } else if ([segment isKindOfClass:[ENRMTextSegment class]]) { + ENRMTextSegment *textSegment = (ENRMTextSegment *)segment; + ENRMRenderResult *rendered = blockquoteContent + ? ENRMRenderBlockquoteContentNodes(textSegment.nodes, config, allowFontScaling, + maxFontSizeMultiplier, lineBreakStrategy) + : ENRMRenderASTNodes(textSegment.nodes, config, allowTrailingMargin, + allowFontScaling, maxFontSizeMultiplier, lineBreakStrategy); +- uint64_t signature = ENRMSignatureForNodes(textSegment.nodes) ^ kTextKindSalt; ++ uint64_t signature = ENRMSignatureForNodes(textSegment.nodes) ^ ++ ENRMImageSourceSignatureForNodes(textSegment.nodes) ^ kTextKindSalt; + [renderedSegments addObject:[ENRMRenderedSegment textSegmentWithResult:rendered signature:signature]]; + } else if ([segment isKindOfClass:[ENRMTableSegment class]]) { + ENRMTableSegment *tableSegment = (ENRMTableSegment *)segment; +- uint64_t signature = ENRMSignatureForNode(tableSegment.tableNode) ^ kTableKindSalt; ++ uint64_t signature = ENRMSignatureForNode(tableSegment.tableNode) ^ ++ ENRMImageSourceSignatureForNode(tableSegment.tableNode) ^ kTableKindSalt; + [renderedSegments addObject:[ENRMRenderedSegment tableSegmentWithSegment:tableSegment signature:signature]]; + } + #if ENRICHED_MARKDOWN_MATH +@@ -117,7 +132,8 @@ NSArray *ENRMRenderSegmentsFromAST(MarkdownASTNode *ast, + signature:signature]]; + } else if ([segment isKindOfClass:[ENRMBlockquoteSegment class]]) { + ENRMBlockquoteSegment *blockquoteSegment = (ENRMBlockquoteSegment *)segment; +- uint64_t signature = ENRMSignatureForNode(blockquoteSegment.blockquoteNode) ^ kBlockquoteKindSalt; ++ uint64_t signature = ENRMSignatureForNode(blockquoteSegment.blockquoteNode) ^ ++ ENRMImageSourceSignatureForNode(blockquoteSegment.blockquoteNode) ^ kBlockquoteKindSalt; + [renderedSegments addObject:[ENRMRenderedSegment blockquoteSegmentWithSegment:blockquoteSegment + signature:signature]]; + } +diff --git a/ios/segments/TableContainerView.m b/ios/segments/TableContainerView.m +index 0423787367f9cae1acf3ebf6d0139c4fc24e984e..47ba558a1caf42684bae8ccf1d35ff59091cbad6 100644 +--- a/ios/segments/TableContainerView.m ++++ b/ios/segments/TableContainerView.m +@@ -2,6 +2,7 @@ + #import "AttributedRenderer.h" + #import "ENRMAccessibilityLabels.h" + #import "ENRMImageAttachment.h" ++#import "ENRMLinkPillAttachment.h" + #import "HTMLGenerator.h" + #import "LinkTapUtils.h" + #import "MarkdownASTNode.h" +@@ -190,10 +191,14 @@ static void ENRMTableComputeLayout(NSArray *> *rows, NS + + for (NSArray *row in rows) { + for (NSUInteger column = 0; column < row.count; column++) { ++#if !TARGET_OS_OSX ++ CGRect boundingRect = ENRMLinkPillTextBounds(row[column].attributedText, maximumColumnWidth); ++#else + CGRect boundingRect = [row[column].attributedText + boundingRectWithSize:CGSizeMake(maximumColumnWidth, CGFLOAT_MAX) + options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading + context:nil]; ++#endif + CGFloat width = MIN(MAX(ceil(boundingRect.size.width) + horizontalPadding, minimumColumnWidth), + maximumColumnWidth + horizontalPadding); + if (width > [colWidths[column] doubleValue]) +@@ -206,10 +211,14 @@ static void ENRMTableComputeLayout(NSArray *> *rows, NS + CGFloat maxHeight = 0; + for (NSUInteger column = 0; column < row.count; column++) { + CGFloat availableWidth = [colWidths[column] doubleValue] - horizontalPadding; ++#if !TARGET_OS_OSX ++ CGRect boundingRect = ENRMLinkPillTextBounds(row[column].attributedText, availableWidth); ++#else + CGRect boundingRect = [row[column].attributedText + boundingRectWithSize:CGSizeMake(availableWidth, CGFLOAT_MAX) + options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading + context:nil]; ++#endif + maxHeight = MAX(maxHeight, ceil(boundingRect.size.height) + verticalPadding); + } + [rowHeights addObject:@(maxHeight)]; +diff --git a/ios/styles/StyleConfig.h b/ios/styles/StyleConfig.h +index d4491f69aded5b7368ae915aef5cc88a1aa706a1..04869dce2cf958d1543d96f4f70edf92b4ca7232 100644 +--- a/ios/styles/StyleConfig.h ++++ b/ios/styles/StyleConfig.h +@@ -9,6 +9,17 @@ NS_ASSUME_NONNULL_BEGIN + * Populated from the JS `linkVariants` map by StylePropsUtils and consumed by LinkRenderer. + */ + @interface LinkVariantConfig : NSObject ++@property (nonatomic, copy) NSString *fontFamily; ++@property (nonatomic, assign) BOOL pill; ++@property (nonatomic, copy) NSString *label; ++@property (nonatomic, copy) NSString *iconUri; ++@property (nonatomic, strong, nullable) RCTUIColor *iconTintColor; ++@property (nonatomic, assign) CGFloat borderRadius; ++@property (nonatomic, assign) CGFloat paddingHorizontal; ++@property (nonatomic, assign) CGFloat paddingVertical; ++@property (nonatomic, assign) CGFloat borderWidth; ++@property (nonatomic, strong) RCTUIColor *borderColor; ++@property (nonatomic, assign) CGFloat maxWidth; + @property (nonatomic, copy) NSString *pattern; + @property (nonatomic, strong) RCTUIColor *color; + @property (nonatomic, assign) BOOL underline; +diff --git a/ios/utils/CodeBackground.m b/ios/utils/CodeBackground.m +index 5e5d5bf06370c9a94ed5645ccba4436894fe2bdb..fa30eb3812cf76681778415215da3e0c0319a148 100644 +--- a/ios/utils/CodeBackground.m ++++ b/ios/utils/CodeBackground.m +@@ -1,4 +1,5 @@ + #import "CodeBackground.h" ++#import "ENRMLinkPillAttachment.h" + #import "ENRMUIKit.h" + #import "RenderContext.h" + +@@ -43,12 +44,31 @@ static const CGFloat kCodeBackgroundBorderWidth = 0.5; + if (NSIntersectionRange(range, charRange).length == 0) + return; + +- [self drawCodeBackgroundForRange:range +- layoutManager:layoutManager +- textContainer:textContainer +- atPoint:origin +- backgroundColor:backgroundColor +- borderColor:self->_config.codeBorderColor]; ++#if !TARGET_OS_OSX ++ // Keep CodeAttributeName for extraction; attachments own their visual background. ++ [textStorage enumerateAttribute:NSAttachmentAttributeName ++ inRange:range ++ options:0 ++ usingBlock:^(id attachment, NSRange uncoveredRange, BOOL *innerStop) { ++ if ([attachment isKindOfClass:ENRMLinkPillAttachment.class]) ++ return; ++ if (NSIntersectionRange(uncoveredRange, charRange).length == 0) ++ return; ++ [self drawCodeBackgroundForRange:uncoveredRange ++ layoutManager:layoutManager ++ textContainer:textContainer ++ atPoint:origin ++ backgroundColor:backgroundColor ++ borderColor:self->_config.codeBorderColor]; ++ }]; ++#else ++ [self drawCodeBackgroundForRange:range ++ layoutManager:layoutManager ++ textContainer:textContainer ++ atPoint:origin ++ backgroundColor:backgroundColor ++ borderColor:self->_config.codeBorderColor]; ++#endif + }]; + } + +diff --git a/ios/utils/ENRMDocumentAssets.h b/ios/utils/ENRMDocumentAssets.h +new file mode 100644 +index 0000000000000000000000000000000000000000..c0709eb7376a4ada87a32d5cb5da08db5ecb4fb7 +--- /dev/null ++++ b/ios/utils/ENRMDocumentAssets.h +@@ -0,0 +1,68 @@ ++#pragma once ++#import "ENRMImageSources.h" ++#import "MarkdownASTNode.h" ++#import "StyleConfig.h" ++ ++// Traverses the accepted native AST in source order. IDs identify occurrences, ++// including links, so duplicate URLs remain independent. ++FOUNDATION_EXPORT NSArray *ENRMPrepareDocumentAssets(MarkdownASTNode *ast, BOOL enableMediaSlots, ++ BOOL decisionsAccepted, NSDictionary *overrides); ++FOUNDATION_EXPORT CGFloat ENRMMediaSlotHeight(MarkdownASTNode *node, CGFloat width, StyleConfig *config); ++ ++#ifdef __cplusplus ++#include ++#include ++#include ++#include ++#include ++template struct ENRMHasMediaSlots : std::false_type {}; ++template ++struct ENRMHasMediaSlots().mediaOverrides)>> : std::true_type {}; ++ ++template static inline NSDictionary *ENRMMediaOverridesFromProps(const PropsT &props) ++{ ++ NSMutableDictionary *overrides = [NSMutableDictionary dictionary]; ++ for (const auto &item : props.mediaOverrides) { ++ if (!std::isfinite(item.height) || item.height < 0 || !std::isfinite(item.width) || item.width < 0) ++ continue; ++ NSString *identifier = [[NSString alloc] initWithUTF8String:item.id.c_str()]; ++ overrides[identifier] = @{ ++ @"height" : @(item.height), ++ @"width" : @(item.width), ++ @"url" : [[NSString alloc] initWithUTF8String:item.url.c_str()], ++ @"kind" : [[NSString alloc] initWithUTF8String:item.kind.c_str()], ++ @"anchor" : [[NSString alloc] initWithUTF8String:item.anchor.c_str()] ++ }; ++ } ++ return overrides; ++} ++ ++template static inline size_t ENRMMediaPropsFingerprint(const PropsT &props) ++{ ++ size_t hash = 0; ++ if constexpr (ENRMHasMediaSlots::value) { ++ auto mix = [&](size_t value) { hash ^= value + 0x9e3779b9 + (hash << 6) + (hash >> 2); }; ++ mix(std::hash{}(props.enableMediaSlots)); ++ mix(std::hash{}(props.documentRevision)); ++ mix(std::hash{}(props.mediaOverridesRevision)); ++ for (const auto &item : props.mediaOverrides) { ++ mix(std::hash{}(item.id)); ++ mix(std::hash{}(item.url)); ++ mix(std::hash{}(item.kind)); ++ mix(std::hash{}(item.anchor)); ++ mix(std::hash{}(item.height)); ++ mix(std::hash{}(item.width)); ++ } ++ } ++ return hash ^ ENRMImageSourcesFingerprint(props); ++} ++#endif ++ ++#ifdef __cplusplus ++template static inline bool ENRMMediaSlotsEnabled(const PropsT &props) ++{ ++ if constexpr (ENRMHasMediaSlots::value) ++ return props.enableMediaSlots; ++ return false; ++} ++#endif +diff --git a/ios/utils/ENRMDocumentAssets.m b/ios/utils/ENRMDocumentAssets.m +new file mode 100644 +index 0000000000000000000000000000000000000000..3e643ad0dc76d650aaee75afed741de80fe686d6 +--- /dev/null ++++ b/ios/utils/ENRMDocumentAssets.m +@@ -0,0 +1,94 @@ ++#import "ENRMDocumentAssets.h" ++#import ++ ++static NSString *ENRMAssetText(MarkdownASTNode *node) ++{ ++ NSMutableString *text = [NSMutableString stringWithString:node.content ?: @""]; ++ for (MarkdownASTNode *child in node.children) ++ [text appendString:ENRMAssetText(child)]; ++ return text; ++} ++ ++static void ENRMVisitAssets(MarkdownASTNode *node, MarkdownASTNode *parent, MarkdownASTNode *root, NSString *placement, ++ NSString *anchor, BOOL segmentChild, BOOL parentIsSegmentChild, NSMutableArray *assets, ++ BOOL enableSlots, BOOL decisionsAccepted, NSDictionary *overrides) ++{ ++ if (node.type == MarkdownNodeTypeTable) ++ placement = @"table"; ++ else if (node.type == MarkdownNodeTypeOrderedList || node.type == MarkdownNodeTypeUnorderedList) ++ placement = @"list"; ++ else if (node.type == MarkdownNodeTypeBlockquote || node.type == MarkdownNodeTypeAdmonition) ++ placement = @"blockquote"; ++ ++ BOOL isImage = node.type == MarkdownNodeTypeImage; ++ BOOL isVideo = node.type == MarkdownNodeTypeVideo; ++ if (isImage || isVideo || node.type == MarkdownNodeTypeLink) { ++ BOOL blockImage = ++ isImage && parent.type == MarkdownNodeTypeParagraph && parent.children.count == 1 && parentIsSegmentChild; ++ BOOL eligible = blockImage || (isVideo && segmentChild); ++ NSString *identifier = [NSString stringWithFormat:@"asset-%lu", (unsigned long)assets.count]; ++ NSString *assetPlacement = eligible && ![placement isEqualToString:@"blockquote"] ? @"block" : placement; ++ NSString *assetAnchor = ++ blockImage ? [anchor substringToIndex:[anchor rangeOfString:@"." options:NSBackwardsSearch].location] : anchor; ++ NSString *kind = isImage ? @"image" : (isVideo ? @"video" : @"link"); ++ NSString *url = node.attributes[@"url"] ?: @""; ++ [assets addObject:@{ ++ @"id" : identifier, ++ @"kind" : kind, ++ @"url" : url, ++ @"anchor" : assetAnchor, ++ @"altText" : ++ [ENRMAssetText(node) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]], ++ @"title" : node.attributes[@"title"] ?: @"", ++ @"placement" : assetPlacement, ++ @"eligible" : @(eligible) ++ }]; ++ NSDictionary *override = overrides[identifier]; ++ if (eligible && enableSlots && (!decisionsAccepted || override)) { ++ MarkdownASTNode *slot = blockImage ? parent : node; ++ slot.attributes[@"_enrmMediaSlot"] = identifier; ++ slot.attributes[@"_enrmMediaKind"] = isVideo ? @"video" : @"image"; ++ BOOL matchesIdentity = override && [override[@"url"] isEqualToString:url] && ++ [override[@"kind"] isEqualToString:kind] && ++ [override[@"anchor"] isEqualToString:assetAnchor]; ++ // JS carries overrides only across safe trailing appends. The accepted ++ // native parse still verifies occurrence identity before using its height. ++ if (matchesIdentity) { ++ slot.attributes[@"_enrmMediaHeight"] = [override[@"height"] stringValue]; ++ slot.attributes[@"_enrmMediaWidth"] = [override[@"width"] stringValue]; ++ } ++ } ++ } ++ // Only document/quote segment containers can host slots. Once traversal enters ++ // a list, table, paragraph, or link, descendant quotes stay in the text path. ++ BOOL childrenAreSegmentChildren = ++ node == root || ++ (segmentChild && (node.type == MarkdownNodeTypeBlockquote || node.type == MarkdownNodeTypeAdmonition)); ++ [node.children enumerateObjectsUsingBlock:^(MarkdownASTNode *child, NSUInteger index, BOOL *stop) { ++ NSString *childAnchor = anchor.length > 0 ? [anchor stringByAppendingFormat:@".%lu", (unsigned long)index] ++ : [NSString stringWithFormat:@"%lu", (unsigned long)index]; ++ ENRMVisitAssets(child, node, root, placement, childAnchor, childrenAreSegmentChildren, segmentChild, assets, ++ enableSlots, decisionsAccepted, overrides); ++ }]; ++} ++ ++NSArray *ENRMPrepareDocumentAssets(MarkdownASTNode *ast, BOOL enableMediaSlots, BOOL decisionsAccepted, ++ NSDictionary *overrides) ++{ ++ NSMutableArray *assets = [NSMutableArray array]; ++ ENRMVisitAssets(ast, nil, ast, @"inline", @"0", NO, NO, assets, enableMediaSlots, decisionsAccepted, overrides); ++ return assets; ++} ++ ++CGFloat ENRMMediaSlotHeight(MarkdownASTNode *node, CGFloat width, StyleConfig *config) ++{ ++ NSString *height = node.attributes[@"_enrmMediaHeight"]; ++ CGFloat measuredWidth = [node.attributes[@"_enrmMediaWidth"] doubleValue]; ++ if (height && (measuredWidth == 0 || fabs(measuredWidth - width) < 0.5)) ++ return MAX(0, height.doubleValue); ++ if ([node.attributes[@"_enrmMediaKind"] isEqualToString:@"video"]) ++ return width / MAX(config.videoAspectRatio, 0.01); ++ if (config.imageAspectRatio > 0) ++ return width / config.imageAspectRatio; ++ return config.imageMaxHeight > 0 ? config.imageMaxHeight : MAX(config.imageHeight, 1); ++} +diff --git a/ios/utils/ENRMImageDownloader.h b/ios/utils/ENRMImageDownloader.h +index af39f58ac2ee4cbd0431b07f2851fefe580a982b..434cca4d3b275ab954a05033406b4d776a687e59 100644 +--- a/ios/utils/ENRMImageDownloader.h ++++ b/ios/utils/ENRMImageDownloader.h +@@ -11,7 +11,7 @@ typedef void (^ENRMImageDownloadCompletion)(RCTUIImage *_Nullable image); + * pairs, so the same URL fetched with different headers is cached and + * deduplicated separately without embedding header values in the key. + */ +-NSString *ENRMImageCacheKey(NSString *url, NSDictionary *_Nullable headers); ++FOUNDATION_EXPORT NSString *ENRMImageCacheKey(NSString *url, NSDictionary *_Nullable headers); + + @interface ENRMImageDownloader : NSObject + +diff --git a/ios/utils/ENRMImageDownloader.m b/ios/utils/ENRMImageDownloader.m +index 974154201f4d923f61b19c8814b17a02fc335f9d..d9b85049972861afde530b5e766c3ee908383063 100644 +--- a/ios/utils/ENRMImageDownloader.m ++++ b/ios/utils/ENRMImageDownloader.m +@@ -38,6 +38,7 @@ NSString *ENRMImageCacheKey(NSString *url, NSDictionary + + @implementation ENRMImageDownloader { + NSURLSession *_session; ++ NSURLSession *_headerSession; + NSMutableDictionary *> *_inFlightRequests; + } + +@@ -61,6 +62,12 @@ NSString *ENRMImageCacheKey(NSString *url, NSDictionary + config.timeoutIntervalForRequest = 15; + config.timeoutIntervalForResource = 30; + _session = [NSURLSession sessionWithConfiguration:config]; ++ // URLCache does not provide our effective URI/header identity. Header-bearing ++ // requests use only the decoded cache above, which includes every header. ++ NSURLSessionConfiguration *headerConfig = [config copy]; ++ headerConfig.URLCache = nil; ++ headerConfig.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData; ++ _headerSession = [NSURLSession sessionWithConfiguration:headerConfig]; + _inFlightRequests = [NSMutableDictionary dictionary]; + } + return self; +@@ -76,7 +83,7 @@ NSString *ENRMImageCacheKey(NSString *url, NSDictionary + } + + BOOL isLocal = ENRMIsLocalImageURL(url); +- NSString *cacheKey = isLocal ? url : ENRMImageCacheKey(url, headers); ++ NSString *cacheKey = ENRMImageCacheKey(url, headers); + + RCTUIImage *cached = [[ENRMImageAttachment originalImageCache] objectForKey:cacheKey]; + if (cached) { +@@ -113,22 +120,25 @@ NSString *ENRMImageCacheKey(NSString *url, NSDictionary + [request setValue:value forHTTPHeaderField:name]; + }]; + +- [[_session dataTaskWithRequest:request +- completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { ++ NSURLSession *session = headers.count > 0 ? _headerSession : _session; ++ if (headers.count > 0) ++ request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData; ++ [[session dataTaskWithRequest:request ++ completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + #if !TARGET_OS_OSX +- RCTUIImage *image = (data && !error) ? [RCTUIImage imageWithData:data] : nil; ++ RCTUIImage *image = (data && !error) ? [RCTUIImage imageWithData:data] : nil; + #else + RCTUIImage *image = (data && !error) ? [[RCTUIImage alloc] initWithData:data] : nil; + #endif + +- if (image) { +- [[ENRMImageAttachment originalImageCache] setObject:image +- forKey:cacheKey +- cost:ENRMImageByteCost(image)]; +- } ++ if (image) { ++ [[ENRMImageAttachment originalImageCache] setObject:image ++ forKey:cacheKey ++ cost:ENRMImageByteCost(image)]; ++ } + +- [self dispatchCallbacksForKey:cacheKey image:image]; +- }] resume]; ++ [self dispatchCallbacksForKey:cacheKey image:image]; ++ }] resume]; + } + + - (void)dispatchCallbacksForKey:(NSString *)cacheKey image:(RCTUIImage *_Nullable)image +diff --git a/ios/utils/ENRMImageSources.h b/ios/utils/ENRMImageSources.h +new file mode 100644 +index 0000000000000000000000000000000000000000..5ceba7b78d29ca90f1024ff487fa5239d5e85227 +--- /dev/null ++++ b/ios/utils/ENRMImageSources.h +@@ -0,0 +1,72 @@ ++#pragma once ++#import "ImageRequestHeaderUtils.h" ++#import "MarkdownASTNode.h" ++ ++// Annotates only transport on the accepted AST. The manifest owns occurrence identity. ++FOUNDATION_EXPORT void ENRMPrepareImageSources(MarkdownASTNode *ast, NSArray *assets, BOOL enabled, ++ BOOL decisionsAccepted, NSDictionary *sources); ++FOUNDATION_EXPORT NSDictionary *ENRMImageSourceDecisionForNode(MarkdownASTNode *node); ++// Render signatures include transport state without changing semantic AST signatures. ++FOUNDATION_EXPORT uint64_t ENRMImageSourceSignatureForNode(MarkdownASTNode *node); ++FOUNDATION_EXPORT uint64_t ENRMImageSourceSignatureForNodes(NSArray *nodes); ++FOUNDATION_EXPORT NSDictionary *ENRMMergeImageRequestHeaders(NSDictionary *documentHeaders, ++ NSDictionary *sourceHeaders); ++ ++#ifdef __cplusplus ++#include ++#include ++#include ++#include ++template struct ENRMHasImageSources : std::false_type {}; ++template ++struct ENRMHasImageSources().imageSources)>> : std::true_type {}; ++ ++template static inline NSDictionary *ENRMImageSourcesFromProps(const PropsT &props) ++{ ++ NSMutableDictionary *sources = [NSMutableDictionary dictionary]; ++ for (const auto &item : props.imageSources) { ++ sources[@(item.id.c_str())] = @{ ++ @"id" : @(item.id.c_str()), ++ @"url" : @(item.url.c_str()), ++ @"anchor" : @(item.anchor.c_str()), ++ @"uri" : @(item.uri.c_str()), ++ @"useDefault" : @(item.useDefault), ++ @"headers" : ENRMImageRequestHeadersFromProps(item.headers) ?: @{} ++ }; ++ } ++ return sources; ++} ++ ++template static inline BOOL ENRMImageSourcesAccepted(const PropsT &props) ++{ ++ return props.imageSourcesRevision >= props.imageSourcesContinuityStart && ++ props.imageSourcesRevision <= props.documentRevision; ++} ++ ++template static inline size_t ENRMImageSourcesFingerprint(const PropsT &props) ++{ ++ size_t hash = 0; ++ if constexpr (ENRMHasImageSources::value) { ++ auto mix = [&](size_t value) { hash ^= value + 0x9e3779b9 + (hash << 6) + (hash >> 2); }; ++ mix(std::hash{}(props.enableImageSourceResolution)); ++ for (const auto &header : props.imageRequestHeaders) { ++ mix(std::hash{}(header.name)); ++ mix(std::hash{}(header.value)); ++ } ++ mix(std::hash{}(props.imageSourcesRevision)); ++ mix(std::hash{}(props.imageSourcesContinuityStart)); ++ for (const auto &item : props.imageSources) { ++ mix(std::hash{}(item.id)); ++ mix(std::hash{}(item.url)); ++ mix(std::hash{}(item.anchor)); ++ mix(std::hash{}(item.uri)); ++ mix(std::hash{}(item.useDefault)); ++ for (const auto &header : item.headers) { ++ mix(std::hash{}(header.name)); ++ mix(std::hash{}(header.value)); ++ } ++ } ++ } ++ return hash; ++} ++#endif +diff --git a/ios/utils/ENRMImageSources.m b/ios/utils/ENRMImageSources.m +new file mode 100644 +index 0000000000000000000000000000000000000000..fb8faac1698315f8624eccd41d673dbde5373aca +--- /dev/null ++++ b/ios/utils/ENRMImageSources.m +@@ -0,0 +1,120 @@ ++#import "ENRMImageSources.h" ++#import ++ ++static char ENRMImageSourceDecisionKey; ++ ++NSDictionary *ENRMImageSourceDecisionForNode(MarkdownASTNode *node) ++{ ++ return objc_getAssociatedObject(node, &ENRMImageSourceDecisionKey); ++} ++ ++NSDictionary *ENRMMergeImageRequestHeaders(NSDictionary *documentHeaders, ++ NSDictionary *sourceHeaders) ++{ ++ NSMutableDictionary *merged = [NSMutableDictionary dictionary]; ++ // Lowercase keys make overrides and cache identity independent of HTTP header casing. ++ for (NSString *name in documentHeaders) ++ merged[name.lowercaseString] = documentHeaders[name]; ++ for (NSString *name in sourceHeaders) ++ merged[name.lowercaseString] = sourceHeaders[name]; ++ return merged; ++} ++ ++static void ENRMVisitImageSources(MarkdownASTNode *node, NSArray *assets, NSDictionary *sources, ++ BOOL decisionsAccepted, NSUInteger *occurrence) ++{ ++ // Match the accepted collector's image/video/link occurrence order. No source parse. ++ if (node.type == MarkdownNodeTypeImage || node.type == MarkdownNodeTypeVideo || node.type == MarkdownNodeTypeLink) { ++ NSUInteger index = (*occurrence)++; ++ if (node.type == MarkdownNodeTypeImage) { ++ NSDictionary *decision = @{@"pending" : @YES}; ++ NSDictionary *asset = index < assets.count ? assets[index] : nil; ++ NSDictionary *source = asset ? sources[asset[@"id"]] : nil; ++ BOOL matches = ++ decisionsAccepted && [asset[@"kind"] isEqualToString:@"image"] && ++ [source[@"id"] isEqualToString:asset[@"id"]] && [asset[@"url"] isEqualToString:node.attributes[@"url"]] && ++ [source[@"url"] isEqualToString:asset[@"url"]] && [source[@"anchor"] isEqualToString:asset[@"anchor"]]; ++ if (matches && ([source[@"useDefault"] boolValue] || [source[@"uri"] length] > 0)) { ++ decision = [source[@"useDefault"] boolValue] ++ ? @{@"pending" : @NO} ++ : @{@"pending" : @NO, ++ @"uri" : source[@"uri"], ++ @"headers" : source[@"headers"] ?: @{}}; ++ } ++ objc_setAssociatedObject(node, &ENRMImageSourceDecisionKey, decision, OBJC_ASSOCIATION_RETAIN_NONATOMIC); ++ } ++ } ++ for (MarkdownASTNode *child in node.children) ++ ENRMVisitImageSources(child, assets, sources, decisionsAccepted, occurrence); ++} ++ ++static void ENRMClearImageSources(MarkdownASTNode *node) ++{ ++ objc_setAssociatedObject(node, &ENRMImageSourceDecisionKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); ++ for (MarkdownASTNode *child in node.children) ++ ENRMClearImageSources(child); ++} ++ ++void ENRMPrepareImageSources(MarkdownASTNode *ast, NSArray *assets, BOOL enabled, ++ BOOL decisionsAccepted, NSDictionary *sources) ++{ ++ if (!enabled) { ++ ENRMClearImageSources(ast); ++ return; ++ } ++ NSUInteger occurrence = 0; ++ ENRMVisitImageSources(ast, assets, sources, decisionsAccepted, &occurrence); ++} ++ ++static uint64_t ENRMSourceMixUInt64(uint64_t hash, uint64_t value) ++{ ++ for (NSUInteger i = 0; i < 8; i++) { ++ hash ^= (uint8_t)(value & 0xFF); ++ hash *= 1099511628211ULL; ++ value >>= 8; ++ } ++ return hash; ++} ++ ++static uint64_t ENRMSourceMixString(uint64_t hash, NSString *value) ++{ ++ NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding]; ++ hash = ENRMSourceMixUInt64(hash, data.length); ++ const uint8_t *bytes = data.bytes; ++ for (NSUInteger i = 0; i < data.length; i++) { ++ hash ^= bytes[i]; ++ hash *= 1099511628211ULL; ++ } ++ return hash; ++} ++ ++uint64_t ENRMImageSourceSignatureForNode(MarkdownASTNode *node) ++{ ++ NSDictionary *source = ENRMImageSourceDecisionForNode(node); ++ uint64_t hash = 0; ++ if (source) { ++ hash = ENRMSourceMixUInt64(14695981039346656037ULL, [source[@"pending"] boolValue] ? 1 : 2); ++ hash = ENRMSourceMixString(hash, source[@"uri"] ?: @""); ++ NSDictionary *headers = ENRMMergeImageRequestHeaders(nil, source[@"headers"]); ++ for (NSString *name in [headers.allKeys sortedArrayUsingSelector:@selector(compare:)]) { ++ hash = ENRMSourceMixString(hash, name); ++ hash = ENRMSourceMixString(hash, headers[name]); ++ } ++ } ++ uint64_t children = ENRMImageSourceSignatureForNodes(node.children); ++ if (children) ++ hash = ENRMSourceMixUInt64(hash ?: 14695981039346656037ULL, children); ++ return hash; ++} ++ ++uint64_t ENRMImageSourceSignatureForNodes(NSArray *nodes) ++{ ++ uint64_t hash = 14695981039346656037ULL; ++ BOOL hasSources = NO; ++ for (MarkdownASTNode *node in nodes) { ++ uint64_t source = ENRMImageSourceSignatureForNode(node); ++ hasSources |= source != 0; ++ hash = ENRMSourceMixUInt64(hash, source); ++ } ++ return hasSources ? hash : 0; ++} +diff --git a/ios/utils/ENRMTextViewSetup.h b/ios/utils/ENRMTextViewSetup.h +index 0151d0fc54691c34348be6e77febd693a725c3fa..9e74e78e20958cc393988b85a668babe6be0ce58 100644 +--- a/ios/utils/ENRMTextViewSetup.h ++++ b/ios/utils/ENRMTextViewSetup.h +@@ -1,4 +1,6 @@ + #pragma once ++#import "ENRMLinkPillAttachment.h" ++#import "ENRMLinkPillTextStorage.h" + #import "ENRMUIKit.h" + #import "LastElementUtils.h" + #import "StyleConfig.h" +@@ -15,6 +17,9 @@ static inline void ENRMAttachLayoutManager(ENRMPlatformTextView *textView, Style + return; + } + layoutManager.allowsNonContiguousLayout = NO; ++#if !TARGET_OS_OSX ++ layoutManager.delegate = ENRMLinkPillLayoutDelegate.shared; ++#endif + object_setClass(layoutManager, [TextViewLayoutManager class]); + if (config != nil) { + [layoutManager setValue:config forKey:@"config"]; +@@ -26,6 +31,9 @@ static inline void ENRMDetachLayoutManager(ENRMPlatformTextView *textView) + NSLayoutManager *layoutManager = textView.layoutManager; + if (layoutManager != nil && [object_getClass(layoutManager) isEqual:[TextViewLayoutManager class]]) { + [layoutManager setValue:nil forKey:@"config"]; ++#if !TARGET_OS_OSX ++ layoutManager.delegate = nil; ++#endif + object_setClass(layoutManager, [NSLayoutManager class]); + } + } +diff --git a/ios/utils/MarkdownASTSerializer.m b/ios/utils/MarkdownASTSerializer.m +index 01b9054bc29b0608594c08248acc0206d0f5d1c2..c6ce7efb444190450b9430fa31e2ea93f6500fc4 100644 +--- a/ios/utils/MarkdownASTSerializer.m ++++ b/ios/utils/MarkdownASTSerializer.m +@@ -81,6 +81,10 @@ static void serializeNode(MarkdownASTNode *node, NSMutableString *buffer) + break; + + case MarkdownNodeTypeLink: { ++ if ([node.attributes[@"recognizedLink"] isEqualToString:@"true"]) { ++ serializeChildren(node, buffer); ++ break; ++ } + NSString *url = node.attributes[@"url"] ?: @""; + [buffer appendString:@"["]; + serializeChildren(node, buffer); diff --git a/ios/utils/MarkdownExtractor.m b/ios/utils/MarkdownExtractor.m -index eb4482c6cdf842dfbd952b8c6cdb9ce836579b53..c6dcd1f6e0807f3561830ff3fa88fde8b204d7a8 100644 +index eb4482c6cdf842dfbd952b8c6cdb9ce836579b53..ff3426ea7e13a9503f3fe309df84d45521a73ac4 100644 --- a/ios/utils/MarkdownExtractor.m +++ b/ios/utils/MarkdownExtractor.m -@@ -1,4 +1,5 @@ +@@ -1,7 +1,11 @@ #import "MarkdownExtractor.h" +#import "BaselineShiftTextAttributes.h" #import "BlockquoteBorder.h" ++#import "CodeBackground.h" #import "ENRMFeatureFlags.h" #import "ENRMImageAttachment.h" -@@ -300,9 +301,11 @@ NSString *_Nullable extractMarkdownFromAttributedString(NSAttributedString *attr ++#import "ENRMLinkPillAttachment.h" ++#import "ENRMTextLinkAttributes.h" + #import "ENRMUIKit.h" + #import "HighlightRenderer.h" + #include +@@ -126,6 +130,17 @@ NSString *_Nullable extractMarkdownFromAttributedString(NSAttributedString *attr + } + + range.length = MIN(range.length, attributedText.length - range.location); ++#if !TARGET_OS_OSX ++ NSMutableAttributedString *semanticText = [attributedText mutableCopy]; ++ [attributedText enumerateAttribute:NSAttachmentAttributeName ++ inRange:range ++ options:0 ++ usingBlock:^(id value, NSRange attachmentRange, BOOL *stop) { ++ if ([value isKindOfClass:ENRMLinkPillAttachment.class]) ++ [semanticText removeAttribute:NSAttachmentAttributeName range:attachmentRange]; ++ }]; ++ attributedText = semanticText; ++#endif + + NSMutableString *result = [NSMutableString string]; + +@@ -294,18 +309,25 @@ NSString *_Nullable extractMarkdownFromAttributedString(NSAttributedString *attr + + // Inline formatting + BOOL isBold, isItalic, isMonospace; ++ BOOL recognizedLink = [attrs[ENRMRecognizedLinkAttributeName] boolValue]; + extractFontTraits(attrs, &isBold, &isItalic, &isMonospace); ++ if (recognizedLink) ++ isMonospace = [attrs[CodeAttributeName] boolValue]; + + NSNumber *strikethroughStyle = attrs[NSStrikethroughStyleAttributeName]; BOOL isStrikethrough = (strikethroughStyle != nil && [strikethroughStyle integerValue] != 0); - NSNumber *underlineStyle = attrs[NSUnderlineStyleAttributeName]; +- NSNumber *underlineStyle = attrs[NSUnderlineStyleAttributeName]; ++ NSNumber *underlineStyle = recognizedLink ++ ? attrs[ENRMRecognizedLinkOriginalUnderlineAttributeName] ++ : attrs[NSUnderlineStyleAttributeName]; BOOL isUnderline = (underlineStyle != nil && [underlineStyle integerValue] != 0); - NSNumber *baselineOffset = attrs[NSBaselineOffsetAttributeName]; - BOOL isSuperscript = baselineOffset != nil && [baselineOffset doubleValue] > 0; @@ -109,4 +7018,2696 @@ index eb4482c6cdf842dfbd952b8c6cdb9ce836579b53..c6dcd1f6e0807f3561830ff3fa88fde8 + BOOL isSubscript = [script isEqualToString:@"subscript"]; BOOL isHighlight = [attrs[HighlightAttributeName] boolValue]; - NSString *linkURL = attrs[NSLinkAttributeName]; +- NSString *linkURL = attrs[NSLinkAttributeName]; ++ NSString *linkURL = recognizedLink ? nil : attrs[NSLinkAttributeName]; + NSString *segment = + applyInlineFormatting(text, isBold, isItalic, isMonospace, isStrikethrough, isUnderline, + isSuperscript, isSubscript, isHighlight, linkURL); +diff --git a/ios/utils/ParagraphStyleUtils.m b/ios/utils/ParagraphStyleUtils.m +index c625941ed8e0e0bf2fea05c87fb121cdb71b83b1..85e5223d6b66993df784efd49b5964cc542cd043 100644 +--- a/ios/utils/ParagraphStyleUtils.m ++++ b/ios/utils/ParagraphStyleUtils.m +@@ -1,6 +1,7 @@ + #import "ParagraphStyleUtils.h" + #import "ENRMFeatureFlags.h" + #import "ENRMImageAttachment.h" ++#import "ENRMLinkPillAttachment.h" + #import "LastElementUtils.h" + #import + +@@ -299,12 +300,24 @@ void applyLineHeight(NSMutableAttributedString *output, NSRange range, CGFloat l + }]; + #endif + ++ __block BOOL hasPill = NO; ++#if !TARGET_OS_OSX ++ [output enumerateAttribute:NSAttachmentAttributeName ++ inRange:range ++ options:0 ++ usingBlock:^(id value, NSRange subrange, BOOL *stop) { ++ if ([value isKindOfClass:ENRMLinkPillAttachment.class]) { ++ hasPill = YES; ++ *stop = YES; ++ } ++ }]; ++#endif + BOOL hasBlockImage = ENRMRangeContainsBlockImage(output, range); + + NSMutableParagraphStyle *style = getOrCreateParagraphStyle(output, range.location); + + style.minimumLineHeight = lineHeight; +- style.maximumLineHeight = (hasMath || hasBlockImage) ? 0 : lineHeight; ++ style.maximumLineHeight = (hasMath || hasBlockImage || hasPill) ? 0 : lineHeight; + + [output addAttribute:NSParagraphStyleAttributeName value:style range:range]; + } +@@ -358,6 +371,17 @@ void applyBaselineOffset(NSMutableAttributedString *output, NSRange range) + }]; + + CGFloat contentLineHeight = textLineHeight; ++#if !TARGET_OS_OSX ++ __block CGFloat pillBoxHeight = 0; ++ [output enumerateAttribute:NSAttachmentAttributeName ++ inRange:range ++ options:0 ++ usingBlock:^(id value, NSRange subrange, BOOL *stop) { ++ if ([value isKindOfClass:ENRMLinkPillAttachment.class]) ++ pillBoxHeight = MAX(pillBoxHeight, ((ENRMLinkPillAttachment *)value).boxHeight); ++ }]; ++ contentLineHeight = MAX(contentLineHeight, pillBoxHeight); ++#endif + + #if ENRICHED_MARKDOWN_MATH + // Math only grows the content height, so measure it (parsing LaTeX) only when text +@@ -372,7 +396,7 @@ void applyBaselineOffset(NSMutableAttributedString *output, NSRange range) + mathBoxHeight = MAX(((ENRMMathInlineAttachment *)value).boxHeight, mathBoxHeight); + } + }]; +- contentLineHeight = MAX(textLineHeight, mathBoxHeight); ++ contentLineHeight = MAX(contentLineHeight, mathBoxHeight); + } + #endif + +diff --git a/ios/utils/RTFExportUtils.m b/ios/utils/RTFExportUtils.m +index cf64c1a8080b922aabbd0f2628990204d96ac282..b00ead9106b36542e2ae3e1b267b26601392c68a 100644 +--- a/ios/utils/RTFExportUtils.m ++++ b/ios/utils/RTFExportUtils.m +@@ -1,6 +1,7 @@ + #import "RTFExportUtils.h" + #import "BlockquoteBorder.h" + #import "CodeBackground.h" ++#import "ENRMLinkPillAttachment.h" + #import "LastElementUtils.h" + #import "ListItemRenderer.h" + #import "RenderContext.h" +@@ -282,6 +283,15 @@ NSAttributedString *prepareAttributedStringForRTFExport(NSAttributedString *attr + return attributedString; + + NSMutableAttributedString *prepared = [attributedString mutableCopy]; ++#if !TARGET_OS_OSX ++ [attributedString enumerateAttribute:NSAttachmentAttributeName ++ inRange:NSMakeRange(0, attributedString.length) ++ options:0 ++ usingBlock:^(id value, NSRange range, BOOL *stop) { ++ if ([value isKindOfClass:ENRMLinkPillAttachment.class]) ++ [prepared removeAttribute:NSAttachmentAttributeName range:range]; ++ }]; ++#endif + + RCTUIColor *codeBgColor = [styleConfig codeBackgroundColor]; + RCTUIColor *codeBlockBgColor = [styleConfig codeBlockBackgroundColor]; +diff --git a/ios/utils/StylePropsUtils.h b/ios/utils/StylePropsUtils.h +index 1c34ada6dd16daa253e2b00054fe60a4d38f8ca4..8926a0aef6fe59cbbf81a5ed1c4537cbfc228bd2 100644 +--- a/ios/utils/StylePropsUtils.h ++++ b/ios/utils/StylePropsUtils.h +@@ -560,7 +560,15 @@ BOOL applyMarkdownStyleToConfig(StyleConfig *config, const MarkdownStyle &newSty + const auto &newVariant = newStyle.linkVariants[i]; + const auto &oldVariant = oldStyle.linkVariants[i]; + if (newVariant.pattern != oldVariant.pattern || newVariant.color != oldVariant.color || +- newVariant.underline != oldVariant.underline || newVariant.backgroundColor != oldVariant.backgroundColor) { ++ newVariant.underline != oldVariant.underline || newVariant.backgroundColor != oldVariant.backgroundColor || ++ newVariant.fontFamily != oldVariant.fontFamily || newVariant.pill != oldVariant.pill || ++ newVariant.label != oldVariant.label || newVariant.iconUri != oldVariant.iconUri || ++ newVariant.iconTintColor != oldVariant.iconTintColor || ++ newVariant.borderRadius != oldVariant.borderRadius || ++ newVariant.paddingHorizontal != oldVariant.paddingHorizontal || ++ newVariant.paddingVertical != oldVariant.paddingVertical || ++ newVariant.borderWidth != oldVariant.borderWidth || newVariant.borderColor != oldVariant.borderColor || ++ newVariant.maxWidth != oldVariant.maxWidth) { + linkVariantsChanged = YES; + break; + } +@@ -573,6 +581,17 @@ BOOL applyMarkdownStyleToConfig(StyleConfig *config, const MarkdownStyle &newSty + variant.pattern = [[NSString alloc] initWithUTF8String:entry.pattern.c_str()]; + variant.color = RCTUIColorFromSharedColor(entry.color); + variant.underline = entry.underline; ++ variant.fontFamily = [[NSString alloc] initWithUTF8String:entry.fontFamily.c_str()]; ++ variant.pill = entry.pill; ++ variant.label = [[NSString alloc] initWithUTF8String:entry.label.c_str()]; ++ variant.iconUri = [[NSString alloc] initWithUTF8String:entry.iconUri.c_str()]; ++ variant.iconTintColor = entry.iconTintColor ? RCTUIColorFromSharedColor(entry.iconTintColor) : nil; ++ variant.borderRadius = entry.borderRadius; ++ variant.paddingHorizontal = entry.paddingHorizontal; ++ variant.paddingVertical = entry.paddingVertical; ++ variant.borderWidth = entry.borderWidth; ++ variant.borderColor = RCTUIColorFromSharedColor(entry.borderColor); ++ variant.maxWidth = entry.maxWidth; + RCTUIColor *backgroundColor = RCTUIColorFromSharedColor(entry.backgroundColor); + variant.backgroundColor = CGColorGetAlpha(backgroundColor.CGColor) > 0 ? backgroundColor : nil; + [variants addObject:variant]; +diff --git a/ios/views/EnrichedMarkdownInternalText.m b/ios/views/EnrichedMarkdownInternalText.m +index 93eef7ac4edf45f001a93ebb230588817e3e921b..0696e112f693e93e6674472ae734272ce9e8bbee 100644 +--- a/ios/views/EnrichedMarkdownInternalText.m ++++ b/ios/views/EnrichedMarkdownInternalText.m +@@ -35,7 +35,7 @@ + - (void)setupTextView + { + #if !TARGET_OS_OSX +- _textView = [[ENRMPlatformTextView alloc] init]; ++ _textView = ENRMCreateMarkdownTextView(); + _textView.text = @""; + #else + _textView = [[ENRMContextMenuTextView alloc] init]; +diff --git a/lib/module/EnrichedMarkdownNativeComponent.ts b/lib/module/EnrichedMarkdownNativeComponent.ts +index 66d200af977b0c9a4086f4e621bb26f8400eb68b..db8e832e498ffa1fa1482f68e40d387421761a34 100644 +--- a/lib/module/EnrichedMarkdownNativeComponent.ts ++++ b/lib/module/EnrichedMarkdownNativeComponent.ts +@@ -97,6 +97,17 @@ interface LinkVariantEntryInternal { + color: ColorValue; + underline: boolean; + backgroundColor: ColorValue; ++ fontFamily: string; ++ pill: boolean; ++ label: string; ++ iconUri: string; ++ iconTintColor?: ColorValue; ++ borderRadius: CodegenTypes.Float; ++ paddingHorizontal: CodegenTypes.Float; ++ paddingVertical: CodegenTypes.Float; ++ borderWidth: CodegenTypes.Float; ++ borderColor: ColorValue; ++ maxWidth: CodegenTypes.Float; + } + + interface StrongStyleInternal { +@@ -406,7 +417,92 @@ interface StreamingConfigInternal { + codeBlockMode: string; + } + ++// Same transport as EnrichedMarkdownTextInput.linkRegex. Kept local for codegen. ++interface TextLinkNativeRegex { ++ pattern: string; ++ caseInsensitive: boolean; ++ dotAll: boolean; ++ isDisabled: boolean; ++ isDefault: boolean; ++} ++ ++export interface DocumentAssetInternal { ++ anchor: string; ++ id: string; ++ kind: string; ++ url: string; ++ altText: string; ++ title: string; ++ placement: string; ++ eligible: boolean; ++} ++ ++export interface DocumentAssetsEventInternal { ++ revision: CodegenTypes.Int32; ++ assets: { ++ anchor: string; ++ id: string; ++ kind: string; ++ url: string; ++ altText: string; ++ title: string; ++ placement: string; ++ eligible: boolean; ++ }[]; ++} ++ ++export interface MediaFrameInternal { ++ id: string; ++ x: CodegenTypes.Float; ++ y: CodegenTypes.Float; ++ width: CodegenTypes.Float; ++ height: CodegenTypes.Float; ++} ++ ++export interface MediaLayoutEventInternal { ++ revision: CodegenTypes.Int32; ++ frames: { ++ id: string; ++ x: CodegenTypes.Float; ++ y: CodegenTypes.Float; ++ width: CodegenTypes.Float; ++ height: CodegenTypes.Float; ++ }[]; ++} ++ ++export interface MediaOverrideInternal { ++ url: string; ++ kind: string; ++ anchor: string; ++ id: string; ++ height: CodegenTypes.Float; ++ width: CodegenTypes.Float; ++} ++ ++export interface ImageSourceInternal { ++ id: string; ++ url: string; ++ anchor: string; ++ uri: string; ++ headers: ReadonlyArray>; ++ useDefault: boolean; ++} ++ + export interface NativeProps extends ViewProps { ++ enableImageSourceResolution?: CodegenTypes.WithDefault; ++ imageSourcesRevision?: CodegenTypes.WithDefault; ++ imageSourcesContinuityStart?: CodegenTypes.WithDefault; ++ imageSources?: ReadonlyArray>; ++ documentRevision?: CodegenTypes.WithDefault; ++ enableDocumentAssets?: CodegenTypes.WithDefault; ++ enableMediaSlots?: CodegenTypes.WithDefault; ++ mediaOverridesRevision?: CodegenTypes.WithDefault; ++ mediaOverrides?: ReadonlyArray>; ++ onDocumentAssets?: CodegenTypes.DirectEventHandler; ++ onMediaLayout?: CodegenTypes.DirectEventHandler; ++ ++ linkRegex?: Readonly; ++ inlineCodeLinkRegex?: Readonly; + /** + * Markdown content to render. + */ +diff --git a/lib/module/EnrichedMarkdownTextNativeComponent.ts b/lib/module/EnrichedMarkdownTextNativeComponent.ts +index c034dd109ce151f9d6163a989f8f5ad651029a25..fcf45a04d1984bcdc210445beca44513a1fbb7b4 100644 +--- a/lib/module/EnrichedMarkdownTextNativeComponent.ts ++++ b/lib/module/EnrichedMarkdownTextNativeComponent.ts +@@ -97,6 +97,17 @@ interface LinkVariantEntryInternal { + color: ColorValue; + underline: boolean; + backgroundColor: ColorValue; ++ fontFamily: string; ++ pill: boolean; ++ label: string; ++ iconUri: string; ++ iconTintColor?: ColorValue; ++ borderRadius: CodegenTypes.Float; ++ paddingHorizontal: CodegenTypes.Float; ++ paddingVertical: CodegenTypes.Float; ++ borderWidth: CodegenTypes.Float; ++ borderColor: ColorValue; ++ maxWidth: CodegenTypes.Float; + } + + interface StrongStyleInternal { +@@ -407,7 +418,18 @@ interface StreamingConfigInternal { + codeBlockMode: string; + } + ++// Same transport as EnrichedMarkdownTextInput.linkRegex. Kept local for codegen. ++interface TextLinkNativeRegex { ++ pattern: string; ++ caseInsensitive: boolean; ++ dotAll: boolean; ++ isDisabled: boolean; ++ isDefault: boolean; ++} ++ + export interface NativeProps extends ViewProps { ++ linkRegex?: Readonly; ++ inlineCodeLinkRegex?: Readonly; + /** + * Markdown content to render. + */ +diff --git a/lib/module/imageSourceState.js b/lib/module/imageSourceState.js +new file mode 100644 +index 0000000000000000000000000000000000000000..fe20f71679a82362c263b2f148f402737099feb3 +--- /dev/null ++++ b/lib/module/imageSourceState.js +@@ -0,0 +1,86 @@ ++"use strict"; ++ ++const identity = asset => JSON.stringify(asset); ++const stripAnchor = ({ ++ anchor: _anchor, ++ ...asset ++}) => asset; ++ ++/** Per-occurrence decisions; superseded promises still count against the bound. */ ++export class ImageSourceState { ++ lineage = -1; ++ entries = new Map(); ++ active = 0; ++ running = false; ++ configure(resolver, lineage, assets) { ++ if (resolver !== this.resolver || lineage !== this.lineage) { ++ this.entries.clear(); ++ this.resolver = resolver; ++ this.lineage = lineage; ++ } ++ const next = new Map(); ++ if (resolver) { ++ for (const asset of assets) { ++ const key = identity(asset); ++ const previous = this.entries.get(asset.id); ++ next.set(asset.id, previous?.identity === key ? previous : { ++ asset, ++ identity: key, ++ status: 'queued' ++ }); ++ } ++ } ++ this.entries = next; ++ } ++ sources() { ++ return [...this.entries.values()].flatMap(entry => entry.source ? [entry.source] : []); ++ } ++ start(changed) { ++ this.running = true; ++ this.changed = changed; ++ this.pump(); ++ } ++ stop() { ++ this.running = false; ++ this.changed = undefined; ++ this.entries.clear(); ++ } ++ pump() { ++ if (!this.running || !this.resolver) return; ++ for (const entry of this.entries.values()) { ++ if (this.active >= 4) break; ++ if (entry.status !== 'queued') continue; ++ const resolve = this.resolver; ++ entry.status = 'active'; ++ this.active++; ++ // Always execute outside render. Synchronous throws follow rejection policy. ++ Promise.resolve().then(() => { ++ if (this.entries.get(entry.asset.id) !== entry || !this.running) return undefined; ++ return resolve(stripAnchor(entry.asset)); ++ }).then(result => { ++ if (this.entries.get(entry.asset.id) !== entry) return; ++ if (result === null || result && typeof result.uri === 'string' && result.uri.length > 0) { ++ entry.source = { ++ id: entry.asset.id, ++ url: entry.asset.url, ++ anchor: entry.asset.anchor, ++ uri: result?.uri ?? '', ++ headers: Object.entries(result?.headers ?? {}).map(([name, value]) => ({ ++ name, ++ value ++ })), ++ useDefault: result === null ++ }; ++ } ++ }).catch(() => { ++ // A rejected source remains a placeholder until its identity changes. ++ }).finally(() => { ++ entry.status = 'done'; ++ this.active--; ++ if (this.entries.get(entry.asset.id) === entry) this.changed?.(); ++ this.pump(); ++ }); ++ } ++ } ++} ++//# sourceMappingURL=imageSourceState.js.map +\ No newline at end of file +diff --git a/lib/module/imageSourceState.js.map b/lib/module/imageSourceState.js.map +new file mode 100644 +index 0000000000000000000000000000000000000000..54dae207fb8d9b6472de70c0bc6e7effe911518e +--- /dev/null ++++ b/lib/module/imageSourceState.js.map +@@ -0,0 +1 @@ ++{"version":3,"names":["identity","asset","JSON","stringify","stripAnchor","anchor","_anchor","ImageSourceState","lineage","entries","Map","active","running","configure","resolver","assets","clear","next","key","previous","get","id","set","status","sources","values","flatMap","entry","source","start","changed","pump","stop","undefined","resolve","Promise","then","result","uri","length","url","headers","Object","map","name","value","useDefault","catch","finally"],"sourceRoot":"../../src","sources":["imageSourceState.ts"],"mappings":"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","ignoreList":[]} +diff --git a/lib/module/index.js.map b/lib/module/index.js.map +index e76dd1e98e27d72f25bd51287eb1865ea4fe8bf8..5c6af988714ded6e343237bb5deee86562c27099 100644 +--- a/lib/module/index.js.map ++++ b/lib/module/index.js.map +@@ -1 +1 @@ +-{"version":3,"names":["default","EnrichedMarkdownText","DEFAULT_ACCESSIBILITY_LABELS","resolveAccessibilityLabels","EnrichedMarkdownTextInput"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,OAAO,IAAIC,oBAAoB,QAAQ,kCAA+B;AAuB/E,SACEC,4BAA4B,EAC5BC,0BAA0B,QACrB,iCAA8B;AAErC,SAASC,yBAAyB,QAAQ,gCAA6B","ignoreList":[]} ++{"version":3,"names":["default","EnrichedMarkdownText","DEFAULT_ACCESSIBILITY_LABELS","resolveAccessibilityLabels","EnrichedMarkdownTextInput"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AACA,SAASA,OAAO,IAAIC,oBAAoB,QAAQ,kCAA+B;AAuB/E,SACEC,4BAA4B,EAC5BC,0BAA0B,QACrB,iCAA8B;AAErC,SAASC,yBAAyB,QAAQ,gCAA6B","ignoreList":[]} +diff --git a/lib/module/jest/index.js b/lib/module/jest/index.js +index 98c0792354014f64a5a93b194dea0e0e23a492e3..0a6a6faaae108f5cd469a6002c860d659cd7f5ef 100644 +--- a/lib/module/jest/index.js ++++ b/lib/module/jest/index.js +@@ -237,6 +237,7 @@ export const EnrichedMarkdownText = ({ + spoilerOverlay: _spoilerOverlay, + contextMenuItems: _contextMenuItems, + imageRequestHeaders: _imageRequestHeaders, ++ resolveImageSource: _resolveImageSource, + selectionMenuConfig: _selectionMenuConfig, + accessibilityLabels: _accessibilityLabels, + selectionColor: _selectionColor, +diff --git a/lib/module/jest/index.js.map b/lib/module/jest/index.js.map +index 443a10290ab432eb59038f1bf71a03cfd4b7879d..4e2027ea41745c447beea3d6ea9eab4897e17d7d 100644 +--- a/lib/module/jest/index.js.map ++++ b/lib/module/jest/index.js.map +@@ -1 +1 @@ +-{"version":3,"names":["useImperativeHandle","useRef","useState","Text","TextInput","jsx","_jsx","DEFAULT_ACCESSIBILITY_LABELS","resolveAccessibilityLabels","spy","impl","jest","fn","EMPTY_CARET_RECT","x","y","width","height","EnrichedMarkdownTextInput","ref","defaultValue","onChangeText","onChangeMarkdown","onFocus","onBlur","editable","placeholder","placeholderTextColor","autoFocus","multiline","scrollEnabled","style","testID","accessible","accessibilityLabel","accessibilityHint","accessibilityRole","accessibilityState","nativeID","markdownStyle","_markdownStyle","cursorColor","_cursorColor","selectionColor","_selectionColor","autoCapitalize","_autoCapitalize","onChangeSelection","_onChangeSelection","onChangeState","_onChangeState","onKeyPress","_onKeyPress","onCaretRectChange","_onCaretRectChange","onLinkDetected","_onLinkDetected","mentionIndicators","_mentionIndicators","onStartMention","_onStartMention","onChangeMention","_onChangeMention","onEndMention","_onEndMention","contextMenuItems","_contextMenuItems","selectionMenuConfig","_selectionMenuConfig","formatMenuConfig","_formatMenuConfig","linkRegex","_linkRegex","writingDirection","_writingDirection","text","setText","textRef","inputRef","applyText","next","current","handleChangeText","instanceRef","focus","blur","measure","callback","measureInWindow","measureLayout","_relativeToNativeNode","onSuccess","setValue","markdown","setSelection","_start","_end","toggleBold","toggleItalic","toggleUnderline","toggleStrikethrough","toggleSpoiler","toggleHeading","_level","toggleUnorderedList","toggleOrderedList","indentList","outdentList","setLink","_url","insertLink","_text","insertText","insertMention","_displayText","startMention","_indicator","removeLink","copyToClipboard","getMarkdown","Promise","resolve","getCaretRect","value","INLINE_FMT_RE","LINK_RE","TASK_ITEM_RE","stripInlineFormatting","replace","splitByPattern","segment","regex","renderMatch","parts","lastIndex","match","exec","index","push","slice","length","applyTransform","children","transformFn","flatMap","child","createLinkTransform","onLinkPress","onLinkLongPress","keyCounter","linkText","url","onPress","onLongPress","undefined","createTaskListTransform","onTaskListItemPress","itemIndex","checked","currentIndex","buildChildren","opts","String","transforms","filter","t","transform","EnrichedMarkdownText","containerStyle","enableLinkPreview","_enableLinkPreview","selectable","_selectable","md4cFlags","_md4cFlags","allowFontScaling","_allowFontScaling","maxFontSizeMultiplier","_maxFontSizeMultiplier","allowTrailingMargin","_allowTrailingMargin","flavor","_flavor","streamingAnimation","_streamingAnimation","streamingConfig","_streamingConfig","spoilerOverlay","_spoilerOverlay","imageRequestHeaders","_imageRequestHeaders","accessibilityLabels","_accessibilityLabels","selectionHandleColor","_selectionHandleColor","textBreakStrategy","_textBreakStrategy","lineBreakStrategyIOS","_lineBreakStrategyIOS"],"sourceRoot":"../../../src","sources":["jest/index.tsx"],"mappings":"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","ignoreList":[]} ++{"version":3,"names":["useImperativeHandle","useRef","useState","Text","TextInput","jsx","_jsx","DEFAULT_ACCESSIBILITY_LABELS","resolveAccessibilityLabels","spy","impl","jest","fn","EMPTY_CARET_RECT","x","y","width","height","EnrichedMarkdownTextInput","ref","defaultValue","onChangeText","onChangeMarkdown","onFocus","onBlur","editable","placeholder","placeholderTextColor","autoFocus","multiline","scrollEnabled","style","testID","accessible","accessibilityLabel","accessibilityHint","accessibilityRole","accessibilityState","nativeID","markdownStyle","_markdownStyle","cursorColor","_cursorColor","selectionColor","_selectionColor","autoCapitalize","_autoCapitalize","onChangeSelection","_onChangeSelection","onChangeState","_onChangeState","onKeyPress","_onKeyPress","onCaretRectChange","_onCaretRectChange","onLinkDetected","_onLinkDetected","mentionIndicators","_mentionIndicators","onStartMention","_onStartMention","onChangeMention","_onChangeMention","onEndMention","_onEndMention","contextMenuItems","_contextMenuItems","selectionMenuConfig","_selectionMenuConfig","formatMenuConfig","_formatMenuConfig","linkRegex","_linkRegex","writingDirection","_writingDirection","text","setText","textRef","inputRef","applyText","next","current","handleChangeText","instanceRef","focus","blur","measure","callback","measureInWindow","measureLayout","_relativeToNativeNode","onSuccess","setValue","markdown","setSelection","_start","_end","toggleBold","toggleItalic","toggleUnderline","toggleStrikethrough","toggleSpoiler","toggleHeading","_level","toggleUnorderedList","toggleOrderedList","indentList","outdentList","setLink","_url","insertLink","_text","insertText","insertMention","_displayText","startMention","_indicator","removeLink","copyToClipboard","getMarkdown","Promise","resolve","getCaretRect","value","INLINE_FMT_RE","LINK_RE","TASK_ITEM_RE","stripInlineFormatting","replace","splitByPattern","segment","regex","renderMatch","parts","lastIndex","match","exec","index","push","slice","length","applyTransform","children","transformFn","flatMap","child","createLinkTransform","onLinkPress","onLinkLongPress","keyCounter","linkText","url","onPress","onLongPress","undefined","createTaskListTransform","onTaskListItemPress","itemIndex","checked","currentIndex","buildChildren","opts","String","transforms","filter","t","transform","EnrichedMarkdownText","containerStyle","enableLinkPreview","_enableLinkPreview","selectable","_selectable","md4cFlags","_md4cFlags","allowFontScaling","_allowFontScaling","maxFontSizeMultiplier","_maxFontSizeMultiplier","allowTrailingMargin","_allowTrailingMargin","flavor","_flavor","streamingAnimation","_streamingAnimation","streamingConfig","_streamingConfig","spoilerOverlay","_spoilerOverlay","imageRequestHeaders","_imageRequestHeaders","resolveImageSource","_resolveImageSource","accessibilityLabels","_accessibilityLabels","selectionHandleColor","_selectionHandleColor","textBreakStrategy","_textBreakStrategy","lineBreakStrategyIOS","_lineBreakStrategyIOS"],"sourceRoot":"../../../src","sources":["jest/index.tsx"],"mappings":"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","ignoreList":[]} +diff --git a/lib/module/linkVariantUtils.js b/lib/module/linkVariantUtils.js +index 8e758d18d34ea308c180bfa822ea8eed3ca450f6..2f3c050db6e974b42087d264ad408325af73fa71 100644 +--- a/lib/module/linkVariantUtils.js ++++ b/lib/module/linkVariantUtils.js +@@ -25,4 +25,19 @@ export function normalizeLinkVariantEntries(linkVariants) { + return true; + }); + } ++ ++/** Native pill geometry is finite and nonnegative before crossing codegen. */ ++export function normalizeLinkPillStyle(style) { ++ const dimension = (value, fallback) => value === undefined || !Number.isFinite(value) ? fallback : Math.max(0, value); ++ return { ++ pill: style.pill ?? false, ++ label: style.label ?? '', ++ iconUri: style.iconUri ?? '', ++ borderRadius: dimension(style.borderRadius, 8), ++ paddingHorizontal: dimension(style.paddingHorizontal, 6), ++ paddingVertical: dimension(style.paddingVertical, 2), ++ borderWidth: dimension(style.borderWidth, 0), ++ maxWidth: dimension(style.maxWidth, 0) ++ }; ++} + //# sourceMappingURL=linkVariantUtils.js.map +\ No newline at end of file +diff --git a/lib/module/linkVariantUtils.js.map b/lib/module/linkVariantUtils.js.map +index 05d599bd7d2e3e6f9917dab29f2c35b8acc58b0b..dd6409335c09860ac08e9c5759d08554aba2dc60 100644 +--- a/lib/module/linkVariantUtils.js.map ++++ b/lib/module/linkVariantUtils.js.map +@@ -1 +1 @@ +-{"version":3,"names":["UNSAFE_LOOKBEHIND_RE","warnAboutUnsafePattern","pattern","test","console","warn","normalizeLinkVariantEntries","linkVariants","Object","entries","sort","a","b","length","filter","RegExp","__DEV__"],"sourceRoot":"../../src","sources":["linkVariantUtils.ts"],"mappings":";;AAIA;AACA;AACA;AACA,MAAMA,oBAAoB,GAAG,WAAW;AAExC,SAASC,sBAAsBA,CAACC,OAAe,EAAQ;EACrD,IAAIF,oBAAoB,CAACG,IAAI,CAACD,OAAO,CAAC,EAAE;IACtCE,OAAO,CAACC,IAAI,CACV,yCAAyCH,OAAO,kDAAkD,GAChG,oFAAoF,GACpF,2DACJ,CAAC;EACH;AACF;AAEA,OAAO,SAASI,2BAA2BA,CACzCC,YAA+C,EAC3B;EACpB,OAAOC,MAAM,CAACC,OAAO,CAACF,YAAY,IAAI,CAAC,CAAC,CAAC,CACtCG,IAAI,CAAC,CAAC,CAACC,CAAC,CAAC,EAAE,CAACC,CAAC,CAAC,KAAKA,CAAC,CAACC,MAAM,GAAGF,CAAC,CAACE,MAAM,CAAC,CACvCC,MAAM,CAAC,CAAC,CAACZ,OAAO,CAAC,KAAK;IACrB,IAAI;MACFa,MAAM,CAACb,OAAO,CAAC;IACjB,CAAC,CAAC,MAAM;MACN,IAAIc,OAAO,EAAE;QACXZ,OAAO,CAACC,IAAI,CACV,yCAAyCH,OAAO,6CAClD,CAAC;MACH;MACA,OAAO,KAAK;IACd;IAEA,IAAIc,OAAO,EAAE;MACXf,sBAAsB,CAACC,OAAO,CAAC;IACjC;IACA,OAAO,IAAI;EACb,CAAC,CAAC;AACN","ignoreList":[]} ++{"version":3,"names":["UNSAFE_LOOKBEHIND_RE","warnAboutUnsafePattern","pattern","test","console","warn","normalizeLinkVariantEntries","linkVariants","Object","entries","sort","a","b","length","filter","RegExp","__DEV__","normalizeLinkPillStyle","style","dimension","value","fallback","undefined","Number","isFinite","Math","max","pill","label","iconUri","borderRadius","paddingHorizontal","paddingVertical","borderWidth","maxWidth"],"sourceRoot":"../../src","sources":["linkVariantUtils.ts"],"mappings":";;AAIA;AACA;AACA;AACA,MAAMA,oBAAoB,GAAG,WAAW;AAExC,SAASC,sBAAsBA,CAACC,OAAe,EAAQ;EACrD,IAAIF,oBAAoB,CAACG,IAAI,CAACD,OAAO,CAAC,EAAE;IACtCE,OAAO,CAACC,IAAI,CACV,yCAAyCH,OAAO,kDAAkD,GAChG,oFAAoF,GACpF,2DACJ,CAAC;EACH;AACF;AAEA,OAAO,SAASI,2BAA2BA,CACzCC,YAA+C,EAC3B;EACpB,OAAOC,MAAM,CAACC,OAAO,CAACF,YAAY,IAAI,CAAC,CAAC,CAAC,CACtCG,IAAI,CAAC,CAAC,CAACC,CAAC,CAAC,EAAE,CAACC,CAAC,CAAC,KAAKA,CAAC,CAACC,MAAM,GAAGF,CAAC,CAACE,MAAM,CAAC,CACvCC,MAAM,CAAC,CAAC,CAACZ,OAAO,CAAC,KAAK;IACrB,IAAI;MACFa,MAAM,CAACb,OAAO,CAAC;IACjB,CAAC,CAAC,MAAM;MACN,IAAIc,OAAO,EAAE;QACXZ,OAAO,CAACC,IAAI,CACV,yCAAyCH,OAAO,6CAClD,CAAC;MACH;MACA,OAAO,KAAK;IACd;IAEA,IAAIc,OAAO,EAAE;MACXf,sBAAsB,CAACC,OAAO,CAAC;IACjC;IACA,OAAO,IAAI;EACb,CAAC,CAAC;AACN;;AAEA;AACA,OAAO,SAASe,sBAAsBA,CAACC,KAAuB,EAAE;EAC9D,MAAMC,SAAS,GAAGA,CAACC,KAAyB,EAAEC,QAAgB,KAC5DD,KAAK,KAAKE,SAAS,IAAI,CAACC,MAAM,CAACC,QAAQ,CAACJ,KAAK,CAAC,GAC1CC,QAAQ,GACRI,IAAI,CAACC,GAAG,CAAC,CAAC,EAAEN,KAAK,CAAC;EACxB,OAAO;IACLO,IAAI,EAAET,KAAK,CAACS,IAAI,IAAI,KAAK;IACzBC,KAAK,EAAEV,KAAK,CAACU,KAAK,IAAI,EAAE;IACxBC,OAAO,EAAEX,KAAK,CAACW,OAAO,IAAI,EAAE;IAC5BC,YAAY,EAAEX,SAAS,CAACD,KAAK,CAACY,YAAY,EAAE,CAAC,CAAC;IAC9CC,iBAAiB,EAAEZ,SAAS,CAACD,KAAK,CAACa,iBAAiB,EAAE,CAAC,CAAC;IACxDC,eAAe,EAAEb,SAAS,CAACD,KAAK,CAACc,eAAe,EAAE,CAAC,CAAC;IACpDC,WAAW,EAAEd,SAAS,CAACD,KAAK,CAACe,WAAW,EAAE,CAAC,CAAC;IAC5CC,QAAQ,EAAEf,SAAS,CAACD,KAAK,CAACgB,QAAQ,EAAE,CAAC;EACvC,CAAC;AACH","ignoreList":[]} +diff --git a/lib/module/mediaSlotState.js b/lib/module/mediaSlotState.js +new file mode 100644 +index 0000000000000000000000000000000000000000..6b4693fb44451c0a0c8efc7bcc2a6e30b6521a1d +--- /dev/null ++++ b/lib/module/mediaSlotState.js +@@ -0,0 +1,22 @@ ++"use strict"; ++ ++export const sameMediaSize = (a, b) => Math.abs(a - b) < 0.5; ++ ++/** Accept only finite native frames with usable widths. */ ++export const validMediaFrames = frames => frames.filter(({ ++ x, ++ y, ++ width, ++ height ++}) => [x, y, width, height].every(Number.isFinite) && width > 0 && height >= 0); ++ ++/** A width change requires React to measure again before native uses the height. */ ++export const mediaOverrideForFrame = (id, frame, measurement) => frame && measurement && sameMediaSize(frame.width, measurement.width) ? measurement : { ++ id, ++ width: 0, ++ height: 1 ++}; ++ ++/** Reject stale onLayout callbacks and suppress subpixel feedback loops. */ ++export const acceptMediaMeasurement = (eventRevision, revision, frame, next, previous) => eventRevision === revision && !!frame && Number.isFinite(next.width) && Number.isFinite(next.height) && next.width > 0 && next.height >= 0 && sameMediaSize(frame.width, next.width) && (!previous || !sameMediaSize(previous.width, next.width) || !sameMediaSize(previous.height, next.height)); ++//# sourceMappingURL=mediaSlotState.js.map +\ No newline at end of file +diff --git a/lib/module/mediaSlotState.js.map b/lib/module/mediaSlotState.js.map +new file mode 100644 +index 0000000000000000000000000000000000000000..1a7a4bacc98f8e187a3259408fe628f2121118cc +--- /dev/null ++++ b/lib/module/mediaSlotState.js.map +@@ -0,0 +1 @@ ++{"version":3,"names":["sameMediaSize","a","b","Math","abs","validMediaFrames","frames","filter","x","y","width","height","every","Number","isFinite","mediaOverrideForFrame","id","frame","measurement","acceptMediaMeasurement","eventRevision","revision","next","previous"],"sourceRoot":"../../src","sources":["mediaSlotState.ts"],"mappings":";;AAQA,OAAO,MAAMA,aAAa,GAAGA,CAACC,CAAS,EAAEC,CAAS,KAAKC,IAAI,CAACC,GAAG,CAACH,CAAC,GAAGC,CAAC,CAAC,GAAG,GAAG;;AAE5E;AACA,OAAO,MAAMG,gBAAgB,GAC3BC,MAAqC,IAErCA,MAAM,CAACC,MAAM,CACX,CAAC;EAAEC,CAAC;EAAEC,CAAC;EAAEC,KAAK;EAAEC;AAAO,CAAC,KACtB,CAACH,CAAC,EAAEC,CAAC,EAAEC,KAAK,EAAEC,MAAM,CAAC,CAACC,KAAK,CAACC,MAAM,CAACC,QAAQ,CAAC,IAAIJ,KAAK,GAAG,CAAC,IAAIC,MAAM,IAAI,CAC3E,CAAC;;AAEH;AACA,OAAO,MAAMI,qBAAqB,GAAGA,CACnCC,EAAU,EACVC,KAAqC,EACrCC,WAAyC,KAEzCD,KAAK,IAAIC,WAAW,IAAIlB,aAAa,CAACiB,KAAK,CAACP,KAAK,EAAEQ,WAAW,CAACR,KAAK,CAAC,GACjEQ,WAAW,GACX;EAAEF,EAAE;EAAEN,KAAK,EAAE,CAAC;EAAEC,MAAM,EAAE;AAAE,CAAC;;AAEjC;AACA,OAAO,MAAMQ,sBAAsB,GAAGA,CACpCC,aAAqB,EACrBC,QAAgB,EAChBJ,KAAqC,EACrCK,IAAsB,EACtBC,QAAsC,KAEtCH,aAAa,KAAKC,QAAQ,IAC1B,CAAC,CAACJ,KAAK,IACPJ,MAAM,CAACC,QAAQ,CAACQ,IAAI,CAACZ,KAAK,CAAC,IAC3BG,MAAM,CAACC,QAAQ,CAACQ,IAAI,CAACX,MAAM,CAAC,IAC5BW,IAAI,CAACZ,KAAK,GAAG,CAAC,IACdY,IAAI,CAACX,MAAM,IAAI,CAAC,IAChBX,aAAa,CAACiB,KAAK,CAACP,KAAK,EAAEY,IAAI,CAACZ,KAAK,CAAC,KACrC,CAACa,QAAQ,IACR,CAACvB,aAAa,CAACuB,QAAQ,CAACb,KAAK,EAAEY,IAAI,CAACZ,KAAK,CAAC,IAC1C,CAACV,aAAa,CAACuB,QAAQ,CAACZ,MAAM,EAAEW,IAAI,CAACX,MAAM,CAAC,CAAC","ignoreList":[]} +diff --git a/lib/module/native/EnrichedMarkdownText.js b/lib/module/native/EnrichedMarkdownText.js +index ab5f4a794bac16e8e8a6ca9fba753cadf17e0532..c37db5a374fed3de6b661c6fd5f2dd4ca5e7594c 100644 +--- a/lib/module/native/EnrichedMarkdownText.js ++++ b/lib/module/native/EnrichedMarkdownText.js +@@ -1,12 +1,15 @@ + "use strict"; + ++import { StyleSheet, View } from 'react-native'; ++import { useMediaSlots } from "./useMediaSlots.js"; + import { useMemo, useCallback, useRef, useEffect } from 'react'; + import EnrichedMarkdownTextNativeComponent from '../EnrichedMarkdownTextNativeComponent'; + import EnrichedMarkdownNativeComponent from '../EnrichedMarkdownNativeComponent'; ++import { toNativeTextLinkRegexConfig } from "../utils/regexParser.js"; + import { normalizeMarkdownStyle } from '../normalizeMarkdownStyle'; + import { resolveAccessibilityLabels } from "../accessibilityLabelDefaults.js"; + import { normalizeMenuItem, normalizeLegacyBooleanMenuItem } from "../normalizeMenuItem.js"; +-import { jsx as _jsx } from "react/jsx-runtime"; ++import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; + // Default English labels for the built-in selection menu actions. Defaults are + // resolved here (JS-side) so the native code always receives a concrete string. + const DEFAULT_COPY_LABEL = 'Copy'; +@@ -68,11 +71,16 @@ const defaultMd4cFlags = { + }; + export const EnrichedMarkdownText = ({ + markdown, ++ linkRegex: _linkRegex, ++ inlineCodeLinkRegex: _inlineCodeLinkRegex, + markdownStyle = {}, + containerStyle, + onLinkPress, + onLinkLongPress, + onImagePress, ++ renderMedia, ++ resolveImageSource, ++ onDocumentAssets, + onTaskListItemPress, + enableTaskListItemToggle = true, + onCopyPress, +@@ -102,6 +110,8 @@ export const EnrichedMarkdownText = ({ + ellipsizeMode, + ...rest + }) => { ++ const linkRegex = useMemo(() => toNativeTextLinkRegexConfig(_linkRegex), [_linkRegex]); ++ const inlineCodeLinkRegex = useMemo(() => toNativeTextLinkRegexConfig(_inlineCodeLinkRegex), [_inlineCodeLinkRegex]); + const normalizedStyleRef = useRef(null); + const normalized = normalizeMarkdownStyle(markdownStyle); + // normalizeMarkdownStyle returns cached objects for structurally equal inputs, +@@ -253,6 +263,8 @@ export const EnrichedMarkdownText = ({ + const resolvedAccessibilityLabels = useMemo(() => resolveAccessibilityLabels(accessibilityLabels), [accessibilityLabels]); + const sharedProps = { + markdown, ++ linkRegex, ++ inlineCodeLinkRegex, + markdownStyle: normalizedStyle, + onLinkPress: handleLinkPress, + onLinkLongPress: handleLinkLongPress, +@@ -290,9 +302,27 @@ export const EnrichedMarkdownText = ({ + ellipsizeMode, + ...rest + }; ++ ++ // Include native recognition configs when composed with the optional text ++ // recognition API. Asset revisions must follow all parser inputs. ++ const nativeParserProps = sharedProps; ++ const media = useMediaSlots(markdown, JSON.stringify([normalizedMd4cFlags, streamingAnimation, normalizedStreamingConfig, flavor, !!renderMedia, !!onDocumentAssets, !!resolveImageSource, nativeParserProps.linkRegex, nativeParserProps.inlineCodeLinkRegex]), flavor === 'github' ? renderMedia : undefined, flavor === 'github' ? onDocumentAssets : undefined, flavor === 'github' ? resolveImageSource : undefined); + if (flavor === 'github') { ++ if (renderMedia) { ++ return /*#__PURE__*/_jsxs(View, { ++ style: containerStyle, ++ onLayout: rest.onLayout, ++ children: [/*#__PURE__*/_jsx(EnrichedMarkdownNativeComponent, { ++ ...sharedProps, ++ ...media.nativeProps, ++ style: mediaStyles.native, ++ onLayout: media.onNativeLayout ++ }), media.slots] ++ }); ++ } + return /*#__PURE__*/_jsx(EnrichedMarkdownNativeComponent, { +- ...sharedProps ++ ...sharedProps, ++ ...media.nativeProps + }); + } + return /*#__PURE__*/_jsx(EnrichedMarkdownTextNativeComponent, { +@@ -300,4 +330,9 @@ export const EnrichedMarkdownText = ({ + }); + }; + export default EnrichedMarkdownText; ++const mediaStyles = StyleSheet.create({ ++ native: { ++ alignSelf: 'stretch' ++ } ++}); + //# sourceMappingURL=EnrichedMarkdownText.js.map +\ No newline at end of file +diff --git a/lib/module/native/EnrichedMarkdownText.js.map b/lib/module/native/EnrichedMarkdownText.js.map +index 5f02ffeff3e46cb58659f2ddaa5d6580af1c3367..5b66c8eb5068fa32edca4a10cef9686e3889216a 100644 +--- a/lib/module/native/EnrichedMarkdownText.js.map ++++ b/lib/module/native/EnrichedMarkdownText.js.map +@@ -1 +1 @@ +-{"version":3,"names":["useMemo","useCallback","useRef","useEffect","EnrichedMarkdownTextNativeComponent","EnrichedMarkdownNativeComponent","normalizeMarkdownStyle","resolveAccessibilityLabels","normalizeMenuItem","normalizeLegacyBooleanMenuItem","jsx","_jsx","DEFAULT_COPY_LABEL","DEFAULT_COPY_AS_MARKDOWN_LABEL","DEFAULT_COPY_IMAGE_URL_LABEL","DEFAULT_COPY_IMAGE_URLS_LABEL","buildPluralTemplates","pluralLabels","singularLabel","IntlRef","Intl","PluralRules","pluralRules","other","byCategory","zero","one","two","few","many","templates","n","push","select","defaultMd4cFlags","underline","superscript","subscript","latexMath","highlight","hardSoftBreaks","preserveBlankLines","admonitions","EnrichedMarkdownText","markdown","markdownStyle","containerStyle","onLinkPress","onLinkLongPress","onImagePress","onTaskListItemPress","enableTaskListItemToggle","onCopyPress","onLatexError","onCodeBlockPress","enableBlockContextMenu","enableLinkPreview","selectable","md4cFlags","allowFontScaling","maxFontSizeMultiplier","allowTrailingMargin","flavor","streamingAnimation","streamingConfig","spoilerOverlay","contextMenuItems","imageRequestHeaders","selectionMenuConfig","accessibilityLabels","selectionColor","selectionHandleColor","textBreakStrategy","lineBreakStrategyIOS","writingDirection","numberOfLines","ellipsizeMode","rest","normalizedStyleRef","normalized","current","normalizedStyle","normalizedMd4cFlags","contextMenuCallbacksRef","Map","callbacksMap","item","set","text","onPress","nativeContextMenuItems","filter","visible","map","icon","nativeImageRequestHeaders","Object","entries","name","value","sort","a","b","undefined","handleContextMenuItemPress","e","itemText","selectedText","selectionStart","selectionEnd","nativeEvent","callback","get","selection","start","end","handleLinkPress","url","handleLinkLongPress","handleImagePress","altText","handleTaskListItemPress","index","checked","handleCopyPress","code","language","handleLatexError","source","message","displayMode","handleCodeBlockPress","tableMode","codeBlockMode","normalizedStreamingConfig","normalizedSelectionMenuConfig","config","copy","copyAsMarkdown","copyImageUrl","enabled","copyLabel","label","copyAsMarkdownLabel","copyImageUrlLabel","copyImageUrlsLabel","copyImageUrlPluralTemplates","resolvedAccessibilityLabels","sharedProps","enableImagePress","enableCodeBlockPress","isGFM","style","onContextMenuItemPress"],"sourceRoot":"../../../src","sources":["native/EnrichedMarkdownText.tsx"],"mappings":"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","ignoreList":[]} ++{"version":3,"names":["StyleSheet","View","useMediaSlots","useMemo","useCallback","useRef","useEffect","EnrichedMarkdownTextNativeComponent","EnrichedMarkdownNativeComponent","toNativeTextLinkRegexConfig","normalizeMarkdownStyle","resolveAccessibilityLabels","normalizeMenuItem","normalizeLegacyBooleanMenuItem","jsx","_jsx","jsxs","_jsxs","DEFAULT_COPY_LABEL","DEFAULT_COPY_AS_MARKDOWN_LABEL","DEFAULT_COPY_IMAGE_URL_LABEL","DEFAULT_COPY_IMAGE_URLS_LABEL","buildPluralTemplates","pluralLabels","singularLabel","IntlRef","Intl","PluralRules","pluralRules","other","byCategory","zero","one","two","few","many","templates","n","push","select","defaultMd4cFlags","underline","superscript","subscript","latexMath","highlight","hardSoftBreaks","preserveBlankLines","admonitions","EnrichedMarkdownText","markdown","linkRegex","_linkRegex","inlineCodeLinkRegex","_inlineCodeLinkRegex","markdownStyle","containerStyle","onLinkPress","onLinkLongPress","onImagePress","renderMedia","resolveImageSource","onDocumentAssets","onTaskListItemPress","enableTaskListItemToggle","onCopyPress","onLatexError","onCodeBlockPress","enableBlockContextMenu","enableLinkPreview","selectable","md4cFlags","allowFontScaling","maxFontSizeMultiplier","allowTrailingMargin","flavor","streamingAnimation","streamingConfig","spoilerOverlay","contextMenuItems","imageRequestHeaders","selectionMenuConfig","accessibilityLabels","selectionColor","selectionHandleColor","textBreakStrategy","lineBreakStrategyIOS","writingDirection","numberOfLines","ellipsizeMode","rest","normalizedStyleRef","normalized","current","normalizedStyle","normalizedMd4cFlags","contextMenuCallbacksRef","Map","callbacksMap","item","set","text","onPress","nativeContextMenuItems","filter","visible","map","icon","nativeImageRequestHeaders","Object","entries","name","value","sort","a","b","undefined","handleContextMenuItemPress","e","itemText","selectedText","selectionStart","selectionEnd","nativeEvent","callback","get","selection","start","end","handleLinkPress","url","handleLinkLongPress","handleImagePress","altText","handleTaskListItemPress","index","checked","handleCopyPress","code","language","handleLatexError","source","message","displayMode","handleCodeBlockPress","tableMode","codeBlockMode","normalizedStreamingConfig","normalizedSelectionMenuConfig","config","copy","copyAsMarkdown","copyImageUrl","enabled","copyLabel","label","copyAsMarkdownLabel","copyImageUrlLabel","copyImageUrlsLabel","copyImageUrlPluralTemplates","resolvedAccessibilityLabels","sharedProps","enableImagePress","enableCodeBlockPress","isGFM","style","onContextMenuItemPress","nativeParserProps","media","JSON","stringify","onLayout","children","nativeProps","mediaStyles","native","onNativeLayout","slots","create","alignSelf"],"sourceRoot":"../../../src","sources":["native/EnrichedMarkdownText.tsx"],"mappings":";;AAAA,SAASA,UAAU,EAAEC,IAAI,QAAQ,cAAc;AAC/C,SAASC,aAAa,QAAQ,oBAAiB;AAC/C,SAASC,OAAO,EAAEC,WAAW,EAAEC,MAAM,EAAEC,SAAS,QAAQ,OAAO;AAC/D,OAAOC,mCAAmC,MAAM,wCAAwC;AAExF,OAAOC,+BAA+B,MAAM,oCAAoC;AAChF,SAASC,2BAA2B,QAAQ,yBAAsB;AAClE,SAASC,sBAAsB,QAAQ,2BAA2B;AAClE,SAASC,0BAA0B,QAAQ,kCAA+B;AAC1E,SACEC,iBAAiB,EACjBC,8BAA8B,QACzB,yBAAsB;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAuC9B;AACA;AACA,MAAMC,kBAAkB,GAAG,MAAM;AACjC,MAAMC,8BAA8B,GAAG,kBAAkB;AACzD,MAAMC,4BAA4B,GAAG,gBAAgB;AACrD,MAAMC,6BAA6B,GAAG,yBAAyB;;AAE/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,oBAAoB,GAAGA,CAC3BC,YAAmD,EACnDC,aAAqB,KACR;EACb,IAAI,CAACD,YAAY,EAAE,OAAO,EAAE;EAE5B,MAAME,OAAO,GAAGC,IAIf;EACD,IAAI,OAAOD,OAAO,CAACE,WAAW,KAAK,UAAU,EAAE,OAAO,EAAE;EAExD,IAAIC,WAA0C;EAC9C,IAAI;IACF;IACA;IACA;IACA;IACAA,WAAW,GAAG,IAAIH,OAAO,CAACE,WAAW,CAAC,CAAC;EACzC,CAAC,CAAC,MAAM;IACN,OAAO,EAAE;EACX;EAEA,MAAM;IAAEE;EAAM,CAAC,GAAGN,YAAY;EAC9B,MAAMO,UAAkC,GAAG;IACzCC,IAAI,EAAER,YAAY,CAACQ,IAAI,IAAIF,KAAK;IAChCG,GAAG,EAAET,YAAY,CAACS,GAAG,IAAIH,KAAK;IAC9BI,GAAG,EAAEV,YAAY,CAACU,GAAG,IAAIJ,KAAK;IAC9BK,GAAG,EAAEX,YAAY,CAACW,GAAG,IAAIL,KAAK;IAC9BM,IAAI,EAAEZ,YAAY,CAACY,IAAI,IAAIN,KAAK;IAChCA;EACF,CAAC;EAED,MAAMO,SAAmB,GAAG,EAAE;EAC9B,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,IAAI,GAAG,EAAEA,CAAC,EAAE,EAAE;IAC7B;IACA;IACAD,SAAS,CAACE,IAAI,CACZD,CAAC,KAAK,CAAC,GAAGb,aAAa,GAAIM,UAAU,CAACF,WAAW,CAACW,MAAM,CAACF,CAAC,CAAC,CAAC,IAAIR,KAClE,CAAC;EACH;EACA,OAAOO,SAAS;AAClB,CAAC;AAED,MAAMI,gBAA2B,GAAG;EAClCC,SAAS,EAAE,KAAK;EAChBC,WAAW,EAAE,KAAK;EAClBC,SAAS,EAAE,KAAK;EAChBC,SAAS,EAAE,IAAI;EACfC,SAAS,EAAE,KAAK;EAChBC,cAAc,EAAE,KAAK;EACrBC,kBAAkB,EAAE,KAAK;EACzBC,WAAW,EAAE;AACf,CAAC;AAED,OAAO,MAAMC,oBAAoB,GAAGA,CAAC;EACnCC,QAAQ;EACRC,SAAS,EAAEC,UAAU;EACrBC,mBAAmB,EAAEC,oBAAoB;EACzCC,aAAa,GAAG,CAAC,CAAC;EAClBC,cAAc;EACdC,WAAW;EACXC,eAAe;EACfC,YAAY;EACZC,WAAW;EACXC,kBAAkB;EAClBC,gBAAgB;EAChBC,mBAAmB;EACnBC,wBAAwB,GAAG,IAAI;EAC/BC,WAAW;EACXC,YAAY;EACZC,gBAAgB;EAChBC,sBAAsB,GAAG,IAAI;EAC7BC,iBAAiB;EACjBC,UAAU,GAAG,IAAI;EACjBC,SAAS,GAAG/B,gBAAgB;EAC5BgC,gBAAgB,GAAG,IAAI;EACvBC,qBAAqB;EACrBC,mBAAmB,GAAG,KAAK;EAC3BC,MAAM,GAAG,YAAY;EACrBC,kBAAkB,GAAG,KAAK;EAC1BC,eAAe;EACfC,cAAc,GAAG,WAAW;EAC5BC,gBAAgB;EAChBC,mBAAmB;EACnBC,mBAAmB;EACnBC,mBAAmB;EACnBC,cAAc;EACdC,oBAAoB;EACpBC,iBAAiB;EACjBC,oBAAoB;EACpBC,gBAAgB,GAAG,cAAc;EACjCC,aAAa;EACbC,aAAa;EACb,GAAGC;AACsB,CAAC,KAAK;EAC/B,MAAMvC,SAAS,GAAGhD,OAAO,CACvB,MAAMM,2BAA2B,CAAC2C,UAAU,CAAC,EAC7C,CAACA,UAAU,CACb,CAAC;EACD,MAAMC,mBAAmB,GAAGlD,OAAO,CACjC,MAAMM,2BAA2B,CAAC6C,oBAAoB,CAAC,EACvD,CAACA,oBAAoB,CACvB,CAAC;EACD,MAAMqC,kBAAkB,GAAGtF,MAAM,CAA+B,IAAI,CAAC;EACrE,MAAMuF,UAAU,GAAGlF,sBAAsB,CAAC6C,aAAa,CAAC;EACxD;EACA;EACA,IAAIoC,kBAAkB,CAACE,OAAO,KAAKD,UAAU,EAAE;IAC7CD,kBAAkB,CAACE,OAAO,GAAGD,UAAU;EACzC;EACA,MAAME,eAAe,GAAGH,kBAAkB,CAACE,OAAQ;EAEnD,MAAME,mBAAmB,GAAG5F,OAAO,CACjC,OAAO;IACLsC,SAAS,EAAE8B,SAAS,CAAC9B,SAAS,IAAI,KAAK;IACvCC,WAAW,EAAE6B,SAAS,CAAC7B,WAAW,IAAI,KAAK;IAC3CC,SAAS,EAAE4B,SAAS,CAAC5B,SAAS,IAAI,KAAK;IACvCC,SAAS,EAAE2B,SAAS,CAAC3B,SAAS,IAAI,IAAI;IACtCC,SAAS,EAAE0B,SAAS,CAAC1B,SAAS,IAAI,KAAK;IACvCC,cAAc,EAAEyB,SAAS,CAACzB,cAAc,IAAI,KAAK;IACjDC,kBAAkB,EAAEwB,SAAS,CAACxB,kBAAkB,IAAI,KAAK;IACzD;IACA;IACAC,WAAW,EACT2B,MAAM,KAAK,QAAQ,GAAIJ,SAAS,CAACvB,WAAW,IAAI,IAAI,GAAI;EAC5D,CAAC,CAAC,EACF,CAACuB,SAAS,EAAEI,MAAM,CACpB,CAAC;EAED,MAAMqB,uBAAuB,GAAG3F,MAAM,CAEpC,IAAI4F,GAAG,CAAC,CAAC,CAAC;EAEZ3F,SAAS,CAAC,MAAM;IACd,MAAM4F,YAAY,GAAG,IAAID,GAAG,CAAqC,CAAC;IAClE,IAAIlB,gBAAgB,EAAE;MACpB,KAAK,MAAMoB,IAAI,IAAIpB,gBAAgB,EAAE;QACnCmB,YAAY,CAACE,GAAG,CAACD,IAAI,CAACE,IAAI,EAAEF,IAAI,CAACG,OAAO,CAAC;MAC3C;IACF;IACAN,uBAAuB,CAACH,OAAO,GAAGK,YAAY;EAChD,CAAC,EAAE,CAACnB,gBAAgB,CAAC,CAAC;EAEtB,MAAMwB,sBAAsB,GAAGpG,OAAO,CACpC,MACE4E,gBAAgB,EACZyB,MAAM,CAAEL,IAAI,IAAKA,IAAI,CAACM,OAAO,KAAK,KAAK,CAAC,CACzCC,GAAG,CAAEP,IAAI,KAAM;IAAEE,IAAI,EAAEF,IAAI,CAACE,IAAI;IAAEM,IAAI,EAAER,IAAI,CAACQ;EAAK,CAAC,CAAC,CAAC,EAC1D,CAAC5B,gBAAgB,CACnB,CAAC;EAED,MAAM6B,yBAAyB,GAAGzG,OAAO,CACvC,MACE6E,mBAAmB,GACf6B,MAAM,CAACC,OAAO,CAAC9B,mBAAmB,CAAC,CAChC0B,GAAG,CAAC,CAAC,CAACK,IAAI,EAAEC,KAAK,CAAC,MAAM;IAAED,IAAI;IAAEC;EAAM,CAAC,CAAC,CAAC,CACzCC,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC,KAAMD,CAAC,CAACH,IAAI,GAAGI,CAAC,CAACJ,IAAI,GAAG,CAAC,CAAC,GAAGG,CAAC,CAACH,IAAI,GAAGI,CAAC,CAACJ,IAAI,GAAG,CAAC,GAAG,CAAE,CAAC,GACnEK,SAAS,EACf,CAACpC,mBAAmB,CACtB,CAAC;EAED,MAAMqC,0BAA0B,GAAGjH,WAAW,CAC3CkH,CAAoD,IAAK;IACxD,MAAM;MAAEC,QAAQ;MAAEC,YAAY;MAAEC,cAAc;MAAEC;IAAa,CAAC,GAC5DJ,CAAC,CAACK,WAAW;IACf,MAAMC,QAAQ,GAAG5B,uBAAuB,CAACH,OAAO,CAACgC,GAAG,CAACN,QAAQ,CAAC;IAC9DK,QAAQ,GAAG;MACTvB,IAAI,EAAEmB,YAAY;MAClBM,SAAS,EAAE;QAAEC,KAAK,EAAEN,cAAc;QAAEO,GAAG,EAAEN;MAAa;IACxD,CAAC,CAAC;EACJ,CAAC,EACD,EACF,CAAC;EAED,MAAMO,eAAe,GAAG7H,WAAW,CAChCkH,CAAuC,IAAK;IAC3C,MAAM;MAAEY;IAAI,CAAC,GAAGZ,CAAC,CAACK,WAAW;IAC7BlE,WAAW,GAAG;MAAEyE;IAAI,CAAC,CAAC;EACxB,CAAC,EACD,CAACzE,WAAW,CACd,CAAC;EAED,MAAM0E,mBAAmB,GAAG/H,WAAW,CACpCkH,CAA2C,IAAK;IAC/C,MAAM;MAAEY;IAAI,CAAC,GAAGZ,CAAC,CAACK,WAAW;IAC7BjE,eAAe,GAAG;MAAEwE;IAAI,CAAC,CAAC;EAC5B,CAAC,EACD,CAACxE,eAAe,CAClB,CAAC;EAED,MAAM0E,gBAAgB,GAAGhI,WAAW,CACjCkH,CAAwC,IAAK;IAC5C,MAAM;MAAEY,GAAG;MAAEG;IAAQ,CAAC,GAAGf,CAAC,CAACK,WAAW;IACtChE,YAAY,GAAG;MAAEuE,GAAG;MAAEG;IAAQ,CAAC,CAAC;EAClC,CAAC,EACD,CAAC1E,YAAY,CACf,CAAC;EAED,MAAM2E,uBAAuB,GAAGlI,WAAW,CACxCkH,CAA+C,IAAK;IACnD,MAAM;MAAEiB,KAAK;MAAEC,OAAO;MAAEnC;IAAK,CAAC,GAAGiB,CAAC,CAACK,WAAW;IAC9C5D,mBAAmB,GAAG;MAAEwE,KAAK;MAAEC,OAAO;MAAEnC;IAAK,CAAC,CAAC;EACjD,CAAC,EACD,CAACtC,mBAAmB,CACtB,CAAC;EAED,MAAM0E,eAAe,GAAGrI,WAAW,CAChCkH,CAAuC,IAAK;IAC3C,MAAM;MAAEoB,IAAI;MAAEC;IAAS,CAAC,GAAGrB,CAAC,CAACK,WAAW;IACxC1D,WAAW,GAAG;MAAEyE,IAAI;MAAEC;IAAS,CAAC,CAAC;EACnC,CAAC,EACD,CAAC1E,WAAW,CACd,CAAC;EAED,MAAM2E,gBAAgB,GAAGxI,WAAW,CACjCkH,CAAwC,IAAK;IAC5C,MAAM;MAAEuB,MAAM;MAAEC,OAAO;MAAEC;IAAY,CAAC,GAAGzB,CAAC,CAACK,WAAW;IACtDzD,YAAY,GAAG;MAAE2E,MAAM;MAAEC,OAAO,EAAEA,OAAO,IAAI1B,SAAS;MAAE2B;IAAY,CAAC,CAAC;EACxE,CAAC,EACD,CAAC7E,YAAY,CACf,CAAC;EAED,MAAM8E,oBAAoB,GAAG5I,WAAW,CACrCkH,CAA4C,IAAK;IAChD,MAAM;MAAEoB,IAAI;MAAEC;IAAS,CAAC,GAAGrB,CAAC,CAACK,WAAW;IACxCxD,gBAAgB,GAAG;MAAEuE,IAAI;MAAEC;IAAS,CAAC,CAAC;EACxC,CAAC,EACD,CAACxE,gBAAgB,CACnB,CAAC;EAED,MAAM8E,SAAS,GAAGpE,eAAe,EAAEoE,SAAS,IAAI,aAAa;EAC7D,MAAMC,aAAa,GAAGrE,eAAe,EAAEqE,aAAa,IAAI,aAAa;EACrE,MAAMC,yBAAyB,GAAGhJ,OAAO,CACvC,OAAO;IAAE8I,SAAS;IAAEC;EAAc,CAAC,CAAC,EACpC,CAACD,SAAS,EAAEC,aAAa,CAC3B,CAAC;EACD,MAAME,6BAA6B,GAAGjJ,OAAO,CAAC,MAAM;IAClD;IACA;IACA,MAAMkJ,MAAM,GAAGpE,mBAMF;IAEb,MAAMqE,IAAI,GAAG1I,iBAAiB,CAACyI,MAAM,EAAEC,IAAI,EAAE,IAAI,EAAEpI,kBAAkB,CAAC;IACtE,MAAMqI,cAAc,GAAG1I,8BAA8B,CACnDwI,MAAM,EAAEE,cAAc,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,IAAI,EACJpI,8BACF,CAAC;IACD,MAAMqI,YAAY,GAAG3I,8BAA8B,CACjDwI,MAAM,EAAEG,YAAY,EACpB,qBAAqB,EACrB,cAAc,EACd,IAAI,EACJpI,4BACF,CAAC;IAED,MAAMG,YAAY,GAChB8H,MAAM,EAAEG,YAAY,EAGnBjI,YAAY;IAEf,OAAO;MACLgI,cAAc,EAAEA,cAAc,CAACE,OAAO;MACtCD,YAAY,EAAEA,YAAY,CAACC,OAAO;MAClCC,SAAS,EAAEJ,IAAI,CAACK,KAAK;MACrBC,mBAAmB,EAAEL,cAAc,CAACI,KAAK;MACzCE,iBAAiB,EAAEL,YAAY,CAACG,KAAK;MACrCG,kBAAkB,EAAEvI,YAAY,EAAEM,KAAK,IAAIR,6BAA6B;MACxE0I,2BAA2B,EAAEzI,oBAAoB,CAC/CC,YAAY,EACZiI,YAAY,CAACG,KACf;IACF,CAAC;EACH,CAAC,EAAE,CAAC1E,mBAAmB,CAAC,CAAC;EAEzB,MAAM+E,2BAA2B,GAAG7J,OAAO,CACzC,MAAMQ,0BAA0B,CAACuE,mBAAmB,CAAC,EACrD,CAACA,mBAAmB,CACtB,CAAC;EAED,MAAM+E,WAAW,GAAG;IAClB/G,QAAQ;IACRC,SAAS;IACTE,mBAAmB;IACnBE,aAAa,EAAEuC,eAAe;IAC9BrC,WAAW,EAAEwE,eAAe;IAC5BvE,eAAe,EAAEyE,mBAAmB;IACpCxE,YAAY,EAAEyE,gBAAgB;IAC9B8B,gBAAgB,EAAEvG,YAAY,IAAI,IAAI;IACtCI,mBAAmB,EAAEuE,uBAAuB;IAC5CtE,wBAAwB;IACxBC,WAAW,EAAEwE,eAAe;IAC5BvE,YAAY,EAAE0E,gBAAgB;IAC9BzE,gBAAgB,EAAE6E,oBAAoB;IACtCmB,oBAAoB,EAAEhG,gBAAgB,IAAI,IAAI;IAC9CC,sBAAsB;IACtBC,iBAAiB,EAAEX,eAAe,IAAI,IAAI,KAAKW,iBAAiB,IAAI,IAAI,CAAC;IACzEC,UAAU;IACVC,SAAS,EAAEwB,mBAAmB;IAC9BqE,KAAK,EAAEzF,MAAM,KAAK,QAAQ;IAC1BH,gBAAgB;IAChBC,qBAAqB;IACrBC,mBAAmB;IACnBE,kBAAkB;IAClBC,eAAe,EAAEsE,yBAAyB;IAC1CrE,cAAc;IACduF,KAAK,EAAE7G,cAAc;IACrBuB,gBAAgB,EAAEwB,sBAAsB;IACxCvB,mBAAmB,EAAE4B,yBAAyB;IAC9C3B,mBAAmB,EAAEmE,6BAA6B;IAClDlE,mBAAmB,EAAE8E,2BAA2B;IAChDM,sBAAsB,EAAEjD,0BAA0B;IAClDlC,cAAc;IACdC,oBAAoB;IACpBC,iBAAiB;IACjBC,oBAAoB;IACpBC,gBAAgB;IAChBC,aAAa;IACbC,aAAa;IACb,GAAGC;EACL,CAAC;;EAED;EACA;EACA,MAAM6E,iBAA0C,GAAGN,WAAW;EAC9D,MAAMO,KAAK,GAAGtK,aAAa,CACzBgD,QAAQ,EACRuH,IAAI,CAACC,SAAS,CAAC,CACb3E,mBAAmB,EACnBnB,kBAAkB,EAClBuE,yBAAyB,EACzBxE,MAAM,EACN,CAAC,CAACf,WAAW,EACb,CAAC,CAACE,gBAAgB,EAClB,CAAC,CAACD,kBAAkB,EACpB0G,iBAAiB,CAACpH,SAAS,EAC3BoH,iBAAiB,CAAClH,mBAAmB,CACtC,CAAC,EACFsB,MAAM,KAAK,QAAQ,GAAGf,WAAW,GAAGwD,SAAS,EAC7CzC,MAAM,KAAK,QAAQ,GAAGb,gBAAgB,GAAGsD,SAAS,EAClDzC,MAAM,KAAK,QAAQ,GAAGd,kBAAkB,GAAGuD,SAC7C,CAAC;EAED,IAAIzC,MAAM,KAAK,QAAQ,EAAE;IACvB,IAAIf,WAAW,EAAE;MACf,oBACE3C,KAAA,CAAChB,IAAI;QAACoK,KAAK,EAAE7G,cAAe;QAACmH,QAAQ,EAAEjF,IAAI,CAACiF,QAAS;QAAAC,QAAA,gBACnD7J,IAAA,CAACP,+BAA+B;UAAA,GAC1ByJ,WAAW;UAAA,GACXO,KAAK,CAACK,WAAW;UACrBR,KAAK,EAAES,WAAW,CAACC,MAAO;UAC1BJ,QAAQ,EAAEH,KAAK,CAACQ;QAAe,CAChC,CAAC,EACDR,KAAK,CAACS,KAAK;MAAA,CACR,CAAC;IAEX;IACA,oBACElK,IAAA,CAACP,+BAA+B;MAAA,GAC1ByJ,WAAW;MAAA,GACXO,KAAK,CAACK;IAAW,CACtB,CAAC;EAEN;EAEA,oBAAO9J,IAAA,CAACR,mCAAmC;IAAA,GAAK0J;EAAW,CAAG,CAAC;AACjE,CAAC;AAED,eAAehH,oBAAoB;AAEnC,MAAM6H,WAAW,GAAG9K,UAAU,CAACkL,MAAM,CAAC;EAAEH,MAAM,EAAE;IAAEI,SAAS,EAAE;EAAU;AAAE,CAAC,CAAC","ignoreList":[]} +diff --git a/lib/module/native/useImageSources.js b/lib/module/native/useImageSources.js +new file mode 100644 +index 0000000000000000000000000000000000000000..d1a3999db1e1b4c089326f6d0f186f7a91055b82 +--- /dev/null ++++ b/lib/module/native/useImageSources.js +@@ -0,0 +1,24 @@ ++"use strict"; ++ ++import { useEffect, useRef, useState } from 'react'; ++import { ImageSourceState } from "../imageSourceState.js"; ++export function useImageSources(resolver, continuityStart, assetsRevision, assets) { ++ const state = useRef(undefined); ++ if (!state.current) state.current = new ImageSourceState(); ++ const current = state.current; ++ const [, refresh] = useState(0); ++ current.configure(resolver, continuityStart, assets); ++ // Reconcile after every commit. Configure deduplicates layout-only renders. ++ useEffect(() => { ++ current.configure(resolver, continuityStart, assets); ++ current.start(() => refresh(value => value + 1)); ++ }); ++ useEffect(() => () => current.stop(), [current]); ++ return { ++ enableImageSourceResolution: !!resolver, ++ imageSourcesContinuityStart: resolver ? continuityStart : 1, ++ imageSourcesRevision: resolver ? assetsRevision : -1, ++ imageSources: current.sources() ++ }; ++} ++//# sourceMappingURL=useImageSources.js.map +\ No newline at end of file +diff --git a/lib/module/native/useImageSources.js.map b/lib/module/native/useImageSources.js.map +new file mode 100644 +index 0000000000000000000000000000000000000000..79366ad6f065cbaac348f00d8c66cd677820ccef +--- /dev/null ++++ b/lib/module/native/useImageSources.js.map +@@ -0,0 +1 @@ ++{"version":3,"names":["useEffect","useRef","useState","ImageSourceState","useImageSources","resolver","continuityStart","assetsRevision","assets","state","undefined","current","refresh","configure","start","value","stop","enableImageSourceResolution","imageSourcesContinuityStart","imageSourcesRevision","imageSources","sources"],"sourceRoot":"../../../src","sources":["native/useImageSources.ts"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AACnD,SAASC,gBAAgB,QAAQ,wBAAqB;AAItD,OAAO,SAASC,eAAeA,CAC7BC,QAAyD,EACzDC,eAAuB,EACvBC,cAAsB,EACtBC,MAA0B,EAC1B;EACA,MAAMC,KAAK,GAAGR,MAAM,CAA+BS,SAAS,CAAC;EAC7D,IAAI,CAACD,KAAK,CAACE,OAAO,EAAEF,KAAK,CAACE,OAAO,GAAG,IAAIR,gBAAgB,CAAC,CAAC;EAC1D,MAAMQ,OAAO,GAAGF,KAAK,CAACE,OAAO;EAC7B,MAAM,GAAGC,OAAO,CAAC,GAAGV,QAAQ,CAAC,CAAC,CAAC;EAC/BS,OAAO,CAACE,SAAS,CAACR,QAAQ,EAAEC,eAAe,EAAEE,MAAM,CAAC;EACpD;EACAR,SAAS,CAAC,MAAM;IACdW,OAAO,CAACE,SAAS,CAACR,QAAQ,EAAEC,eAAe,EAAEE,MAAM,CAAC;IACpDG,OAAO,CAACG,KAAK,CAAC,MAAMF,OAAO,CAAEG,KAAK,IAAKA,KAAK,GAAG,CAAC,CAAC,CAAC;EACpD,CAAC,CAAC;EACFf,SAAS,CAAC,MAAM,MAAMW,OAAO,CAACK,IAAI,CAAC,CAAC,EAAE,CAACL,OAAO,CAAC,CAAC;EAChD,OAAO;IACLM,2BAA2B,EAAE,CAAC,CAACZ,QAAQ;IACvCa,2BAA2B,EAAEb,QAAQ,GAAGC,eAAe,GAAG,CAAC;IAC3Da,oBAAoB,EAAEd,QAAQ,GAAGE,cAAc,GAAG,CAAC,CAAC;IACpDa,YAAY,EAAET,OAAO,CAACU,OAAO,CAAC;EAChC,CAAC;AACH","ignoreList":[]} +diff --git a/lib/module/native/useMediaSlots.js b/lib/module/native/useMediaSlots.js +new file mode 100644 +index 0000000000000000000000000000000000000000..f149720cf0d0aea874ea2c8e1eb341dc07377e93 +--- /dev/null ++++ b/lib/module/native/useMediaSlots.js +@@ -0,0 +1,203 @@ ++"use strict"; ++ ++import { useRef, useState } from 'react'; ++import { useImageSources } from "./useImageSources.js"; ++import { StyleSheet, View } from 'react-native'; ++import { acceptMediaMeasurement, mediaOverrideForFrame, sameMediaSize, validMediaFrames } from "../mediaSlotState.js"; ++import { jsx as _jsx } from "react/jsx-runtime"; ++const stripAnchor = ({ ++ anchor: _anchor, ++ ...asset ++}) => asset; ++const identity = asset => JSON.stringify([asset.id, asset.kind, asset.url, asset.anchor, asset.eligible]); ++const identities = assets => Object.fromEntries(assets.map(asset => [asset.id, identity(asset)])); ++export function useMediaSlots(markdown, parserKey, renderMedia, onDocumentAssets, resolveImageSource) { ++ const document = useRef({ ++ markdown, ++ parserKey, ++ revision: 1, ++ continuityStart: 1, ++ generation: 0 ++ }); ++ if (document.current.markdown !== markdown || document.current.parserKey !== parserKey) { ++ const previous = document.current; ++ const append = previous.parserKey === parserKey && previous.markdown.length > 0 && markdown.length > previous.markdown.length && markdown.startsWith(previous.markdown); ++ document.current = { ++ markdown, ++ parserKey, ++ revision: previous.revision + 1, ++ continuityStart: append ? previous.continuityStart : previous.revision + 1, ++ generation: previous.generation + (append ? 0 : 1) ++ }; ++ } ++ const { ++ revision, ++ continuityStart, ++ generation ++ } = document.current; ++ const [manifest, setManifest] = useState(); ++ const acceptedManifest = useRef(undefined); ++ const [layout, setLayout] = useState(); ++ const latestLayout = useRef(undefined); ++ const pendingLayout = useRef(undefined); ++ const [origin, setOrigin] = useState({ ++ x: 0, ++ y: 0 ++ }); ++ const [measurements, setMeasurements] = useState({}); ++ const reported = useRef(-1); ++ // Only uninterrupted appends with identical parser inputs retain prior data. ++ // Native revalidates each carried decision against the newly accepted AST. ++ const assets = manifest && manifest.revision >= continuityStart ? manifest.assets : []; ++ const frames = layout && layout.revision >= continuityStart ? layout.frames : []; ++ const frameForAsset = asset => layout?.identities[asset.id] === identity(asset) ? frames.find(entry => entry.id === asset.id) : undefined; ++ const rendered = assets.flatMap(asset => { ++ if (asset.kind === 'link' || !asset.eligible || !renderMedia) return []; ++ const content = renderMedia(stripAnchor(asset)); ++ if (content == null || typeof content === 'boolean') return []; ++ return [{ ++ asset, ++ content ++ }]; ++ }); ++ const imageSources = useImageSources(resolveImageSource, continuityStart, manifest && manifest.revision >= continuityStart ? manifest.revision : -1, assets.filter(asset => asset.kind === 'image' && !rendered.some(entry => entry.asset.id === asset.id))); ++ const overrides = rendered.map(({ ++ asset ++ }) => { ++ const measurement = measurements[asset.id]; ++ const box = mediaOverrideForFrame(asset.id, frameForAsset(asset), measurement?.identity === identity(asset) && measurement.generation === generation ? measurement : undefined); ++ return { ++ id: box.id, ++ height: box.height, ++ width: box.width, ++ url: asset.url, ++ kind: asset.kind, ++ anchor: asset.anchor ++ }; ++ }); ++ const onNativeDocumentAssets = event => { ++ if (event.nativeEvent.revision !== document.current.revision) return; ++ const next = event.nativeEvent; ++ acceptedManifest.current = next; ++ setManifest(previous => previous?.revision === next.revision && JSON.stringify(previous.assets) === JSON.stringify(next.assets) ? previous : next); ++ // A frame can arrive before its manifest. Stamp only frames of this exact ++ // revision; older frames keep their original occurrence identities. ++ const received = pendingLayout.current?.revision === next.revision ? pendingLayout.current : latestLayout.current?.revision === next.revision ? latestLayout.current : undefined; ++ if (received) { ++ const updated = { ++ ...received, ++ identities: identities(next.assets) ++ }; ++ latestLayout.current = updated; ++ pendingLayout.current = undefined; ++ setLayout(updated); ++ } ++ if (reported.current !== next.revision) { ++ reported.current = next.revision; ++ onDocumentAssets?.({ ++ revision: next.revision, ++ assets: next.assets.map(stripAnchor) ++ }); ++ } ++ }; ++ const onNativeMediaLayout = event => { ++ const next = event.nativeEvent; ++ if (next.revision !== document.current.revision) return; ++ const valid = validMediaFrames(next.frames); ++ const current = acceptedManifest.current; ++ if (current?.revision !== next.revision) { ++ // Keep mounted slots until the accepted manifest can identify new frames. ++ pendingLayout.current = { ++ revision: next.revision, ++ frames: valid ++ }; ++ return; ++ } ++ const nextLayout = { ++ revision: next.revision, ++ frames: valid, ++ identities: current?.revision === next.revision ? identities(current.assets) : {} ++ }; ++ latestLayout.current = nextLayout; ++ setLayout(previous => { ++ if (previous?.revision === next.revision && JSON.stringify(previous.identities) === JSON.stringify(nextLayout.identities) && previous.frames.length === valid.length && previous.frames.every((frame, index) => { ++ const other = valid[index]; ++ return frame.id === other.id && sameMediaSize(frame.x, other.x) && sameMediaSize(frame.y, other.y) && sameMediaSize(frame.width, other.width) && sameMediaSize(frame.height, other.height); ++ })) return previous; ++ return nextLayout; ++ }); ++ }; ++ const onNativeLayout = ({ ++ nativeEvent ++ }) => { ++ const { ++ x, ++ y ++ } = nativeEvent.layout; ++ setOrigin(previous => sameMediaSize(previous.x, x) && sameMediaSize(previous.y, y) ? previous : { ++ x, ++ y ++ }); ++ }; ++ const onSlotLayout = (asset, frame, event) => { ++ const { ++ width, ++ height ++ } = event.nativeEvent.layout; ++ const next = { ++ id: asset.id, ++ width, ++ height ++ }; ++ setMeasurements(previous => { ++ const current = acceptedManifest.current; ++ const currentAsset = current?.assets.find(entry => entry.id === asset.id); ++ if (!current || current.revision < document.current.continuityStart || !currentAsset || identity(currentAsset) !== identity(asset) || !acceptMediaMeasurement(revision, document.current.revision, pendingLayout.current?.revision === revision ? pendingLayout.current.frames.find(entry => entry.id === frame.id) : latestLayout.current?.identities[asset.id] === identity(asset) && latestLayout.current.revision >= document.current.continuityStart ? latestLayout.current.frames.find(entry => entry.id === frame.id) : undefined, next, previous[asset.id]?.identity === identity(asset) && previous[asset.id]?.generation === generation ? previous[asset.id] : undefined)) return previous; ++ return { ++ ...previous, ++ [asset.id]: { ++ ...next, ++ identity: identity(asset), ++ generation ++ } ++ }; ++ }); ++ }; ++ const slots = rendered.map(({ ++ asset, ++ content ++ }) => { ++ const frame = frameForAsset(asset); ++ if (!frame) return null; ++ return /*#__PURE__*/_jsx(View, { ++ collapsable: false, ++ style: [styles.slot, { ++ left: origin.x + frame.x, ++ top: origin.y + frame.y, ++ width: frame.width ++ }], ++ onLayout: event => onSlotLayout(asset, frame, event), ++ children: content ++ }, `${generation}:${identity(asset)}`); ++ }); ++ return { ++ slots, ++ onNativeLayout, ++ nativeProps: { ++ ...imageSources, ++ documentRevision: revision, ++ enableDocumentAssets: !!renderMedia || !!onDocumentAssets || !!resolveImageSource, ++ enableMediaSlots: !!renderMedia, ++ mediaOverridesRevision: manifest && manifest.revision >= continuityStart ? manifest.revision : -1, ++ mediaOverrides: overrides, ++ onDocumentAssets: onNativeDocumentAssets, ++ onMediaLayout: onNativeMediaLayout ++ } ++ }; ++} ++const styles = StyleSheet.create({ ++ slot: { ++ position: 'absolute' ++ } ++}); ++//# sourceMappingURL=useMediaSlots.js.map +\ No newline at end of file +diff --git a/lib/module/native/useMediaSlots.js.map b/lib/module/native/useMediaSlots.js.map +new file mode 100644 +index 0000000000000000000000000000000000000000..c20941a5e09cbaccb6a0a601b77d38c13f4c59cc +--- /dev/null ++++ b/lib/module/native/useMediaSlots.js.map +@@ -0,0 +1 @@ ++{"version":3,"names":["useRef","useState","useImageSources","StyleSheet","View","acceptMediaMeasurement","mediaOverrideForFrame","sameMediaSize","validMediaFrames","jsx","_jsx","stripAnchor","anchor","_anchor","asset","identity","JSON","stringify","id","kind","url","eligible","identities","assets","Object","fromEntries","map","useMediaSlots","markdown","parserKey","renderMedia","onDocumentAssets","resolveImageSource","document","revision","continuityStart","generation","current","previous","append","length","startsWith","manifest","setManifest","acceptedManifest","undefined","layout","setLayout","latestLayout","pendingLayout","origin","setOrigin","x","y","measurements","setMeasurements","reported","frames","frameForAsset","find","entry","rendered","flatMap","content","imageSources","filter","some","overrides","measurement","box","height","width","onNativeDocumentAssets","event","nativeEvent","next","received","updated","onNativeMediaLayout","valid","nextLayout","every","frame","index","other","onNativeLayout","onSlotLayout","currentAsset","slots","collapsable","style","styles","slot","left","top","onLayout","children","nativeProps","documentRevision","enableDocumentAssets","enableMediaSlots","mediaOverridesRevision","mediaOverrides","onMediaLayout","create","position"],"sourceRoot":"../../../src","sources":["native/useMediaSlots.tsx"],"mappings":"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","ignoreList":[]} +diff --git a/lib/module/normalizeMarkdownStyle.js b/lib/module/normalizeMarkdownStyle.js +index cc43227ba04341f1d1ba7bf0540840ec09fdfe90..5727f6b53d9d89aef7ef8f2f574238fc4970e25d 100644 +--- a/lib/module/normalizeMarkdownStyle.js ++++ b/lib/module/normalizeMarkdownStyle.js +@@ -2,7 +2,7 @@ + + import { Platform } from 'react-native'; + import { isStyleEqual, normalizeColor, mergeSubStyle } from "./styleUtils.js"; +-import { normalizeLinkVariantEntries } from "./linkVariantUtils.js"; ++import { normalizeLinkVariantEntries, normalizeLinkPillStyle } from "./linkVariantUtils.js"; + import { resolveAdmonitionColors } from "./admonitionDefaults.js"; + import { DEFAULT_HEADING_FONT_WEIGHT, HEADING_DEFAULTS } from "./headingDefaults.js"; + const getSystemFont = () => Platform.select({ +@@ -362,6 +362,10 @@ export const normalizeMarkdownStyle = style => { + result.linkVariants = normalizeLinkVariantEntries(style.linkVariants).map(([pattern, override]) => { + return { + pattern, ++ ...normalizeLinkPillStyle(override), ++ iconTintColor: normalizeColor(override.iconTintColor), ++ fontFamily: override.fontFamily ?? linkBase.fontFamily, ++ borderColor: normalizeColor(override.borderColor ?? 'transparent') ?? transparent, + color: (override.color ? normalizeColor(override.color) : null) ?? linkBase.color, + underline: override.underline ?? linkBase.underline, + backgroundColor: override.backgroundColor ? normalizeColor(override.backgroundColor) ?? transparent : transparent +diff --git a/lib/module/normalizeMarkdownStyle.js.map b/lib/module/normalizeMarkdownStyle.js.map +index c3114c52abfa69c5ebfca1c4769d055fefd71c92..c016713a564fc9099436d5b9c0f45c99d58f6c5c 100644 +--- a/lib/module/normalizeMarkdownStyle.js.map ++++ b/lib/module/normalizeMarkdownStyle.js.map +@@ -1 +1 @@ +-{"version":3,"names":["Platform","isStyleEqual","normalizeColor","mergeSubStyle","normalizeLinkVariantEntries","resolveAdmonitionColors","DEFAULT_HEADING_FONT_WEIGHT","HEADING_DEFAULTS","getSystemFont","select","ios","android","web","default","getMonospaceFont","defaultTextColor","codeBlockTextColor","DEFAULT_CODE_BLOCK_SYNTAX_COLORS","keyword","operatorColor","punctuation","string","number","constant","comment","function","type","variable","property","tag","attribute","embedded","INHERIT_SYNTAX_TOKENS","Set","PUBLIC_SYNTAX_TOKEN_KEYS","baseHeader","fontFamily","fontWeight","marginTop","marginBottom","textAlign","DEFAULT_NORMALIZED_STYLE","Object","freeze","paragraph","fontSize","color","lineHeight","h1","h2","h3","h4","h5","h6","blockquote","borderColor","borderWidth","gapWidth","backgroundColor","borderRadius","padding","admonitions","undefined","list","bulletColor","bulletSize","markerMinWidth","markerColor","markerFontWeight","marginLeft","itemSpacing","codeBlock","syntaxColors","link","underline","linkVariants","strong","em","fontStyle","strikethrough","code","image","height","maxHeight","aspectRatio","resizeMode","video","inlineImage","size","thematicBreak","table","headerFontFamily","headerBackgroundColor","headerTextColor","rowEvenBackgroundColor","rowOddBackgroundColor","cellPaddingHorizontal","cellPaddingVertical","horizontalOverflow","align","math","inlineMath","taskList","checkedColor","checkboxSize","checkboxBorderRadius","checkmarkColor","checkedTextColor","checkedStrikethrough","spoiler","particles","density","speed","solid","superscript","fontScale","baselineOffsetScale","subscript","highlight","refCache","WeakMap","structuralCache","LRU_MAX","styleReferenceKeys","keys","normalizeMarkdownStyle","style","length","refHit","get","structIdx","findIndex","e","entry","splice","unshift","set","result","forEach","key","Array","isArray","userValue","transparent","linkBase","map","pattern","override","listSize","Math","round","paragraphColor","userSyntaxColors","resolvedSyntaxColors","token","publicKey","has","finalResult","pop"],"sourceRoot":"../../src","sources":["normalizeMarkdownStyle.ts"],"mappings":"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","ignoreList":[]} ++{"version":3,"names":["Platform","isStyleEqual","normalizeColor","mergeSubStyle","normalizeLinkVariantEntries","normalizeLinkPillStyle","resolveAdmonitionColors","DEFAULT_HEADING_FONT_WEIGHT","HEADING_DEFAULTS","getSystemFont","select","ios","android","web","default","getMonospaceFont","defaultTextColor","codeBlockTextColor","DEFAULT_CODE_BLOCK_SYNTAX_COLORS","keyword","operatorColor","punctuation","string","number","constant","comment","function","type","variable","property","tag","attribute","embedded","INHERIT_SYNTAX_TOKENS","Set","PUBLIC_SYNTAX_TOKEN_KEYS","baseHeader","fontFamily","fontWeight","marginTop","marginBottom","textAlign","DEFAULT_NORMALIZED_STYLE","Object","freeze","paragraph","fontSize","color","lineHeight","h1","h2","h3","h4","h5","h6","blockquote","borderColor","borderWidth","gapWidth","backgroundColor","borderRadius","padding","admonitions","undefined","list","bulletColor","bulletSize","markerMinWidth","markerColor","markerFontWeight","marginLeft","itemSpacing","codeBlock","syntaxColors","link","underline","linkVariants","strong","em","fontStyle","strikethrough","code","image","height","maxHeight","aspectRatio","resizeMode","video","inlineImage","size","thematicBreak","table","headerFontFamily","headerBackgroundColor","headerTextColor","rowEvenBackgroundColor","rowOddBackgroundColor","cellPaddingHorizontal","cellPaddingVertical","horizontalOverflow","align","math","inlineMath","taskList","checkedColor","checkboxSize","checkboxBorderRadius","checkmarkColor","checkedTextColor","checkedStrikethrough","spoiler","particles","density","speed","solid","superscript","fontScale","baselineOffsetScale","subscript","highlight","refCache","WeakMap","structuralCache","LRU_MAX","styleReferenceKeys","keys","normalizeMarkdownStyle","style","length","refHit","get","structIdx","findIndex","e","entry","splice","unshift","set","result","forEach","key","Array","isArray","userValue","transparent","linkBase","map","pattern","override","iconTintColor","listSize","Math","round","paragraphColor","userSyntaxColors","resolvedSyntaxColors","token","publicKey","has","finalResult","pop"],"sourceRoot":"../../src","sources":["normalizeMarkdownStyle.ts"],"mappings":"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","ignoreList":[]} +diff --git a/lib/module/normalizeMarkdownStyle.web.js b/lib/module/normalizeMarkdownStyle.web.js +index 6d21cbb6caacac946dc65fdce6bc4114b67ad6c1..b06258ab32a008b0cf5d0c43ff9ad7052098ad89 100644 +--- a/lib/module/normalizeMarkdownStyle.web.js ++++ b/lib/module/normalizeMarkdownStyle.web.js +@@ -1,7 +1,7 @@ + "use strict"; + + import { isStyleEqual, mergeSubStyle } from "./styleUtils.js"; +-import { normalizeLinkVariantEntries } from "./linkVariantUtils.js"; ++import { normalizeLinkVariantEntries, normalizeLinkPillStyle } from "./linkVariantUtils.js"; + import { resolveAdmonitionColors } from "./admonitionDefaults.js"; + import { DEFAULT_HEADING_FONT_WEIGHT, HEADING_DEFAULTS } from "./headingDefaults.js"; + const SYSTEM_FONT = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'; +@@ -272,6 +272,10 @@ export const normalizeMarkdownStyle = style => { + result.linkVariants = normalizeLinkVariantEntries(style.linkVariants).map(([pattern, override]) => { + return { + pattern, ++ ...normalizeLinkPillStyle(override), ++ iconTintColor: override.iconTintColor, ++ fontFamily: override.fontFamily ?? linkBase.fontFamily, ++ borderColor: override.borderColor ?? 'transparent', + color: override.color ?? linkBase.color, + underline: override.underline ?? linkBase.underline, + backgroundColor: override.backgroundColor ?? 'transparent' +diff --git a/lib/module/normalizeMarkdownStyle.web.js.map b/lib/module/normalizeMarkdownStyle.web.js.map +index 2ea4122d84d61e392aa679d828f4bc2b458d3d23..f3b1bb07fc4ec11790c54f84531421458340ffb7 100644 +--- a/lib/module/normalizeMarkdownStyle.web.js.map ++++ b/lib/module/normalizeMarkdownStyle.web.js.map +@@ -1 +1 @@ +-{"version":3,"names":["isStyleEqual","mergeSubStyle","normalizeLinkVariantEntries","resolveAdmonitionColors","DEFAULT_HEADING_FONT_WEIGHT","HEADING_DEFAULTS","SYSTEM_FONT","MONOSPACE_FONT","defaultTextColor","baseHeader","fontFamily","fontWeight","marginTop","marginBottom","textAlign","DEFAULT_NORMALIZED_STYLE","Object","freeze","paragraph","fontSize","color","lineHeight","h1","h2","h3","h4","h5","h6","blockquote","borderColor","borderWidth","gapWidth","backgroundColor","borderRadius","padding","admonitions","undefined","list","bulletColor","bulletSize","markerMinWidth","markerColor","markerFontWeight","marginLeft","itemSpacing","codeBlock","syntaxColors","keyword","operatorColor","punctuation","string","number","constant","comment","function","type","variable","property","tag","attribute","embedded","link","underline","linkVariants","strong","em","fontStyle","strikethrough","code","image","height","maxHeight","aspectRatio","resizeMode","video","inlineImage","size","thematicBreak","table","headerFontFamily","headerBackgroundColor","headerTextColor","rowEvenBackgroundColor","rowOddBackgroundColor","cellPaddingHorizontal","cellPaddingVertical","horizontalOverflow","align","math","inlineMath","taskList","checkedColor","checkboxSize","checkboxBorderRadius","checkmarkColor","checkedTextColor","checkedStrikethrough","spoiler","particles","density","speed","solid","superscript","fontScale","baselineOffsetScale","subscript","highlight","refCache","WeakMap","structuralCache","LRU_MAX","styleReferenceKeys","keys","normalizeMarkdownStyle","style","length","refHit","get","structIdx","findIndex","e","entry","splice","unshift","set","result","forEach","key","Array","isArray","userValue","linkBase","map","pattern","override","listSize","Math","round","paragraphColor","operator","finalResult","pop"],"sourceRoot":"../../src","sources":["normalizeMarkdownStyle.web.ts"],"mappings":"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","ignoreList":[]} ++{"version":3,"names":["isStyleEqual","mergeSubStyle","normalizeLinkVariantEntries","normalizeLinkPillStyle","resolveAdmonitionColors","DEFAULT_HEADING_FONT_WEIGHT","HEADING_DEFAULTS","SYSTEM_FONT","MONOSPACE_FONT","defaultTextColor","baseHeader","fontFamily","fontWeight","marginTop","marginBottom","textAlign","DEFAULT_NORMALIZED_STYLE","Object","freeze","paragraph","fontSize","color","lineHeight","h1","h2","h3","h4","h5","h6","blockquote","borderColor","borderWidth","gapWidth","backgroundColor","borderRadius","padding","admonitions","undefined","list","bulletColor","bulletSize","markerMinWidth","markerColor","markerFontWeight","marginLeft","itemSpacing","codeBlock","syntaxColors","keyword","operatorColor","punctuation","string","number","constant","comment","function","type","variable","property","tag","attribute","embedded","link","underline","linkVariants","strong","em","fontStyle","strikethrough","code","image","height","maxHeight","aspectRatio","resizeMode","video","inlineImage","size","thematicBreak","table","headerFontFamily","headerBackgroundColor","headerTextColor","rowEvenBackgroundColor","rowOddBackgroundColor","cellPaddingHorizontal","cellPaddingVertical","horizontalOverflow","align","math","inlineMath","taskList","checkedColor","checkboxSize","checkboxBorderRadius","checkmarkColor","checkedTextColor","checkedStrikethrough","spoiler","particles","density","speed","solid","superscript","fontScale","baselineOffsetScale","subscript","highlight","refCache","WeakMap","structuralCache","LRU_MAX","styleReferenceKeys","keys","normalizeMarkdownStyle","style","length","refHit","get","structIdx","findIndex","e","entry","splice","unshift","set","result","forEach","key","Array","isArray","userValue","linkBase","map","pattern","override","iconTintColor","listSize","Math","round","paragraphColor","operator","finalResult","pop"],"sourceRoot":"../../src","sources":["normalizeMarkdownStyle.web.ts"],"mappings":"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","ignoreList":[]} +diff --git a/lib/module/types/media.js b/lib/module/types/media.js +new file mode 100644 +index 0000000000000000000000000000000000000000..dab2d1653ce3da767a7baa02bf41cd7f298b05b6 +--- /dev/null ++++ b/lib/module/types/media.js +@@ -0,0 +1,2 @@ ++"use strict"; ++//# sourceMappingURL=media.js.map +\ No newline at end of file +diff --git a/lib/module/types/media.js.map b/lib/module/types/media.js.map +new file mode 100644 +index 0000000000000000000000000000000000000000..005523763c066c72185889ea1013c941e82f911b +--- /dev/null ++++ b/lib/module/types/media.js.map +@@ -0,0 +1 @@ ++{"version":3,"names":[],"sourceRoot":"../../../src","sources":["types/media.ts"],"mappings":"","ignoreList":[]} +diff --git a/lib/module/utils/regexParser.js b/lib/module/utils/regexParser.js +index 6aa8f78d7f4fc0635a0272ee5adf70054950c835..45d748fcfbf75d07c3340e06bd36ad64d3f18d5f 100644 +--- a/lib/module/utils/regexParser.js ++++ b/lib/module/utils/regexParser.js +@@ -40,4 +40,10 @@ export const toNativeRegexConfig = regex => { + isDefault: false + }; + }; ++ ++/** Renderer recognition is opt-in, including when input normalization falls back. */ ++export const toNativeTextLinkRegexConfig = regex => { ++ const config = toNativeRegexConfig(regex ?? null); ++ return config.isDefault ? DISABLED_REGEX : config; ++}; + //# sourceMappingURL=regexParser.js.map +\ No newline at end of file +diff --git a/lib/module/utils/regexParser.js.map b/lib/module/utils/regexParser.js.map +index 4f280570d1deced993a29fd572c36bab9c30f49e..38e490b0258cf3e2e1168b6493b5415f38a89909 100644 +--- a/lib/module/utils/regexParser.js.map ++++ b/lib/module/utils/regexParser.js.map +@@ -1 +1 @@ +-{"version":3,"names":["DISABLED_REGEX","pattern","caseInsensitive","dotAll","isDisabled","isDefault","DEFAULT_REGEX","toNativeRegexConfig","regex","undefined","source","hasLookbehind","includes","lookbehindContent","match","test","__DEV__","console","error","ignoreCase"],"sourceRoot":"../../../src","sources":["utils/regexParser.ts"],"mappings":";;AAEA,MAAMA,cAA+B,GAAG;EACtCC,OAAO,EAAE,EAAE;EACXC,eAAe,EAAE,KAAK;EACtBC,MAAM,EAAE,KAAK;EACbC,UAAU,EAAE,IAAI;EAChBC,SAAS,EAAE;AACb,CAAC;AAED,MAAMC,aAA8B,GAAG;EACrCL,OAAO,EAAE,EAAE;EACXC,eAAe,EAAE,KAAK;EACtBC,MAAM,EAAE,KAAK;EACbC,UAAU,EAAE,KAAK;EACjBC,SAAS,EAAE;AACb,CAAC;AAED,OAAO,MAAME,mBAAmB,GAC9BC,KAAgC,IACZ;EACpB,IAAIA,KAAK,KAAK,IAAI,EAAE;IAClB,OAAOR,cAAc;EACvB;EAEA,IAAIQ,KAAK,KAAKC,SAAS,EAAE;IACvB,OAAOH,aAAa;EACtB;EAEA,MAAMI,MAAM,GAAGF,KAAK,CAACE,MAAM;EAE3B,MAAMC,aAAa,GAAGD,MAAM,CAACE,QAAQ,CAAC,MAAM,CAAC,IAAIF,MAAM,CAACE,QAAQ,CAAC,MAAM,CAAC;EAExE,IAAID,aAAa,EAAE;IACjB,MAAME,iBAAiB,GAAGH,MAAM,CAACI,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE;IACrE,IAAI,OAAO,CAACC,IAAI,CAACF,iBAAiB,CAAC,EAAE;MACnC,IAAIG,OAAO,EAAE;QACXC,OAAO,CAACC,KAAK,CACX,yEACF,CAAC;MACH;MAEA,OAAOZ,aAAa;IACtB;EACF;EAEA,OAAO;IACLL,OAAO,EAAES,MAAM;IACfR,eAAe,EAAEM,KAAK,CAACW,UAAU;IACjChB,MAAM,EAAEK,KAAK,CAACL,MAAM;IACpBC,UAAU,EAAE,KAAK;IACjBC,SAAS,EAAE;EACb,CAAC;AACH,CAAC","ignoreList":[]} ++{"version":3,"names":["DISABLED_REGEX","pattern","caseInsensitive","dotAll","isDisabled","isDefault","DEFAULT_REGEX","toNativeRegexConfig","regex","undefined","source","hasLookbehind","includes","lookbehindContent","match","test","__DEV__","console","error","ignoreCase","toNativeTextLinkRegexConfig","config"],"sourceRoot":"../../../src","sources":["utils/regexParser.ts"],"mappings":";;AAEA,MAAMA,cAA+B,GAAG;EACtCC,OAAO,EAAE,EAAE;EACXC,eAAe,EAAE,KAAK;EACtBC,MAAM,EAAE,KAAK;EACbC,UAAU,EAAE,IAAI;EAChBC,SAAS,EAAE;AACb,CAAC;AAED,MAAMC,aAA8B,GAAG;EACrCL,OAAO,EAAE,EAAE;EACXC,eAAe,EAAE,KAAK;EACtBC,MAAM,EAAE,KAAK;EACbC,UAAU,EAAE,KAAK;EACjBC,SAAS,EAAE;AACb,CAAC;AAED,OAAO,MAAME,mBAAmB,GAC9BC,KAAgC,IACZ;EACpB,IAAIA,KAAK,KAAK,IAAI,EAAE;IAClB,OAAOR,cAAc;EACvB;EAEA,IAAIQ,KAAK,KAAKC,SAAS,EAAE;IACvB,OAAOH,aAAa;EACtB;EAEA,MAAMI,MAAM,GAAGF,KAAK,CAACE,MAAM;EAE3B,MAAMC,aAAa,GAAGD,MAAM,CAACE,QAAQ,CAAC,MAAM,CAAC,IAAIF,MAAM,CAACE,QAAQ,CAAC,MAAM,CAAC;EAExE,IAAID,aAAa,EAAE;IACjB,MAAME,iBAAiB,GAAGH,MAAM,CAACI,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE;IACrE,IAAI,OAAO,CAACC,IAAI,CAACF,iBAAiB,CAAC,EAAE;MACnC,IAAIG,OAAO,EAAE;QACXC,OAAO,CAACC,KAAK,CACX,yEACF,CAAC;MACH;MAEA,OAAOZ,aAAa;IACtB;EACF;EAEA,OAAO;IACLL,OAAO,EAAES,MAAM;IACfR,eAAe,EAAEM,KAAK,CAACW,UAAU;IACjChB,MAAM,EAAEK,KAAK,CAACL,MAAM;IACpBC,UAAU,EAAE,KAAK;IACjBC,SAAS,EAAE;EACb,CAAC;AACH,CAAC;;AAED;AACA,OAAO,MAAMe,2BAA2B,GACtCZ,KAAgC,IACZ;EACpB,MAAMa,MAAM,GAAGd,mBAAmB,CAACC,KAAK,IAAI,IAAI,CAAC;EACjD,OAAOa,MAAM,CAAChB,SAAS,GAAGL,cAAc,GAAGqB,MAAM;AACnD,CAAC","ignoreList":[]} +diff --git a/lib/module/web/styles.js b/lib/module/web/styles.js +index dde8f0093080dd4612f49f157830cf8f1111e238..4d745c0fdcdee23b1108aa412d5e752c527cb41a 100644 +--- a/lib/module/web/styles.js ++++ b/lib/module/web/styles.js +@@ -314,7 +314,7 @@ export function linkStyleForUrl(style, url) { + const backgroundColor = resolved.backgroundColor; + return { + color: resolved.color, +- fontFamily: normalizeFontFamily(base.fontFamily), ++ fontFamily: normalizeFontFamily(resolved.fontFamily), + textDecoration: resolved.underline ? 'underline' : 'none', + ...(backgroundColor && backgroundColor !== 'transparent' ? { + backgroundColor +diff --git a/lib/module/web/styles.js.map b/lib/module/web/styles.js.map +index 01776d3f34bb046542243700bb61aaa6c60d64f1..a4d85f687dd0ad27fb9604ec967a9f9fe84f6c62 100644 +--- a/lib/module/web/styles.js.map ++++ b/lib/module/web/styles.js.map +@@ -1 +1 @@ +-{"version":3,"names":["normalizeFontFamily","value","undefined","VALID_FONT_WEIGHTS","Set","normalizeFontWeight","has","normalizeTextAlign","resolveColumnAlign","align","zeroTrailingMargins","style","paragraph","marginBottom","h1","h2","h3","h4","h5","h6","blockquote","list","codeBlock","thematicBreak","image","video","math","table","toHeadingLevel","level","clamped","Math","max","min","parseInt","baseBlock","block","fontSize","fontFamily","fontWeight","color","lineHeight","marginTop","textAlign","paragraphStyle","paragraphInBlockquoteStyle","headingStyle","blockquoteStyle","marginInlineStart","marginInlineEnd","paddingInlineStart","gapWidth","padding","paddingInlineEnd","paddingTop","paddingBottom","borderInlineStart","borderWidth","borderColor","borderRadius","backgroundColor","listStyle","isTaskList","listStylePosition","marginLeft","codeBlockStyle","border","margin","overflowX","direction","thematicBreakStyle","borderTop","height","width","RESIZE_MODE_TO_OBJECT_FIT","contain","cover","stretch","center","none","imageStyle","base","maxWidth","display","resizeMode","objectFit","aspectRatio","maxHeight","videoStyle","inlineImageStyle","size","inlineImage","verticalAlign","strongStyle","strong","emphasisStyle","emphasis","em","fontStyle","codeStyle","code","unicodeBidi","linkStyle","link","textDecoration","underline","_variantRegexCache","WeakMap","getCompiledVariantRegexes","variants","compiled","get","map","variant","RegExp","pattern","set","linkStyleForUrl","url","compiledVariantRegexes","linkVariants","variantIndex","findIndex","regex","test","resolved","strikethroughStyle","textDecorationLine","textDecorationColor","strikethrough","underlineStyle","superscriptStyle","fontScale","baselineOffsetScale","superscript","subscriptStyle","subscript","highlightStyle","highlight","mathInlineStyle","inlineMath","mathDisplayStyle","tableStyle","borderCollapse","listItemStyle","isTask","isFirstChild","itemSpacing","checkedTaskTextStyle","taskList","checkedTextColor","checkedStrikethrough","taskCheckboxDisabledStyle","taskCheckboxStyle","pointerEvents","cursor","checkboxSize","checkboxBorderRadius","accentColor","checkedColor","tableBodyRowStyle","rowIndex","rowEvenBackgroundColor","rowOddBackgroundColor","tableWrapperStyle","alignment","marginRight","overflowY","tableHeaderCellStyle","headerBackgroundColor","headerTextColor","headerFontFamily","cellPaddingVertical","cellPaddingHorizontal","tableCellStyle","parseErrorFallbackStyle","whiteSpace","stylesStore","buildStyles","cached","result","paragraphInBlockquote","listNested","listTask","codeBlockFont","mathInline","mathDisplay","tableWrapper","tableHeaderCell","left","right","default","tableCell","taskCheckbox","taskCheckboxDisabled"],"sourceRoot":"../../../src","sources":["web/styles.ts"],"mappings":"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","ignoreList":[]} ++{"version":3,"names":["normalizeFontFamily","value","undefined","VALID_FONT_WEIGHTS","Set","normalizeFontWeight","has","normalizeTextAlign","resolveColumnAlign","align","zeroTrailingMargins","style","paragraph","marginBottom","h1","h2","h3","h4","h5","h6","blockquote","list","codeBlock","thematicBreak","image","video","math","table","toHeadingLevel","level","clamped","Math","max","min","parseInt","baseBlock","block","fontSize","fontFamily","fontWeight","color","lineHeight","marginTop","textAlign","paragraphStyle","paragraphInBlockquoteStyle","headingStyle","blockquoteStyle","marginInlineStart","marginInlineEnd","paddingInlineStart","gapWidth","padding","paddingInlineEnd","paddingTop","paddingBottom","borderInlineStart","borderWidth","borderColor","borderRadius","backgroundColor","listStyle","isTaskList","listStylePosition","marginLeft","codeBlockStyle","border","margin","overflowX","direction","thematicBreakStyle","borderTop","height","width","RESIZE_MODE_TO_OBJECT_FIT","contain","cover","stretch","center","none","imageStyle","base","maxWidth","display","resizeMode","objectFit","aspectRatio","maxHeight","videoStyle","inlineImageStyle","size","inlineImage","verticalAlign","strongStyle","strong","emphasisStyle","emphasis","em","fontStyle","codeStyle","code","unicodeBidi","linkStyle","link","textDecoration","underline","_variantRegexCache","WeakMap","getCompiledVariantRegexes","variants","compiled","get","map","variant","RegExp","pattern","set","linkStyleForUrl","url","compiledVariantRegexes","linkVariants","variantIndex","findIndex","regex","test","resolved","strikethroughStyle","textDecorationLine","textDecorationColor","strikethrough","underlineStyle","superscriptStyle","fontScale","baselineOffsetScale","superscript","subscriptStyle","subscript","highlightStyle","highlight","mathInlineStyle","inlineMath","mathDisplayStyle","tableStyle","borderCollapse","listItemStyle","isTask","isFirstChild","itemSpacing","checkedTaskTextStyle","taskList","checkedTextColor","checkedStrikethrough","taskCheckboxDisabledStyle","taskCheckboxStyle","pointerEvents","cursor","checkboxSize","checkboxBorderRadius","accentColor","checkedColor","tableBodyRowStyle","rowIndex","rowEvenBackgroundColor","rowOddBackgroundColor","tableWrapperStyle","alignment","marginRight","overflowY","tableHeaderCellStyle","headerBackgroundColor","headerTextColor","headerFontFamily","cellPaddingVertical","cellPaddingHorizontal","tableCellStyle","parseErrorFallbackStyle","whiteSpace","stylesStore","buildStyles","cached","result","paragraphInBlockquote","listNested","listTask","codeBlockFont","mathInline","mathDisplay","tableWrapper","tableHeaderCell","left","right","default","tableCell","taskCheckbox","taskCheckboxDisabled"],"sourceRoot":"../../../src","sources":["web/styles.ts"],"mappings":"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","ignoreList":[]} +diff --git a/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts b/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +index 2fd15eea6cf92b99549507f8d7c9d3ddb3473ead..8b995d4aa7c95362e04e8dc00a91d8c69c3506aa 100644 +--- a/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts ++++ b/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +@@ -79,6 +79,17 @@ interface LinkVariantEntryInternal { + color: ColorValue; + underline: boolean; + backgroundColor: ColorValue; ++ fontFamily: string; ++ pill: boolean; ++ label: string; ++ iconUri: string; ++ iconTintColor?: ColorValue; ++ borderRadius: CodegenTypes.Float; ++ paddingHorizontal: CodegenTypes.Float; ++ paddingVertical: CodegenTypes.Float; ++ borderWidth: CodegenTypes.Float; ++ borderColor: ColorValue; ++ maxWidth: CodegenTypes.Float; + } + interface StrongStyleInternal { + fontFamily: string; +@@ -351,7 +362,86 @@ interface StreamingConfigInternal { + tableMode: string; + codeBlockMode: string; + } ++interface TextLinkNativeRegex { ++ pattern: string; ++ caseInsensitive: boolean; ++ dotAll: boolean; ++ isDisabled: boolean; ++ isDefault: boolean; ++} ++export interface DocumentAssetInternal { ++ anchor: string; ++ id: string; ++ kind: string; ++ url: string; ++ altText: string; ++ title: string; ++ placement: string; ++ eligible: boolean; ++} ++export interface DocumentAssetsEventInternal { ++ revision: CodegenTypes.Int32; ++ assets: { ++ anchor: string; ++ id: string; ++ kind: string; ++ url: string; ++ altText: string; ++ title: string; ++ placement: string; ++ eligible: boolean; ++ }[]; ++} ++export interface MediaFrameInternal { ++ id: string; ++ x: CodegenTypes.Float; ++ y: CodegenTypes.Float; ++ width: CodegenTypes.Float; ++ height: CodegenTypes.Float; ++} ++export interface MediaLayoutEventInternal { ++ revision: CodegenTypes.Int32; ++ frames: { ++ id: string; ++ x: CodegenTypes.Float; ++ y: CodegenTypes.Float; ++ width: CodegenTypes.Float; ++ height: CodegenTypes.Float; ++ }[]; ++} ++export interface MediaOverrideInternal { ++ url: string; ++ kind: string; ++ anchor: string; ++ id: string; ++ height: CodegenTypes.Float; ++ width: CodegenTypes.Float; ++} ++export interface ImageSourceInternal { ++ id: string; ++ url: string; ++ anchor: string; ++ uri: string; ++ headers: ReadonlyArray>; ++ useDefault: boolean; ++} + export interface NativeProps extends ViewProps { ++ enableImageSourceResolution?: CodegenTypes.WithDefault; ++ imageSourcesRevision?: CodegenTypes.WithDefault; ++ imageSourcesContinuityStart?: CodegenTypes.WithDefault; ++ imageSources?: ReadonlyArray>; ++ documentRevision?: CodegenTypes.WithDefault; ++ enableDocumentAssets?: CodegenTypes.WithDefault; ++ enableMediaSlots?: CodegenTypes.WithDefault; ++ mediaOverridesRevision?: CodegenTypes.WithDefault; ++ mediaOverrides?: ReadonlyArray>; ++ onDocumentAssets?: CodegenTypes.DirectEventHandler; ++ onMediaLayout?: CodegenTypes.DirectEventHandler; ++ linkRegex?: Readonly; ++ inlineCodeLinkRegex?: Readonly; + /** + * Markdown content to render. + */ +diff --git a/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map b/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +index 48e42b9ac1cb79b3aee796a2c55ddf9dcfc4174c..dddaecfab08a143eccf89955a840f34e0752ca87 100644 +--- a/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map ++++ b/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +@@ -1 +1 @@ +-{"version":3,"file":"EnrichedMarkdownNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/EnrichedMarkdownNativeComponent.ts"],"names":[],"mappings":"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"} +\ No newline at end of file ++{"version":3,"file":"EnrichedMarkdownNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/EnrichedMarkdownNativeComponent.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts b/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +index 11572f06f21502dfab016495ad7ec3dad1874876..28379bf3f53eb02db71fa49069bcf1b9a9423d16 100644 +--- a/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts ++++ b/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +@@ -79,6 +79,17 @@ interface LinkVariantEntryInternal { + color: ColorValue; + underline: boolean; + backgroundColor: ColorValue; ++ fontFamily: string; ++ pill: boolean; ++ label: string; ++ iconUri: string; ++ iconTintColor?: ColorValue; ++ borderRadius: CodegenTypes.Float; ++ paddingHorizontal: CodegenTypes.Float; ++ paddingVertical: CodegenTypes.Float; ++ borderWidth: CodegenTypes.Float; ++ borderColor: ColorValue; ++ maxWidth: CodegenTypes.Float; + } + interface StrongStyleInternal { + fontFamily: string; +@@ -351,7 +362,16 @@ interface StreamingConfigInternal { + tableMode: string; + codeBlockMode: string; + } ++interface TextLinkNativeRegex { ++ pattern: string; ++ caseInsensitive: boolean; ++ dotAll: boolean; ++ isDisabled: boolean; ++ isDefault: boolean; ++} + export interface NativeProps extends ViewProps { ++ linkRegex?: Readonly; ++ inlineCodeLinkRegex?: Readonly; + /** + * Markdown content to render. + */ +diff --git a/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map b/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +index 3fca5357839d5a384796ad528d623a9646a8b4f3..91b2e26b14100d6232e0ed22b655cac8cf09074e 100644 +--- a/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map ++++ b/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +@@ -1 +1 @@ +-{"version":3,"file":"EnrichedMarkdownTextNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/EnrichedMarkdownTextNativeComponent.ts"],"names":[],"mappings":"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"} +\ No newline at end of file ++{"version":3,"file":"EnrichedMarkdownTextNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/EnrichedMarkdownTextNativeComponent.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/lib/typescript/src/imageSourceState.d.ts b/lib/typescript/src/imageSourceState.d.ts +new file mode 100644 +index 0000000000000000000000000000000000000000..97a0831ddf6feefb8ea0f844d58a761badecfca3 +--- /dev/null ++++ b/lib/typescript/src/imageSourceState.d.ts +@@ -0,0 +1,23 @@ ++import type { ImageSourceInternal } from './EnrichedMarkdownNativeComponent'; ++import type { EnrichedMarkdownTextProps } from './types/MarkdownTextProps'; ++import type { MarkdownMediaAsset } from './types/media'; ++export type NativeImageAsset = MarkdownMediaAsset & { ++ anchor: string; ++}; ++type Resolver = NonNullable; ++/** Per-occurrence decisions; superseded promises still count against the bound. */ ++export declare class ImageSourceState { ++ private resolver?; ++ private lineage; ++ private entries; ++ private active; ++ private running; ++ private changed?; ++ configure(resolver: Resolver | undefined, lineage: number, assets: NativeImageAsset[]): void; ++ sources(): ImageSourceInternal[]; ++ start(changed: () => void): void; ++ stop(): void; ++ private pump; ++} ++export {}; ++//# sourceMappingURL=imageSourceState.d.ts.map +\ No newline at end of file +diff --git a/lib/typescript/src/imageSourceState.d.ts.map b/lib/typescript/src/imageSourceState.d.ts.map +new file mode 100644 +index 0000000000000000000000000000000000000000..844f7b3cd918c8abecdf367b5b2cd48f941de926 +--- /dev/null ++++ b/lib/typescript/src/imageSourceState.d.ts.map +@@ -0,0 +1 @@ ++{"version":3,"file":"imageSourceState.d.ts","sourceRoot":"","sources":["../../../src/imageSourceState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AACvE,KAAK,QAAQ,GAAG,WAAW,CAAC,yBAAyB,CAAC,oBAAoB,CAAC,CAAC,CAAC;AAW7E,mFAAmF;AACnF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,CAAW;IAC5B,OAAO,CAAC,OAAO,CAAM;IACrB,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAC,CAAa;IAE7B,SAAS,CACP,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,gBAAgB,EAAE;IAuB5B,OAAO,IAAI,mBAAmB,EAAE;IAMhC,KAAK,CAAC,OAAO,EAAE,MAAM,IAAI;IAMzB,IAAI;IAMJ,OAAO,CAAC,IAAI;CA4Cb"} +\ No newline at end of file +diff --git a/lib/typescript/src/index.d.ts b/lib/typescript/src/index.d.ts +index 46496a5325e79c553d83cf8128016ce1d7a874cc..b0290881c5043de1060731a76812c055fb219ec0 100644 +--- a/lib/typescript/src/index.d.ts ++++ b/lib/typescript/src/index.d.ts +@@ -1,3 +1,4 @@ ++export type { LinkVariantStyle } from './types/MarkdownStyle'; + export { default as EnrichedMarkdownText } from './native/EnrichedMarkdownText'; + export type { EnrichedMarkdownTextProps, StreamingConfig, MarkdownStyle, Md4cFlags, ContextMenuItem as TextContextMenuItem, SelectionMenuConfig as TextSelectionMenuConfig, SelectionMenuPluralLabels as TextSelectionMenuPluralLabels, } from './native/EnrichedMarkdownText'; + export type { LinkPressEvent, LinkLongPressEvent, ImagePressEvent, TaskListItemPressEvent, CopyPressEvent, LatexErrorEvent, CodeBlockPressEvent, } from './types/events'; +@@ -5,4 +6,5 @@ export type { AccessibilityLabels, ResolvedAccessibilityLabels, } from './types/ + export { DEFAULT_ACCESSIBILITY_LABELS, resolveAccessibilityLabels, } from './accessibilityLabelDefaults'; + export { EnrichedMarkdownTextInput } from './EnrichedMarkdownTextInput'; + export type { EnrichedMarkdownTextInputProps, EnrichedMarkdownTextInputInstance, MarkdownTextInputStyle, StyleState, ContextMenuItem, InputSelectionMenuConfig, FormatMenuConfig, OnKeyPressEvent, OnLinkDetected, OnStartMentionEvent, OnChangeMentionEvent, OnEndMentionEvent, CaretRect, HeadingLevel, HeadingStyle, } from './EnrichedMarkdownTextInput'; ++export type { MarkdownAssetPlacement, MarkdownMediaAsset, MarkdownImageSource, MarkdownLinkAsset, MarkdownDocumentAsset, DocumentAssetsEvent, } from './types/media'; + //# sourceMappingURL=index.d.ts.map +\ No newline at end of file +diff --git a/lib/typescript/src/index.d.ts.map b/lib/typescript/src/index.d.ts.map +index c2863d1b435aed9117cf65de4ca4bd8a345cde26..423f68150a88f61a45c110299c4faf135f05e20c 100644 +--- a/lib/typescript/src/index.d.ts.map ++++ b/lib/typescript/src/index.d.ts.map +@@ -1 +1 @@ +-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAChF,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,aAAa,EACb,SAAS,EACT,eAAe,IAAI,mBAAmB,EACtC,mBAAmB,IAAI,uBAAuB,EAC9C,yBAAyB,IAAI,6BAA6B,GAC3D,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EACV,8BAA8B,EAC9B,iCAAiC,EACjC,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,wBAAwB,EACxB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,YAAY,GACb,MAAM,6BAA6B,CAAC"} +\ No newline at end of file ++{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAChF,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,aAAa,EACb,SAAS,EACT,eAAe,IAAI,mBAAmB,EACtC,mBAAmB,IAAI,uBAAuB,EAC9C,yBAAyB,IAAI,6BAA6B,GAC3D,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EACV,8BAA8B,EAC9B,iCAAiC,EACjC,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,wBAAwB,EACxB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,YAAY,GACb,MAAM,6BAA6B,CAAC;AAErC,YAAY,EACV,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,eAAe,CAAC"} +\ No newline at end of file +diff --git a/lib/typescript/src/jest/index.d.ts b/lib/typescript/src/jest/index.d.ts +index 1640dcc465e7320663a13e340824a0ba3007233c..d0061c29b488605d1d6df6d40795735d05dd7248 100644 +--- a/lib/typescript/src/jest/index.d.ts ++++ b/lib/typescript/src/jest/index.d.ts +@@ -2,5 +2,5 @@ import type { EnrichedMarkdownTextInputProps } from '../EnrichedMarkdownTextInpu + import type { EnrichedMarkdownTextProps } from '../native/EnrichedMarkdownText'; + export { DEFAULT_ACCESSIBILITY_LABELS, resolveAccessibilityLabels, } from '../accessibilityLabelDefaults'; + export declare const EnrichedMarkdownTextInput: ({ ref, defaultValue, onChangeText, onChangeMarkdown, onFocus, onBlur, editable, placeholder, placeholderTextColor, autoFocus, multiline, scrollEnabled, style, testID, accessible, accessibilityLabel, accessibilityHint, accessibilityRole, accessibilityState, nativeID, markdownStyle: _markdownStyle, cursorColor: _cursorColor, selectionColor: _selectionColor, autoCapitalize: _autoCapitalize, onChangeSelection: _onChangeSelection, onChangeState: _onChangeState, onKeyPress: _onKeyPress, onCaretRectChange: _onCaretRectChange, onLinkDetected: _onLinkDetected, mentionIndicators: _mentionIndicators, onStartMention: _onStartMention, onChangeMention: _onChangeMention, onEndMention: _onEndMention, contextMenuItems: _contextMenuItems, selectionMenuConfig: _selectionMenuConfig, formatMenuConfig: _formatMenuConfig, linkRegex: _linkRegex, writingDirection: _writingDirection, }: EnrichedMarkdownTextInputProps) => import("react/jsx-runtime").JSX.Element; +-export declare const EnrichedMarkdownText: ({ markdown, containerStyle, testID, accessible, accessibilityLabel, accessibilityHint, accessibilityRole, accessibilityState, nativeID, markdownStyle: _markdownStyle, onLinkPress, onLinkLongPress, onTaskListItemPress, enableLinkPreview: _enableLinkPreview, selectable: _selectable, md4cFlags: _md4cFlags, allowFontScaling: _allowFontScaling, maxFontSizeMultiplier: _maxFontSizeMultiplier, allowTrailingMargin: _allowTrailingMargin, flavor: _flavor, streamingAnimation: _streamingAnimation, streamingConfig: _streamingConfig, spoilerOverlay: _spoilerOverlay, contextMenuItems: _contextMenuItems, imageRequestHeaders: _imageRequestHeaders, selectionMenuConfig: _selectionMenuConfig, accessibilityLabels: _accessibilityLabels, selectionColor: _selectionColor, selectionHandleColor: _selectionHandleColor, textBreakStrategy: _textBreakStrategy, lineBreakStrategyIOS: _lineBreakStrategyIOS, writingDirection: _writingDirection, }: EnrichedMarkdownTextProps) => import("react/jsx-runtime").JSX.Element; ++export declare const EnrichedMarkdownText: ({ markdown, containerStyle, testID, accessible, accessibilityLabel, accessibilityHint, accessibilityRole, accessibilityState, nativeID, markdownStyle: _markdownStyle, onLinkPress, onLinkLongPress, onTaskListItemPress, enableLinkPreview: _enableLinkPreview, selectable: _selectable, md4cFlags: _md4cFlags, allowFontScaling: _allowFontScaling, maxFontSizeMultiplier: _maxFontSizeMultiplier, allowTrailingMargin: _allowTrailingMargin, flavor: _flavor, streamingAnimation: _streamingAnimation, streamingConfig: _streamingConfig, spoilerOverlay: _spoilerOverlay, contextMenuItems: _contextMenuItems, imageRequestHeaders: _imageRequestHeaders, resolveImageSource: _resolveImageSource, selectionMenuConfig: _selectionMenuConfig, accessibilityLabels: _accessibilityLabels, selectionColor: _selectionColor, selectionHandleColor: _selectionHandleColor, textBreakStrategy: _textBreakStrategy, lineBreakStrategyIOS: _lineBreakStrategyIOS, writingDirection: _writingDirection, }: EnrichedMarkdownTextProps) => import("react/jsx-runtime").JSX.Element; + //# sourceMappingURL=index.d.ts.map +\ No newline at end of file +diff --git a/lib/typescript/src/jest/index.d.ts.map b/lib/typescript/src/jest/index.d.ts.map +index e5a7a11601241d44583b9f00c1a1bf4e088cd7ac..570efcf12b442a8b595cd12a895c3b9ad7cac1ce 100644 +--- a/lib/typescript/src/jest/index.d.ts.map ++++ b/lib/typescript/src/jest/index.d.ts.map +@@ -1 +1 @@ +-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/jest/index.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAGV,8BAA8B,EAC/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAOhF,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,+BAA+B,CAAC;AASvC,eAAO,MAAM,yBAAyB,GAAI,02BAuCvC,8BAA8B,4CA2EhC,CAAC;AA6HF,eAAO,MAAM,oBAAoB,GAAI,85BAiClC,yBAAyB,4CAmB3B,CAAC"} +\ No newline at end of file ++{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/jest/index.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAGV,8BAA8B,EAC/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAOhF,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,+BAA+B,CAAC;AASvC,eAAO,MAAM,yBAAyB,GAAI,02BAuCvC,8BAA8B,4CA2EhC,CAAC;AA6HF,eAAO,MAAM,oBAAoB,GAAI,u8BAkClC,yBAAyB,4CAmB3B,CAAC"} +\ No newline at end of file +diff --git a/lib/typescript/src/linkVariantUtils.d.ts b/lib/typescript/src/linkVariantUtils.d.ts +index 17139662039594be8780398f8dd5de4e774478f9..7003bc7c09ab814c4087c353431a5f3f65231c94 100644 +--- a/lib/typescript/src/linkVariantUtils.d.ts ++++ b/lib/typescript/src/linkVariantUtils.d.ts +@@ -1,5 +1,16 @@ + import type { LinkVariantStyle } from './types/MarkdownStyle'; + type LinkVariantEntry = [pattern: string, style: LinkVariantStyle]; + export declare function normalizeLinkVariantEntries(linkVariants?: Record): LinkVariantEntry[]; ++/** Native pill geometry is finite and nonnegative before crossing codegen. */ ++export declare function normalizeLinkPillStyle(style: LinkVariantStyle): { ++ pill: boolean; ++ label: string; ++ iconUri: string; ++ borderRadius: number; ++ paddingHorizontal: number; ++ paddingVertical: number; ++ borderWidth: number; ++ maxWidth: number; ++}; + export {}; + //# sourceMappingURL=linkVariantUtils.d.ts.map +\ No newline at end of file +diff --git a/lib/typescript/src/linkVariantUtils.d.ts.map b/lib/typescript/src/linkVariantUtils.d.ts.map +index 7a2a032f991fa0a5361700973afbd988207e09b7..da46e5b0ef0602a9bbdc6506e2112f7a7525cc1b 100644 +--- a/lib/typescript/src/linkVariantUtils.d.ts.map ++++ b/lib/typescript/src/linkVariantUtils.d.ts.map +@@ -1 +1 @@ +-{"version":3,"file":"linkVariantUtils.d.ts","sourceRoot":"","sources":["../../../src/linkVariantUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,KAAK,gBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;AAiBnE,wBAAgB,2BAA2B,CACzC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAC9C,gBAAgB,EAAE,CAoBpB"} +\ No newline at end of file ++{"version":3,"file":"linkVariantUtils.d.ts","sourceRoot":"","sources":["../../../src/linkVariantUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,KAAK,gBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;AAiBnE,wBAAgB,2BAA2B,CACzC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAC9C,gBAAgB,EAAE,CAoBpB;AAED,8EAA8E;AAC9E,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,gBAAgB;;;;;;;;;EAe7D"} +\ No newline at end of file +diff --git a/lib/typescript/src/mediaSlotState.d.ts b/lib/typescript/src/mediaSlotState.d.ts +new file mode 100644 +index 0000000000000000000000000000000000000000..4ac70c5459463b25c0db4af6dab704af5372a55b +--- /dev/null ++++ b/lib/typescript/src/mediaSlotState.d.ts +@@ -0,0 +1,14 @@ ++import type { MediaFrameInternal } from './EnrichedMarkdownNativeComponent'; ++export interface MediaMeasurement { ++ id: string; ++ width: number; ++ height: number; ++} ++export declare const sameMediaSize: (a: number, b: number) => boolean; ++/** Accept only finite native frames with usable widths. */ ++export declare const validMediaFrames: (frames: readonly MediaFrameInternal[]) => MediaFrameInternal[]; ++/** A width change requires React to measure again before native uses the height. */ ++export declare const mediaOverrideForFrame: (id: string, frame: MediaFrameInternal | undefined, measurement: MediaMeasurement | undefined) => MediaMeasurement; ++/** Reject stale onLayout callbacks and suppress subpixel feedback loops. */ ++export declare const acceptMediaMeasurement: (eventRevision: number, revision: number, frame: MediaFrameInternal | undefined, next: MediaMeasurement, previous: MediaMeasurement | undefined) => boolean; ++//# sourceMappingURL=mediaSlotState.d.ts.map +\ No newline at end of file +diff --git a/lib/typescript/src/mediaSlotState.d.ts.map b/lib/typescript/src/mediaSlotState.d.ts.map +new file mode 100644 +index 0000000000000000000000000000000000000000..a8c18129cd717121decfd68b5b5e814066fb69c1 +--- /dev/null ++++ b/lib/typescript/src/mediaSlotState.d.ts.map +@@ -0,0 +1 @@ ++{"version":3,"file":"mediaSlotState.d.ts","sourceRoot":"","sources":["../../../src/mediaSlotState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAE5E,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,aAAa,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,YAA0B,CAAC;AAE7E,2DAA2D;AAC3D,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,SAAS,kBAAkB,EAAE,KACpC,kBAAkB,EAIlB,CAAC;AAEJ,oFAAoF;AACpF,eAAO,MAAM,qBAAqB,GAChC,IAAI,MAAM,EACV,OAAO,kBAAkB,GAAG,SAAS,EACrC,aAAa,gBAAgB,GAAG,SAAS,KACxC,gBAG8B,CAAC;AAElC,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,GACjC,eAAe,MAAM,EACrB,UAAU,MAAM,EAChB,OAAO,kBAAkB,GAAG,SAAS,EACrC,MAAM,gBAAgB,EACtB,UAAU,gBAAgB,GAAG,SAAS,KACrC,OAU8C,CAAC"} +\ No newline at end of file +diff --git a/lib/typescript/src/native/EnrichedMarkdownText.d.ts b/lib/typescript/src/native/EnrichedMarkdownText.d.ts +index 6a1c672c2ac8ac257eb94b116583a8b584709046..985ea633b05acff479d0aff48dc6db20a1361d88 100644 +--- a/lib/typescript/src/native/EnrichedMarkdownText.d.ts ++++ b/lib/typescript/src/native/EnrichedMarkdownText.d.ts +@@ -4,6 +4,6 @@ import type { LinkPressEvent, LinkLongPressEvent, ImagePressEvent, TaskListItemP + export type { MarkdownStyle, Md4cFlags }; + export type { EnrichedMarkdownTextProps, StreamingConfig, ContextMenuItem, SelectionMenuConfig, SelectionMenuPluralLabels, }; + export type { LinkPressEvent, LinkLongPressEvent, ImagePressEvent, TaskListItemPressEvent, CopyPressEvent, LatexErrorEvent, CodeBlockPressEvent, }; +-export declare const EnrichedMarkdownText: ({ markdown, markdownStyle, containerStyle, onLinkPress, onLinkLongPress, onImagePress, onTaskListItemPress, enableTaskListItemToggle, onCopyPress, onLatexError, onCodeBlockPress, enableBlockContextMenu, enableLinkPreview, selectable, md4cFlags, allowFontScaling, maxFontSizeMultiplier, allowTrailingMargin, flavor, streamingAnimation, streamingConfig, spoilerOverlay, contextMenuItems, imageRequestHeaders, selectionMenuConfig, accessibilityLabels, selectionColor, selectionHandleColor, textBreakStrategy, lineBreakStrategyIOS, writingDirection, numberOfLines, ellipsizeMode, ...rest }: EnrichedMarkdownTextProps) => import("react/jsx-runtime").JSX.Element; ++export declare const EnrichedMarkdownText: ({ markdown, linkRegex: _linkRegex, inlineCodeLinkRegex: _inlineCodeLinkRegex, markdownStyle, containerStyle, onLinkPress, onLinkLongPress, onImagePress, renderMedia, resolveImageSource, onDocumentAssets, onTaskListItemPress, enableTaskListItemToggle, onCopyPress, onLatexError, onCodeBlockPress, enableBlockContextMenu, enableLinkPreview, selectable, md4cFlags, allowFontScaling, maxFontSizeMultiplier, allowTrailingMargin, flavor, streamingAnimation, streamingConfig, spoilerOverlay, contextMenuItems, imageRequestHeaders, selectionMenuConfig, accessibilityLabels, selectionColor, selectionHandleColor, textBreakStrategy, lineBreakStrategyIOS, writingDirection, numberOfLines, ellipsizeMode, ...rest }: EnrichedMarkdownTextProps) => import("react/jsx-runtime").JSX.Element; + export default EnrichedMarkdownText; + //# sourceMappingURL=EnrichedMarkdownText.d.ts.map +\ No newline at end of file +diff --git a/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map b/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +index d99c4224b331b298175e9d32e24d6f8cc572d01a..7325ad7b010f50d5617ceea4486cef128494a7cc 100644 +--- a/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map ++++ b/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +@@ -1 +1 @@ +-{"version":3,"file":"EnrichedMarkdownText.d.ts","sourceRoot":"","sources":["../../../../src/native/EnrichedMarkdownText.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,KAAK,EACV,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,mBAAmB,EAEpB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AACzC,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,yBAAyB,GAC1B,CAAC;AACF,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,mBAAmB,GACpB,CAAC;AA0EF,eAAO,MAAM,oBAAoB,GAAI,2kBAmClC,yBAAyB,4CAuO3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"} +\ No newline at end of file ++{"version":3,"file":"EnrichedMarkdownText.d.ts","sourceRoot":"","sources":["../../../../src/native/EnrichedMarkdownText.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,KAAK,EACV,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,mBAAmB,EAEpB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AACzC,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,yBAAyB,GAC1B,CAAC;AACF,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,mBAAmB,GACpB,CAAC;AA0EF,eAAO,MAAM,oBAAoB,GAAI,gsBAwClC,yBAAyB,4CAwR3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"} +\ No newline at end of file +diff --git a/lib/typescript/src/native/useImageSources.d.ts b/lib/typescript/src/native/useImageSources.d.ts +new file mode 100644 +index 0000000000000000000000000000000000000000..90480fa0f74c772e267c6cab2d94f28feab3fd6b +--- /dev/null ++++ b/lib/typescript/src/native/useImageSources.d.ts +@@ -0,0 +1,9 @@ ++import type { NativeImageAsset } from '../imageSourceState'; ++import type { EnrichedMarkdownTextProps } from '../types/MarkdownTextProps'; ++export declare function useImageSources(resolver: EnrichedMarkdownTextProps['resolveImageSource'], continuityStart: number, assetsRevision: number, assets: NativeImageAsset[]): { ++ enableImageSourceResolution: boolean; ++ imageSourcesContinuityStart: number; ++ imageSourcesRevision: number; ++ imageSources: import("../EnrichedMarkdownNativeComponent").ImageSourceInternal[]; ++}; ++//# sourceMappingURL=useImageSources.d.ts.map +\ No newline at end of file +diff --git a/lib/typescript/src/native/useImageSources.d.ts.map b/lib/typescript/src/native/useImageSources.d.ts.map +new file mode 100644 +index 0000000000000000000000000000000000000000..441a78598ecf861f68dfefacab3784e923301ea4 +--- /dev/null ++++ b/lib/typescript/src/native/useImageSources.d.ts.map +@@ -0,0 +1 @@ ++{"version":3,"file":"useImageSources.d.ts","sourceRoot":"","sources":["../../../../src/native/useImageSources.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAE5E,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,yBAAyB,CAAC,oBAAoB,CAAC,EACzD,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,gBAAgB,EAAE;;;;;EAmB3B"} +\ No newline at end of file +diff --git a/lib/typescript/src/native/useMediaSlots.d.ts b/lib/typescript/src/native/useMediaSlots.d.ts +new file mode 100644 +index 0000000000000000000000000000000000000000..5b9265f5f2365e1fa810e320be9f982ca9f69ff6 +--- /dev/null ++++ b/lib/typescript/src/native/useMediaSlots.d.ts +@@ -0,0 +1,28 @@ ++import type { LayoutChangeEvent, NativeSyntheticEvent } from 'react-native'; ++import type { DocumentAssetsEventInternal, MediaLayoutEventInternal } from '../EnrichedMarkdownNativeComponent'; ++import type { EnrichedMarkdownTextProps } from '../types/MarkdownTextProps'; ++export declare function useMediaSlots(markdown: string, parserKey: string, renderMedia: EnrichedMarkdownTextProps['renderMedia'], onDocumentAssets: EnrichedMarkdownTextProps['onDocumentAssets'], resolveImageSource: EnrichedMarkdownTextProps['resolveImageSource']): { ++ slots: (import("react/jsx-runtime").JSX.Element | null)[]; ++ onNativeLayout: ({ nativeEvent }: LayoutChangeEvent) => void; ++ nativeProps: { ++ documentRevision: number; ++ enableDocumentAssets: boolean; ++ enableMediaSlots: boolean; ++ mediaOverridesRevision: number; ++ mediaOverrides: { ++ id: string; ++ height: number; ++ width: number; ++ url: string; ++ kind: "video" | "image"; ++ anchor: string; ++ }[]; ++ onDocumentAssets: (event: NativeSyntheticEvent) => void; ++ onMediaLayout: (event: NativeSyntheticEvent) => void; ++ enableImageSourceResolution: boolean; ++ imageSourcesContinuityStart: number; ++ imageSourcesRevision: number; ++ imageSources: import("../EnrichedMarkdownNativeComponent").ImageSourceInternal[]; ++ }; ++}; ++//# sourceMappingURL=useMediaSlots.d.ts.map +\ No newline at end of file +diff --git a/lib/typescript/src/native/useMediaSlots.d.ts.map b/lib/typescript/src/native/useMediaSlots.d.ts.map +new file mode 100644 +index 0000000000000000000000000000000000000000..1d0ea5399f2d38532398cbca02cc7febd1e44457 +--- /dev/null ++++ b/lib/typescript/src/native/useMediaSlots.d.ts.map +@@ -0,0 +1 @@ ++{"version":3,"file":"useMediaSlots.d.ts","sourceRoot":"","sources":["../../../../src/native/useMediaSlots.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,KAAK,EACV,2BAA2B,EAC3B,wBAAwB,EAEzB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AA4B5E,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,yBAAyB,CAAC,aAAa,CAAC,EACrD,gBAAgB,EAAE,yBAAyB,CAAC,kBAAkB,CAAC,EAC/D,kBAAkB,EAAE,yBAAyB,CAAC,oBAAoB,CAAC;;sCAgK1B,iBAAiB;;;;;;;;;;;;;;kCAzEjD,oBAAoB,CAAC,2BAA2B,CAAC;+BAkCjD,oBAAoB,CAAC,wBAAwB,CAAC;;;;;;EAoIxD"} +\ No newline at end of file +diff --git a/lib/typescript/src/normalizeMarkdownStyle.d.ts.map b/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +index 9a11306c12c94675cf05a157abc971c54e1db8bc..d8507b4a8f51ea3fdd8067e515975be109ebfbd0 100644 +--- a/lib/typescript/src/normalizeMarkdownStyle.d.ts.map ++++ b/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +@@ -1 +1 @@ +-{"version":3,"file":"normalizeMarkdownStyle.d.ts","sourceRoot":"","sources":["../../../src/normalizeMarkdownStyle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAIV,qBAAqB,EACtB,MAAM,+BAA+B,CAAC;AAsSvC,eAAO,MAAM,sBAAsB,GACjC,OAAO,aAAa,KACnB,qBA4GF,CAAC"} +\ No newline at end of file ++{"version":3,"file":"normalizeMarkdownStyle.d.ts","sourceRoot":"","sources":["../../../src/normalizeMarkdownStyle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAIV,qBAAqB,EACtB,MAAM,+BAA+B,CAAC;AAySvC,eAAO,MAAM,sBAAsB,GACjC,OAAO,aAAa,KACnB,qBAmHF,CAAC"} +\ No newline at end of file +diff --git a/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map b/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +index b964e9e107bc0b9ddfdb141d5c22f00497f9b133..c92cc24d9393436a4405fc1ba89988615f6c94f5 100644 +--- a/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map ++++ b/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +@@ -1 +1 @@ +-{"version":3,"file":"normalizeMarkdownStyle.web.d.ts","sourceRoot":"","sources":["../../../src/normalizeMarkdownStyle.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAIV,qBAAqB,EACtB,MAAM,+BAA+B,CAAC;AAwPvC,eAAO,MAAM,sBAAsB,GACjC,OAAO,aAAa,KACnB,qBAwFF,CAAC"} +\ No newline at end of file ++{"version":3,"file":"normalizeMarkdownStyle.web.d.ts","sourceRoot":"","sources":["../../../src/normalizeMarkdownStyle.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAIV,qBAAqB,EACtB,MAAM,+BAA+B,CAAC;AA2PvC,eAAO,MAAM,sBAAsB,GACjC,OAAO,aAAa,KACnB,qBA4FF,CAAC"} +\ No newline at end of file +diff --git a/lib/typescript/src/types/MarkdownStyle.d.ts b/lib/typescript/src/types/MarkdownStyle.d.ts +index 34f22f3eb614338da146f6c93a378832e11f7046..a275469457d857b50abe6a1305b6f4ffdf238676 100644 +--- a/lib/typescript/src/types/MarkdownStyle.d.ts ++++ b/lib/typescript/src/types/MarkdownStyle.d.ts +@@ -114,6 +114,22 @@ export interface LinkVariantStyle { + color?: string; + underline?: boolean; + backgroundColor?: string; ++ fontFamily?: string; ++ /** Render the link as one native pill. Original text and URL remain selectable. */ ++ pill?: boolean; ++ /** Presentation label only. Missing or empty uses the original link text. */ ++ label?: string; ++ /** Local file:// image URI. Unreadable files are ignored. Native pills only. */ ++ iconUri?: string; ++ /** Optional source-in icon tint. Omitted preserves original image colors and alpha. */ ++ iconTintColor?: string; ++ borderRadius?: number; ++ paddingHorizontal?: number; ++ paddingVertical?: number; ++ borderWidth?: number; ++ borderColor?: string; ++ /** Maximum pill width in points/DIP. 0 uses the available text width. */ ++ maxWidth?: number; + } + interface StrongStyle { + fontFamily?: string; +@@ -326,7 +342,8 @@ export interface MarkdownStyle { + * + * `color` and `underline` inherit from the base `link` style when omitted. + * `backgroundColor` defaults to `transparent`. +- * `fontFamily` always follows the base `link` style and cannot be overridden per-variant. ++ * `fontFamily` inherits the base `link` family and can be overridden per variant. ++ * `pill: true` enables atomic native presentation with optional label, icon, and geometry. + * + * @example + * linkVariants: { +diff --git a/lib/typescript/src/types/MarkdownStyle.d.ts.map b/lib/typescript/src/types/MarkdownStyle.d.ts.map +index de80055783d57781bcb2dd860ecaf933fa28c086..d5168a7ef595e8087d1103d4019439150bae1351 100644 +--- a/lib/typescript/src/types/MarkdownStyle.d.ts.map ++++ b/lib/typescript/src/types/MarkdownStyle.d.ts.map +@@ -1 +1 @@ +-{"version":3,"file":"MarkdownStyle.d.ts","sourceRoot":"","sources":["../../../../src/types/MarkdownStyle.ts"],"names":[],"mappings":"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"} +\ No newline at end of file ++{"version":3,"file":"MarkdownStyle.d.ts","sourceRoot":"","sources":["../../../../src/types/MarkdownStyle.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/lib/typescript/src/types/MarkdownStyleInternal.d.ts b/lib/typescript/src/types/MarkdownStyleInternal.d.ts +index 45eef337364aa7e5806e4769ab794c5c77737f33..993d6daf572ca7958d5811e21563c47ae8fffd57 100644 +--- a/lib/typescript/src/types/MarkdownStyleInternal.d.ts ++++ b/lib/typescript/src/types/MarkdownStyleInternal.d.ts +@@ -82,6 +82,17 @@ export interface LinkVariantEntryInternal { + color: string; + underline: boolean; + backgroundColor: string; ++ fontFamily: string; ++ pill: boolean; ++ label: string; ++ iconUri: string; ++ iconTintColor?: string; ++ borderRadius: number; ++ paddingHorizontal: number; ++ paddingVertical: number; ++ borderWidth: number; ++ borderColor: string; ++ maxWidth: number; + } + interface StrongStyleInternal { + fontFamily: string; +diff --git a/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map b/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +index e37cd26e931d112b3e99a3c7b415e3c5589266bf..0b5a8d4f4a0af51c1e3eab6462fba23a07475dc7 100644 +--- a/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map ++++ b/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +@@ -1 +1 @@ +-{"version":3,"file":"MarkdownStyleInternal.d.ts","sourceRoot":"","sources":["../../../../src/types/MarkdownStyleInternal.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AAG9E,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,EAAE,CAAC;AAGrE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,EAAE,CAAC;AAI1D,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,OAAO,GACP,SAAS,GACT,QAAQ,GACR,MAAM,GACN,EAAE,CAAC;AAEP,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,sBAAuB,SAAQ,sBAAsB;IAC7D,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED,UAAU,oBAAqB,SAAQ,sBAAsB;IAC3D,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,wBAAwB,CAAC;IAC/B,GAAG,EAAE,wBAAwB,CAAC;IAC9B,SAAS,EAAE,wBAAwB,CAAC;IACpC,OAAO,EAAE,wBAAwB,CAAC;IAClC,OAAO,EAAE,wBAAwB,CAAC;CACnC;AAED,UAAU,uBAAwB,SAAQ,sBAAsB;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,wBAAwB,CAAC;CACvC;AAED,UAAU,iBAAkB,SAAQ,sBAAsB;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,sBAAuB,SAAQ,sBAAsB;IAC7D,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,6BAA6B,CAAC;CAC7C;AAED,UAAU,iBAAiB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,mBAAmB;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,qBAAqB;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,0BAA0B;IAClC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,sBAAsB;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,iBAAiB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,kBAAkB;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,eAAe,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,kBAAkB;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,wBAAwB;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,0BAA0B;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,kBAAmB,SAAQ,sBAAsB;IACzD,gBAAgB,EAAE,MAAM,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,UAAU,qBAAqB;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,6BAA6B;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,yBAAyB;IACjC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,oBAAoB;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,6BAA6B,CAAC;IACzC,KAAK,EAAE,yBAAyB,CAAC;CAClC;AAED,UAAU,wBAAwB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,UAAU,sBAAsB;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,UAAU,sBAAsB;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,sBAAsB,CAAC;IAClC,EAAE,EAAE,oBAAoB,CAAC;IACzB,EAAE,EAAE,oBAAoB,CAAC;IACzB,EAAE,EAAE,oBAAoB,CAAC;IACzB,EAAE,EAAE,oBAAoB,CAAC;IACzB,EAAE,EAAE,oBAAoB,CAAC;IACzB,EAAE,EAAE,oBAAoB,CAAC;IACzB,UAAU,EAAE,uBAAuB,CAAC;IACpC,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,EAAE,sBAAsB,CAAC;IAClC,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAChE,MAAM,EAAE,mBAAmB,CAAC;IAC5B,EAAE,EAAE,qBAAqB,CAAC;IAC1B,aAAa,EAAE,0BAA0B,CAAC;IAC1C,SAAS,EAAE,sBAAsB,CAAC;IAClC,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,WAAW,EAAE,wBAAwB,CAAC;IACtC,aAAa,EAAE,0BAA0B,CAAC;IAC1C,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,qBAAqB,CAAC;IAChC,IAAI,EAAE,iBAAiB,CAAC;IACxB,UAAU,EAAE,uBAAuB,CAAC;IACpC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,WAAW,EAAE,wBAAwB,CAAC;IACtC,SAAS,EAAE,sBAAsB,CAAC;IAClC,SAAS,EAAE,sBAAsB,CAAC;CACnC"} +\ No newline at end of file ++{"version":3,"file":"MarkdownStyleInternal.d.ts","sourceRoot":"","sources":["../../../../src/types/MarkdownStyleInternal.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AAG9E,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,EAAE,CAAC;AAGrE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,EAAE,CAAC;AAI1D,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,OAAO,GACP,SAAS,GACT,QAAQ,GACR,MAAM,GACN,EAAE,CAAC;AAEP,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,sBAAuB,SAAQ,sBAAsB;IAC7D,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED,UAAU,oBAAqB,SAAQ,sBAAsB;IAC3D,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,wBAAwB,CAAC;IAC/B,GAAG,EAAE,wBAAwB,CAAC;IAC9B,SAAS,EAAE,wBAAwB,CAAC;IACpC,OAAO,EAAE,wBAAwB,CAAC;IAClC,OAAO,EAAE,wBAAwB,CAAC;CACnC;AAED,UAAU,uBAAwB,SAAQ,sBAAsB;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,wBAAwB,CAAC;CACvC;AAED,UAAU,iBAAkB,SAAQ,sBAAsB;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,sBAAuB,SAAQ,sBAAsB;IAC7D,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,6BAA6B,CAAC;CAC7C;AAED,UAAU,iBAAiB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,mBAAmB;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,qBAAqB;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,0BAA0B;IAClC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,sBAAsB;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,iBAAiB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,kBAAkB;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,eAAe,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,kBAAkB;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,wBAAwB;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,0BAA0B;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,kBAAmB,SAAQ,sBAAsB;IACzD,gBAAgB,EAAE,MAAM,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,UAAU,qBAAqB;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,6BAA6B;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,yBAAyB;IACjC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,oBAAoB;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,6BAA6B,CAAC;IACzC,KAAK,EAAE,yBAAyB,CAAC;CAClC;AAED,UAAU,wBAAwB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,UAAU,sBAAsB;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,UAAU,sBAAsB;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,sBAAsB,CAAC;IAClC,EAAE,EAAE,oBAAoB,CAAC;IACzB,EAAE,EAAE,oBAAoB,CAAC;IACzB,EAAE,EAAE,oBAAoB,CAAC;IACzB,EAAE,EAAE,oBAAoB,CAAC;IACzB,EAAE,EAAE,oBAAoB,CAAC;IACzB,EAAE,EAAE,oBAAoB,CAAC;IACzB,UAAU,EAAE,uBAAuB,CAAC;IACpC,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,EAAE,sBAAsB,CAAC;IAClC,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAChE,MAAM,EAAE,mBAAmB,CAAC;IAC5B,EAAE,EAAE,qBAAqB,CAAC;IAC1B,aAAa,EAAE,0BAA0B,CAAC;IAC1C,SAAS,EAAE,sBAAsB,CAAC;IAClC,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,WAAW,EAAE,wBAAwB,CAAC;IACtC,aAAa,EAAE,0BAA0B,CAAC;IAC1C,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,qBAAqB,CAAC;IAChC,IAAI,EAAE,iBAAiB,CAAC;IACxB,UAAU,EAAE,uBAAuB,CAAC;IACpC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,WAAW,EAAE,wBAAwB,CAAC;IACtC,SAAS,EAAE,sBAAsB,CAAC;IAClC,SAAS,EAAE,sBAAsB,CAAC;CACnC"} +\ No newline at end of file +diff --git a/lib/typescript/src/types/MarkdownTextProps.d.ts b/lib/typescript/src/types/MarkdownTextProps.d.ts +index 379af3df3b1d0084efc20bef202889feaa7c0902..cc93ad5e559e12d89fbafe15bbae80ce09b12265 100644 +--- a/lib/typescript/src/types/MarkdownTextProps.d.ts ++++ b/lib/typescript/src/types/MarkdownTextProps.d.ts +@@ -1,3 +1,5 @@ ++import type { ReactNode } from 'react'; ++import type { MarkdownMediaAsset, MarkdownImageSource, DocumentAssetsEvent } from './media'; + import type { ColorValue, ViewProps, ViewStyle, TextStyle } from 'react-native'; + import type { MarkdownStyle, Md4cFlags } from './MarkdownStyle'; + import type { AccessibilityLabels } from './AccessibilityLabels'; +@@ -117,6 +119,44 @@ export interface EnrichedMarkdownTextProps extends Omit { + * @platform ios, android, web + */ + markdown: string; ++ /** ++ * Render an eligible native media occurrence as a React sibling. Returning ++ * null keeps native rendering. Supports standalone image paragraphs and direct ++ * videos at the document root or in recursive quote/admonition containers in ++ * GitHub flavor on iOS and Android. React content owns interaction ++ * and accessibility; its intrinsic height reserves native layout space. ++ */ ++ renderMedia?: (asset: MarkdownMediaAsset) => ReactNode | null; ++ /** ++ * Resolve image download URI and headers from the accepted native AST. ++ * Null selects native fallback. Pending or rejected resolutions keep a ++ * placeholder. React renderMedia overrides take precedence. Supported only ++ * for GitHub flavor on iOS and Android, including nested/linked images. ++ * Keep the callback identity stable to retain decisions across renders. ++ */ ++ resolveImageSource?: (asset: MarkdownMediaAsset) => MarkdownImageSource | null | Promise; ++ /** Native parsed media and link occurrences, including unsupported placements. ++ * Supported in GitHub flavor on iOS and Android. ++ */ ++ onDocumentAssets?: (event: DocumentAssetsEvent) => void; ++ /** ++ * Recognize nonempty matches within parsed plain-text nodes as native links. ++ * The exact matched text is the URL. Existing links and code are excluded. ++ * Uses the input linkRegex conventions: native regex source plus i/s flags. ++ * Other JS flags are not transported; all non-overlapping matches are found. ++ * Patterns must work in NSRegularExpression and java.util.regex.Pattern. ++ * Undefined, null, rejected lookbehinds and invalid native patterns disable it. ++ * @default null ++ * @platform ios, android ++ */ ++ linkRegex?: RegExp | null; ++ /** ++ * Recognize an entire inline-code span as a native link, preserving its code ++ * node and text. Partial matches are ignored. Uses linkRegex conventions. ++ * @default null ++ * @platform ios, android ++ */ ++ inlineCodeLinkRegex?: RegExp | null; + /** + * Style configuration for markdown elements. + * @platform ios, android, web +diff --git a/lib/typescript/src/types/MarkdownTextProps.d.ts.map b/lib/typescript/src/types/MarkdownTextProps.d.ts.map +index c6f5e2a37e81174d7562a9012a2d714b8fb3ec4f..acb5cbcfa685c7f2285f6db91f8a42a7c24e5efa 100644 +--- a/lib/typescript/src/types/MarkdownTextProps.d.ts.map ++++ b/lib/typescript/src/types/MarkdownTextProps.d.ts.map +@@ -1 +1 @@ +-{"version":3,"file":"MarkdownTextProps.d.ts","sourceRoot":"","sources":["../../../../src/types/MarkdownTextProps.ts"],"names":[],"mappings":"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"} +\ No newline at end of file ++{"version":3,"file":"MarkdownTextProps.d.ts","sourceRoot":"","sources":["../../../../src/types/MarkdownTextProps.ts"],"names":[],"mappings":"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"} +\ No newline at end of file +diff --git a/lib/typescript/src/types/media.d.ts b/lib/typescript/src/types/media.d.ts +new file mode 100644 +index 0000000000000000000000000000000000000000..28a342625a9ead85fb1e07742f38153e55c556ca +--- /dev/null ++++ b/lib/typescript/src/types/media.d.ts +@@ -0,0 +1,31 @@ ++/** Placement in the native parsed document. */ ++export type MarkdownAssetPlacement = 'block' | 'inline' | 'list' | 'table' | 'blockquote'; ++interface MarkdownAssetDescriptor { ++ /** Occurrence ID, scoped to the component and document lineage. */ ++ id: string; ++ url: string; ++ altText: string; ++ title: string; ++ placement: MarkdownAssetPlacement; ++} ++export interface MarkdownMediaAsset extends MarkdownAssetDescriptor { ++ kind: 'image' | 'video'; ++ /** Whether this placement supports renderMedia. */ ++ eligible: boolean; ++} ++export interface MarkdownLinkAsset extends MarkdownAssetDescriptor { ++ kind: 'link'; ++ eligible: false; ++} ++export type MarkdownDocumentAsset = MarkdownMediaAsset | MarkdownLinkAsset; ++export interface DocumentAssetsEvent { ++ revision: number; ++ assets: MarkdownDocumentAsset[]; ++} ++/** Download transport only; semantic image metadata retains the original URL. */ ++export interface MarkdownImageSource { ++ uri: string; ++ headers?: Record; ++} ++export {}; ++//# sourceMappingURL=media.d.ts.map +\ No newline at end of file +diff --git a/lib/typescript/src/types/media.d.ts.map b/lib/typescript/src/types/media.d.ts.map +new file mode 100644 +index 0000000000000000000000000000000000000000..dbefdb4cb5caf6377006ee1ad26b3e93ae8dfa5b +--- /dev/null ++++ b/lib/typescript/src/types/media.d.ts.map +@@ -0,0 +1 @@ ++{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../../../src/types/media.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,MAAM,MAAM,sBAAsB,GAC9B,OAAO,GACP,QAAQ,GACR,MAAM,GACN,OAAO,GACP,YAAY,CAAC;AAEjB,UAAU,uBAAuB;IAC/B,mEAAmE;IACnE,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,sBAAsB,CAAC;CACnC;AAED,MAAM,WAAW,kBAAmB,SAAQ,uBAAuB;IACjE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,mDAAmD;IACnD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAkB,SAAQ,uBAAuB;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC;CACjB;AAED,MAAM,MAAM,qBAAqB,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;AAE3E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,qBAAqB,EAAE,CAAC;CACjC;AAED,iFAAiF;AACjF,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC"} +\ No newline at end of file +diff --git a/lib/typescript/src/utils/regexParser.d.ts b/lib/typescript/src/utils/regexParser.d.ts +index 972dc6cfb39b54a181abf758663d61f13304642a..b69a29e3b65f7e5e0132c78fe4bb0b94ae548c14 100644 +--- a/lib/typescript/src/utils/regexParser.d.ts ++++ b/lib/typescript/src/utils/regexParser.d.ts +@@ -1,3 +1,5 @@ + import type { LinkNativeRegex } from '../EnrichedMarkdownTextInputNativeComponent'; + export declare const toNativeRegexConfig: (regex: RegExp | undefined | null) => LinkNativeRegex; ++/** Renderer recognition is opt-in, including when input normalization falls back. */ ++export declare const toNativeTextLinkRegexConfig: (regex: RegExp | undefined | null) => LinkNativeRegex; + //# sourceMappingURL=regexParser.d.ts.map +\ No newline at end of file +diff --git a/lib/typescript/src/utils/regexParser.d.ts.map b/lib/typescript/src/utils/regexParser.d.ts.map +index 1e918889d77f96c40c305f2d0568f5311b6c0b9f..0b601754665fcff671c37fbf864e8614f2cfefb3 100644 +--- a/lib/typescript/src/utils/regexParser.d.ts.map ++++ b/lib/typescript/src/utils/regexParser.d.ts.map +@@ -1 +1 @@ +-{"version":3,"file":"regexParser.d.ts","sourceRoot":"","sources":["../../../../src/utils/regexParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAkBnF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,MAAM,GAAG,SAAS,GAAG,IAAI,KAC/B,eAiCF,CAAC"} +\ No newline at end of file ++{"version":3,"file":"regexParser.d.ts","sourceRoot":"","sources":["../../../../src/utils/regexParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAkBnF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,MAAM,GAAG,SAAS,GAAG,IAAI,KAC/B,eAiCF,CAAC;AAEF,qFAAqF;AACrF,eAAO,MAAM,2BAA2B,GACtC,OAAO,MAAM,GAAG,SAAS,GAAG,IAAI,KAC/B,eAGF,CAAC"} +\ No newline at end of file +diff --git a/src/EnrichedMarkdownNativeComponent.ts b/src/EnrichedMarkdownNativeComponent.ts +index 66d200af977b0c9a4086f4e621bb26f8400eb68b..db8e832e498ffa1fa1482f68e40d387421761a34 100644 +--- a/src/EnrichedMarkdownNativeComponent.ts ++++ b/src/EnrichedMarkdownNativeComponent.ts +@@ -97,6 +97,17 @@ interface LinkVariantEntryInternal { + color: ColorValue; + underline: boolean; + backgroundColor: ColorValue; ++ fontFamily: string; ++ pill: boolean; ++ label: string; ++ iconUri: string; ++ iconTintColor?: ColorValue; ++ borderRadius: CodegenTypes.Float; ++ paddingHorizontal: CodegenTypes.Float; ++ paddingVertical: CodegenTypes.Float; ++ borderWidth: CodegenTypes.Float; ++ borderColor: ColorValue; ++ maxWidth: CodegenTypes.Float; + } + + interface StrongStyleInternal { +@@ -406,7 +417,92 @@ interface StreamingConfigInternal { + codeBlockMode: string; + } + ++// Same transport as EnrichedMarkdownTextInput.linkRegex. Kept local for codegen. ++interface TextLinkNativeRegex { ++ pattern: string; ++ caseInsensitive: boolean; ++ dotAll: boolean; ++ isDisabled: boolean; ++ isDefault: boolean; ++} ++ ++export interface DocumentAssetInternal { ++ anchor: string; ++ id: string; ++ kind: string; ++ url: string; ++ altText: string; ++ title: string; ++ placement: string; ++ eligible: boolean; ++} ++ ++export interface DocumentAssetsEventInternal { ++ revision: CodegenTypes.Int32; ++ assets: { ++ anchor: string; ++ id: string; ++ kind: string; ++ url: string; ++ altText: string; ++ title: string; ++ placement: string; ++ eligible: boolean; ++ }[]; ++} ++ ++export interface MediaFrameInternal { ++ id: string; ++ x: CodegenTypes.Float; ++ y: CodegenTypes.Float; ++ width: CodegenTypes.Float; ++ height: CodegenTypes.Float; ++} ++ ++export interface MediaLayoutEventInternal { ++ revision: CodegenTypes.Int32; ++ frames: { ++ id: string; ++ x: CodegenTypes.Float; ++ y: CodegenTypes.Float; ++ width: CodegenTypes.Float; ++ height: CodegenTypes.Float; ++ }[]; ++} ++ ++export interface MediaOverrideInternal { ++ url: string; ++ kind: string; ++ anchor: string; ++ id: string; ++ height: CodegenTypes.Float; ++ width: CodegenTypes.Float; ++} ++ ++export interface ImageSourceInternal { ++ id: string; ++ url: string; ++ anchor: string; ++ uri: string; ++ headers: ReadonlyArray>; ++ useDefault: boolean; ++} ++ + export interface NativeProps extends ViewProps { ++ enableImageSourceResolution?: CodegenTypes.WithDefault; ++ imageSourcesRevision?: CodegenTypes.WithDefault; ++ imageSourcesContinuityStart?: CodegenTypes.WithDefault; ++ imageSources?: ReadonlyArray>; ++ documentRevision?: CodegenTypes.WithDefault; ++ enableDocumentAssets?: CodegenTypes.WithDefault; ++ enableMediaSlots?: CodegenTypes.WithDefault; ++ mediaOverridesRevision?: CodegenTypes.WithDefault; ++ mediaOverrides?: ReadonlyArray>; ++ onDocumentAssets?: CodegenTypes.DirectEventHandler; ++ onMediaLayout?: CodegenTypes.DirectEventHandler; ++ ++ linkRegex?: Readonly; ++ inlineCodeLinkRegex?: Readonly; + /** + * Markdown content to render. + */ +diff --git a/src/EnrichedMarkdownTextNativeComponent.ts b/src/EnrichedMarkdownTextNativeComponent.ts +index c034dd109ce151f9d6163a989f8f5ad651029a25..fcf45a04d1984bcdc210445beca44513a1fbb7b4 100644 +--- a/src/EnrichedMarkdownTextNativeComponent.ts ++++ b/src/EnrichedMarkdownTextNativeComponent.ts +@@ -97,6 +97,17 @@ interface LinkVariantEntryInternal { + color: ColorValue; + underline: boolean; + backgroundColor: ColorValue; ++ fontFamily: string; ++ pill: boolean; ++ label: string; ++ iconUri: string; ++ iconTintColor?: ColorValue; ++ borderRadius: CodegenTypes.Float; ++ paddingHorizontal: CodegenTypes.Float; ++ paddingVertical: CodegenTypes.Float; ++ borderWidth: CodegenTypes.Float; ++ borderColor: ColorValue; ++ maxWidth: CodegenTypes.Float; + } + + interface StrongStyleInternal { +@@ -407,7 +418,18 @@ interface StreamingConfigInternal { + codeBlockMode: string; + } + ++// Same transport as EnrichedMarkdownTextInput.linkRegex. Kept local for codegen. ++interface TextLinkNativeRegex { ++ pattern: string; ++ caseInsensitive: boolean; ++ dotAll: boolean; ++ isDisabled: boolean; ++ isDefault: boolean; ++} ++ + export interface NativeProps extends ViewProps { ++ linkRegex?: Readonly; ++ inlineCodeLinkRegex?: Readonly; + /** + * Markdown content to render. + */ +diff --git a/src/imageSourceState.ts b/src/imageSourceState.ts +new file mode 100644 +index 0000000000000000000000000000000000000000..3754fa6d159f221964b7ebe8b33ef0843141c5c1 +--- /dev/null ++++ b/src/imageSourceState.ts +@@ -0,0 +1,114 @@ ++import type { ImageSourceInternal } from './EnrichedMarkdownNativeComponent'; ++import type { EnrichedMarkdownTextProps } from './types/MarkdownTextProps'; ++import type { MarkdownMediaAsset } from './types/media'; ++ ++export type NativeImageAsset = MarkdownMediaAsset & { anchor: string }; ++type Resolver = NonNullable; ++type Entry = { ++ asset: NativeImageAsset; ++ identity: string; ++ status: 'queued' | 'active' | 'done'; ++ source?: ImageSourceInternal; ++}; ++ ++const identity = (asset: NativeImageAsset) => JSON.stringify(asset); ++const stripAnchor = ({ anchor: _anchor, ...asset }: NativeImageAsset) => asset; ++ ++/** Per-occurrence decisions; superseded promises still count against the bound. */ ++export class ImageSourceState { ++ private resolver?: Resolver; ++ private lineage = -1; ++ private entries = new Map(); ++ private active = 0; ++ private running = false; ++ private changed?: () => void; ++ ++ configure( ++ resolver: Resolver | undefined, ++ lineage: number, ++ assets: NativeImageAsset[] ++ ) { ++ if (resolver !== this.resolver || lineage !== this.lineage) { ++ this.entries.clear(); ++ this.resolver = resolver; ++ this.lineage = lineage; ++ } ++ const next = new Map(); ++ if (resolver) { ++ for (const asset of assets) { ++ const key = identity(asset); ++ const previous = this.entries.get(asset.id); ++ next.set( ++ asset.id, ++ previous?.identity === key ++ ? previous ++ : { asset, identity: key, status: 'queued' } ++ ); ++ } ++ } ++ this.entries = next; ++ } ++ ++ sources(): ImageSourceInternal[] { ++ return [...this.entries.values()].flatMap((entry) => ++ entry.source ? [entry.source] : [] ++ ); ++ } ++ ++ start(changed: () => void) { ++ this.running = true; ++ this.changed = changed; ++ this.pump(); ++ } ++ ++ stop() { ++ this.running = false; ++ this.changed = undefined; ++ this.entries.clear(); ++ } ++ ++ private pump() { ++ if (!this.running || !this.resolver) return; ++ for (const entry of this.entries.values()) { ++ if (this.active >= 4) break; ++ if (entry.status !== 'queued') continue; ++ const resolve = this.resolver; ++ entry.status = 'active'; ++ this.active++; ++ // Always execute outside render. Synchronous throws follow rejection policy. ++ Promise.resolve() ++ .then(() => { ++ if (this.entries.get(entry.asset.id) !== entry || !this.running) ++ return undefined; ++ return resolve(stripAnchor(entry.asset)); ++ }) ++ .then((result) => { ++ if (this.entries.get(entry.asset.id) !== entry) return; ++ if ( ++ result === null || ++ (result && typeof result.uri === 'string' && result.uri.length > 0) ++ ) { ++ entry.source = { ++ id: entry.asset.id, ++ url: entry.asset.url, ++ anchor: entry.asset.anchor, ++ uri: result?.uri ?? '', ++ headers: Object.entries(result?.headers ?? {}).map( ++ ([name, value]) => ({ name, value }) ++ ), ++ useDefault: result === null, ++ }; ++ } ++ }) ++ .catch(() => { ++ // A rejected source remains a placeholder until its identity changes. ++ }) ++ .finally(() => { ++ entry.status = 'done'; ++ this.active--; ++ if (this.entries.get(entry.asset.id) === entry) this.changed?.(); ++ this.pump(); ++ }); ++ } ++ } ++} +diff --git a/src/index.tsx b/src/index.tsx +index 7ef02af9aaf268a2173901e4c06caaca6c777ce8..6f34160af71a99360eb307d0dbff2d8692a632e1 100644 +--- a/src/index.tsx ++++ b/src/index.tsx +@@ -1,3 +1,4 @@ ++export type { LinkVariantStyle } from './types/MarkdownStyle'; + export { default as EnrichedMarkdownText } from './native/EnrichedMarkdownText'; + export type { + EnrichedMarkdownTextProps, +@@ -44,3 +45,12 @@ export type { + HeadingLevel, + HeadingStyle, + } from './EnrichedMarkdownTextInput'; ++ ++export type { ++ MarkdownAssetPlacement, ++ MarkdownMediaAsset, ++ MarkdownImageSource, ++ MarkdownLinkAsset, ++ MarkdownDocumentAsset, ++ DocumentAssetsEvent, ++} from './types/media'; +diff --git a/src/jest/index.tsx b/src/jest/index.tsx +index f51c03152d64d6f3bb12941e86ac8f92464b3bde..28fece29049dbbbcb6824979314792aa6e44b423 100644 +--- a/src/jest/index.tsx ++++ b/src/jest/index.tsx +@@ -309,6 +309,7 @@ export const EnrichedMarkdownText = ({ + spoilerOverlay: _spoilerOverlay, + contextMenuItems: _contextMenuItems, + imageRequestHeaders: _imageRequestHeaders, ++ resolveImageSource: _resolveImageSource, + selectionMenuConfig: _selectionMenuConfig, + accessibilityLabels: _accessibilityLabels, + selectionColor: _selectionColor, +diff --git a/src/linkVariantUtils.ts b/src/linkVariantUtils.ts +index fe705dbe7dbbf4b7144d7c90b3e9d3ee0690b119..6cc83545811a63acaa08dee46a7bace5b2c1bfa7 100644 +--- a/src/linkVariantUtils.ts ++++ b/src/linkVariantUtils.ts +@@ -40,3 +40,21 @@ export function normalizeLinkVariantEntries( + return true; + }); + } ++ ++/** Native pill geometry is finite and nonnegative before crossing codegen. */ ++export function normalizeLinkPillStyle(style: LinkVariantStyle) { ++ const dimension = (value: number | undefined, fallback: number) => ++ value === undefined || !Number.isFinite(value) ++ ? fallback ++ : Math.max(0, value); ++ return { ++ pill: style.pill ?? false, ++ label: style.label ?? '', ++ iconUri: style.iconUri ?? '', ++ borderRadius: dimension(style.borderRadius, 8), ++ paddingHorizontal: dimension(style.paddingHorizontal, 6), ++ paddingVertical: dimension(style.paddingVertical, 2), ++ borderWidth: dimension(style.borderWidth, 0), ++ maxWidth: dimension(style.maxWidth, 0), ++ }; ++} +diff --git a/src/mediaSlotState.ts b/src/mediaSlotState.ts +new file mode 100644 +index 0000000000000000000000000000000000000000..f34b4f80cb38facc19046d04e2be31244e480479 +--- /dev/null ++++ b/src/mediaSlotState.ts +@@ -0,0 +1,47 @@ ++import type { MediaFrameInternal } from './EnrichedMarkdownNativeComponent'; ++ ++export interface MediaMeasurement { ++ id: string; ++ width: number; ++ height: number; ++} ++ ++export const sameMediaSize = (a: number, b: number) => Math.abs(a - b) < 0.5; ++ ++/** Accept only finite native frames with usable widths. */ ++export const validMediaFrames = ( ++ frames: readonly MediaFrameInternal[] ++): MediaFrameInternal[] => ++ frames.filter( ++ ({ x, y, width, height }) => ++ [x, y, width, height].every(Number.isFinite) && width > 0 && height >= 0 ++ ); ++ ++/** A width change requires React to measure again before native uses the height. */ ++export const mediaOverrideForFrame = ( ++ id: string, ++ frame: MediaFrameInternal | undefined, ++ measurement: MediaMeasurement | undefined ++): MediaMeasurement => ++ frame && measurement && sameMediaSize(frame.width, measurement.width) ++ ? measurement ++ : { id, width: 0, height: 1 }; ++ ++/** Reject stale onLayout callbacks and suppress subpixel feedback loops. */ ++export const acceptMediaMeasurement = ( ++ eventRevision: number, ++ revision: number, ++ frame: MediaFrameInternal | undefined, ++ next: MediaMeasurement, ++ previous: MediaMeasurement | undefined ++): boolean => ++ eventRevision === revision && ++ !!frame && ++ Number.isFinite(next.width) && ++ Number.isFinite(next.height) && ++ next.width > 0 && ++ next.height >= 0 && ++ sameMediaSize(frame.width, next.width) && ++ (!previous || ++ !sameMediaSize(previous.width, next.width) || ++ !sameMediaSize(previous.height, next.height)); +diff --git a/src/native/EnrichedMarkdownText.tsx b/src/native/EnrichedMarkdownText.tsx +index 267a2463ec341b677b10943b531f2055cb34662d..9607e4049475aa6565544ee30fa54a4b9eb02e0f 100644 +--- a/src/native/EnrichedMarkdownText.tsx ++++ b/src/native/EnrichedMarkdownText.tsx +@@ -1,7 +1,10 @@ ++import { StyleSheet, View } from 'react-native'; ++import { useMediaSlots } from './useMediaSlots'; + import { useMemo, useCallback, useRef, useEffect } from 'react'; + import EnrichedMarkdownTextNativeComponent from '../EnrichedMarkdownTextNativeComponent'; + import type { MarkdownStyleInternal } from '../EnrichedMarkdownTextNativeComponent'; + import EnrichedMarkdownNativeComponent from '../EnrichedMarkdownNativeComponent'; ++import { toNativeTextLinkRegexConfig } from '../utils/regexParser'; + import { normalizeMarkdownStyle } from '../normalizeMarkdownStyle'; + import { resolveAccessibilityLabels } from '../accessibilityLabelDefaults'; + import { +@@ -120,11 +123,16 @@ const defaultMd4cFlags: Md4cFlags = { + + export const EnrichedMarkdownText = ({ + markdown, ++ linkRegex: _linkRegex, ++ inlineCodeLinkRegex: _inlineCodeLinkRegex, + markdownStyle = {}, + containerStyle, + onLinkPress, + onLinkLongPress, + onImagePress, ++ renderMedia, ++ resolveImageSource, ++ onDocumentAssets, + onTaskListItemPress, + enableTaskListItemToggle = true, + onCopyPress, +@@ -154,6 +162,14 @@ export const EnrichedMarkdownText = ({ + ellipsizeMode, + ...rest + }: EnrichedMarkdownTextProps) => { ++ const linkRegex = useMemo( ++ () => toNativeTextLinkRegexConfig(_linkRegex), ++ [_linkRegex] ++ ); ++ const inlineCodeLinkRegex = useMemo( ++ () => toNativeTextLinkRegexConfig(_inlineCodeLinkRegex), ++ [_inlineCodeLinkRegex] ++ ); + const normalizedStyleRef = useRef(null); + const normalized = normalizeMarkdownStyle(markdownStyle); + // normalizeMarkdownStyle returns cached objects for structurally equal inputs, +@@ -341,6 +357,8 @@ export const EnrichedMarkdownText = ({ + + const sharedProps = { + markdown, ++ linkRegex, ++ inlineCodeLinkRegex, + markdownStyle: normalizedStyle, + onLinkPress: handleLinkPress, + onLinkLongPress: handleLinkLongPress, +@@ -379,11 +397,52 @@ export const EnrichedMarkdownText = ({ + ...rest, + }; + ++ // Include native recognition configs when composed with the optional text ++ // recognition API. Asset revisions must follow all parser inputs. ++ const nativeParserProps: Record = sharedProps; ++ const media = useMediaSlots( ++ markdown, ++ JSON.stringify([ ++ normalizedMd4cFlags, ++ streamingAnimation, ++ normalizedStreamingConfig, ++ flavor, ++ !!renderMedia, ++ !!onDocumentAssets, ++ !!resolveImageSource, ++ nativeParserProps.linkRegex, ++ nativeParserProps.inlineCodeLinkRegex, ++ ]), ++ flavor === 'github' ? renderMedia : undefined, ++ flavor === 'github' ? onDocumentAssets : undefined, ++ flavor === 'github' ? resolveImageSource : undefined ++ ); ++ + if (flavor === 'github') { +- return ; ++ if (renderMedia) { ++ return ( ++ ++ ++ {media.slots} ++ ++ ); ++ } ++ return ( ++ ++ ); + } + + return ; + }; + + export default EnrichedMarkdownText; ++ ++const mediaStyles = StyleSheet.create({ native: { alignSelf: 'stretch' } }); +diff --git a/src/native/useImageSources.ts b/src/native/useImageSources.ts +new file mode 100644 +index 0000000000000000000000000000000000000000..18a6c59b6b4337f8d5e37e42134fc252773f33e8 +--- /dev/null ++++ b/src/native/useImageSources.ts +@@ -0,0 +1,29 @@ ++import { useEffect, useRef, useState } from 'react'; ++import { ImageSourceState } from '../imageSourceState'; ++import type { NativeImageAsset } from '../imageSourceState'; ++import type { EnrichedMarkdownTextProps } from '../types/MarkdownTextProps'; ++ ++export function useImageSources( ++ resolver: EnrichedMarkdownTextProps['resolveImageSource'], ++ continuityStart: number, ++ assetsRevision: number, ++ assets: NativeImageAsset[] ++) { ++ const state = useRef(undefined); ++ if (!state.current) state.current = new ImageSourceState(); ++ const current = state.current; ++ const [, refresh] = useState(0); ++ current.configure(resolver, continuityStart, assets); ++ // Reconcile after every commit. Configure deduplicates layout-only renders. ++ useEffect(() => { ++ current.configure(resolver, continuityStart, assets); ++ current.start(() => refresh((value) => value + 1)); ++ }); ++ useEffect(() => () => current.stop(), [current]); ++ return { ++ enableImageSourceResolution: !!resolver, ++ imageSourcesContinuityStart: resolver ? continuityStart : 1, ++ imageSourcesRevision: resolver ? assetsRevision : -1, ++ imageSources: current.sources(), ++ }; ++} +diff --git a/src/native/useMediaSlots.tsx b/src/native/useMediaSlots.tsx +new file mode 100644 +index 0000000000000000000000000000000000000000..ecdb68f748d980b899b8d4ed3c1b4bbbd290831d +--- /dev/null ++++ b/src/native/useMediaSlots.tsx +@@ -0,0 +1,298 @@ ++import { useRef, useState } from 'react'; ++import { useImageSources } from './useImageSources'; ++import { StyleSheet, View } from 'react-native'; ++import type { LayoutChangeEvent, NativeSyntheticEvent } from 'react-native'; ++import type { ++ DocumentAssetsEventInternal, ++ MediaLayoutEventInternal, ++ MediaFrameInternal, ++} from '../EnrichedMarkdownNativeComponent'; ++import type { EnrichedMarkdownTextProps } from '../types/MarkdownTextProps'; ++import type { MarkdownDocumentAsset, MarkdownMediaAsset } from '../types/media'; ++import { ++ acceptMediaMeasurement, ++ mediaOverrideForFrame, ++ sameMediaSize, ++ validMediaFrames, ++} from '../mediaSlotState'; ++import type { MediaMeasurement } from '../mediaSlotState'; ++ ++type NativeAsset = MarkdownDocumentAsset & { anchor: string }; ++type Manifest = { revision: number; assets: NativeAsset[] }; ++type MediaLayout = MediaLayoutEventInternal & { ++ identities: Record; ++}; ++const stripAnchor = ({ anchor: _anchor, ...asset }: T) => ++ asset; ++const identity = (asset: NativeAsset) => ++ JSON.stringify([ ++ asset.id, ++ asset.kind, ++ asset.url, ++ asset.anchor, ++ asset.eligible, ++ ]); ++const identities = (assets: NativeAsset[]) => ++ Object.fromEntries(assets.map((asset) => [asset.id, identity(asset)])); ++ ++export function useMediaSlots( ++ markdown: string, ++ parserKey: string, ++ renderMedia: EnrichedMarkdownTextProps['renderMedia'], ++ onDocumentAssets: EnrichedMarkdownTextProps['onDocumentAssets'], ++ resolveImageSource: EnrichedMarkdownTextProps['resolveImageSource'] ++) { ++ const document = useRef({ ++ markdown, ++ parserKey, ++ revision: 1, ++ continuityStart: 1, ++ generation: 0, ++ }); ++ if ( ++ document.current.markdown !== markdown || ++ document.current.parserKey !== parserKey ++ ) { ++ const previous = document.current; ++ const append = ++ previous.parserKey === parserKey && ++ previous.markdown.length > 0 && ++ markdown.length > previous.markdown.length && ++ markdown.startsWith(previous.markdown); ++ document.current = { ++ markdown, ++ parserKey, ++ revision: previous.revision + 1, ++ continuityStart: append ++ ? previous.continuityStart ++ : previous.revision + 1, ++ generation: previous.generation + (append ? 0 : 1), ++ }; ++ } ++ const { revision, continuityStart, generation } = document.current; ++ const [manifest, setManifest] = useState(); ++ const acceptedManifest = useRef(undefined); ++ const [layout, setLayout] = useState(); ++ const latestLayout = useRef(undefined); ++ const pendingLayout = useRef(undefined); ++ const [origin, setOrigin] = useState({ x: 0, y: 0 }); ++ const [measurements, setMeasurements] = useState< ++ Record ++ >({}); ++ const reported = useRef(-1); ++ // Only uninterrupted appends with identical parser inputs retain prior data. ++ // Native revalidates each carried decision against the newly accepted AST. ++ const assets = ++ manifest && manifest.revision >= continuityStart ? manifest.assets : []; ++ const frames = ++ layout && layout.revision >= continuityStart ? layout.frames : []; ++ const frameForAsset = (asset: NativeAsset) => ++ layout?.identities[asset.id] === identity(asset) ++ ? frames.find((entry) => entry.id === asset.id) ++ : undefined; ++ const rendered = assets.flatMap((asset) => { ++ if (asset.kind === 'link' || !asset.eligible || !renderMedia) return []; ++ const content = renderMedia(stripAnchor(asset)); ++ if (content == null || typeof content === 'boolean') return []; ++ return [{ asset, content }]; ++ }); ++ const imageSources = useImageSources( ++ resolveImageSource, ++ continuityStart, ++ manifest && manifest.revision >= continuityStart ? manifest.revision : -1, ++ assets.filter( ++ (asset): asset is NativeAsset & MarkdownMediaAsset => ++ asset.kind === 'image' && ++ !rendered.some((entry) => entry.asset.id === asset.id) ++ ) ++ ); ++ const overrides = rendered.map(({ asset }) => { ++ const measurement = measurements[asset.id]; ++ const box = mediaOverrideForFrame( ++ asset.id, ++ frameForAsset(asset), ++ measurement?.identity === identity(asset) && ++ measurement.generation === generation ++ ? measurement ++ : undefined ++ ); ++ return { ++ id: box.id, ++ height: box.height, ++ width: box.width, ++ url: asset.url, ++ kind: asset.kind, ++ anchor: asset.anchor, ++ }; ++ }); ++ ++ const onNativeDocumentAssets = ( ++ event: NativeSyntheticEvent ++ ) => { ++ if (event.nativeEvent.revision !== document.current.revision) return; ++ const next = event.nativeEvent as unknown as Manifest; ++ acceptedManifest.current = next; ++ setManifest((previous) => ++ previous?.revision === next.revision && ++ JSON.stringify(previous.assets) === JSON.stringify(next.assets) ++ ? previous ++ : next ++ ); ++ // A frame can arrive before its manifest. Stamp only frames of this exact ++ // revision; older frames keep their original occurrence identities. ++ const received = ++ pendingLayout.current?.revision === next.revision ++ ? pendingLayout.current ++ : latestLayout.current?.revision === next.revision ++ ? latestLayout.current ++ : undefined; ++ if (received) { ++ const updated = { ...received, identities: identities(next.assets) }; ++ latestLayout.current = updated; ++ pendingLayout.current = undefined; ++ setLayout(updated); ++ } ++ if (reported.current !== next.revision) { ++ reported.current = next.revision; ++ onDocumentAssets?.({ ++ revision: next.revision, ++ assets: next.assets.map(stripAnchor) as MarkdownDocumentAsset[], ++ }); ++ } ++ }; ++ const onNativeMediaLayout = ( ++ event: NativeSyntheticEvent ++ ) => { ++ const next = event.nativeEvent; ++ if (next.revision !== document.current.revision) return; ++ const valid = validMediaFrames(next.frames); ++ const current = acceptedManifest.current; ++ if (current?.revision !== next.revision) { ++ // Keep mounted slots until the accepted manifest can identify new frames. ++ pendingLayout.current = { revision: next.revision, frames: valid }; ++ return; ++ } ++ const nextLayout = { ++ revision: next.revision, ++ frames: valid, ++ identities: ++ current?.revision === next.revision ? identities(current.assets) : {}, ++ }; ++ latestLayout.current = nextLayout; ++ setLayout((previous) => { ++ if ( ++ previous?.revision === next.revision && ++ JSON.stringify(previous.identities) === ++ JSON.stringify(nextLayout.identities) && ++ previous.frames.length === valid.length && ++ previous.frames.every((frame, index) => { ++ const other = valid[index]!; ++ return ( ++ frame.id === other.id && ++ sameMediaSize(frame.x, other.x) && ++ sameMediaSize(frame.y, other.y) && ++ sameMediaSize(frame.width, other.width) && ++ sameMediaSize(frame.height, other.height) ++ ); ++ }) ++ ) ++ return previous; ++ return nextLayout; ++ }); ++ }; ++ const onNativeLayout = ({ nativeEvent }: LayoutChangeEvent) => { ++ const { x, y } = nativeEvent.layout; ++ setOrigin((previous) => ++ sameMediaSize(previous.x, x) && sameMediaSize(previous.y, y) ++ ? previous ++ : { x, y } ++ ); ++ }; ++ const onSlotLayout = ( ++ asset: NativeAsset & MarkdownMediaAsset, ++ frame: MediaFrameInternal, ++ event: LayoutChangeEvent ++ ) => { ++ const { width, height } = event.nativeEvent.layout; ++ const next = { id: asset.id, width, height }; ++ setMeasurements((previous) => { ++ const current = acceptedManifest.current; ++ const currentAsset = current?.assets.find( ++ (entry) => entry.id === asset.id ++ ); ++ if ( ++ !current || ++ current.revision < document.current.continuityStart || ++ !currentAsset || ++ identity(currentAsset) !== identity(asset) || ++ !acceptMediaMeasurement( ++ revision, ++ document.current.revision, ++ pendingLayout.current?.revision === revision ++ ? pendingLayout.current.frames.find( ++ (entry) => entry.id === frame.id ++ ) ++ : latestLayout.current?.identities[asset.id] === identity(asset) && ++ latestLayout.current.revision >= ++ document.current.continuityStart ++ ? latestLayout.current.frames.find( ++ (entry) => entry.id === frame.id ++ ) ++ : undefined, ++ next, ++ previous[asset.id]?.identity === identity(asset) && ++ previous[asset.id]?.generation === generation ++ ? previous[asset.id] ++ : undefined ++ ) ++ ) ++ return previous; ++ return { ++ ...previous, ++ [asset.id]: { ...next, identity: identity(asset), generation }, ++ }; ++ }); ++ }; ++ ++ const slots = rendered.map(({ asset, content }) => { ++ const frame = frameForAsset(asset); ++ if (!frame) return null; ++ return ( ++ onSlotLayout(asset, frame, event)} ++ > ++ {content} ++ ++ ); ++ }); ++ return { ++ slots, ++ onNativeLayout, ++ nativeProps: { ++ ...imageSources, ++ documentRevision: revision, ++ enableDocumentAssets: ++ !!renderMedia || !!onDocumentAssets || !!resolveImageSource, ++ enableMediaSlots: !!renderMedia, ++ mediaOverridesRevision: ++ manifest && manifest.revision >= continuityStart ++ ? manifest.revision ++ : -1, ++ mediaOverrides: overrides, ++ onDocumentAssets: onNativeDocumentAssets, ++ onMediaLayout: onNativeMediaLayout, ++ }, ++ }; ++} ++ ++const styles = StyleSheet.create({ slot: { position: 'absolute' } }); +diff --git a/src/normalizeMarkdownStyle.ts b/src/normalizeMarkdownStyle.ts +index 6ad61af1a423944dc7e1cd5e0d37e7feda41b20a..c5b4a292c4662a4220382c1f3d1def73e19412ab 100644 +--- a/src/normalizeMarkdownStyle.ts ++++ b/src/normalizeMarkdownStyle.ts +@@ -7,7 +7,10 @@ import type { + MarkdownStyleInternal, + } from './types/MarkdownStyleInternal'; + import { isStyleEqual, normalizeColor, mergeSubStyle } from './styleUtils'; +-import { normalizeLinkVariantEntries } from './linkVariantUtils'; ++import { ++ normalizeLinkVariantEntries, ++ normalizeLinkPillStyle, ++} from './linkVariantUtils'; + import { resolveAdmonitionColors } from './admonitionDefaults'; + import { + DEFAULT_HEADING_FONT_WEIGHT, +@@ -339,6 +342,13 @@ export const normalizeMarkdownStyle = ( + ([pattern, override]): LinkVariantEntryInternal => { + return { + pattern, ++ ...normalizeLinkPillStyle(override), ++ iconTintColor: normalizeColor(override.iconTintColor) as ++ | string ++ | undefined, ++ fontFamily: override.fontFamily ?? linkBase.fontFamily, ++ borderColor: (normalizeColor(override.borderColor ?? 'transparent') ?? ++ transparent) as string, + color: ((override.color ? normalizeColor(override.color) : null) ?? + linkBase.color) as string, + underline: override.underline ?? linkBase.underline, +diff --git a/src/normalizeMarkdownStyle.web.ts b/src/normalizeMarkdownStyle.web.ts +index 1ba83c8335880638ce087e86bb19fdfcc87e8224..63709e57df42ad0c2fe02617fa588c9a5df638b5 100644 +--- a/src/normalizeMarkdownStyle.web.ts ++++ b/src/normalizeMarkdownStyle.web.ts +@@ -6,7 +6,10 @@ import type { + MarkdownStyleInternal, + } from './types/MarkdownStyleInternal'; + import { isStyleEqual, mergeSubStyle } from './styleUtils'; +-import { normalizeLinkVariantEntries } from './linkVariantUtils'; ++import { ++ normalizeLinkVariantEntries, ++ normalizeLinkPillStyle, ++} from './linkVariantUtils'; + import { resolveAdmonitionColors } from './admonitionDefaults'; + import { + DEFAULT_HEADING_FONT_WEIGHT, +@@ -291,6 +294,10 @@ export const normalizeMarkdownStyle = ( + ([pattern, override]): LinkVariantEntryInternal => { + return { + pattern, ++ ...normalizeLinkPillStyle(override), ++ iconTintColor: override.iconTintColor, ++ fontFamily: override.fontFamily ?? linkBase.fontFamily, ++ borderColor: override.borderColor ?? 'transparent', + color: override.color ?? linkBase.color, + underline: override.underline ?? linkBase.underline, + backgroundColor: override.backgroundColor ?? 'transparent', +diff --git a/src/types/MarkdownStyle.ts b/src/types/MarkdownStyle.ts +index d4b3bb05964a3d19f33fd0b5504f365c183ddea9..0d63fc50f713509723999e9f2ca11cbb59f4fbca 100644 +--- a/src/types/MarkdownStyle.ts ++++ b/src/types/MarkdownStyle.ts +@@ -126,6 +126,22 @@ export interface LinkVariantStyle { + color?: string; + underline?: boolean; + backgroundColor?: string; ++ fontFamily?: string; ++ /** Render the link as one native pill. Original text and URL remain selectable. */ ++ pill?: boolean; ++ /** Presentation label only. Missing or empty uses the original link text. */ ++ label?: string; ++ /** Local file:// image URI. Unreadable files are ignored. Native pills only. */ ++ iconUri?: string; ++ /** Optional source-in icon tint. Omitted preserves original image colors and alpha. */ ++ iconTintColor?: string; ++ borderRadius?: number; ++ paddingHorizontal?: number; ++ paddingVertical?: number; ++ borderWidth?: number; ++ borderColor?: string; ++ /** Maximum pill width in points/DIP. 0 uses the available text width. */ ++ maxWidth?: number; + } + + interface StrongStyle { +@@ -358,7 +374,8 @@ export interface MarkdownStyle { + * + * `color` and `underline` inherit from the base `link` style when omitted. + * `backgroundColor` defaults to `transparent`. +- * `fontFamily` always follows the base `link` style and cannot be overridden per-variant. ++ * `fontFamily` inherits the base `link` family and can be overridden per variant. ++ * `pill: true` enables atomic native presentation with optional label, icon, and geometry. + * + * @example + * linkVariants: { +diff --git a/src/types/MarkdownStyleInternal.ts b/src/types/MarkdownStyleInternal.ts +index 7e1e5ab2a9fdcb1755cd56988cd9464281911d4d..922ae8b74de9e030b8ec3103774231cbc9da1c9d 100644 +--- a/src/types/MarkdownStyleInternal.ts ++++ b/src/types/MarkdownStyleInternal.ts +@@ -109,6 +109,17 @@ export interface LinkVariantEntryInternal { + color: string; + underline: boolean; + backgroundColor: string; ++ fontFamily: string; ++ pill: boolean; ++ label: string; ++ iconUri: string; ++ iconTintColor?: string; ++ borderRadius: number; ++ paddingHorizontal: number; ++ paddingVertical: number; ++ borderWidth: number; ++ borderColor: string; ++ maxWidth: number; + } + + interface StrongStyleInternal { +diff --git a/src/types/MarkdownTextProps.ts b/src/types/MarkdownTextProps.ts +index c088b59d799cc4741f007a97517a1e4cacf95683..fb838c3e7ed163a6c52c14efdcf72ca482044ef8 100644 +--- a/src/types/MarkdownTextProps.ts ++++ b/src/types/MarkdownTextProps.ts +@@ -1,3 +1,9 @@ ++import type { ReactNode } from 'react'; ++import type { ++ MarkdownMediaAsset, ++ MarkdownImageSource, ++ DocumentAssetsEvent, ++} from './media'; + import type { ColorValue, ViewProps, ViewStyle, TextStyle } from 'react-native'; + import type { MarkdownStyle, Md4cFlags } from './MarkdownStyle'; + import type { AccessibilityLabels } from './AccessibilityLabels'; +@@ -122,6 +128,46 @@ export interface EnrichedMarkdownTextProps extends Omit { + * @platform ios, android, web + */ + markdown: string; ++ /** ++ * Render an eligible native media occurrence as a React sibling. Returning ++ * null keeps native rendering. Supports standalone image paragraphs and direct ++ * videos at the document root or in recursive quote/admonition containers in ++ * GitHub flavor on iOS and Android. React content owns interaction ++ * and accessibility; its intrinsic height reserves native layout space. ++ */ ++ renderMedia?: (asset: MarkdownMediaAsset) => ReactNode | null; ++ /** ++ * Resolve image download URI and headers from the accepted native AST. ++ * Null selects native fallback. Pending or rejected resolutions keep a ++ * placeholder. React renderMedia overrides take precedence. Supported only ++ * for GitHub flavor on iOS and Android, including nested/linked images. ++ * Keep the callback identity stable to retain decisions across renders. ++ */ ++ resolveImageSource?: ( ++ asset: MarkdownMediaAsset ++ ) => MarkdownImageSource | null | Promise; ++ /** Native parsed media and link occurrences, including unsupported placements. ++ * Supported in GitHub flavor on iOS and Android. ++ */ ++ onDocumentAssets?: (event: DocumentAssetsEvent) => void; ++ /** ++ * Recognize nonempty matches within parsed plain-text nodes as native links. ++ * The exact matched text is the URL. Existing links and code are excluded. ++ * Uses the input linkRegex conventions: native regex source plus i/s flags. ++ * Other JS flags are not transported; all non-overlapping matches are found. ++ * Patterns must work in NSRegularExpression and java.util.regex.Pattern. ++ * Undefined, null, rejected lookbehinds and invalid native patterns disable it. ++ * @default null ++ * @platform ios, android ++ */ ++ linkRegex?: RegExp | null; ++ /** ++ * Recognize an entire inline-code span as a native link, preserving its code ++ * node and text. Partial matches are ignored. Uses linkRegex conventions. ++ * @default null ++ * @platform ios, android ++ */ ++ inlineCodeLinkRegex?: RegExp | null; + /** + * Style configuration for markdown elements. + * @platform ios, android, web +diff --git a/src/types/media.ts b/src/types/media.ts +new file mode 100644 +index 0000000000000000000000000000000000000000..022d8a784ceacac3fd57ead2155dd899bd9fd4af +--- /dev/null ++++ b/src/types/media.ts +@@ -0,0 +1,40 @@ ++/** Placement in the native parsed document. */ ++export type MarkdownAssetPlacement = ++ | 'block' ++ | 'inline' ++ | 'list' ++ | 'table' ++ | 'blockquote'; ++ ++interface MarkdownAssetDescriptor { ++ /** Occurrence ID, scoped to the component and document lineage. */ ++ id: string; ++ url: string; ++ altText: string; ++ title: string; ++ placement: MarkdownAssetPlacement; ++} ++ ++export interface MarkdownMediaAsset extends MarkdownAssetDescriptor { ++ kind: 'image' | 'video'; ++ /** Whether this placement supports renderMedia. */ ++ eligible: boolean; ++} ++ ++export interface MarkdownLinkAsset extends MarkdownAssetDescriptor { ++ kind: 'link'; ++ eligible: false; ++} ++ ++export type MarkdownDocumentAsset = MarkdownMediaAsset | MarkdownLinkAsset; ++ ++export interface DocumentAssetsEvent { ++ revision: number; ++ assets: MarkdownDocumentAsset[]; ++} ++ ++/** Download transport only; semantic image metadata retains the original URL. */ ++export interface MarkdownImageSource { ++ uri: string; ++ headers?: Record; ++} +diff --git a/src/utils/regexParser.ts b/src/utils/regexParser.ts +index cee4b2c679896d79609bc2a242cf6ca9b2598332..bcdfcef476f7ec879e11026d49f6adadcc5bb0c2 100644 +--- a/src/utils/regexParser.ts ++++ b/src/utils/regexParser.ts +@@ -52,3 +52,11 @@ export const toNativeRegexConfig = ( + isDefault: false, + }; + }; ++ ++/** Renderer recognition is opt-in, including when input normalization falls back. */ ++export const toNativeTextLinkRegexConfig = ( ++ regex: RegExp | undefined | null ++): LinkNativeRegex => { ++ const config = toNativeRegexConfig(regex ?? null); ++ return config.isDefault ? DISABLED_REGEX : config; ++}; +diff --git a/src/web/styles.ts b/src/web/styles.ts +index 77d803d2bc12c38bbfe0fb7b1b89cf16a2dc938a..d21ac2b1d4be8835fe01a803ec4d28f0cdc5288b 100644 +--- a/src/web/styles.ts ++++ b/src/web/styles.ts +@@ -348,7 +348,7 @@ export function linkStyleForUrl( + const backgroundColor = resolved.backgroundColor; + return { + color: resolved.color, +- fontFamily: normalizeFontFamily(base.fontFamily), ++ fontFamily: normalizeFontFamily(resolved.fontFamily), + textDecoration: resolved.underline ? 'underline' : 'none', + ...(backgroundColor && backgroundColor !== 'transparent' + ? { backgroundColor } diff --git a/patches/react-native-nitro-modules@0.35.9.patch b/patches/react-native-nitro-modules@0.35.9.patch deleted file mode 100644 index d70069dd4d1a..000000000000 --- a/patches/react-native-nitro-modules@0.35.9.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/package.json b/package.json -index 4e4366fb9d05a6c250acfc62e79487475d8ac05b..200e4680d77cbb4f14d22eb986efde1275a0d3e8 100644 ---- a/package.json -+++ b/package.json -@@ -88,6 +88,11 @@ - "jsSrcsDir": "./src", - "android": { - "javaPackageName": "com.margelo.nitro" -+ }, -+ "ios": { -+ "modulesProvider": { -+ "NitroModules": "NativeNitroModules" -+ } - } - }, - "jest": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6e7e0a72ddf1..3fd29649f543 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,10 +106,9 @@ patchedDependencies: expo-notifications@57.0.15: f89252c2c08dc7b3acb8415f319ebbe15fff8c9f88a64ebe1830cd5ac5c9ac40 expo-sharing@57.0.17: 8d2e3b10eb3f52036a9a086800180ec6cebf3b75bccc5b1775117a7244d4ac45 expo-widgets@57.0.15: 319a9ded5db49c5b5215c511a138b33f44c7ea2972eb418192e8d5342fe75ce6 - react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a: 23cd65b5b41858ca4373112cf3861fddff058ffe04e68f92d56940d895bb1490 + react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a: a522dccc5ff04896285a631f856f5c36fd737d41db7483f6dc1345057d513639 react-native-gesture-handler@2.32.0: 0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2 react-native-keyboard-controller@1.21.13: 6e4339347bc5bb3c9ea67d85ff5c814058b211c5750f247aba59d07869a2e787 - react-native-nitro-modules@0.35.9: 825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675 react-native-reanimated@4.5.5: bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d react-native-screens@4.26.2: 8156dd0f3407822404793cfdaa95639a36b62102f4507c981b8be83600bb382d uniwind@1.11.0: 17d92be2eec71bb6396b402e8d034968e54b28746876d7977cb3139655f42b90 @@ -437,7 +436,7 @@ importers: version: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) react-native-enriched-markdown: specifier: 1.1.0-nightly-20260918-bb2b0942a - version: 1.1.0-nightly-20260918-bb2b0942a(patch_hash=23cd65b5b41858ca4373112cf3861fddff058ffe04e68f92d56940d895bb1490)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + version: 1.1.0-nightly-20260918-bb2b0942a(patch_hash=a522dccc5ff04896285a631f856f5c36fd737d41db7483f6dc1345057d513639)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) react-native-gesture-handler: specifier: ~2.32.0 version: 2.32.0(patch_hash=0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) @@ -447,9 +446,6 @@ importers: react-native-keyboard-controller: specifier: 1.21.13 version: 1.21.13(patch_hash=6e4339347bc5bb3c9ea67d85ff5c814058b211c5750f247aba59d07869a2e787)(react-native-reanimated@4.5.5(patch_hash=bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - react-native-nitro-modules: - specifier: 0.35.9 - version: 0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) react-native-reanimated: specifier: 4.5.5 version: 4.5.5(patch_hash=bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) @@ -9357,12 +9353,6 @@ packages: react-native: '*' react-native-reanimated: '>=3.0.0' - react-native-nitro-modules@0.35.9: - resolution: {integrity: sha512-yCO6eJ85SPPUo4a4an7H5oj6wPCSIT72fbjr5WZ/20n6zswaJ2gNNpnWtg2We0AZwkAOjSqkOJ0Vjc05p6kGiA==} - peerDependencies: - react: '*' - react-native: '*' - react-native-reanimated@4.5.5: resolution: {integrity: sha512-xtJXZRZ1vkec1AIUVG02St2sbyZS5jc7227TlDu/HonqUYPeZAfiC4RI2jqL1dVMNBu1+7oBx/c9QkjF2kg6Lg==} peerDependencies: @@ -20315,7 +20305,7 @@ snapshots: transitivePeerDependencies: - supports-color - react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a(patch_hash=23cd65b5b41858ca4373112cf3861fddff058ffe04e68f92d56940d895bb1490)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a(patch_hash=a522dccc5ff04896285a631f856f5c36fd737d41db7483f6dc1345057d513639)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): dependencies: react: 19.2.3 react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) @@ -20346,11 +20336,6 @@ snapshots: react-native-is-edge-to-edge: 1.3.1(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) react-native-reanimated: 4.5.5(patch_hash=bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) - react-native-nitro-modules@0.35.9(patch_hash=825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): - dependencies: - react: 19.2.3 - react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) - react-native-reanimated@4.5.5(patch_hash=bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d)(react-native-worklets@0.11.4(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): dependencies: react: 19.2.3 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f183db16a6ae..3098032c8466 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -196,7 +196,6 @@ patchedDependencies: react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a: patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch react-native-gesture-handler@2.32.0: patches/react-native-gesture-handler@2.32.0.patch react-native-keyboard-controller@1.21.13: patches/react-native-keyboard-controller@1.21.13.patch - react-native-nitro-modules@0.35.9: patches/react-native-nitro-modules@0.35.9.patch # Preserve the final layout frame. Backport of [#10171](https://github.com/software-mansion/react-native-reanimated/pull/10171). react-native-reanimated@4.5.5: patches/react-native-reanimated@4.5.5.patch react-native-screens@4.26.2: patches/react-native-screens@4.26.2.patch diff --git a/scripts/release-smoke.ts b/scripts/release-smoke.ts index e33116bb1dbf..96af9d410280 100644 --- a/scripts/release-smoke.ts +++ b/scripts/release-smoke.ts @@ -17,7 +17,6 @@ const workspaceFiles = [ "apps/desktop/package.json", "apps/web/package.json", "apps/mobile/package.json", - "apps/mobile/deps/react-native-nitro-markdown-0.5.0.tgz", "apps/mobile/modules/t3-markdown-text/package.json", "apps/mobile/modules/t3-review-diff/package.json", "apps/mobile/modules/t3-terminal/package.json", diff --git a/third-party-licenses.config.json b/third-party-licenses.config.json index 01955554adf6..d72ad7f2e6e1 100644 --- a/third-party-licenses.config.json +++ b/third-party-licenses.config.json @@ -445,13 +445,6 @@ "preamble": ["badgin is a refactored fork of Tinycon."] } }, - { - "name": "react-native-nitro-modules", - "generatedNotice": { - "licenseId": "MIT", - "copyrights": ["Copyright (c) 2024 Marc Rousavy"] - } - }, { "name": "boolbase", "generatedNotice": { From e3c6df7607e15a62274f6bf11ef1fca7db836f6d Mon Sep 17 00:00:00 2001 From: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com> Date: Sun, 20 Sep 2026 16:10:08 -0700 Subject: [PATCH 03/11] fix(mobile): anchor Enriched iOS pills to one source character --- ...own@1.1.0-nightly-20260918-bb2b0942a.patch | 54 ++++++++++++++++--- pnpm-lock.yaml | 6 +-- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch b/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch index c2102028d845..a6cf9cffdefa 100644 --- a/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch +++ b/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch @@ -4122,14 +4122,15 @@ index 0000000000000000000000000000000000000000..344ee92b158abc55e2b3db6b70e34e20 +#endif diff --git a/ios/attachments/ENRMLinkPillAttachment.m b/ios/attachments/ENRMLinkPillAttachment.m new file mode 100644 -index 0000000000000000000000000000000000000000..9e1a6ccca25b049c7db2a9006663fdc5d28213a4 +index 0000000000000000000000000000000000000000..c16deed6aa45f04c3539d7d2cfbf60583de409c9 --- /dev/null +++ b/ios/attachments/ENRMLinkPillAttachment.m -@@ -0,0 +1,241 @@ +@@ -0,0 +1,281 @@ +#import "ENRMLinkPillAttachment.h" +#import "ENRMLinkPillIconCache.h" +#import "ENRMLinkPillTextStorage.h" +#import "StyleConfig.h" ++#import + +#if !TARGET_OS_OSX + @@ -4169,11 +4170,30 @@ index 0000000000000000000000000000000000000000..9e1a6ccca25b049c7db2a9006663fdc5 + return MAX(1, MIN(natural, limit)); +} + ++- (BOOL)startsAttachmentInTextContainer:(NSTextContainer *)container characterIndex:(NSUInteger)index ++{ ++ NSTextStorage *storage = container.layoutManager.textStorage; ++ if (!storage) ++ return YES; ++ if (index >= storage.length) ++ return NO; ++ NSRange range; ++ id attachment = [storage attribute:NSAttachmentAttributeName ++ atIndex:index ++ longestEffectiveRange:&range ++ inRange:NSMakeRange(0, storage.length)]; ++ return attachment == self && index == range.location; ++} ++ +- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)container + proposedLineFragment:(CGRect)lineFragment + glyphPosition:(CGPoint)position + characterIndex:(NSUInteger)characterIndex +{ ++ // TextKit can query attachments directly, bypassing the glyph delegate for ++ // attachment characters. Only the first source character owns the pill box. ++ if (![self startsAttachmentInTextContainer:container characterIndex:characterIndex]) ++ return CGRectZero; + // Use the full container width, not the remainder of the current line. TextKit then moves + // the whole attachment to the next line if it doesn't fit the remainder. + NSParagraphStyle *paragraph = [container.layoutManager.textStorage attribute:NSParagraphStyleAttributeName @@ -4188,6 +4208,9 @@ index 0000000000000000000000000000000000000000..9e1a6ccca25b049c7db2a9006663fdc5 + +- (UIImage *)imageForBounds:(CGRect)bounds textContainer:(NSTextContainer *)container characterIndex:(NSUInteger)index +{ ++ if (bounds.size.width <= 0 || bounds.size.height <= 0 || ++ ![self startsAttachmentInTextContainer:container characterIndex:index]) ++ return nil; + CGSize size = bounds.size; + UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat preferredFormat]; + format.opaque = NO; @@ -4235,6 +4258,15 @@ index 0000000000000000000000000000000000000000..9e1a6ccca25b049c7db2a9006663fdc5 +} +@end + ++@interface ENRMPillGlyphTail : NSObject ++@property (nonatomic) NSUInteger glyphEnd; ++@property (nonatomic) NSUInteger characterIndex; ++@end ++@implementation ENRMPillGlyphTail ++@end ++ ++static char ENRMPillGlyphTailKey; ++ +@implementation ENRMLinkPillLayoutDelegate ++ (instancetype)shared +{ @@ -4252,6 +4284,18 @@ index 0000000000000000000000000000000000000000..9e1a6ccca25b049c7db2a9006663fdc5 + forGlyphRange:(NSRange)glyphRange +{ + NSUInteger count = glyphRange.length; ++ if (count == 0) ++ return 0; ++ ENRMPillGlyphTail *tail = objc_getAssociatedObject(manager, &ENRMPillGlyphTailKey); ++ BOOL continuesFirstCharacter = tail && tail.glyphEnd == glyphRange.location && tail.characterIndex == indexes[0]; ++ if (!tail) { ++ tail = [ENRMPillGlyphTail new]; ++ objc_setAssociatedObject(manager, &ENRMPillGlyphTailKey, tail, OBJC_ASSOCIATION_RETAIN_NONATOMIC); ++ } ++ // Remember only the immediately preceding callback. Querying surrounding glyphs ++ // during generation can recurse into this delegate before those glyphs exist. ++ tail.glyphEnd = NSMaxRange(glyphRange); ++ tail.characterIndex = indexes[count - 1]; + NSMutableData *glyphData = [NSMutableData dataWithBytes:glyphs length:count * sizeof(CGGlyph)]; + NSMutableData *propertyData = [NSMutableData dataWithBytes:properties length:count * sizeof(NSGlyphProperty)]; + CGGlyph *replacement = glyphData.mutableBytes; @@ -4269,12 +4313,8 @@ index 0000000000000000000000000000000000000000..9e1a6ccca25b049c7db2a9006663fdc5 + continue; + changed = YES; + // A character can have multiple glyphs, even across font/callback boundaries. -+ // The preceding glyph is outside this callback's range and is already generated. + BOOL startsAttachment = indexes[i] == range.location; -+ BOOL continuesCharacter = -+ startsAttachment && (i > 0 ? indexes[i - 1] == indexes[i] -+ : glyphRange.location > 0 && -+ [manager characterIndexForGlyphAtIndex:glyphRange.location - 1] == indexes[i]); ++ BOOL continuesCharacter = startsAttachment && (i > 0 ? indexes[i - 1] == indexes[i] : continuesFirstCharacter); + if (startsAttachment && !continuesCharacter) { + // TextKit's attachment glyph exists only in the glyph buffer, never in text storage. + replacement[i] = 0xFFFC; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3fd29649f543..9b7c9838c686 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,7 +106,7 @@ patchedDependencies: expo-notifications@57.0.15: f89252c2c08dc7b3acb8415f319ebbe15fff8c9f88a64ebe1830cd5ac5c9ac40 expo-sharing@57.0.17: 8d2e3b10eb3f52036a9a086800180ec6cebf3b75bccc5b1775117a7244d4ac45 expo-widgets@57.0.15: 319a9ded5db49c5b5215c511a138b33f44c7ea2972eb418192e8d5342fe75ce6 - react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a: a522dccc5ff04896285a631f856f5c36fd737d41db7483f6dc1345057d513639 + react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a: 2675a3f4b924f4363fa5d3ecdac9c97e77d93873b3da0ec590cd2b86b3a77ea3 react-native-gesture-handler@2.32.0: 0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2 react-native-keyboard-controller@1.21.13: 6e4339347bc5bb3c9ea67d85ff5c814058b211c5750f247aba59d07869a2e787 react-native-reanimated@4.5.5: bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d @@ -436,7 +436,7 @@ importers: version: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) react-native-enriched-markdown: specifier: 1.1.0-nightly-20260918-bb2b0942a - version: 1.1.0-nightly-20260918-bb2b0942a(patch_hash=a522dccc5ff04896285a631f856f5c36fd737d41db7483f6dc1345057d513639)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + version: 1.1.0-nightly-20260918-bb2b0942a(patch_hash=2675a3f4b924f4363fa5d3ecdac9c97e77d93873b3da0ec590cd2b86b3a77ea3)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) react-native-gesture-handler: specifier: ~2.32.0 version: 2.32.0(patch_hash=0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) @@ -20305,7 +20305,7 @@ snapshots: transitivePeerDependencies: - supports-color - react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a(patch_hash=a522dccc5ff04896285a631f856f5c36fd737d41db7483f6dc1345057d513639)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a(patch_hash=2675a3f4b924f4363fa5d3ecdac9c97e77d93873b3da0ec590cd2b86b3a77ea3)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): dependencies: react: 19.2.3 react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) From 6dd1e28fd709fd8d8b36afbf27142218ab31d4e5 Mon Sep 17 00:00:00 2001 From: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com> Date: Sun, 20 Sep 2026 16:14:38 -0700 Subject: [PATCH 04/11] fix(mobile): retain direct previews in captured Markdown --- .../src/features/files/FileMarkdownPreview.tsx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/apps/mobile/src/features/files/FileMarkdownPreview.tsx b/apps/mobile/src/features/files/FileMarkdownPreview.tsx index 573fa8104e63..c5e4c5430db6 100644 --- a/apps/mobile/src/features/files/FileMarkdownPreview.tsx +++ b/apps/mobile/src/features/files/FileMarkdownPreview.tsx @@ -162,13 +162,11 @@ export function FileMarkdownPreview(props: { /> ); } - const preview = props.threadId - ? resolveMarkdownMediaPreview(image.href, { - environmentId: props.environmentId, - threadId: props.threadId, - workspaceRoot: markdownDirectory, - }) - : null; + const preview = resolveMarkdownMediaPreview(image.href, { + environmentId: props.environmentId, + threadId: props.threadId, + workspaceRoot: markdownDirectory, + }); return preview?.kind === "video" ? ( ) : ( @@ -196,7 +194,6 @@ export function FileMarkdownPreview(props: { }); const onImagePress = useCallback( (href: string) => { - if (props.captured) return; const direct = resolveMobileMarkdownMediaSource(href, { threadId: props.threadId ?? undefined, workspaceRoot: markdownDirectory, @@ -210,6 +207,7 @@ export function FileMarkdownPreview(props: { }); return; } + if (props.captured) return; if (!props.threadId) { if (direct?.access === "environment" && direct.kind === "image") { setExpandedFile({ From 9133818bd08a16932c8e51b481add37865616395 Mon Sep 17 00:00:00 2001 From: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com> Date: Sun, 20 Sep 2026 16:23:46 -0700 Subject: [PATCH 05/11] perf(mobile): skip pill glyph work for ordinary Markdown --- ...own@1.1.0-nightly-20260918-bb2b0942a.patch | 48 +++++++++++-------- pnpm-lock.yaml | 6 +-- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch b/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch index a6cf9cffdefa..aa6a29e6e1ab 100644 --- a/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch +++ b/patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch @@ -4122,10 +4122,10 @@ index 0000000000000000000000000000000000000000..344ee92b158abc55e2b3db6b70e34e20 +#endif diff --git a/ios/attachments/ENRMLinkPillAttachment.m b/ios/attachments/ENRMLinkPillAttachment.m new file mode 100644 -index 0000000000000000000000000000000000000000..c16deed6aa45f04c3539d7d2cfbf60583de409c9 +index 0000000000000000000000000000000000000000..9314cebe1cf6415fd5105e24c4507b954e538c7e --- /dev/null +++ b/ios/attachments/ENRMLinkPillAttachment.m -@@ -0,0 +1,281 @@ +@@ -0,0 +1,289 @@ +#import "ENRMLinkPillAttachment.h" +#import "ENRMLinkPillIconCache.h" +#import "ENRMLinkPillTextStorage.h" @@ -4296,22 +4296,27 @@ index 0000000000000000000000000000000000000000..c16deed6aa45f04c3539d7d2cfbf6058 + // during generation can recurse into this delegate before those glyphs exist. + tail.glyphEnd = NSMaxRange(glyphRange); + tail.characterIndex = indexes[count - 1]; -+ NSMutableData *glyphData = [NSMutableData dataWithBytes:glyphs length:count * sizeof(CGGlyph)]; -+ NSMutableData *propertyData = [NSMutableData dataWithBytes:properties length:count * sizeof(NSGlyphProperty)]; -+ CGGlyph *replacement = glyphData.mutableBytes; -+ NSGlyphProperty *replacementProperties = propertyData.mutableBytes; -+ BOOL changed = NO; ++ NSMutableData *glyphData = nil; ++ NSMutableData *propertyData = nil; ++ CGGlyph *replacement = NULL; ++ NSGlyphProperty *replacementProperties = NULL; + for (NSUInteger i = 0; i < count; i++) { ++ id attachment = [manager.textStorage attribute:NSAttachmentAttributeName atIndex:indexes[i] effectiveRange:NULL]; ++ if (![attachment isKindOfClass:ENRMLinkPillAttachment.class]) ++ continue; + NSRange range; + // Attribute runs may split at every source character after UIKit fixes fonts/colors. + // The pill starts at the longest range of the attachment alone, not the current run. -+ id attachment = [manager.textStorage attribute:NSAttachmentAttributeName -+ atIndex:indexes[i] -+ longestEffectiveRange:&range -+ inRange:NSMakeRange(0, manager.textStorage.length)]; -+ if (![attachment isKindOfClass:ENRMLinkPillAttachment.class]) -+ continue; -+ changed = YES; ++ [manager.textStorage attribute:NSAttachmentAttributeName ++ atIndex:indexes[i] ++ longestEffectiveRange:&range ++ inRange:NSMakeRange(0, manager.textStorage.length)]; ++ if (!glyphData) { ++ glyphData = [NSMutableData dataWithBytes:glyphs length:count * sizeof(CGGlyph)]; ++ propertyData = [NSMutableData dataWithBytes:properties length:count * sizeof(NSGlyphProperty)]; ++ replacement = glyphData.mutableBytes; ++ replacementProperties = propertyData.mutableBytes; ++ } + // A character can have multiple glyphs, even across font/callback boundaries. + BOOL startsAttachment = indexes[i] == range.location; + BOOL continuesCharacter = startsAttachment && (i > 0 ? indexes[i - 1] == indexes[i] : continuesFirstCharacter); @@ -4324,7 +4329,7 @@ index 0000000000000000000000000000000000000000..c16deed6aa45f04c3539d7d2cfbf6058 + replacementProperties[i] = NSGlyphPropertyNull; + } + } -+ if (!changed) ++ if (!glyphData) + return 0; + [manager setGlyphs:replacement + properties:replacementProperties @@ -4338,12 +4343,15 @@ index 0000000000000000000000000000000000000000..c16deed6aa45f04c3539d7d2cfbf6058 +{ + if (index >= manager.textStorage.length) + return YES; ++ id attachment = [manager.textStorage attribute:NSAttachmentAttributeName atIndex:index effectiveRange:NULL]; ++ if (![attachment isKindOfClass:ENRMLinkPillAttachment.class]) ++ return YES; + NSRange range; -+ id attachment = [manager.textStorage attribute:NSAttachmentAttributeName -+ atIndex:index -+ longestEffectiveRange:&range -+ inRange:NSMakeRange(0, manager.textStorage.length)]; -+ return ![attachment isKindOfClass:ENRMLinkPillAttachment.class] || index == range.location; ++ [manager.textStorage attribute:NSAttachmentAttributeName ++ atIndex:index ++ longestEffectiveRange:&range ++ inRange:NSMakeRange(0, manager.textStorage.length)]; ++ return index == range.location; +} +@end + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9b7c9838c686..a785eca9c594 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,7 +106,7 @@ patchedDependencies: expo-notifications@57.0.15: f89252c2c08dc7b3acb8415f319ebbe15fff8c9f88a64ebe1830cd5ac5c9ac40 expo-sharing@57.0.17: 8d2e3b10eb3f52036a9a086800180ec6cebf3b75bccc5b1775117a7244d4ac45 expo-widgets@57.0.15: 319a9ded5db49c5b5215c511a138b33f44c7ea2972eb418192e8d5342fe75ce6 - react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a: 2675a3f4b924f4363fa5d3ecdac9c97e77d93873b3da0ec590cd2b86b3a77ea3 + react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a: b51bef3b188eaad24f1cf0d59fd84a1f187e9862e6ddd38417357f22ec988f37 react-native-gesture-handler@2.32.0: 0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2 react-native-keyboard-controller@1.21.13: 6e4339347bc5bb3c9ea67d85ff5c814058b211c5750f247aba59d07869a2e787 react-native-reanimated@4.5.5: bae9878a5bdba94e11c890e5ee164542feb622624fc81c13890063094608216d @@ -436,7 +436,7 @@ importers: version: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) react-native-enriched-markdown: specifier: 1.1.0-nightly-20260918-bb2b0942a - version: 1.1.0-nightly-20260918-bb2b0942a(patch_hash=2675a3f4b924f4363fa5d3ecdac9c97e77d93873b3da0ec590cd2b86b3a77ea3)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) + version: 1.1.0-nightly-20260918-bb2b0942a(patch_hash=b51bef3b188eaad24f1cf0d59fd84a1f187e9862e6ddd38417357f22ec988f37)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) react-native-gesture-handler: specifier: ~2.32.0 version: 2.32.0(patch_hash=0579f8e4dad02bf3183d95b02620358412983c36f9bda7425dc8bcb9643b5ce2)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) @@ -20305,7 +20305,7 @@ snapshots: transitivePeerDependencies: - supports-color - react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a(patch_hash=2675a3f4b924f4363fa5d3ecdac9c97e77d93873b3da0ec590cd2b86b3a77ea3)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): + react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a(patch_hash=b51bef3b188eaad24f1cf0d59fd84a1f187e9862e6ddd38417357f22ec988f37)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3): dependencies: react: 19.2.3 react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6) From 7f91ec6b7bfaf0368af11a07d374042bef113df3 Mon Sep 17 00:00:00 2001 From: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com> Date: Sun, 20 Sep 2026 17:07:09 -0700 Subject: [PATCH 06/11] chore(mobile): package Enriched prototype as a local tarball --- apps/mobile/package.json | 2 +- apps/mobile/vendor/README.md | 20 + ...kdown-1.1.0-nightly-20260918-bb2b0942a.tgz | Bin 0 -> 1012334 bytes ...own@1.1.0-nightly-20260918-bb2b0942a.patch | 9761 ----------------- pnpm-lock.yaml | 12 +- pnpm-workspace.yaml | 3 +- scripts/release-smoke.ts | 7 + 7 files changed, 35 insertions(+), 9770 deletions(-) create mode 100644 apps/mobile/vendor/README.md create mode 100644 apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz delete mode 100644 patches/react-native-enriched-markdown@1.1.0-nightly-20260918-bb2b0942a.patch diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 521e31483a3f..ab5ee0a59f23 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -112,7 +112,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "react-native": "0.86.3", - "react-native-enriched-markdown": "1.1.0-nightly-20260918-bb2b0942a", + "react-native-enriched-markdown": "file:./vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz", "react-native-gesture-handler": "~2.32.0", "react-native-image-viewing": "^0.2.2", "react-native-keyboard-controller": "1.21.13", diff --git a/apps/mobile/vendor/README.md b/apps/mobile/vendor/README.md new file mode 100644 index 000000000000..47294491ae97 --- /dev/null +++ b/apps/mobile/vendor/README.md @@ -0,0 +1,20 @@ +# Enriched Markdown prototype package + +The tarball contains the prepared `react-native-enriched-markdown` package based on +upstream [bb2b0942](https://github.com/software-mansion/enriched-markdown/commit/bb2b0942a55555463fe129899d9c922038f10c41), +including the prototype's generic API extensions and native fixes. It replaces +the pnpm patch without changing the library's runtime sources. JS, TypeScript +declarations, generated native bindings, native sources, and the MIT license are +included. Enriched's postinstall restores its grammar dependencies as usual. + +To inspect the package, extract it with `tar -xzf `. The resulting +`package/` directory contains the sources as well as the built outputs. + +To replace it, build and prepare the updated Enriched package for npm publication, +then run `npm pack --ignore-scripts --pack-destination ` from that +prepared package directory. Do not pack an installed copy after postinstall has +downloaded the grammar sources. Use a new filename for each rebuilt package, +update the mobile dependency path, and run `vp install` to refresh the lockfile's +integrity hash and the matching `allowBuilds` entry in `pnpm-workspace.yaml`. + +Switch back to the published dependency once the required upstream APIs ship. diff --git a/apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz b/apps/mobile/vendor/react-native-enriched-markdown-1.1.0-nightly-20260918-bb2b0942a.tgz new file mode 100644 index 0000000000000000000000000000000000000000..20d0c8b92ce12834eaa2cdb9eb2c233db93daf79 GIT binary patch literal 1012334 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%0DVlPR`!EI@tup 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 |YmAsm|>(NNy4mscJ{vGiR| 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