From 171b6d40a00bce6d1f0183319a6108648d200602 Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Tue, 12 May 2020 13:33:59 +0300 Subject: [PATCH] ImageDestinationProcessor (before UrlProcessor), limit usage to images only --- CHANGELOG.md | 1 + ...ageDestinationProcessorInitialReadme.java} | 10 ++-- .../noties/markwon/app/MarkdownRenderer.java | 12 ++-- docs/docs/v4/core/configuration.md | 27 +++++---- .../noties/markwon/MarkwonConfiguration.java | 31 ++++++---- .../io/noties/markwon/core/CorePlugin.java | 5 +- .../ImageDestinationProcessor.java | 27 +++++++++ .../ImageDestinationProcessorAssets.java | 59 +++++++++++++++++++ ...stinationProcessorRelativeToAbsolute.java} | 23 ++++++-- .../markwon/urlprocessor/UrlProcessor.java | 8 --- .../UrlProcessorAndroidAssets.java | 49 --------------- .../urlprocessor/UrlProcessorNoOp.java | 11 ---- .../ImageDestinationProcessorAssetsTest.java} | 10 ++-- ...ationProcessorRelativeToAbsoluteTest.java} | 16 ++--- .../noties/markwon/html/tag/ImageHandler.java | 2 +- .../noties/markwon/html/tag/LinkHandler.java | 3 +- .../markwon/image/file/FileSchemeHandler.java | 10 ++-- .../basicplugins/BasicPluginsActivity.java | 20 +++++-- .../sample/recycler/RecyclerActivity.java | 12 ++-- 19 files changed, 193 insertions(+), 143 deletions(-) rename app/src/main/java/io/noties/markwon/app/{UrlProcessorInitialReadme.java => ImageDestinationProcessorInitialReadme.java} (59%) create mode 100644 markwon-core/src/main/java/io/noties/markwon/image/destination/ImageDestinationProcessor.java create mode 100644 markwon-core/src/main/java/io/noties/markwon/image/destination/ImageDestinationProcessorAssets.java rename markwon-core/src/main/java/io/noties/markwon/{urlprocessor/UrlProcessorRelativeToAbsolute.java => image/destination/ImageDestinationProcessorRelativeToAbsolute.java} (54%) delete mode 100644 markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessor.java delete mode 100644 markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessorAndroidAssets.java delete mode 100644 markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessorNoOp.java rename markwon-core/src/test/java/io/noties/markwon/{urlprocessor/UrlProcessorAndroidAssetsTest.java => image/destination/ImageDestinationProcessorAssetsTest.java} (77%) rename markwon-core/src/test/java/io/noties/markwon/{urlprocessor/UrlProcessorRelativeToAbsoluteTest.java => image/destination/ImageDestinationProcessorRelativeToAbsoluteTest.java} (59%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 420c2215..293be7ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * Expose `enabledBlockTypes` in `CorePlugin` * Update `jlatexmath-android` dependency ([#225]) * Update `image-coil` module (Coil version `0.10.1`) ([#244])
Thanks to [@tylerbwong] +* Rename `UrlProcessor` to `ImageDestinationProcessor` (`io.noties.markwon.urlprocessor` -> `io.noties.markwon.image.destination`) and limit its usage to process **only** destination URL of images (was used to also process links before) [#235]: https://github.com/noties/Markwon/issues/235 [#225]: https://github.com/noties/Markwon/issues/225 diff --git a/app/src/main/java/io/noties/markwon/app/UrlProcessorInitialReadme.java b/app/src/main/java/io/noties/markwon/app/ImageDestinationProcessorInitialReadme.java similarity index 59% rename from app/src/main/java/io/noties/markwon/app/UrlProcessorInitialReadme.java rename to app/src/main/java/io/noties/markwon/app/ImageDestinationProcessorInitialReadme.java index 571bb395..26653af9 100644 --- a/app/src/main/java/io/noties/markwon/app/UrlProcessorInitialReadme.java +++ b/app/src/main/java/io/noties/markwon/app/ImageDestinationProcessorInitialReadme.java @@ -5,15 +5,15 @@ import android.text.TextUtils; import androidx.annotation.NonNull; -import io.noties.markwon.urlprocessor.UrlProcessor; -import io.noties.markwon.urlprocessor.UrlProcessorRelativeToAbsolute; +import io.noties.markwon.image.destination.ImageDestinationProcessor; +import io.noties.markwon.image.destination.ImageDestinationProcessorRelativeToAbsolute; -class UrlProcessorInitialReadme implements UrlProcessor { +class ImageDestinationProcessorInitialReadme extends ImageDestinationProcessor { private static final String GITHUB_BASE = "https://github.com/noties/Markwon/raw/master/"; - private final UrlProcessorRelativeToAbsolute processor - = new UrlProcessorRelativeToAbsolute(GITHUB_BASE); + private final ImageDestinationProcessorRelativeToAbsolute processor + = new ImageDestinationProcessorRelativeToAbsolute(GITHUB_BASE); @NonNull @Override diff --git a/app/src/main/java/io/noties/markwon/app/MarkdownRenderer.java b/app/src/main/java/io/noties/markwon/app/MarkdownRenderer.java index cc339083..d820733e 100644 --- a/app/src/main/java/io/noties/markwon/app/MarkdownRenderer.java +++ b/app/src/main/java/io/noties/markwon/app/MarkdownRenderer.java @@ -24,6 +24,8 @@ import io.noties.markwon.ext.tables.TablePlugin; import io.noties.markwon.ext.tasklist.TaskListPlugin; import io.noties.markwon.html.HtmlPlugin; import io.noties.markwon.image.ImagesPlugin; +import io.noties.markwon.image.destination.ImageDestinationProcessor; +import io.noties.markwon.image.destination.ImageDestinationProcessorRelativeToAbsolute; import io.noties.markwon.image.file.FileSchemeHandler; import io.noties.markwon.image.gif.GifMediaDecoder; import io.noties.markwon.image.network.OkHttpNetworkSchemeHandler; @@ -31,8 +33,6 @@ import io.noties.markwon.syntax.Prism4jTheme; import io.noties.markwon.syntax.Prism4jThemeDarkula; import io.noties.markwon.syntax.Prism4jThemeDefault; import io.noties.markwon.syntax.SyntaxHighlightPlugin; -import io.noties.markwon.urlprocessor.UrlProcessor; -import io.noties.markwon.urlprocessor.UrlProcessorRelativeToAbsolute; import io.noties.prism4j.Prism4j; @ActivityScope @@ -86,11 +86,11 @@ public class MarkdownRenderer { } private void execute() { - final UrlProcessor urlProcessor; + final ImageDestinationProcessor imageDestinationProcessor; if (uri == null) { - urlProcessor = new UrlProcessorInitialReadme(); + imageDestinationProcessor = new ImageDestinationProcessorInitialReadme(); } else { - urlProcessor = new UrlProcessorRelativeToAbsolute(uri.toString()); + imageDestinationProcessor = new ImageDestinationProcessorRelativeToAbsolute(uri.toString()); } final Prism4jTheme prism4jTheme = isLightTheme @@ -119,7 +119,7 @@ public class MarkdownRenderer { .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.urlProcessor(urlProcessor); + builder.imageDestinationProcessor(imageDestinationProcessor); } }) .build(); diff --git a/docs/docs/v4/core/configuration.md b/docs/docs/v4/core/configuration.md index 23a32fb0..e012dd33 100644 --- a/docs/docs/v4/core/configuration.md +++ b/docs/docs/v4/core/configuration.md @@ -5,7 +5,7 @@ These are _configurable_ properties: * `AsyncDrawableLoader` (back here since ) * `SyntaxHighlight` * `LinkResolver` (since , before — `LinkSpan.Resolver`) -* `UrlProcessor` +* `ImageDestinationProcessor` (since , before — `UrlProcessor`) * `ImageSizeResolver` :::tip @@ -36,10 +36,11 @@ final Markwon markwon = Markwon.builder(context) .build(); ``` -Currently `Markwon` provides 3 implementations for loading images: +Currently `Markwon` provides 4 implementations for loading images: * [markwon implementation](/docs/v4/image/) with SVG, GIF, data uri and android_assets support * [based on Picasso](/docs/v4/image-picasso/) * [based on Glide](/docs/v4/image-glide/) +* [base on Coil](/docs/v4/image-coil/) ## SyntaxHighlight @@ -87,32 +88,32 @@ if there is none registered. if you wish to register own instance of a `Movement apply it directly to a TextView or use [MovementMethodPlugin](/docs/v4/core/movement-method-plugin.md) ::: -## UrlProcessor +## ImageDestinationProcessor -Process URLs in your markdown (for links and images). If not provided explicitly, +Process destinations (URLs) of images in your markdown. If not provided explicitly, default **no-op** implementation will be used, which does not modify URLs (keeping them as-is). `Markwon` provides 2 implementations of `UrlProcessor`: -* `UrlProcessorRelativeToAbsolute` -* `UrlProcessorAndroidAssets` +* `ImageDestinationProcessorRelativeToAbsolute` +* `ImageDestinationProcessorAssets` -### UrlProcessorRelativeToAbsolute +### ImageDestinationProcessorRelativeToAbsolute -`UrlProcessorRelativeToAbsolute` can be used to make relative URL absolute. For example if an image is -defined like this: `![img](./art/image.JPG)` and `UrlProcessorRelativeToAbsolute` +`ImageDestinationProcessorRelativeToAbsolute` can be used to make relative URL absolute. For example if an image is +defined like this: `![img](./art/image.JPG)` and `ImageDestinationProcessorRelativeToAbsolute` is created with `https://github.com/noties/Markwon/raw/master/` as the base: -`new UrlProcessorRelativeToAbsolute("https://github.com/noties/Markwon/raw/master/")`, +`new ImageDestinationProcessorRelativeToAbsolute("https://github.com/noties/Markwon/raw/master/")`, then final image will have `https://github.com/noties/Markwon/raw/master/art/image.JPG` as the destination. -### UrlProcessorAndroidAssets +### ImageDestinationProcessorAssets -`UrlProcessorAndroidAssets` can be used to make processed links to point to Android assets folder. +`ImageDestinationProcessorAssets` can be used to make processed destinations to point to Android assets folder. So an image: `![img](./art/image.JPG)` will have `file:///android_asset/art/image.JPG` as the destination. :::tip -Please note that `UrlProcessorAndroidAssets` will process only URLs that have no `scheme` information, +Please note that `ImageDestinationProcessorAssets` will process only URLs that have no `scheme` information, so a `./art/image.png` will become `file:///android_asset/art/image.JPG` whilst `https://so.me/where.png` will be kept as-is. ::: diff --git a/markwon-core/src/main/java/io/noties/markwon/MarkwonConfiguration.java b/markwon-core/src/main/java/io/noties/markwon/MarkwonConfiguration.java index 5b22623f..e19c8228 100644 --- a/markwon-core/src/main/java/io/noties/markwon/MarkwonConfiguration.java +++ b/markwon-core/src/main/java/io/noties/markwon/MarkwonConfiguration.java @@ -6,15 +6,13 @@ import io.noties.markwon.core.MarkwonTheme; import io.noties.markwon.image.AsyncDrawableLoader; import io.noties.markwon.image.ImageSizeResolver; import io.noties.markwon.image.ImageSizeResolverDef; +import io.noties.markwon.image.destination.ImageDestinationProcessor; import io.noties.markwon.syntax.SyntaxHighlight; import io.noties.markwon.syntax.SyntaxHighlightNoOp; -import io.noties.markwon.urlprocessor.UrlProcessor; -import io.noties.markwon.urlprocessor.UrlProcessorNoOp; /** * since 3.0.0 renamed `SpannableConfiguration` -> `MarkwonConfiguration` */ -@SuppressWarnings("WeakerAccess") public class MarkwonConfiguration { @NonNull @@ -26,7 +24,8 @@ public class MarkwonConfiguration { private final AsyncDrawableLoader asyncDrawableLoader; private final SyntaxHighlight syntaxHighlight; private final LinkResolver linkResolver; - private final UrlProcessor urlProcessor; + // @since $nap; + private final ImageDestinationProcessor imageDestinationProcessor; private final ImageSizeResolver imageSizeResolver; // @since 3.0.0 @@ -37,7 +36,7 @@ public class MarkwonConfiguration { this.asyncDrawableLoader = builder.asyncDrawableLoader; this.syntaxHighlight = builder.syntaxHighlight; this.linkResolver = builder.linkResolver; - this.urlProcessor = builder.urlProcessor; + this.imageDestinationProcessor = builder.imageDestinationProcessor; this.imageSizeResolver = builder.imageSizeResolver; this.spansFactory = builder.spansFactory; } @@ -62,9 +61,12 @@ public class MarkwonConfiguration { return linkResolver; } + /** + * @since $nap; + */ @NonNull - public UrlProcessor urlProcessor() { - return urlProcessor; + public ImageDestinationProcessor imageDestinationProcessor() { + return imageDestinationProcessor; } @NonNull @@ -87,7 +89,8 @@ public class MarkwonConfiguration { private AsyncDrawableLoader asyncDrawableLoader; private SyntaxHighlight syntaxHighlight; private LinkResolver linkResolver; - private UrlProcessor urlProcessor; + // @since $nap; + private ImageDestinationProcessor imageDestinationProcessor; private ImageSizeResolver imageSizeResolver; private MarkwonSpansFactory spansFactory; @@ -115,9 +118,12 @@ public class MarkwonConfiguration { return this; } + /** + * @since $nap; + */ @NonNull - public Builder urlProcessor(@NonNull UrlProcessor urlProcessor) { - this.urlProcessor = urlProcessor; + public Builder imageDestinationProcessor(@NonNull ImageDestinationProcessor imageDestinationProcessor) { + this.imageDestinationProcessor = imageDestinationProcessor; return this; } @@ -151,8 +157,9 @@ public class MarkwonConfiguration { linkResolver = new LinkResolverDef(); } - if (urlProcessor == null) { - urlProcessor = new UrlProcessorNoOp(); + // @since $nap; + if (imageDestinationProcessor == null) { + imageDestinationProcessor = ImageDestinationProcessor.noOp(); } if (imageSizeResolver == null) { diff --git a/markwon-core/src/main/java/io/noties/markwon/core/CorePlugin.java b/markwon-core/src/main/java/io/noties/markwon/core/CorePlugin.java index 08c1c45a..36b8b277 100644 --- a/markwon-core/src/main/java/io/noties/markwon/core/CorePlugin.java +++ b/markwon-core/src/main/java/io/noties/markwon/core/CorePlugin.java @@ -320,7 +320,7 @@ public class CorePlugin extends AbstractMarkwonPlugin { final boolean link = parent instanceof Link; final String destination = configuration - .urlProcessor() + .imageDestinationProcessor() .process(image.getDestination()); final RenderProps props = visitor.renderProps(); @@ -524,8 +524,7 @@ public class CorePlugin extends AbstractMarkwonPlugin { final int length = visitor.length(); visitor.visitChildren(link); - final MarkwonConfiguration configuration = visitor.configuration(); - final String destination = configuration.urlProcessor().process(link.getDestination()); + final String destination = link.getDestination(); CoreProps.LINK_DESTINATION.set(visitor.renderProps(), destination); diff --git a/markwon-core/src/main/java/io/noties/markwon/image/destination/ImageDestinationProcessor.java b/markwon-core/src/main/java/io/noties/markwon/image/destination/ImageDestinationProcessor.java new file mode 100644 index 00000000..831c0b7c --- /dev/null +++ b/markwon-core/src/main/java/io/noties/markwon/image/destination/ImageDestinationProcessor.java @@ -0,0 +1,27 @@ +package io.noties.markwon.image.destination; + +import androidx.annotation.NonNull; + +/** + * Process destination of image nodes + * + * @since $nap; + */ +public abstract class ImageDestinationProcessor { + @NonNull + public abstract String process(@NonNull String destination); + + @NonNull + public static ImageDestinationProcessor noOp() { + return new NoOp(); + } + + private static class NoOp extends ImageDestinationProcessor { + + @NonNull + @Override + public String process(@NonNull String destination) { + return destination; + } + } +} diff --git a/markwon-core/src/main/java/io/noties/markwon/image/destination/ImageDestinationProcessorAssets.java b/markwon-core/src/main/java/io/noties/markwon/image/destination/ImageDestinationProcessorAssets.java new file mode 100644 index 00000000..169d2527 --- /dev/null +++ b/markwon-core/src/main/java/io/noties/markwon/image/destination/ImageDestinationProcessorAssets.java @@ -0,0 +1,59 @@ +package io.noties.markwon.image.destination; + +import android.net.Uri; +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +/** + * {@link ImageDestinationProcessor} that treats all destinations without scheme + * information as pointing to the {@code assets} folder of an application. Please note that this + * processor only adds required {@code file:///android_asset/} prefix to destinations and + * actual image loading must take that into account (implement this functionality). + *

+ * {@code FileSchemeHandler} from the {@code image} module supports asset images when created with + * {@code createWithAssets} factory method + * + * @since $nap; + */ +public class ImageDestinationProcessorAssets extends ImageDestinationProcessor { + + @NonNull + public static ImageDestinationProcessorAssets create(@Nullable ImageDestinationProcessor parent) { + return new ImageDestinationProcessorAssets(parent); + } + + static final String MOCK = "https://android.asset/"; + static final String BASE = "file:///android_asset/"; + + private final ImageDestinationProcessorRelativeToAbsolute assetsProcessor + = new ImageDestinationProcessorRelativeToAbsolute(MOCK); + + private final ImageDestinationProcessor processor; + + public ImageDestinationProcessorAssets() { + this(null); + } + + public ImageDestinationProcessorAssets(@Nullable ImageDestinationProcessor parent) { + this.processor = parent; + } + + @NonNull + @Override + public String process(@NonNull String destination) { + final String out; + final Uri uri = Uri.parse(destination); + if (TextUtils.isEmpty(uri.getScheme())) { + out = assetsProcessor.process(destination).replace(MOCK, BASE); + } else { + if (processor != null) { + out = processor.process(destination); + } else { + out = destination; + } + } + return out; + } +} diff --git a/markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessorRelativeToAbsolute.java b/markwon-core/src/main/java/io/noties/markwon/image/destination/ImageDestinationProcessorRelativeToAbsolute.java similarity index 54% rename from markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessorRelativeToAbsolute.java rename to markwon-core/src/main/java/io/noties/markwon/image/destination/ImageDestinationProcessorRelativeToAbsolute.java index 99a19226..9e04e1aa 100644 --- a/markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessorRelativeToAbsolute.java +++ b/markwon-core/src/main/java/io/noties/markwon/image/destination/ImageDestinationProcessorRelativeToAbsolute.java @@ -1,4 +1,4 @@ -package io.noties.markwon.urlprocessor; +package io.noties.markwon.image.destination; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -6,15 +6,30 @@ import androidx.annotation.Nullable; import java.net.MalformedURLException; import java.net.URL; -@SuppressWarnings("WeakerAccess") -public class UrlProcessorRelativeToAbsolute implements UrlProcessor { +/** + * @since $nap; + */ +public class ImageDestinationProcessorRelativeToAbsolute extends ImageDestinationProcessor { + + @NonNull + public static ImageDestinationProcessorRelativeToAbsolute create(@NonNull String base) { + return new ImageDestinationProcessorRelativeToAbsolute(base); + } + + public static ImageDestinationProcessorRelativeToAbsolute create(@NonNull URL base) { + return new ImageDestinationProcessorRelativeToAbsolute(base); + } private final URL base; - public UrlProcessorRelativeToAbsolute(@NonNull String base) { + public ImageDestinationProcessorRelativeToAbsolute(@NonNull String base) { this.base = obtain(base); } + public ImageDestinationProcessorRelativeToAbsolute(@NonNull URL base) { + this.base = base; + } + @NonNull @Override public String process(@NonNull String destination) { diff --git a/markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessor.java b/markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessor.java deleted file mode 100644 index b49585e5..00000000 --- a/markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessor.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.noties.markwon.urlprocessor; - -import androidx.annotation.NonNull; - -public interface UrlProcessor { - @NonNull - String process(@NonNull String destination); -} diff --git a/markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessorAndroidAssets.java b/markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessorAndroidAssets.java deleted file mode 100644 index bd3c74cb..00000000 --- a/markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessorAndroidAssets.java +++ /dev/null @@ -1,49 +0,0 @@ -package io.noties.markwon.urlprocessor; - -import android.net.Uri; -import android.text.TextUtils; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * Processor that will assume that an URL without scheme points to android assets folder. - * URL with a scheme will be processed by {@link #processor} (if it is specified) or returned `as-is`. - */ -@SuppressWarnings({"unused", "WeakerAccess"}) -public class UrlProcessorAndroidAssets implements UrlProcessor { - - - static final String MOCK = "https://android.asset/"; - static final String BASE = "file:///android_asset/"; - - private final UrlProcessorRelativeToAbsolute assetsProcessor - = new UrlProcessorRelativeToAbsolute(MOCK); - - private final UrlProcessor processor; - - public UrlProcessorAndroidAssets() { - this(null); - } - - public UrlProcessorAndroidAssets(@Nullable UrlProcessor parent) { - this.processor = parent; - } - - @NonNull - @Override - public String process(@NonNull String destination) { - final String out; - final Uri uri = Uri.parse(destination); - if (TextUtils.isEmpty(uri.getScheme())) { - out = assetsProcessor.process(destination).replace(MOCK, BASE); - } else { - if (processor != null) { - out = processor.process(destination); - } else { - out = destination; - } - } - return out; - } -} diff --git a/markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessorNoOp.java b/markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessorNoOp.java deleted file mode 100644 index 1bc15a88..00000000 --- a/markwon-core/src/main/java/io/noties/markwon/urlprocessor/UrlProcessorNoOp.java +++ /dev/null @@ -1,11 +0,0 @@ -package io.noties.markwon.urlprocessor; - -import androidx.annotation.NonNull; - -public class UrlProcessorNoOp implements UrlProcessor { - @NonNull - @Override - public String process(@NonNull String destination) { - return destination; - } -} diff --git a/markwon-core/src/test/java/io/noties/markwon/urlprocessor/UrlProcessorAndroidAssetsTest.java b/markwon-core/src/test/java/io/noties/markwon/image/destination/ImageDestinationProcessorAssetsTest.java similarity index 77% rename from markwon-core/src/test/java/io/noties/markwon/urlprocessor/UrlProcessorAndroidAssetsTest.java rename to markwon-core/src/test/java/io/noties/markwon/image/destination/ImageDestinationProcessorAssetsTest.java index 4129bfb8..4ab57e6b 100644 --- a/markwon-core/src/test/java/io/noties/markwon/urlprocessor/UrlProcessorAndroidAssetsTest.java +++ b/markwon-core/src/test/java/io/noties/markwon/image/destination/ImageDestinationProcessorAssetsTest.java @@ -1,4 +1,4 @@ -package io.noties.markwon.urlprocessor; +package io.noties.markwon.image.destination; import org.junit.Before; import org.junit.Test; @@ -6,18 +6,18 @@ import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; +import static io.noties.markwon.image.destination.ImageDestinationProcessorAssets.BASE; import static org.junit.Assert.assertEquals; -import static io.noties.markwon.urlprocessor.UrlProcessorAndroidAssets.BASE; @RunWith(RobolectricTestRunner.class) @Config(manifest = Config.NONE) -public class UrlProcessorAndroidAssetsTest { +public class ImageDestinationProcessorAssetsTest { - private UrlProcessorAndroidAssets processor; + private ImageDestinationProcessorAssets processor; @Before public void before() { - processor = new UrlProcessorAndroidAssets(); + processor = new ImageDestinationProcessorAssets(); } @Test diff --git a/markwon-core/src/test/java/io/noties/markwon/urlprocessor/UrlProcessorRelativeToAbsoluteTest.java b/markwon-core/src/test/java/io/noties/markwon/image/destination/ImageDestinationProcessorRelativeToAbsoluteTest.java similarity index 59% rename from markwon-core/src/test/java/io/noties/markwon/urlprocessor/UrlProcessorRelativeToAbsoluteTest.java rename to markwon-core/src/test/java/io/noties/markwon/image/destination/ImageDestinationProcessorRelativeToAbsoluteTest.java index afa55b33..36560fb6 100644 --- a/markwon-core/src/test/java/io/noties/markwon/urlprocessor/UrlProcessorRelativeToAbsoluteTest.java +++ b/markwon-core/src/test/java/io/noties/markwon/image/destination/ImageDestinationProcessorRelativeToAbsoluteTest.java @@ -1,4 +1,4 @@ -package io.noties.markwon.urlprocessor; +package io.noties.markwon.image.destination; import org.junit.Test; import org.junit.runner.RunWith; @@ -9,39 +9,39 @@ import static org.junit.Assert.*; @RunWith(RobolectricTestRunner.class) @Config(manifest = Config.NONE) -public class UrlProcessorRelativeToAbsoluteTest { +public class ImageDestinationProcessorRelativeToAbsoluteTest { @Test public void malformed_base_do_not_process() { - final UrlProcessorRelativeToAbsolute processor = new UrlProcessorRelativeToAbsolute("!@#$%^&*("); + final ImageDestinationProcessorRelativeToAbsolute processor = new ImageDestinationProcessorRelativeToAbsolute("!@#$%^&*("); final String destination = "../hey.there.html"; assertEquals(destination, processor.process(destination)); } @Test public void access_root() { - final UrlProcessorRelativeToAbsolute processor = new UrlProcessorRelativeToAbsolute("https://ro.ot/hello/"); + final ImageDestinationProcessorRelativeToAbsolute processor = new ImageDestinationProcessorRelativeToAbsolute("https://ro.ot/hello/"); final String url = "/index.html"; assertEquals("https://ro.ot/index.html", processor.process(url)); } @Test public void access_same_directory() { - final UrlProcessorRelativeToAbsolute processor = new UrlProcessorRelativeToAbsolute("https://ro.ot/hello/"); + final ImageDestinationProcessorRelativeToAbsolute processor = new ImageDestinationProcessorRelativeToAbsolute("https://ro.ot/hello/"); final String url = "./.htaccess"; assertEquals("https://ro.ot/hello/.htaccess", processor.process(url)); } @Test public void asset_directory_up() { - final UrlProcessorRelativeToAbsolute processor = new UrlProcessorRelativeToAbsolute("http://ro.ot/first/second/"); + final ImageDestinationProcessorRelativeToAbsolute processor = new ImageDestinationProcessorRelativeToAbsolute("http://ro.ot/first/second/"); final String url = "../cat.JPG"; assertEquals("http://ro.ot/first/cat.JPG", processor.process(url)); } @Test public void change_directory_inside_destination() { - final UrlProcessorRelativeToAbsolute processor = new UrlProcessorRelativeToAbsolute("http://ro.ot/first/"); + final ImageDestinationProcessorRelativeToAbsolute processor = new ImageDestinationProcessorRelativeToAbsolute("http://ro.ot/first/"); final String url = "../first/../second/./thi.rd"; assertEquals( "http://ro.ot/second/thi.rd", @@ -51,7 +51,7 @@ public class UrlProcessorRelativeToAbsoluteTest { @Test public void with_query_arguments() { - final UrlProcessorRelativeToAbsolute processor = new UrlProcessorRelativeToAbsolute("http://ro.ot/first/"); + final ImageDestinationProcessorRelativeToAbsolute processor = new ImageDestinationProcessorRelativeToAbsolute("http://ro.ot/first/"); final String url = "../index.php?ROOT=1"; assertEquals( "http://ro.ot/index.php?ROOT=1", diff --git a/markwon-html/src/main/java/io/noties/markwon/html/tag/ImageHandler.java b/markwon-html/src/main/java/io/noties/markwon/html/tag/ImageHandler.java index ad170b0e..833c4926 100644 --- a/markwon-html/src/main/java/io/noties/markwon/html/tag/ImageHandler.java +++ b/markwon-html/src/main/java/io/noties/markwon/html/tag/ImageHandler.java @@ -62,7 +62,7 @@ public class ImageHandler extends SimpleTagHandler { return null; } - final String destination = configuration.urlProcessor().process(src); + final String destination = configuration.imageDestinationProcessor().process(src); final ImageSize imageSize = imageSizeParser.parse(tag.attributes()); // todo: replacement text is link... as we are not at block level diff --git a/markwon-html/src/main/java/io/noties/markwon/html/tag/LinkHandler.java b/markwon-html/src/main/java/io/noties/markwon/html/tag/LinkHandler.java index fdd830cc..d5e032f7 100644 --- a/markwon-html/src/main/java/io/noties/markwon/html/tag/LinkHandler.java +++ b/markwon-html/src/main/java/io/noties/markwon/html/tag/LinkHandler.java @@ -27,7 +27,8 @@ public class LinkHandler extends SimpleTagHandler { CoreProps.LINK_DESTINATION.set( renderProps, - configuration.urlProcessor().process(destination)); + destination + ); return spanFactory.getSpans(configuration, renderProps); } diff --git a/markwon-image/src/main/java/io/noties/markwon/image/file/FileSchemeHandler.java b/markwon-image/src/main/java/io/noties/markwon/image/file/FileSchemeHandler.java index d7da6dc5..b29a67b6 100644 --- a/markwon-image/src/main/java/io/noties/markwon/image/file/FileSchemeHandler.java +++ b/markwon-image/src/main/java/io/noties/markwon/image/file/FileSchemeHandler.java @@ -3,11 +3,12 @@ package io.noties.markwon.image.file; import android.content.Context; import android.content.res.AssetManager; import android.net.Uri; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import android.text.TextUtils; import android.webkit.MimeTypeMap; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; @@ -18,7 +19,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import io.noties.markwon.urlprocessor.UrlProcessorAndroidAssets; import io.noties.markwon.image.ImageItem; import io.noties.markwon.image.SchemeHandler; @@ -30,7 +30,7 @@ public class FileSchemeHandler extends SchemeHandler { public static final String SCHEME = "file"; /** - * @see UrlProcessorAndroidAssets + * @see io.noties.markwon.image.destination.ImageDestinationProcessorAssets */ @NonNull public static FileSchemeHandler createWithAssets(@NonNull AssetManager assetManager) { @@ -39,7 +39,7 @@ public class FileSchemeHandler extends SchemeHandler { /** * @see #createWithAssets(AssetManager) - * @see UrlProcessorAndroidAssets + * @see io.noties.markwon.image.destination.ImageDestinationProcessorAssets * @since 4.0.0 */ @NonNull diff --git a/sample/src/main/java/io/noties/markwon/sample/basicplugins/BasicPluginsActivity.java b/sample/src/main/java/io/noties/markwon/sample/basicplugins/BasicPluginsActivity.java index 02d3308a..21ba2bad 100644 --- a/sample/src/main/java/io/noties/markwon/sample/basicplugins/BasicPluginsActivity.java +++ b/sample/src/main/java/io/noties/markwon/sample/basicplugins/BasicPluginsActivity.java @@ -5,6 +5,7 @@ import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; import android.text.style.ForegroundColorSpan; +import android.view.View; import android.widget.ScrollView; import android.widget.TextView; @@ -20,6 +21,7 @@ import java.util.Collections; import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.BlockHandlerDef; +import io.noties.markwon.LinkResolverDef; import io.noties.markwon.Markwon; import io.noties.markwon.MarkwonConfiguration; import io.noties.markwon.MarkwonSpansFactory; @@ -153,7 +155,7 @@ public class BasicPluginsActivity extends ActivityWithMenuOptions { *

    *
  • SyntaxHighlight
  • *
  • LinkSpan.Resolver
  • - *
  • UrlProcessor
  • + *
  • ImageDestinationProcessor
  • *
  • ImageSizeResolver
  • *
*

@@ -173,12 +175,18 @@ public class BasicPluginsActivity extends ActivityWithMenuOptions { public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { // for example if specified destination has no scheme info, we will // _assume_ that it's network request and append HTTPS scheme - builder.urlProcessor(destination -> { - final Uri uri = Uri.parse(destination); - if (TextUtils.isEmpty(uri.getScheme())) { - return "https://" + destination; + builder.linkResolver(new LinkResolverDef() { + @Override + public void resolve(@NonNull View view, @NonNull String link) { + final String destination; + final Uri uri = Uri.parse(link); + if (TextUtils.isEmpty(uri.getScheme())) { + destination = "https://" + link; + } else { + destination = link; + } + super.resolve(view, destination); } - return destination; }); } }) diff --git a/sample/src/main/java/io/noties/markwon/sample/recycler/RecyclerActivity.java b/sample/src/main/java/io/noties/markwon/sample/recycler/RecyclerActivity.java index 84034ce9..50bcd696 100644 --- a/sample/src/main/java/io/noties/markwon/sample/recycler/RecyclerActivity.java +++ b/sample/src/main/java/io/noties/markwon/sample/recycler/RecyclerActivity.java @@ -34,6 +34,8 @@ import io.noties.markwon.MarkwonVisitor; import io.noties.markwon.core.CorePlugin; import io.noties.markwon.html.HtmlPlugin; import io.noties.markwon.image.ImagesPlugin; +import io.noties.markwon.image.destination.ImageDestinationProcessor; +import io.noties.markwon.image.destination.ImageDestinationProcessorRelativeToAbsolute; import io.noties.markwon.image.file.FileSchemeHandler; import io.noties.markwon.image.network.OkHttpNetworkSchemeHandler; import io.noties.markwon.image.svg.SvgMediaDecoder; @@ -42,8 +44,6 @@ import io.noties.markwon.recycler.SimpleEntry; import io.noties.markwon.recycler.table.TableEntry; import io.noties.markwon.recycler.table.TableEntryPlugin; import io.noties.markwon.sample.R; -import io.noties.markwon.urlprocessor.UrlProcessor; -import io.noties.markwon.urlprocessor.UrlProcessorRelativeToAbsolute; public class RecyclerActivity extends Activity { @@ -100,7 +100,7 @@ public class RecyclerActivity extends Activity { .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.urlProcessor(new UrlProcessorInitialReadme()); + builder.imageDestinationProcessor(new ImageDestinationProcessorInitialReadme()); } @Override @@ -182,12 +182,12 @@ public class RecyclerActivity extends Activity { return out; } - private static class UrlProcessorInitialReadme implements UrlProcessor { + private static class ImageDestinationProcessorInitialReadme extends ImageDestinationProcessor { private static final String GITHUB_BASE = "https://github.com/noties/Markwon/raw/master/"; - private final UrlProcessorRelativeToAbsolute processor - = new UrlProcessorRelativeToAbsolute(GITHUB_BASE); + private final ImageDestinationProcessorRelativeToAbsolute processor + = new ImageDestinationProcessorRelativeToAbsolute(GITHUB_BASE); @NonNull @Override