Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
1e900c2
feat: Upgrade task titles with markdown rendering.
Krishna2323 Dec 7, 2024
83c1f02
add task title renderer.
Krishna2323 Dec 7, 2024
6b2dbe7
Merge branch 'Expensify:main' into krishna2323/issue/53175
Krishna2323 Dec 7, 2024
8d850d6
Merge branch 'main' into krishna2323/issue/53175
Krishna2323 Dec 15, 2024
f15c822
Merge branch 'Expensify:main' into krishna2323/issue/53175
Krishna2323 Dec 16, 2024
325eff0
Merge branch 'Expensify:main' into krishna2323/issue/53175
Krishna2323 Dec 22, 2024
d474b5e
Merge branch 'main' into krishna2323/issue/53175
Krishna2323 Jan 5, 2025
4f2ad8d
Merge branch 'main' into krishna2323/issue/53175
Krishna2323 Feb 7, 2025
1ef5238
minor fix.
Krishna2323 Feb 7, 2025
94d7ee9
Merge branch 'Expensify:main' into krishna2323/issue/53175
Krishna2323 Feb 16, 2025
f4bc960
fix failing tests.
Krishna2323 Feb 16, 2025
9169bb4
add changes from PR:55967.
Krishna2323 Feb 16, 2025
6e9fa91
fix: markdown not working after edit.
Krishna2323 Feb 16, 2025
e684a61
fix heading preview for task title.
Krishna2323 Feb 16, 2025
4daa846
fix task title with h1 tag.
Krishna2323 Feb 16, 2025
4d6d79d
remove commented code.
Krishna2323 Feb 16, 2025
cc33f33
fix link rendering.
Krishna2323 Feb 16, 2025
8c1d40e
minor updates.
Krishna2323 Feb 17, 2025
6f0cd06
minor fix.
Krishna2323 Feb 17, 2025
7d0a349
fix ESLint.
Krishna2323 Feb 17, 2025
1714937
Merge branch 'Expensify:main' into krishna2323/issue/53175
Krishna2323 Feb 19, 2025
96e5668
fix heading link rendering.
Krishna2323 Feb 19, 2025
65b649a
remove bolded style for h1 in task title view.
Krishna2323 Feb 19, 2025
556f195
add Heading renderer.
Krishna2323 Feb 19, 2025
d41a830
fix heading renderer file name.
Krishna2323 Feb 19, 2025
38c69a7
remove unused style.
Krishna2323 Feb 19, 2025
75554a3
Merge branch 'Expensify:main' into krishna2323/issue/53175
Krishna2323 Feb 22, 2025
4b01221
add escape markdown rules for task title.
Krishna2323 Feb 22, 2025
c2500de
update code block font size.
Krishna2323 Feb 22, 2025
7d8e3c4
Merge branch 'Expensify:main' into krishna2323/issue/53175
Krishna2323 Feb 26, 2025
7c53869
add em and strong renderers.
Krishna2323 Feb 26, 2025
97a12d0
remove escape rules for task titles.
Krishna2323 Feb 26, 2025
517a9c0
Merge branch 'Expensify:main' into krishna2323/issue/53175
Krishna2323 Mar 1, 2025
42161e4
fix code block size inside isInsideH1 & isInsideTaskTitle.
Krishna2323 Mar 1, 2025
c64126c
Merge branch 'main' into krishna2323/issue/53175
Krishna2323 Mar 5, 2025
3876179
Resolve PR review comments.
Krishna2323 Mar 5, 2025
a372369
memoize parsed task title and description.
Krishna2323 Mar 5, 2025
96ae24d
add unit tests.
Krishna2323 Mar 5, 2025
5f234ac
add tests for task report name case in getReportName.
Krishna2323 Mar 6, 2025
2d63ceb
Merge branch 'main' into krishna2323/issue/53175
Krishna2323 Mar 6, 2025
0e758f8
fix code blocks.
Krishna2323 Mar 6, 2025
4fbb1b3
fix: eslint.
Krishna2323 Mar 6, 2025
4a32291
fix task preview in native devices.
Krishna2323 Mar 7, 2025
1567e14
fix overflowing text on mWeb.
Krishna2323 Mar 7, 2025
26e12ba
add line height to taskTitleMenuItem..
Krishna2323 Mar 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3429,6 +3429,7 @@ const CONST = {
WORKSPACE_REPORT_FIELD_POLICY_MAX_LENGTH: 256,
REPORT_NAME_LIMIT: 100,
TITLE_CHARACTER_LIMIT: 100,
TASK_TITLE_CHARACTER_LIMIT: 10000,
DESCRIPTION_LIMIT: 1000,
SEARCH_QUERY_LIMIT: 1000,
WORKSPACE_NAME_CHARACTER_LIMIT: 80,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,27 @@ import Tooltip from '@components/Tooltip';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
import {canUseTouchScreen} from '@libs/DeviceCapabilities';
import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu';
import CONST from '@src/CONST';
import type {BaseAnchorForCommentsOnlyProps, LinkProps} from './types';

/*
* This is a default anchor component for regular links.
*/
function BaseAnchorForCommentsOnly({onPressIn, onPressOut, href = '', rel = '', target = '', children = null, style, onPress, linkHasImage, ...rest}: BaseAnchorForCommentsOnlyProps) {
function BaseAnchorForCommentsOnly({
onPressIn,
onPressOut,
href = '',
rel = '',
target = '',
children = null,
style,
onPress,
linkHasImage,
wrapperStyle,
...rest
}: BaseAnchorForCommentsOnlyProps) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const linkRef = useRef<RNText>(null);
Expand All @@ -38,7 +50,7 @@ function BaseAnchorForCommentsOnly({onPressIn, onPressOut, href = '', rel = '',
} else {
linkProps.href = href;
}
const defaultTextStyle = DeviceCapabilities.canUseTouchScreen() || shouldUseNarrowLayout ? {} : {...styles.userSelectText, ...styles.cursorPointer};
const defaultTextStyle = canUseTouchScreen() || shouldUseNarrowLayout ? {} : {...styles.userSelectText, ...styles.cursorPointer};
const isEmail = Str.isValidEmail(href.replace(/mailto:/i, ''));
const linkHref = !linkHasImage ? href : undefined;

Expand All @@ -62,6 +74,7 @@ function BaseAnchorForCommentsOnly({onPressIn, onPressOut, href = '', rel = '',
onPressOut={onPressOut}
role={CONST.ROLE.LINK}
accessibilityLabel={href}
wrapperStyle={wrapperStyle}
>
<Tooltip text={linkHref}>
<Text
Expand Down
5 changes: 4 additions & 1 deletion src/components/AnchorForCommentsOnly/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type {StyleProp, TextStyle} from 'react-native';
import type {StyleProp, TextStyle, ViewStyle} from 'react-native';
import type ChildrenProps from '@src/types/utils/ChildrenProps';

type AnchorForCommentsOnlyProps = ChildrenProps & {
Expand All @@ -16,6 +16,9 @@ type AnchorForCommentsOnlyProps = ChildrenProps & {
/** Any additional styles to apply */
style: StyleProp<TextStyle>;

/** Any additional styles to apply to the wrapper */
wrapperStyle?: StyleProp<ViewStyle>;

/** Press handler for the link, when not passed, default href is used to create a link like behaviour */
onPress?: () => void;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ function BaseHTMLEngineProvider({textSelectable = false, children, enableExperim
tagName: 'edited',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we didn't check the styles appropriately, please check #58341

contentModel: HTMLContentModel.textual,
}),
'task-title': HTMLElementModel.fromCustomModel({
tagName: 'task-title',
contentModel: HTMLContentModel.block,
mixedUAStyles: {...styles.taskTitleMenuItem},
}),
'alert-text': HTMLElementModel.fromCustomModel({
tagName: 'alert-text',
mixedUAStyles: {...styles.formError, ...styles.mb0},
Expand Down Expand Up @@ -119,6 +124,7 @@ function BaseHTMLEngineProvider({textSelectable = false, children, enableExperim
styles.mutedNormalTextLabel,
styles.onlyEmojisText,
styles.onlyEmojisTextLineHeight,
styles.taskTitleMenuItem,
],
);
/* eslint-enable @typescript-eslint/naming-convention */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import * as HTMLEngineUtils from '@components/HTMLEngineProvider/htmlEngineUtils
import Text from '@components/Text';
import useEnvironment from '@hooks/useEnvironment';
import useThemeStyles from '@hooks/useThemeStyles';
import {getInternalExpensifyPath, getInternalNewExpensifyPath, openLink} from '@libs/actions/Link';
import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot';
import * as Link from '@userActions/Link';
import CONST from '@src/CONST';

type AnchorRendererProps = CustomRendererProps<TBlock> & {
Expand All @@ -27,22 +27,24 @@ function AnchorRenderer({tnode, style, key}: AnchorRendererProps) {
const displayName = tNodeChild && 'data' in tNodeChild && typeof tNodeChild.data === 'string' ? tNodeChild.data : '';
const attrHref = htmlAttribs.href || htmlAttribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE] || '';
const parentStyle = tnode.parent?.styles?.nativeTextRet ?? {};
const internalNewExpensifyPath = Link.getInternalNewExpensifyPath(attrHref);
const internalExpensifyPath = Link.getInternalExpensifyPath(attrHref);
const internalNewExpensifyPath = getInternalNewExpensifyPath(attrHref);
const internalExpensifyPath = getInternalExpensifyPath(attrHref);
const isVideo = attrHref && Str.isVideo(attrHref);
const linkHasImage = tnode.tagName === 'a' && tnode.children.some((child) => child.tagName === 'img');

const isDeleted = HTMLEngineUtils.isDeletedNode(tnode);
const isChildOfTaskTitle = HTMLEngineUtils.isChildOfTaskTitle(tnode);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Why is this check needed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need that because we want to apply taskTitleMenuItem style when link is a child of task title, basically we want to change font style/size if the link is inside task title.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm did you know that in React Native, the only styles that actually cascade like css are text styles? So you might be able to just alter the text style higher up in the component tree and have it cascade down.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm did you know that in React Native, the only styles that actually cascade like css are text styles? So you might be able to just alter the text style higher up in the component tree and have it cascade down.

In our case, we need to override the text styles that have been directly applied to the text.


const textDecorationLineStyle = isDeleted ? styles.underlineLineThrough : {};

if (!HTMLEngineUtils.isChildOfComment(tnode)) {
if (!HTMLEngineUtils.isChildOfComment(tnode) && !isChildOfTaskTitle) {
// This is not a comment from a chat, the AnchorForCommentsOnly uses a Pressable to create a context menu on right click.
// We don't have this behaviour in other links in NewDot
// TODO: We should use TextLink, but I'm leaving it as Text for now because TextLink breaks the alignment in Android.
return (
<Text
style={styles.link}
onPress={() => Link.openLink(attrHref, environmentURL, isAttachment)}
onPress={() => openLink(attrHref, environmentURL, isAttachment)}
suppressHighlighting
>
<TNodeChildrenRenderer tnode={tnode} />
Expand Down Expand Up @@ -70,10 +72,10 @@ function AnchorRenderer({tnode, style, key}: AnchorRendererProps) {
// eslint-disable-next-line react/jsx-props-no-multi-spaces
target={htmlAttribs.target || '_blank'}
rel={htmlAttribs.rel || 'noopener noreferrer'}
style={[style, parentStyle, textDecorationLineStyle, styles.textUnderlinePositionUnder, styles.textDecorationSkipInkNone]}
style={[style, parentStyle, textDecorationLineStyle, styles.textUnderlinePositionUnder, styles.textDecorationSkipInkNone, isChildOfTaskTitle && styles.taskTitleMenuItem]}
key={key}
// Only pass the press handler for internal links. For public links or whitelisted internal links fallback to default link handling
onPress={internalNewExpensifyPath || internalExpensifyPath ? () => Link.openLink(attrHref, environmentURL, isAttachment) : undefined}
onPress={internalNewExpensifyPath || internalExpensifyPath ? () => openLink(attrHref, environmentURL, isAttachment) : undefined}
linkHasImage={linkHasImage}
>
<TNodeChildrenRenderer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ function CodeRenderer({TDefaultRenderer, key, style, ...defaultRendererProps}: C

// Determine the font size for the code based on whether it's inside an H1 element.
const isInsideH1 = HTMLEngineUtils.isChildOfH1(defaultRendererProps.tnode);
const isInsideTaskTitle = HTMLEngineUtils.isChildOfTaskTitle(defaultRendererProps.tnode);

const fontSize = StyleUtils.getCodeFontSize(isInsideH1);
const fontSize = StyleUtils.getCodeFontSize(isInsideH1, isInsideTaskTitle);

const textStyleOverride = {
fontSize,
Expand Down
33 changes: 33 additions & 0 deletions src/components/HTMLEngineProvider/HTMLRenderers/EMRenderer.tsx
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -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;
17 changes: 13 additions & 4 deletions src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import React from 'react';
import {View} from 'react-native';
import type {GestureResponderEvent} from 'react-native';
import type {CustomRendererProps, TBlock} from 'react-native-render-html';
import * as HTMLEngineUtils from '@components/HTMLEngineProvider/htmlEngineUtils';
import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback';
import {ShowContextMenuContext, showContextMenuForReport} from '@components/ShowContextMenuContext';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ReportUtils from '@libs/ReportUtils';
import {isArchivedNonExpenseReport} from '@libs/ReportUtils';
import CONST from '@src/CONST';

type PreRendererProps = CustomRendererProps<TBlock> & {
Expand All @@ -28,9 +31,13 @@ type PreRendererProps = CustomRendererProps<TBlock> & {

function PreRenderer({TDefaultRenderer, onPressIn, onPressOut, onLongPress, ...defaultRendererProps}: PreRendererProps) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const {translate} = useLocalize();
const isLast = defaultRendererProps.renderIndex === defaultRendererProps.renderLength - 1;

const isInsideTaskTitle = HTMLEngineUtils.isChildOfTaskTitle(defaultRendererProps.tnode);
const fontSize = StyleUtils.getCodeFontSize(false, isInsideTaskTitle);

return (
<View style={isLast ? styles.mt2 : styles.mv2}>
<ShowContextMenuContext.Consumer>
Expand All @@ -43,15 +50,17 @@ function PreRenderer({TDefaultRenderer, onPressIn, onPressOut, onLongPress, ...d
if (isDisabled) {
return;
}
showContextMenuForReport(event, anchor, report?.reportID, action, checkIfContextMenuActive, ReportUtils.isArchivedNonExpenseReport(report, reportNameValuePairs));
showContextMenuForReport(event, anchor, report?.reportID, action, checkIfContextMenuActive, isArchivedNonExpenseReport(report, reportNameValuePairs));
}}
shouldUseHapticsOnLongPress
role={CONST.ROLE.PRESENTATION}
accessibilityLabel={translate('accessibilityHints.prestyledText')}
>
<View>
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<TDefaultRenderer {...defaultRendererProps} />
<Text style={{fontSize}}>
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<TDefaultRenderer {...defaultRendererProps} />
</Text>
</View>
</PressableWithoutFeedback>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -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 StrongRenderer({tnode}: CustomRendererProps<TText | TPhrasing>) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coming from #58242, the styles here caused a regression for the display of a user's custom display name vs. email in the header. More details in the proposal.

const styles = useThemeStyles();
const isChildOfTaskTitle = HTMLEngineUtils.isChildOfTaskTitle(tnode);

return 'data' in tnode ? (
<Text style={[styles.webViewStyles.baseFontStyle, styles.strong, isChildOfTaskTitle && styles.taskTitleMenuItem]}>{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>
);
}}
/>
);
}

StrongRenderer.displayName = 'StrongRenderer';

export default StrongRenderer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import type {CustomRendererProps, TPhrasing, TText} from 'react-native-render-html';
import {TNodeChildrenRenderer} from 'react-native-render-html';
import Text from '@components/Text';
import useThemeStyles from '@hooks/useThemeStyles';

function TaskTitleRenderer({tnode}: CustomRendererProps<TText | TPhrasing>) {
const styles = useThemeStyles();

return (
<TNodeChildrenRenderer
tnode={tnode}
renderChild={(props) => {
return (
<Text
style={[styles.taskTitleMenuItem]}
key={props.key}
>
{props.childElement}
</Text>
);
}}
/>
);
}

TaskTitleRenderer.displayName = 'TaskTitleRenderer';

export default TaskTitleRenderer;
8 changes: 8 additions & 0 deletions src/components/HTMLEngineProvider/HTMLRenderers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ 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';
import MentionUserRenderer from './MentionUserRenderer';
import NextStepEmailRenderer from './NextStepEmailRenderer';
import PreRenderer from './PreRenderer';
import StrongRenderer from './StrongRenderer';
import TaskTitleRenderer from './TaskTitleRenderer';
import VideoRenderer from './VideoRenderer';

/**
Expand All @@ -21,11 +25,15 @@ const HTMLEngineProviderComponentList: CustomTagRendererRecord = {
code: CodeRenderer,
img: ImageRenderer,
video: VideoRenderer,
h1: HeadingRenderer,
strong: StrongRenderer,
em: EMRenderer,

// Custom tag renderers
edited: EditedRenderer,
pre: PreRenderer,
/* eslint-disable @typescript-eslint/naming-convention */
'task-title': TaskTitleRenderer,
'mention-user': MentionUserRenderer,
'mention-report': MentionReportRenderer,
'mention-here': MentionHereRenderer,
Expand Down
6 changes: 5 additions & 1 deletion src/components/HTMLEngineProvider/htmlEngineUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ function isChildOfH1(tnode: TNode): boolean {
return isChildOfNode(tnode, (node) => node.domNode?.name !== undefined && node.domNode.name.toLowerCase() === 'h1');
}

function isChildOfTaskTitle(tnode: TNode): boolean {
return isChildOfNode(tnode, (node) => node.domNode?.name !== undefined && node.domNode.name.toLowerCase() === 'task-title');
}

/**
* Check if the parent node has deleted style.
*/
Expand All @@ -67,4 +71,4 @@ function isDeletedNode(tnode: TNode): boolean {
return 'textDecorationLine' in parentStyle && parentStyle.textDecorationLine === 'line-through';
}

export {computeEmbeddedMaxWidth, isChildOfComment, isCommentTag, isChildOfH1, isDeletedNode};
export {computeEmbeddedMaxWidth, isChildOfComment, isCommentTag, isChildOfH1, isDeletedNode, isChildOfTaskTitle};
Loading