Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 18 additions & 5 deletions ios/inputParser/InputParser.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#import "StyleHeaders.h"
#import "UIView+React.h"
#import "TextInsertionUtils.h"
#import "StringExtension.h"

@implementation InputParser {
EnrichedTextInputView *_input;
Expand Down Expand Up @@ -204,8 +205,8 @@ - (NSString *)parseToHtmlFromRange:(NSRange)range {
[result appendString: [NSString stringWithFormat:@"<%@>", tagContent]];
}

// append the letter
[result appendString:currentCharacterStr];
// append the letter and escape it if needed
[result appendString: [NSString stringByEscapingHtml:currentCharacterStr]];

// save current styles for next character's checks
previousActiveStyles = currentActiveStyles;
Expand Down Expand Up @@ -490,6 +491,7 @@ - (NSArray *)getTextAndStylesFromHtml:(NSString *)fixedHtml {
BOOL closingTag = NO;
NSMutableString *currentTagName = [[NSMutableString alloc] initWithString:@""];
NSMutableString *currentTagParams = [[NSMutableString alloc] initWithString:@""];
NSDictionary *htmlEntitiesDict = [NSString getEscapedCharactersInfoFrom:fixedHtml];

// firstly, extract text and initially processed tags
for(int i = 0; i < fixedHtml.length; i++) {
Expand All @@ -511,7 +513,7 @@ - (NSArray *)getTextAndStylesFromHtml:(NSString *)fixedHtml {
} else if(!closingTag) {
// we finish opening tag - get its location and optionally params and put them under tag name key in ongoingTags
NSMutableArray *tagArr = [[NSMutableArray alloc] init];
[tagArr addObject:[NSNumber numberWithInt:plainText.length]];
[tagArr addObject:[NSNumber numberWithInteger:plainText.length]];
if(currentTagParams.length > 0) {
[tagArr addObject:[currentTagParams copy]];
}
Expand Down Expand Up @@ -550,8 +552,19 @@ - (NSArray *)getTextAndStylesFromHtml:(NSString *)fixedHtml {
currentTagParams = [[NSMutableString alloc] initWithString:@""];
} else {
if(!insideTag) {
// no tags logic - just append text
[plainText appendString:currentCharacterStr];
// no tags logic - just append the right text

// html entity on the index; use unescaped character and forward iterator accordingly
NSArray *entityInfo = htmlEntitiesDict[@(i)];
if(entityInfo != nullptr) {
NSString *escaped = entityInfo[0];
NSString *unescaped = entityInfo[1];
[plainText appendString:unescaped];
// the iterator will forward by 1 itself
i += escaped.length - 1;
} else {
[plainText appendString:currentCharacterStr];
}
} else {
if(gettingTagName) {
if(currentCharacterChar == ' ') {
Expand Down
8 changes: 3 additions & 5 deletions ios/inputTextView/InputTextView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ - (void)copy:(id)sender {
NSString *plainText = [typedInput->textView.textStorage.string substringWithRange:typedInput->textView.selectedRange];
NSString *fixedPlainText = [plainText stringByReplacingOccurrencesOfString:@"\u200B" withString:@""];

NSString *escapedHtml = [NSString stringByEscapingHtml:[typedInput->parser parseToHtmlFromRange:typedInput->textView.selectedRange]];
NSString *parsedHtml = [typedInput->parser parseToHtmlFromRange:typedInput->textView.selectedRange];

NSMutableAttributedString *attrStr = [[typedInput->textView.textStorage attributedSubstringFromRange:typedInput->textView.selectedRange] mutableCopy];
NSRange fullAttrStrRange = NSMakeRange(0, attrStr.length);
Expand All @@ -28,7 +28,7 @@ - (void)copy:(id)sender {
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
[pasteboard setItems:@[@{
UTTypeUTF8PlainText.identifier : fixedPlainText,
UTTypeHTML.identifier : escapedHtml,
UTTypeHTML.identifier : parsedHtml,
UTTypeRTF.identifier : rtfData
}]];
}
Expand All @@ -53,9 +53,7 @@ - (void)paste:(id)sender {
htmlString = htmlValue;
}

// unescape the html
htmlString = [NSString stringByUnescapingHtml:htmlString];
// validate it
// validate the html
NSString *initiallyProcessedHtml = [typedInput->parser initiallyProcessHtml:htmlString];

if(initiallyProcessedHtml != nullptr) {
Expand Down
2 changes: 1 addition & 1 deletion ios/utils/StringExtension.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
- (std::string)toCppString;
+ (NSString *)fromCppString:(std::string)string;
+ (NSString *)stringByEscapingHtml:(NSString *)html;
+ (NSString *)stringByUnescapingHtml:(NSString *)html;
+ (NSDictionary *)getEscapedCharactersInfoFrom:(NSString *)text;
@end

@interface NSMutableString (StringExtension)
Expand Down
25 changes: 17 additions & 8 deletions ios/utils/StringExtension.mm
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ + (NSString *)stringByEscapingHtml:(NSString *)html {
@"&": @"&amp;",
@"<": @"&lt;",
@">": @"&gt;",
@"\"": @"&quot;",
@"'": @"&apos;"
};

for(NSString *key in escapeMap) {
Expand All @@ -26,20 +24,31 @@ + (NSString *)stringByEscapingHtml:(NSString *)html {
return escaped;
}

+ (NSString *)stringByUnescapingHtml:(NSString *)html {
NSMutableString *unescaped = [html mutableCopy];
+ (NSDictionary *)getEscapedCharactersInfoFrom:(NSString *)text {
NSDictionary *unescapeMap = @{
@"&amp;": @"&",
@"&lt;": @"<",
@"&gt;": @">",
@"&quot;": @"\"",
@"&apos;": @"'",
};

NSMutableDictionary *results = [[NSMutableDictionary alloc] init];

for(NSString *key in unescapeMap) {
[unescaped replaceOccurrencesOfString:key withString:unescapeMap[key] options:NSLiteralSearch range:NSMakeRange(0, unescaped.length)];
NSRange searchRange = NSMakeRange(0, text.length);
NSRange foundRange;

while(searchRange.location < text.length) {
foundRange = [text rangeOfString:key options:0 range:searchRange];
if(foundRange.location == NSNotFound) {
break;
}
results[@(foundRange.location)] = @[key, unescapeMap[key]];
searchRange.location = foundRange.location + foundRange.length;
searchRange.length = text.length - searchRange.location;
}
}
return unescaped;

return results;
}

@end
Expand Down
Loading