From 836e4d9645012fc261b863add231e6cd94242ce2 Mon Sep 17 00:00:00 2001
From: Neil Marcellini <neil@expensify.com>
Date: Tue, 1 Apr 2025 14:00:16 -0700
Subject: [PATCH] Revert "Fix nested markdown isn't applied"

---
 .../BaseHTMLEngineProvider.tsx                | 21 ++----------
 .../HTMLRenderers/EMRenderer.tsx              | 33 +++++++++++++++++++
 .../HTMLRenderers/HeadingRenderer.tsx         | 31 +++++++++++++++++
 .../MentionReportRenderer/index.tsx           |  2 +-
 .../HTMLRenderers/StrongRenderer.tsx          | 23 +++++++++++++
 .../HTMLEngineProvider/HTMLRenderers/index.ts |  6 ++++
 src/styles/index.ts                           | 19 ++++++++---
 7 files changed, 111 insertions(+), 24 deletions(-)
 create mode 100644 src/components/HTMLEngineProvider/HTMLRenderers/EMRenderer.tsx
 create mode 100644 src/components/HTMLEngineProvider/HTMLRenderers/HeadingRenderer.tsx
 create mode 100644 src/components/HTMLEngineProvider/HTMLRenderers/StrongRenderer.tsx

diff --git a/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.tsx b/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.tsx
index 0ea56522f74c..d03eea02beb4 100755
--- a/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.tsx
+++ b/src/components/HTMLEngineProvider/BaseHTMLEngineProvider.tsx
@@ -1,12 +1,11 @@
 import React, {useMemo} from 'react';
 import type {TextProps} from 'react-native';
 import {HTMLContentModel, HTMLElementModel, RenderHTMLConfigProvider, TRenderEngineProvider} from 'react-native-render-html';
-import type {TNode} from 'react-native-render-html';
 import useThemeStyles from '@hooks/useThemeStyles';
 import convertToLTR from '@libs/convertToLTR';
 import FontUtils from '@styles/utils/FontUtils';
 import type ChildrenProps from '@src/types/utils/ChildrenProps';
