Merge 619baf3b2a62227c8595d9fe4ae36835e2851ebf into 18938a1aa2e178185de82a4f605d03a0ccb3084d
This commit is contained in:
		
						commit
						f337f7bb6e
					
				@ -0,0 +1,13 @@
 | 
			
		||||
package ru.noties.markwon;
 | 
			
		||||
 | 
			
		||||
import android.support.annotation.NonNull;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author pa.gulko zTrap (25.10.2017)
 | 
			
		||||
 * @since 1.0.1
 | 
			
		||||
 */
 | 
			
		||||
public interface ImageClickResolver {
 | 
			
		||||
 | 
			
		||||
    void resolve(View view, @NonNull String link);
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,30 @@
 | 
			
		||||
package ru.noties.markwon;
 | 
			
		||||
 | 
			
		||||
import android.content.ActivityNotFoundException;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.provider.Browser;
 | 
			
		||||
import android.support.annotation.NonNull;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author pa.gulko zTrap (25.10.2017)
 | 
			
		||||
 * @since 1.0.1
 | 
			
		||||
 */
 | 
			
		||||
public class ImageClickResolverDef implements ImageClickResolver {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void resolve(View view, @NonNull String link) {
 | 
			
		||||
        final Uri uri = Uri.parse(link);
 | 
			
		||||
        final Context context = view.getContext();
 | 
			
		||||
        final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
 | 
			
		||||
        intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
 | 
			
