Skip to content

Commit 46a7981

Browse files
fix(iOS): empty html blocks parsing (#504)
# Summary This PR fixes the crash that occurred when we tried to parse empty html tags: - `<ul></ul>` - `<ol></ol>` - `<codeblock></codeblock>` - `<blockquote></blockquote>` Also fixes parsing of `blockquote` and `codeblock` tags only with text content e.g.: ``` <html> <blockquote> x </blockquote> </html> ``` ## Test Plan Run example app and try to paste html with empty block tags by "Set input's value" button. Example html to paste: ``` <html> <p>Hey, how's it going?</p> <br> <ul> </ul></html> ``` ``` <html> <ol> </ol></html> ``` ``` <html> <codeblock> xxxx </codeblock> </html> ``` The app should not crash! ## Screenshots / Videos https://github.com/user-attachments/assets/e5ea3476-9072-4e1d-9ccd-a130e46a0933 ## Compatibility | OS | Implemented | | ------- | :---------: | | iOS | ✅ | | Android | ❌ | ## Checklist - [x] E2E tests are passing - [x] Required E2E tests have been added (if applicable)
1 parent 437ecf4 commit 46a7981

4 files changed

Lines changed: 55 additions & 12 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
appId: swmansion.enriched.example
2+
---
3+
# PR #504 - fix(iOS): empty html blocks parsing
4+
# Verifies that empty html blocks are parsed correctly
5+
- launchApp
6+
7+
- tapOn:
8+
id: 'toggle-screen-button'
9+
10+
- runFlow:
11+
file: '../subflows/set_editor_value.yaml'
12+
env:
13+
VALUE: '<html><p>hello</p><ul></ul><ol></ol><codeblock></codeblock><blockquote></blockquote><ul data-type="checkbox"></ul></html>'
14+
15+
- runFlow:
16+
file: '../subflows/capture_or_assert_screenshot.yaml'
17+
env:
18+
SCREENSHOT_NAME: 'empty_html_block_parsing'
4 KB
Loading
5 KB
Loading

ios/inputParser/InputParser.mm

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ - (instancetype)initWithInput:(id)input {
1919
return self;
2020
}
2121

22+
- (BOOL)isBlockTag:(NSString *)tagName {
23+
return [tagName isEqualToString:@"ul"] || [tagName isEqualToString:@"ol"] ||
24+
[tagName isEqualToString:@"blockquote"] ||
25+
[tagName isEqualToString:@"codeblock"];
26+
}
27+
2228
- (NSString *)parseToHtmlFromRange:(NSRange)range {
2329
NSInteger offset = range.location;
2430
NSString *text =
@@ -798,6 +804,24 @@ - (NSString *_Nullable)initiallyProcessHtml:(NSString *_Nonnull)html {
798804
fixedHtml = [fixedHtml stringByReplacingOccurrencesOfString:@"<br></p>"
799805
withString:@"<br>"];
800806

807+
// add <br> tags inside empty blockquote and codeblock tags
808+
fixedHtml = [fixedHtml
809+
stringByReplacingOccurrencesOfString:@"<blockquote></blockquote>"
810+
withString:@"<blockquote><br></"
811+
@"blockquote>"];
812+
fixedHtml = [fixedHtml
813+
stringByReplacingOccurrencesOfString:@"<codeblock></codeblock>"
814+
withString:@"<codeblock><br></codeblock>"];
815+
816+
// remove empty ul and ol tags
817+
fixedHtml = [fixedHtml stringByReplacingOccurrencesOfString:@"<ul></ul>"
818+
withString:@""];
819+
fixedHtml = [fixedHtml
820+
stringByReplacingOccurrencesOfString:@"<ul data-type=\"checkbox\"></ul>"
821+
withString:@""];
822+
fixedHtml = [fixedHtml stringByReplacingOccurrencesOfString:@"<ol></ol>"
823+
withString:@""];
824+
801825
// tags that have to be in separate lines
802826
fixedHtml = [self stringByAddingNewlinesToTag:@"<br>"
803827
inString:fixedHtml
@@ -1146,12 +1170,11 @@ - (NSArray *)getTextAndStylesFromHtml:(NSString *)fixedHtml {
11461170
insideCheckboxList = YES;
11471171
}
11481172

1149-
// skip one newline after opening tags that are in separate lines
1150-
// intentionally
1151-
if ([currentTagName isEqualToString:@"ul"] ||
1152-
[currentTagName isEqualToString:@"ol"] ||
1153-
[currentTagName isEqualToString:@"blockquote"] ||
1154-
[currentTagName isEqualToString:@"codeblock"]) {
1173+
// skip one newline if it was added after opening tags that are in
1174+
// separate lines
1175+
if ([self isBlockTag:currentTagName] && i + 1 < fixedHtml.length &&
1176+
[[NSCharacterSet newlineCharacterSet]
1177+
characterIsMember:[fixedHtml characterAtIndex:i + 1]]) {
11551178
i += 1;
11561179
}
11571180

@@ -1171,12 +1194,14 @@ - (NSArray *)getTextAndStylesFromHtml:(NSString *)fixedHtml {
11711194
insideCheckboxList = NO;
11721195
}
11731196

1174-
// skip one newline that was added before some closing tags that are in
1175-
// separate lines
1176-
if ([currentTagName isEqualToString:@"ul"] ||
1177-
[currentTagName isEqualToString:@"ol"] ||
1178-
[currentTagName isEqualToString:@"blockquote"] ||
1179-
[currentTagName isEqualToString:@"codeblock"]) {
1197+
BOOL isBlockTag = [self isBlockTag:currentTagName];
1198+
1199+
// skip one newline if it was added before some closing tags that are
1200+
// in separate lines
1201+
if (isBlockTag && plainText.length > 0 &&
1202+
[[NSCharacterSet newlineCharacterSet]
1203+
characterIsMember:[plainText
1204+
characterAtIndex:plainText.length - 1]]) {
11801205
plainText = [[plainText
11811206
substringWithRange:NSMakeRange(0, plainText.length - 1)]
11821207
mutableCopy];

0 commit comments

Comments
 (0)