-import {computeEmbeddedMaxWidth, isChildOfTaskTitle} from './htmlEngineUtils';
+import * as HTMLEngineUtils from './htmlEngineUtils';
 import htmlRenderers from './HTMLRenderers';
 
 type BaseHTMLEngineProviderProps = ChildrenProps & {
@@ -80,17 +79,7 @@ function BaseHTMLEngineProvider({textSelectable = false, children, enableExperim
             }),
             strong: HTMLElementModel.fromCustomModel({
                 tagName: 'strong',
-                getMixedUAStyles: (tnode) => (isChildOfTaskTitle(tnode as TNode) ? {} : styles.strong),
-                contentModel: HTMLContentModel.textual,
-            }),
-            em: HTMLElementModel.fromCustomModel({
-                tagName: 'em',
-                getMixedUAStyles: (tnode) => (isChildOfTaskTitle(tnode as TNode) ? styles.taskTitleMenuItemItalic : styles.em),
-                contentModel: HTMLContentModel.textual,
-            }),
-            h1: HTMLElementModel.fromCustomModel({
-                tagName: 'h1',
-                getMixedUAStyles: (tnode) => (isChildOfTaskTitle(tnode as TNode) ? {} : styles.h1),
+                mixedUAStyles: {whiteSpace: 'pre'},
                 contentModel: HTMLContentModel.textual,
             }),
             'mention-user': HTMLElementModel.fromCustomModel({tagName: 'mention-user', contentModel: HTMLContentModel.textual}),
@@ -137,10 +126,6 @@ function BaseHTMLEngineProvider({textSelectable = false, children, enableExperim
             styles.onlyEmojisText,
             styles.onlyEmojisTextLineHeight,
             styles.taskTitleMenuItem,
-            styles.taskTitleMenuItemItalic,
-            styles.em,
-            styles.strong,
-            styles.h1,
         ],
     );
     /* eslint-enable @typescript-eslint/naming-convention */
@@ -167,7 +152,7 @@ function BaseHTMLEngineProvider({textSelectable = false, children, enableExperim
                 defaultTextProps={defaultTextProps}
                 defaultViewProps={defaultViewProps}
                 renderers={htmlRenderers}
-                computeEmbeddedMaxWidth={computeEmbeddedMaxWidth}
+                computeEmbeddedMaxWidth={HTMLEngineUtils.computeEmbeddedMaxWidth}
                 enableExperimentalBRCollapsing={enableExperimentalBRCollapsing}
             >
                 {children}
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/EMRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/EMRenderer.tsx
new file mode 100644
index 000000000000..c1f044384fbe
--- /dev/null
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/EMRenderer.tsx
@@ -0,0 +1,33 @@
+import React from 'react';
+import type {CustomRendererProps, TPhrasing, TText} from 'react-native-render-html';
+import {TNodeChildrenRenderer} from 'react-native-render-html';
+import * as HTMLEngineUtils from '@components/HTMLEngineProvider/htmlEngineUtils';
+import Text from '@components/Text';
+import useThemeStyles from '@hooks/useThemeStyles';
+
+function EMRenderer({tnode}: CustomRendererProps<TText | TPhrasing>) {
+    const styles = useThemeStyles();
+    const isChildOfTaskTitle = HTMLEngineUtils.isChildOfTaskTitle(tnode);
+
+    return 'data' in tnode ? (
+        <Text style={[styles.webViewStyles.baseFontStyle, styles.webViewStyles.tagStyles.em, isChildOfTaskTitle && styles.taskTitleMenuItemItalic]}>{tnode.data}</Text>
+    ) : (
+        <TNodeChildrenRenderer
+            tnode={tnode}
+            renderChild={(props) => {
+                return (
+                    <Text
+                        style={[styles.webViewStyles.baseFontStyle, styles.strong, isChildOfTaskTitle && styles.taskTitleMenuItem]}
+                        key={props.key}
+                    >
+                        {props.childElement}
+                    </Text>
+                );
+            }}
+        />
+    );
+}
+
+EMRenderer.displayName = 'EMRenderer';
+
+export default EMRenderer;
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/HeadingRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/HeadingRenderer.tsx
new file mode 100644
index 000000000000..9d7c402e17fd
--- /dev/null
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/HeadingRenderer.tsx
@@ -0,0 +1,31 @@
+import React from 'react';
+import type {CustomRendererProps, TPhrasing, TText} from 'react-native-render-html';
+import {TNodeChildrenRenderer} from 'react-native-render-html';
+import * as HTMLEngineUtils from '@components/HTMLEngineProvider/htmlEngineUtils';
+import Text from '@components/Text';
+import useThemeStyles from '@hooks/useThemeStyles';
+
+function HeadingRenderer({tnode}: CustomRendererProps<TText | TPhrasing>) {
+    const styles = useThemeStyles();
+    const isChildOfTaskTitle = HTMLEngineUtils.isChildOfTaskTitle(tnode);
+
+    return (
+        <TNodeChildrenRenderer
+            tnode={tnode}
+            renderChild={(props) => {
+                return (
+                    <Text
+                        style={[styles.webViewStyles.baseFontStyle, styles.h1, isChildOfTaskTitle && styles.taskTitleMenuItem]}
+                        key={props.key}
+                    >
+                        {props.childElement}
+                    </Text>
+                );
+            }}
+        />
+    );
+}
+
+HeadingRenderer.displayName = 'HeadingRenderer';
+
+export default HeadingRenderer;
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/MentionReportRenderer/index.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/MentionReportRenderer/index.tsx
index f517489191fd..12dec12b2dfd 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/MentionReportRenderer/index.tsx
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/MentionReportRenderer/index.tsx
@@ -60,7 +60,7 @@ function MentionReportRenderer({style, tnode, TDefaultRenderer, ...defaultRender
                     style={
                         isGroupPolicyReport && (!exactlyMatch || navigationRoute)
                             ? [styles.link, styleWithoutColor, StyleUtils.getMentionStyle(isCurrentRoomMention), {color: StyleUtils.getMentionTextColor(isCurrentRoomMention)}]
-                            : [flattenStyle]
+                            : []
                     }
                     suppressHighlighting
                     onPress={
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/StrongRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/StrongRenderer.tsx
new file mode 100644
index 000000000000..5a9f7ca65255
--- /dev/null
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/StrongRenderer.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import type {StyleProp, TextStyle} from 'react-native';
+import type {CustomRendererProps, TPhrasing, TText} from 'react-native-render-html';
+import * as HTMLEngineUtils from '@components/HTMLEngineProvider/htmlEngineUtils';
+import useThemeStyles from '@hooks/useThemeStyles';
+
+function StrongRenderer({tnode, TDefaultRenderer, style, ...props}: CustomRendererProps<TText | TPhrasing>) {
+    const styles = useThemeStyles();
+    const isChildOfTaskTitle = HTMLEngineUtils.isChildOfTaskTitle(tnode);
+
+    return (
+        <TDefaultRenderer
+            // eslint-disable-next-line react/jsx-props-no-spreading
+            {...props}
+            tnode={tnode}
+            style={[style as StyleProp<TextStyle>, isChildOfTaskTitle && styles.taskTitleMenuItem, {fontStyle: (style.fontStyle as TextStyle['fontStyle']) ?? 'normal'}]}
+        />
+    );
+}
+
+StrongRenderer.displayName = 'StrongRenderer';
+
+export default StrongRenderer;
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/index.ts b/src/components/HTMLEngineProvider/HTMLRenderers/index.ts
index c59c9675ec87..2ac2e8591915 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/index.ts
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/index.ts
@@ -4,6 +4,8 @@ import CodeRenderer from './CodeRenderer';
 import DeletedActionRenderer from './DeletedActionRenderer';
 import EditedRenderer from './EditedRenderer';
 import EmojiRenderer from './EmojiRenderer';
+import EMRenderer from './EMRenderer';
+import HeadingRenderer from './HeadingRenderer';
 import ImageRenderer from './ImageRenderer';
 import MentionHereRenderer from './MentionHereRenderer';
 import MentionReportRenderer from './MentionReportRenderer';
@@ -11,6 +13,7 @@ import MentionUserRenderer from './MentionUserRenderer';
 import NextStepEmailRenderer from './NextStepEmailRenderer';
 import PreRenderer from './PreRenderer';
 import ShortMentionRenderer from './ShortMentionRenderer';
+import StrongRenderer from './StrongRenderer';
 import TaskTitleRenderer from './TaskTitleRenderer';
 import VideoRenderer from './VideoRenderer';
 
@@ -23,6 +26,9 @@ const HTMLEngineProviderComponentList: CustomTagRendererRecord = {
     code: CodeRenderer,
     img: ImageRenderer,
     video: VideoRenderer,
+    h1: HeadingRenderer,
+    strong: StrongRenderer,
+    em: EMRenderer,
 
     // Custom tag renderers
     edited: EditedRenderer,
diff --git a/src/styles/index.ts b/src/styles/index.ts
index f9e7f93977b0..beaa81a9436f 100644
--- a/src/styles/index.ts
+++ b/src/styles/index.ts
@@ -150,6 +150,18 @@ const webViewStyles = (theme: ThemeColors) =>
         // styles from the renderer, just pass the "style" prop to the underlying
         // component.
         tagStyles: {
+            em: {
+                // We set fontFamily and fontStyle directly in order to avoid overriding fontWeight.
+                fontFamily: FontUtils.fontFamily.platform.EXP_NEUE_ITALIC.fontFamily,
+                fontStyle: FontUtils.fontFamily.platform.EXP_NEUE_ITALIC.fontStyle,
+            },
+
+            strong: {
+                // We set fontFamily and fontWeight directly in order to avoid overriding fontStyle.
+                fontFamily: FontUtils.fontFamily.platform.EXP_NEUE_BOLD.fontFamily,
+                fontWeight: FontUtils.fontFamily.platform.EXP_NEUE_BOLD.fontWeight,
+            },
+
             del: {
                 textDecorationLine: 'line-through',
                 textDecorationStyle: 'solid',
@@ -217,6 +229,8 @@ const webViewStyles = (theme: ThemeColors) =>
                 marginBottom: 0,
             },
             h1: {
+                fontSize: undefined,
+                fontWeight: undefined,
                 marginBottom: 8,
             },
         },
@@ -275,11 +289,6 @@ const styles = (theme: ThemeColors) =>
             fontWeight: FontUtils.fontFamily.platform.EXP_NEUE_BOLD.fontWeight,
         },
 
-        em: {
-            fontFamily: FontUtils.fontFamily.platform.EXP_NEUE_ITALIC.fontFamily,
-            fontStyle: FontUtils.fontFamily.platform.EXP_NEUE_ITALIC.fontStyle,
-        },
-
         autoCompleteSuggestionContainer: {
             flexDirection: 'row',
             alignItems: 'center',