		||||
        try {
 | 
			
		||||
            context.startActivity(intent);
 | 
			
		||||
        } catch (ActivityNotFoundException e) {
 | 
			
		||||
            Log.w("LinkResolverDef", "Actvity was not found for intent, " + intent.toString());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -26,6 +26,7 @@ public class SpannableConfiguration {
 | 
			
		||||
    private final LinkSpan.Resolver linkResolver;
 | 
			
		||||
    private final UrlProcessor urlProcessor;
 | 
			
		||||
    private final SpannableHtmlParser htmlParser;
 | 
			
		||||
    private final ImageClickResolver imageClickResolver;
 | 
			
		||||
 | 
			
		||||
    private SpannableConfiguration(Builder builder) {
 | 
			
		||||
        this.theme = builder.theme;
 | 
			
		||||
@ -34,6 +35,7 @@ public class SpannableConfiguration {
 | 
			
		||||
        this.linkResolver = builder.linkResolver;
 | 
			
		||||
        this.urlProcessor = builder.urlProcessor;
 | 
			
		||||
        this.htmlParser = builder.htmlParser;
 | 
			
		||||
        this.imageClickResolver = builder.imageClickResolver;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SpannableTheme theme() {
 | 
			
		||||
@ -60,6 +62,10 @@ public class SpannableConfiguration {
 | 
			
		||||
        return htmlParser;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ImageClickResolver imageClickResolver() {
 | 
			
		||||
        return imageClickResolver;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Builder {
 | 
			
		||||
 | 
			
		||||
        private final Context context;
 | 
			
		||||
@ -69,6 +75,7 @@ public class SpannableConfiguration {
 | 
			
		||||
        private LinkSpan.Resolver linkResolver;
 | 
			
		||||
        private UrlProcessor urlProcessor;
 | 
			
		||||
        private SpannableHtmlParser htmlParser;
 | 
			
		||||
        private ImageClickResolver imageClickResolver;
 | 
			
		||||
 | 
			
		||||
        Builder(Context context) {
 | 
			
		||||
            this.context = context;
 | 
			
		||||
@ -104,6 +111,11 @@ public class SpannableConfiguration {
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Builder imageClickResolver(ImageClickResolver imageClickResolver) {
 | 
			
		||||
            this.imageClickResolver = imageClickResolver;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public SpannableConfiguration build() {
 | 
			
		||||
            if (theme == null) {
 | 
			
		||||
                theme = SpannableTheme.create(context);
 | 
			
		||||
@ -120,8 +132,12 @@ public class SpannableConfiguration {
 | 
			
		||||
            if (urlProcessor == null) {
 | 
			
		||||
                urlProcessor = new UrlProcessorNoOp();
 | 
			
		||||
            }
 | 
			
		||||
            if (imageClickResolver == null) {
 | 
			
		||||
                imageClickResolver = new ImageClickResolverDef();
 | 
			
		||||
            }
 | 
			
		||||
            if (htmlParser == null) {
 | 
			
		||||
                htmlParser = SpannableHtmlParser.create(theme, asyncDrawableLoader, urlProcessor, linkResolver);
 | 
			
		||||
                htmlParser = SpannableHtmlParser.create(theme, asyncDrawableLoader, urlProcessor,
 | 
			
		||||
                        linkResolver, imageClickResolver);
 | 
			
		||||
            }
 | 
			
		||||
            return new SpannableConfiguration(this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,9 @@ import android.support.annotation.NonNull;
 | 
			
		||||
import android.text.SpannableStringBuilder;
 | 
			
		||||
import android.text.Spanned;
 | 
			
		||||
import android.text.TextUtils;
 | 
			
		||||
import android.text.style.ClickableSpan;
 | 
			
		||||
import android.text.style.StrikethroughSpan;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
 | 
			
		||||
import org.commonmark.ext.gfm.strikethrough.Strikethrough;
 | 
			
		||||
import org.commonmark.ext.gfm.tables.TableBody;
 | 
			
		||||
@ -431,8 +433,12 @@ public class SpannableMarkdownVisitor extends AbstractVisitor {
 | 
			
		||||
                )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        // todo, maybe, if image is not inside a link, we should make it clickable, so
 | 
			
		||||
        // user can open it in external viewer?
 | 
			
		||||
        setSpan(length, new ClickableSpan() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                configuration.imageClickResolver().resolve(view, destination);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -4,9 +4,12 @@ import android.support.annotation.NonNull;
 | 
			
		||||
import android.text.SpannableString;
 | 
			
		||||
import android.text.Spanned;
 | 
			
		||||
import android.text.TextUtils;
 | 
			
		||||
import android.text.style.ClickableSpan;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import ru.noties.markwon.ImageClickResolver;
 | 
			
		||||
import ru.noties.markwon.UrlProcessor;
 | 
			
		||||
import ru.noties.markwon.spans.AsyncDrawable;
 | 
			
		||||
import ru.noties.markwon.spans.AsyncDrawableSpan;
 | 
			
		||||
@ -17,14 +20,17 @@ class ImageProviderImpl implements SpannableHtmlParser.ImageProvider {
 | 
			
		||||
    private final SpannableTheme theme;
 | 
			
		||||
    private final AsyncDrawable.Loader loader;
 | 
			
		||||
    private final UrlProcessor urlProcessor;
 | 
			
		||||
    private final ImageClickResolver imageClickResolver;
 | 
			
		||||
 | 
			
		||||
    ImageProviderImpl(
 | 
			
		||||
            @NonNull SpannableTheme theme,
 | 
			
		||||
            @NonNull AsyncDrawable.Loader loader,
 | 
			
		||||
            @NonNull UrlProcessor urlProcessor) {
 | 
			
		||||
            @NonNull UrlProcessor urlProcessor,
 | 
			
		||||
            @NonNull ImageClickResolver imageClickResolver) {
 | 
			
		||||
        this.theme = theme;
 | 
			
		||||
        this.loader = loader;
 | 
			
		||||
        this.urlProcessor = urlProcessor;
 | 
			
		||||
        this.imageClickResolver = imageClickResolver;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -53,6 +59,14 @@ class ImageProviderImpl implements SpannableHtmlParser.ImageProvider {
 | 
			
		||||
            final SpannableString string = new SpannableString(replacement);
 | 
			
		||||
            string.setSpan(span, 0, string.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 | 
			
		||||
 | 
			
		||||
            final ClickableSpan clickableSpan = new ClickableSpan() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View view) {
 | 
			
		||||
                    imageClickResolver.resolve(view, destination);
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
            string.setSpan(clickableSpan, 0, string.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 | 
			
		||||
 | 
			
		||||
            spanned = string;
 | 
			
		||||
        } else {
 | 
			
		||||
            spanned = null;
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,8 @@ import android.text.Spanned;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import ru.noties.markwon.ImageClickResolver;
 | 
			
		||||
import ru.noties.markwon.ImageClickResolverDef;
 | 
			
		||||
import ru.noties.markwon.LinkResolverDef;
 | 
			
		||||
import ru.noties.markwon.UrlProcessor;
 | 
			
		||||
import ru.noties.markwon.UrlProcessorNoOp;
 | 
			
		||||
@ -25,7 +27,8 @@ public class SpannableHtmlParser {
 | 
			
		||||
            @NonNull SpannableTheme theme,
 | 
			
		||||
            @NonNull AsyncDrawable.Loader loader
 | 
			
		||||
    ) {
 | 
			
		||||
        return builderWithDefaults(theme, loader, null, null)
 | 
			
		||||
        return builderWithDefaults(theme, loader, null, null,
 | 
			
		||||
                null)
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -33,9 +36,10 @@ public class SpannableHtmlParser {
 | 
			
		||||
            @NonNull SpannableTheme theme,
 | 
			
		||||
            @NonNull AsyncDrawable.Loader loader,
 | 
			
		||||
            @NonNull UrlProcessor urlProcessor,
 | 
			
		||||
            @NonNull LinkSpan.Resolver resolver
 | 
			
		||||
            @NonNull LinkSpan.Resolver linkResolver,
 | 
			
		||||
            @NonNull ImageClickResolver imageClickResolver
 | 
			
		||||
    ) {
 | 
			
		||||
        return builderWithDefaults(theme, loader, urlProcessor, resolver)
 | 
			
		||||
        return builderWithDefaults(theme, loader, urlProcessor, linkResolver, imageClickResolver)
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -44,22 +48,28 @@ public class SpannableHtmlParser {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Builder builderWithDefaults(@NonNull SpannableTheme theme) {
 | 
			
		||||
        return builderWithDefaults(theme, null, null, null);
 | 
			
		||||
        return builderWithDefaults(theme, null, null, null,
 | 
			
		||||
                null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Builder builderWithDefaults(
 | 
			
		||||
            @NonNull SpannableTheme theme,
 | 
			
		||||
            @Nullable AsyncDrawable.Loader asyncDrawableLoader,
 | 
			
		||||
            @Nullable UrlProcessor urlProcessor,
 | 
			
		||||
            @Nullable LinkSpan.Resolver resolver
 | 
			
		||||
            @Nullable LinkSpan.Resolver linkResolver,
 | 
			
		||||
            @Nullable ImageClickResolver imageClickResolver
 | 
			
		||||
    ) {
 | 
			
		||||
 | 
			
		||||
        if (urlProcessor == null) {
 | 
			
		||||
            urlProcessor = new UrlProcessorNoOp();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (resolver == null) {
 | 
			
		||||
            resolver = new LinkResolverDef();
 | 
			
		||||
        if (linkResolver == null) {
 | 
			
		||||
            linkResolver = new LinkResolverDef();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (imageClickResolver == null) {
 | 
			
		||||
            imageClickResolver = new ImageClickResolverDef();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final BoldProvider boldProvider = new BoldProvider();
 | 
			
		||||
@ -68,7 +78,8 @@ public class SpannableHtmlParser {
 | 
			
		||||
 | 
			
		||||
        final ImageProvider imageProvider;
 | 
			
		||||
        if (asyncDrawableLoader != null) {
 | 
			
		||||
            imageProvider = new ImageProviderImpl(theme, asyncDrawableLoader, urlProcessor);
 | 
			
		||||
            imageProvider = new ImageProviderImpl(theme, asyncDrawableLoader, urlProcessor,
 | 
			
		||||
                    imageClickResolver);
 | 
			
		||||
        } else {
 | 
			
		||||
            imageProvider = null;
 | 
			
		||||
        }
 | 
			
		||||
@ -86,7 +97,7 @@ public class SpannableHtmlParser {
 | 
			
		||||
                .simpleTag("del", strikeProvider)
 | 
			
		||||
                .simpleTag("s", strikeProvider)
 | 
			
		||||
                .simpleTag("strike", strikeProvider)
 | 
			
		||||
                .simpleTag("a", new LinkProvider(theme, urlProcessor, resolver))
 | 
			
		||||
                .simpleTag("a", new LinkProvider(theme, urlProcessor, linkResolver))
 | 
			
		||||
                .imageProvider(imageProvider);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user