-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TS migration] Migrate HTMLEngineProvider component #33643
[TS migration] Migrate HTMLEngineProvider component #33643
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
471a606
to
4ba8eb2
Compare
# Conflicts: # src/components/HTMLEngineProvider/BaseHTMLEngineProvider.tsx
/** Optional debug flag. Prints the TRT in the console when true. */ | ||
debug?: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't seem to be using this prop. BaseHTMLEngineProvider
does not make any use of it
|
||
type HTMLEngineProviderProps = { | ||
/** Children to wrap in HTMLEngineProvider. */ | ||
children?: ReactNode; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
children is a required prop.
(Since we will be removing debug
let's just use ChildrenProps
)
return ( | ||
<BaseHTMLEngineProvider | ||
debug={debug} | ||
textSelectable={!DeviceCapabilities.canUseTouchScreen() || isSmallScreenWidth} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
textSelectable={!DeviceCapabilities.canUseTouchScreen() || isSmallScreenWidth} | |
textSelectable={!DeviceCapabilities.canUseTouchScreen() || !isSmallScreenWidth} |
*/ | ||
function isCommentTag(tagName) { | ||
function isCommentTag(tagName?: string): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function isCommentTag(tagName?: string): boolean { | |
function isCommentTag(tagName: string): boolean { |
It does not make much sense to call this function with an undefined
tag name
function isChildOfComment(tnode) { | ||
return isChildOfNode(tnode, (node) => isCommentTag(lodashGet(node, 'domNode.name', ''))); | ||
function isChildOfComment(tnode: TNode): boolean { | ||
return isChildOfNode(tnode, (node) => isCommentTag(node.domNode?.name)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return isChildOfNode(tnode, (node) => isCommentTag(node.domNode?.name)); | |
return isChildOfNode(tnode, (node) => node.domNode?.name != null && isCommentTag(node.domNode.name)); |
function isChildOfH1(tnode) { | ||
return isChildOfNode(tnode, (node) => lodashGet(node, 'domNode.name', '').toLowerCase() === 'h1'); | ||
function isChildOfH1(tnode: TNode): boolean { | ||
return isChildOfNode(tnode, (node) => node.domNode?.name.toLowerCase() === 'h1'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return isChildOfNode(tnode, (node) => node.domNode?.name.toLowerCase() === 'h1'); | |
return isChildOfNode(tnode, (node) => node.domNode?.name != null && node.domNode.name.toLowerCase() === 'h1'); |
This is causing a crash. Apparently ts is not able to detect that name
can be undefined
and it's just okey with calling toLowerCase()
function computeEmbeddedMaxWidth(tagName, contentWidth) { | ||
function computeEmbeddedMaxWidth(contentWidth: number, tagName: string): number { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is interesting were we doing something wrong the whole time? Isn't this param swapping a breaking change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is something that was actually wrong the whole time, if you take a look at function computeEmbeddedMaxWidth from react-native-render-html the parameters order is the one that we have provided now.
I couldn't find any version where this parameters were swapped by the package maintainer.
* @param tagName - The name of the tag for which max width should be constrained. | ||
* @param contentWidth - The content width provided to the HTML |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NAB. Swap the comments lines, first param goes first
Hello @s77rt, Thank you so much for your review, I've agreed and applied your suggestions, please take a look. |
/** Optional debug flag. Prints the TRT in the console when true. */ | ||
debug?: boolean; | ||
}; | ||
type HTMLEngineProviderProps = ChildrenProps; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to define a type that is just another type. We can just use ChildrenProps
and remove HTMLEngineProviderProps
|
||
function HTMLEngineProvider({debug = false, children = null}: HTMLEngineProviderProps) { | ||
function HTMLEngineProvider({children = null}: HTMLEngineProviderProps) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function HTMLEngineProvider({children = null}: HTMLEngineProviderProps) { | |
function HTMLEngineProvider({children}: HTMLEngineProviderProps) { |
No default value is needed since the prop is required
@@ -47,15 +47,15 @@ function isChildOfNode(tnode: TNode, predicate: Predicate): boolean { | |||
* Finding node with name 'comment' flags that we are rendering a comment. | |||
*/ | |||
function isChildOfComment(tnode: TNode): boolean { | |||
return isChildOfNode(tnode, (node) => isCommentTag(node.domNode?.name)); | |||
return isChildOfNode(tnode, (node) => node.domNode?.name !== undefined && isCommentTag(node.domNode?.name)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return isChildOfNode(tnode, (node) => node.domNode?.name !== undefined && isCommentTag(node.domNode?.name)); | |
return isChildOfNode(tnode, (node) => node.domNode?.name !== undefined && isCommentTag(node.domNode.name)); |
} | ||
|
||
/** | ||
* Check if there is an ancestor node with the name 'h1'. | ||
* Finding a node with the name 'h1' flags that we are rendering inside an h1 element. | ||
*/ | ||
function isChildOfH1(tnode: TNode): boolean { | ||
return isChildOfNode(tnode, (node) => node.domNode?.name.toLowerCase() === 'h1'); | ||
return isChildOfNode(tnode, (node) => node.domNode?.name !== null && node.domNode?.name.toLowerCase() === 'h1'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return isChildOfNode(tnode, (node) => node.domNode?.name !== null && node.domNode?.name.toLowerCase() === 'h1'); | |
return isChildOfNode(tnode, (node) => node.domNode?.name !== undefined && node.domNode.name.toLowerCase() === 'h1'); |
The name
is never null, it's either a string or undefined so the condition will always be true and it will cause the app to crash
Hi @s77rt, thank you so much again. |
Reviewer Checklist
Screenshots/Videos |
@ruben-rebelo Thank you! |
We did not find an internal engineer to review this PR, trying to assign a random engineer to #25097 as well as to this PR... Please reach out for help on Slack if no one gets assigned! |
Hello @mountiny, It seems there was an error with the melvin-bot and it didn't assign any engineer from Expensify. |
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🚀 Deployed to staging by https://github.com/nkuoch in version: 1.4.25-0 🚀
|
🚀 Deployed to production by https://github.com/mountiny in version: 1.4.25-10 🚀
|
Details
[TS migration] Migrate HTMLEngineProvider component
Fixed Issues
$ #25097
PROPOSAL: N/A
Tests
How to test
All of the above should work as normally, they work if you press them depending on the functionality
Offline tests
N/A
QA Steps
Same as in the Tests section.
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.src/languages/*
files and using the translation methodWaiting for Copy
label for a copy review on the original GH to get the correct copy.STYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)Design
label so the design team can review the changes.ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Android: Native
android-native.mov
Android: mWeb Chrome
android-web.mov
iOS: Native
ios-native.mov
iOS: mWeb Safari
ios-web.mov
MacOS: Chrome / Safari
macos-web.mov
MacOS: Desktop
macos-desktop.mov