Skip to content
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

Prevent italic or strikethrough emojis on Android #534

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
Expand All @@ -31,6 +32,62 @@ public MarkdownParser(@NonNull ReactContext reactContext) {

private native String nativeParse(@NonNull String text, int parserId);

private void splitRangesOnEmojis(List<MarkdownRange> markdownRanges, String type) {
List<MarkdownRange> emojiRanges = new ArrayList<>();
for (MarkdownRange range : markdownRanges) {
if (range.getType().equals("emoji")) {
emojiRanges.add(range);
}
}

int i = 0;
int j = 0;
while (i < markdownRanges.size() && j < emojiRanges.size()) {
MarkdownRange currentRange = markdownRanges.get(i);
MarkdownRange emojiRange = emojiRanges.get(j);

if (!currentRange.getType().equals(type) || currentRange.getEnd() < emojiRange.getStart()) {
i += 1;
continue;
} else if (emojiRange.getStart() >= currentRange.getStart() && emojiRange.getEnd() <= currentRange.getEnd()) {
// Split range
MarkdownRange startRange = new MarkdownRange(currentRange.getType(), currentRange.getStart(), emojiRange.getStart() - currentRange.getStart(), currentRange.getDepth());
MarkdownRange endRange = new MarkdownRange(currentRange.getType(), emojiRange.getEnd(), currentRange.getEnd() - emojiRange.getEnd(), currentRange.getDepth());

markdownRanges.add(i + 1, startRange);
markdownRanges.add(i + 2, endRange);
markdownRanges.remove(i);
i = i + 1;
}
j += 1;
}
}


private List<MarkdownRange> parseRanges(String rangesJSON, String innerText) {
List<MarkdownRange> markdownRanges = new ArrayList<>();
try {
JSONArray ranges = new JSONArray(rangesJSON);
for (int i = 0; i < ranges.length(); i++) {
JSONObject range = ranges.getJSONObject(i);
String type = range.getString("type");
int start = range.getInt("start");
int length = range.getInt("length");
int depth = range.optInt("depth", 1);

MarkdownRange markdownRange = new MarkdownRange(type, start, length, depth);
if (markdownRange.getLength() == 0 || markdownRange.getEnd() > innerText.length()) {
continue;
}
markdownRanges.add(markdownRange);
}
} catch (JSONException e) {
return Collections.emptyList();
}
splitRangesOnEmojis(markdownRanges, "italic");
splitRangesOnEmojis(markdownRanges, "strikethrough");
return markdownRanges;
}
public synchronized List<MarkdownRange> parse(@NonNull String text, int parserId) {
try {
Systrace.beginSection(0, "parse");
Expand All @@ -53,30 +110,8 @@ public synchronized List<MarkdownRange> parse(@NonNull String text, int parserId
Systrace.endSection(0);
}

List<MarkdownRange> markdownRanges = new LinkedList<>();
try {
Systrace.beginSection(0, "markdownRanges");
JSONArray ranges = new JSONArray(json);
for (int i = 0; i < ranges.length(); i++) {
JSONObject range = ranges.getJSONObject(i);
String type = range.getString("type");
int start = range.getInt("start");
int length = range.getInt("length");
int depth = range.optInt("depth", 1);
if (length == 0 || start + length > text.length()) {
continue;
}
markdownRanges.add(new MarkdownRange(type, start, length, depth));
}
} catch (JSONException e) {
RNLog.w(mReactContext, "[react-native-live-markdown] Incorrect schema of worklet parser output: " + e.getMessage());
mPrevText = text;
mPrevParserId = parserId;
mPrevMarkdownRanges = Collections.emptyList();
return mPrevMarkdownRanges;
} finally {
Systrace.endSection(0);
}
List<MarkdownRange> markdownRanges = parseRanges(json, text);
Systrace.endSection(0);

mPrevText = text;
mPrevParserId = parserId;
Expand Down
2 changes: 2 additions & 0 deletions src/parseExpensiMark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ function getTagPriority(tag: string) {
return 2;
case 'h1':
return 1;
case 'emoji':
return -1;
default:
return 0;
}
Expand Down
9 changes: 7 additions & 2 deletions src/web/utils/blockUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@ function addStyleToBlock(targetElement: HTMLElement, type: NodeType, markdownSty
node.style.textDecoration = 'line-through';
break;
case 'emoji':
Object.assign(node.style, {...markdownStyle.emoji, verticalAlign: 'middle'});
Object.assign(node.style, {
...markdownStyle.emoji,
verticalAlign: 'middle',
fontStyle: 'normal',
textDecoration: 'none',
display: 'inline-block',
});
break;
case 'mention-here':
Object.assign(node.style, markdownStyle.mentionHere);
Expand All @@ -49,7 +55,6 @@ function addStyleToBlock(targetElement: HTMLElement, type: NodeType, markdownSty
case 'pre':
Object.assign(node.style, markdownStyle.pre);
break;

case 'blockquote':
Object.assign(node.style, {
...markdownStyle.blockquote,
Expand Down
Loading