Skip to content

Commit

Permalink
Add warning when worklet parser returns incorrect schema
Browse files Browse the repository at this point in the history
  • Loading branch information
tomekzaw committed Oct 11, 2024
1 parent c506d7b commit 090ec8c
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ public CustomMountingManager(
@NonNull ReadableMap decoratorProps,
int parserId) {
super(viewManagerRegistry, mountItemExecutor);

AssetManager assetManager = context.getAssets();

this.markdownUtils = new MarkdownUtils(assetManager);
this.markdownUtils = new MarkdownUtils((ReactContext) context);
this.markdownUtils.setMarkdownStyle(new MarkdownStyle(decoratorProps, context));
this.markdownUtils.setParserId(parserId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import android.view.ViewGroup;
import android.view.ViewParent;

import com.facebook.react.bridge.ReactContext;
import com.facebook.react.views.textinput.ReactEditText;

public class MarkdownTextInputDecoratorView extends View {
Expand Down Expand Up @@ -54,8 +55,7 @@ protected void onAttachedToWindow() {
}

if (previousSibling instanceof ReactEditText) {
AssetManager assetManager = getContext().getAssets();
mMarkdownUtils = new MarkdownUtils(assetManager);
mMarkdownUtils = new MarkdownUtils((ReactContext) getContext());
mMarkdownUtils.setMarkdownStyle(mMarkdownStyle);
mMarkdownUtils.setParserId(mParserId);
mReactEditText = (ReactEditText) previousSibling;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
import androidx.annotation.NonNull;

import com.expensify.livemarkdown.spans.*;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.util.RNLog;
import com.facebook.react.views.text.internal.span.CustomLineHeightSpan;
import com.facebook.soloader.SoLoader;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;

public class MarkdownUtils {
Expand All @@ -25,10 +25,12 @@ public class MarkdownUtils {

private static synchronized native String nativeParseMarkdown(String input, int parserId);

public MarkdownUtils(@NonNull AssetManager assetManager) {
mAssetManager = assetManager;
public MarkdownUtils(@NonNull ReactContext reactContext) {
mReactContext = reactContext;
mAssetManager = reactContext.getAssets();
}

private final @NonNull ReactContext mReactContext;
private final @NonNull AssetManager mAssetManager;

private String mPrevInput;
Expand Down Expand Up @@ -77,7 +79,7 @@ public void applyMarkdownFormatting(SpannableStringBuilder ssb) {
applyRange(ssb, type, start, end, depth);
}
} catch (JSONException e) {
// Do nothing
RNLog.w(mReactContext, "[react-native-live-markdown] Incorrect schema of worklet parser output: " + e.getMessage());
}
}

Expand Down
60 changes: 31 additions & 29 deletions apple/RCTMarkdownUtils.mm
Original file line number Diff line number Diff line change
Expand Up @@ -33,44 +33,46 @@ - (NSAttributedString *)parseMarkdown:(nullable NSAttributedString *)input withA

auto markdownWorklet = expensify::livemarkdown::getMarkdownWorklet([_parserId intValue]);

auto text = jsi::String::createFromUtf8(rt, [inputString UTF8String]);
auto output = markdownRuntime->runGuarded(markdownWorklet, text);
if (output.isUndefined()) {
return input;
}
const auto &ranges = output.asObject(rt).asArray(rt);
try {
const auto &text = jsi::String::createFromUtf8(rt, [inputString UTF8String]);
const auto &output = markdownRuntime->runGuarded(markdownWorklet, text);
const auto &ranges = output.asObject(rt).asArray(rt);

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:inputString attributes:attributes];
[attributedString beginEditing];
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:inputString attributes:attributes];
[attributedString beginEditing];

// If the attributed string ends with underlined text, blurring the single-line input imprints the underline style across the whole string.
// It looks like a bug in iOS, as there is no underline style to be found in the attributed string, especially after formatting.
// This is a workaround that applies the NSUnderlineStyleNone to the string before iterating over ranges which resolves this problem.
[attributedString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleNone] range:NSMakeRange(0, attributedString.length)];
// If the attributed string ends with underlined text, blurring the single-line input imprints the underline style across the whole string.
// It looks like a bug in iOS, as there is no underline style to be found in the attributed string, especially after formatting.
// This is a workaround that applies the NSUnderlineStyleNone to the string before iterating over ranges which resolves this problem.
[attributedString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleNone] range:NSMakeRange(0, attributedString.length)];

_blockquoteRangesAndLevels = [NSMutableArray new];
_blockquoteRangesAndLevels = [NSMutableArray new];

for (size_t i = 0, n = ranges.size(rt); i < n; ++i) {
const auto &item = ranges.getValueAtIndex(rt, i).asObject(rt);
const auto &type = item.getProperty(rt, "type").asString(rt).utf8(rt);
const auto &start = static_cast<int>(item.getProperty(rt, "start").asNumber());
const auto &length = static_cast<int>(item.getProperty(rt, "length").asNumber());
const auto &depth = item.hasProperty(rt, "depth") ? static_cast<int>(item.getProperty(rt, "depth").asNumber()) : 1;
for (size_t i = 0, n = ranges.size(rt); i < n; ++i) {
const auto &item = ranges.getValueAtIndex(rt, i).asObject(rt);
const auto &type = item.getProperty(rt, "type").asString(rt).utf8(rt);
const auto &start = static_cast<int>(item.getProperty(rt, "start").asNumber());
const auto &length = static_cast<int>(item.getProperty(rt, "length").asNumber());
const auto &depth = item.hasProperty(rt, "depth") ? static_cast<int>(item.getProperty(rt, "depth").asNumber()) : 1;

[self applyRangeToAttributedString:attributedString type:type start:start length:length depth:depth];
}
[self applyRangeToAttributedString:attributedString type:type start:start length:length depth:depth];
}

RCTApplyBaselineOffset(attributedString);
RCTApplyBaselineOffset(attributedString);

[attributedString endEditing];
[attributedString endEditing];

_prevInputString = inputString;
_prevAttributedString = attributedString;
_prevTextAttributes = attributes;
_prevMarkdownStyle = _markdownStyle;
_prevParserId = _parserId;
_prevInputString = inputString;
_prevAttributedString = attributedString;
_prevTextAttributes = attributes;
_prevMarkdownStyle = _markdownStyle;
_prevParserId = _parserId;

return attributedString;
return attributedString;
} catch (const jsi::JSError &error) {
RCTLogWarn(@"[react-native-live-markdown] Incorrect schema of worklet parser output: %s", error.getMessage().c_str());
return input;
}
}
}

Expand Down

0 comments on commit 090ec8c

Please sign in to comment.