Unified html and image modules
This commit is contained in:
parent
dba07e3f3c
commit
4b918bf094
@ -6,7 +6,7 @@ org.gradle.configureondemand=true
|
|||||||
android.enableBuildCache=true
|
android.enableBuildCache=true
|
||||||
android.buildCacheDir=build/pre-dex-cache
|
android.buildCacheDir=build/pre-dex-cache
|
||||||
|
|
||||||
VERSION_NAME=3.1.0-SNAPSHOT
|
VERSION_NAME=4.0.0-SNAPSHOT
|
||||||
|
|
||||||
GROUP=ru.noties.markwon
|
GROUP=ru.noties.markwon
|
||||||
POM_DESCRIPTION=Markwon markdown for Android
|
POM_DESCRIPTION=Markwon markdown for Android
|
||||||
|
@ -10,6 +10,17 @@ import org.commonmark.node.Node;
|
|||||||
import ru.noties.markwon.AbstractMarkwonPlugin;
|
import ru.noties.markwon.AbstractMarkwonPlugin;
|
||||||
import ru.noties.markwon.MarkwonConfiguration;
|
import ru.noties.markwon.MarkwonConfiguration;
|
||||||
import ru.noties.markwon.MarkwonVisitor;
|
import ru.noties.markwon.MarkwonVisitor;
|
||||||
|
import ru.noties.markwon.html.tag.BlockquoteHandler;
|
||||||
|
import ru.noties.markwon.html.tag.EmphasisHandler;
|
||||||
|
import ru.noties.markwon.html.tag.HeadingHandler;
|
||||||
|
import ru.noties.markwon.html.tag.ImageHandler;
|
||||||
|
import ru.noties.markwon.html.tag.LinkHandler;
|
||||||
|
import ru.noties.markwon.html.tag.ListHandler;
|
||||||
|
import ru.noties.markwon.html.tag.StrikeHandler;
|
||||||
|
import ru.noties.markwon.html.tag.StrongEmphasisHandler;
|
||||||
|
import ru.noties.markwon.html.tag.SubScriptHandler;
|
||||||
|
import ru.noties.markwon.html.tag.SuperScriptHandler;
|
||||||
|
import ru.noties.markwon.html.tag.UnderlineHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
@ -73,9 +84,29 @@ public class HtmlPlugin extends AbstractMarkwonPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
|
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder configurationBuilder) {
|
||||||
builder
|
|
||||||
.htmlRenderer(this.builder.build())
|
final MarkwonHtmlRendererImpl.Builder builder = this.builder;
|
||||||
|
|
||||||
|
if (!builder.excludeDefaults()) {
|
||||||
|
// please note that it's better to not checkState for
|
||||||
|
// this method call (minor optimization), final `build` method call
|
||||||
|
// will check for the state and throw an exception if applicable
|
||||||
|
builder.addDefaultTagHandler(ImageHandler.create());
|
||||||
|
builder.addDefaultTagHandler(new LinkHandler());
|
||||||
|
builder.addDefaultTagHandler(new BlockquoteHandler());
|
||||||
|
builder.addDefaultTagHandler(new SubScriptHandler());
|
||||||
|
builder.addDefaultTagHandler(new SuperScriptHandler());
|
||||||
|
builder.addDefaultTagHandler(new StrongEmphasisHandler());
|
||||||
|
builder.addDefaultTagHandler(new StrikeHandler());
|
||||||
|
builder.addDefaultTagHandler(new UnderlineHandler());
|
||||||
|
builder.addDefaultTagHandler(new ListHandler());
|
||||||
|
builder.addDefaultTagHandler(new EmphasisHandler());
|
||||||
|
builder.addDefaultTagHandler(new HeadingHandler());
|
||||||
|
}
|
||||||
|
|
||||||
|
configurationBuilder
|
||||||
|
.htmlRenderer(builder.build())
|
||||||
.htmlParser(MarkwonHtmlParserImpl.create());
|
.htmlParser(MarkwonHtmlParserImpl.create());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,17 +9,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import ru.noties.markwon.MarkwonVisitor;
|
import ru.noties.markwon.MarkwonVisitor;
|
||||||
import ru.noties.markwon.html.tag.BlockquoteHandler;
|
|
||||||
import ru.noties.markwon.html.tag.EmphasisHandler;
|
|
||||||
import ru.noties.markwon.html.tag.HeadingHandler;
|
|
||||||
import ru.noties.markwon.html.tag.ImageHandler;
|
|
||||||
import ru.noties.markwon.html.tag.LinkHandler;
|
|
||||||
import ru.noties.markwon.html.tag.ListHandler;
|
|
||||||
import ru.noties.markwon.html.tag.StrikeHandler;
|
|
||||||
import ru.noties.markwon.html.tag.StrongEmphasisHandler;
|
|
||||||
import ru.noties.markwon.html.tag.SubScriptHandler;
|
|
||||||
import ru.noties.markwon.html.tag.SuperScriptHandler;
|
|
||||||
import ru.noties.markwon.html.tag.UnderlineHandler;
|
|
||||||
|
|
||||||
class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {
|
class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {
|
||||||
|
|
||||||
@ -128,6 +117,10 @@ class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {
|
|||||||
this.excludeDefaults = excludeDefaults;
|
this.excludeDefaults = excludeDefaults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean excludeDefaults() {
|
||||||
|
return excludeDefaults;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public MarkwonHtmlRenderer build() {
|
public MarkwonHtmlRenderer build() {
|
||||||
|
|
||||||
@ -135,11 +128,6 @@ class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {
|
|||||||
|
|
||||||
isBuilt = true;
|
isBuilt = true;
|
||||||
|
|
||||||
if (!excludeDefaults) {
|
|
||||||
// register default handlers, check if a handler is present already for specified tag
|
|
||||||
registerDefaultHandlers();
|
|
||||||
}
|
|
||||||
|
|
||||||
// okay, let's validate that we have at least one tagHandler registered
|
// okay, let's validate that we have at least one tagHandler registered
|
||||||
// if we have none -> return no-op implementation
|
// if we have none -> return no-op implementation
|
||||||
return tagHandlers.size() > 0
|
return tagHandlers.size() > 0
|
||||||
@ -153,21 +141,7 @@ class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerDefaultHandlers() {
|
void addDefaultTagHandler(@NonNull TagHandler tagHandler) {
|
||||||
add(ImageHandler.create());
|
|
||||||
add(new LinkHandler());
|
|
||||||
add(new BlockquoteHandler());
|
|
||||||
add(new SubScriptHandler());
|
|
||||||
add(new SuperScriptHandler());
|
|
||||||
add(new StrongEmphasisHandler());
|
|
||||||
add(new StrikeHandler());
|
|
||||||
add(new UnderlineHandler());
|
|
||||||
add(new ListHandler());
|
|
||||||
add(new EmphasisHandler());
|
|
||||||
add(new HeadingHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void add(@NonNull TagHandler tagHandler) {
|
|
||||||
for (String tag : tagHandler.supportedTags()) {
|
for (String tag : tagHandler.supportedTags()) {
|
||||||
if (!tagHandlers.containsKey(tag)) {
|
if (!tagHandlers.containsKey(tag)) {
|
||||||
tagHandlers.put(tag, tagHandler);
|
tagHandlers.put(tag, tagHandler);
|
||||||
|
@ -34,30 +34,36 @@ class AsyncDrawableLoaderBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void executorService(@NonNull ExecutorService executorService) {
|
void executorService(@NonNull ExecutorService executorService) {
|
||||||
|
checkState();
|
||||||
this.executorService = executorService;
|
this.executorService = executorService;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addSchemeHandler(@NonNull SchemeHandler schemeHandler) {
|
void addSchemeHandler(@NonNull SchemeHandler schemeHandler) {
|
||||||
|
checkState();
|
||||||
for (String scheme : schemeHandler.supportedSchemes()) {
|
for (String scheme : schemeHandler.supportedSchemes()) {
|
||||||
schemeHandlers.put(scheme, schemeHandler);
|
schemeHandlers.put(scheme, schemeHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addMediaDecoder(@NonNull MediaDecoder mediaDecoder) {
|
void addMediaDecoder(@NonNull MediaDecoder mediaDecoder) {
|
||||||
|
checkState();
|
||||||
for (String type : mediaDecoder.supportedTypes()) {
|
for (String type : mediaDecoder.supportedTypes()) {
|
||||||
mediaDecoders.put(type, mediaDecoder);
|
mediaDecoders.put(type, mediaDecoder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void defaultMediaDecoder(@Nullable MediaDecoder mediaDecoder) {
|
void defaultMediaDecoder(@Nullable MediaDecoder mediaDecoder) {
|
||||||
|
checkState();
|
||||||
this.defaultMediaDecoder = mediaDecoder;
|
this.defaultMediaDecoder = mediaDecoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeSchemeHandler(@NonNull String scheme) {
|
void removeSchemeHandler(@NonNull String scheme) {
|
||||||
|
checkState();
|
||||||
schemeHandlers.remove(scheme);
|
schemeHandlers.remove(scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeMediaDecoder(@NonNull String contentType) {
|
void removeMediaDecoder(@NonNull String contentType) {
|
||||||
|
checkState();
|
||||||
mediaDecoders.remove(contentType);
|
mediaDecoders.remove(contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +71,7 @@ class AsyncDrawableLoaderBuilder {
|
|||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
void placeholderProvider(@NonNull ImagesPlugin.PlaceholderProvider placeholderDrawableProvider) {
|
void placeholderProvider(@NonNull ImagesPlugin.PlaceholderProvider placeholderDrawableProvider) {
|
||||||
|
checkState();
|
||||||
this.placeholderProvider = placeholderDrawableProvider;
|
this.placeholderProvider = placeholderDrawableProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,12 +79,15 @@ class AsyncDrawableLoaderBuilder {
|
|||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
void errorHandler(@NonNull ImagesPlugin.ErrorHandler errorHandler) {
|
void errorHandler(@NonNull ImagesPlugin.ErrorHandler errorHandler) {
|
||||||
|
checkState();
|
||||||
this.errorHandler = errorHandler;
|
this.errorHandler = errorHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
AsyncDrawableLoader build() {
|
AsyncDrawableLoader build() {
|
||||||
|
|
||||||
|
checkState();
|
||||||
|
|
||||||
isBuilt = true;
|
isBuilt = true;
|
||||||
|
|
||||||
if (executorService == null) {
|
if (executorService == null) {
|
||||||
@ -86,4 +96,11 @@ class AsyncDrawableLoaderBuilder {
|
|||||||
|
|
||||||
return new AsyncDrawableLoaderImpl(this);
|
return new AsyncDrawableLoaderImpl(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkState() {
|
||||||
|
if (isBuilt) {
|
||||||
|
throw new IllegalStateException("ImagesPlugin has already been configured " +
|
||||||
|
"and cannot be modified any further");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,6 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public ImagesPlugin executorService(@NonNull ExecutorService executorService) {
|
public ImagesPlugin executorService(@NonNull ExecutorService executorService) {
|
||||||
checkBuilderState();
|
|
||||||
builder.executorService(executorService);
|
builder.executorService(executorService);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -87,7 +86,6 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public ImagesPlugin addSchemeHandler(@NonNull SchemeHandler schemeHandler) {
|
public ImagesPlugin addSchemeHandler(@NonNull SchemeHandler schemeHandler) {
|
||||||
checkBuilderState();
|
|
||||||
builder.addSchemeHandler(schemeHandler);
|
builder.addSchemeHandler(schemeHandler);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -100,7 +98,6 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public ImagesPlugin addMediaDecoder(@NonNull MediaDecoder mediaDecoder) {
|
public ImagesPlugin addMediaDecoder(@NonNull MediaDecoder mediaDecoder) {
|
||||||
checkBuilderState();
|
|
||||||
builder.addMediaDecoder(mediaDecoder);
|
builder.addMediaDecoder(mediaDecoder);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -114,7 +111,6 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public ImagesPlugin defaultMediaDecoder(@Nullable MediaDecoder mediaDecoder) {
|
public ImagesPlugin defaultMediaDecoder(@Nullable MediaDecoder mediaDecoder) {
|
||||||
checkBuilderState();
|
|
||||||
builder.defaultMediaDecoder(mediaDecoder);
|
builder.defaultMediaDecoder(mediaDecoder);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -124,7 +120,6 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public ImagesPlugin removeSchemeHandler(@NonNull String scheme) {
|
public ImagesPlugin removeSchemeHandler(@NonNull String scheme) {
|
||||||
checkBuilderState();
|
|
||||||
builder.removeSchemeHandler(scheme);
|
builder.removeSchemeHandler(scheme);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -134,7 +129,6 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public ImagesPlugin removeMediaDecoder(@NonNull String contentType) {
|
public ImagesPlugin removeMediaDecoder(@NonNull String contentType) {
|
||||||
checkBuilderState();
|
|
||||||
builder.removeMediaDecoder(contentType);
|
builder.removeMediaDecoder(contentType);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -144,7 +138,6 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public ImagesPlugin placeholderProvider(@NonNull PlaceholderProvider placeholderProvider) {
|
public ImagesPlugin placeholderProvider(@NonNull PlaceholderProvider placeholderProvider) {
|
||||||
checkBuilderState();
|
|
||||||
builder.placeholderProvider(placeholderProvider);
|
builder.placeholderProvider(placeholderProvider);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -155,14 +148,12 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public ImagesPlugin errorHandler(@NonNull ErrorHandler errorHandler) {
|
public ImagesPlugin errorHandler(@NonNull ErrorHandler errorHandler) {
|
||||||
checkBuilderState();
|
|
||||||
builder.errorHandler(errorHandler);
|
builder.errorHandler(errorHandler);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
|
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
|
||||||
checkBuilderState();
|
|
||||||
builder.asyncDrawableLoader(this.builder.build());
|
builder.asyncDrawableLoader(this.builder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,11 +171,4 @@ public class ImagesPlugin extends AbstractMarkwonPlugin {
|
|||||||
public void afterSetText(@NonNull TextView textView) {
|
public void afterSetText(@NonNull TextView textView) {
|
||||||
AsyncDrawableScheduler.schedule(textView);
|
AsyncDrawableScheduler.schedule(textView);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkBuilderState() {
|
|
||||||
if (builder.isBuilt) {
|
|
||||||
throw new IllegalStateException("ImagesPlugin has already been configured " +
|
|
||||||
"and cannot be modified any further");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,6 @@ Use this module (or take a hint from it) if you would need _linkify_ capabilitie
|
|||||||
use `TextView.setAutolinkMask` (or specify `autolink` in XML) because it will remove all
|
use `TextView.setAutolinkMask` (or specify `autolink` in XML) because it will remove all
|
||||||
existing links and keep only the ones it creates.
|
existing links and keep only the ones it creates.
|
||||||
|
|
||||||
Please note that usage of this plugin introduces significant performance drop due not
|
Please note that usage of this plugin introduces significant performance drop due to not
|
||||||
optimal implementation of underlying `android.text.util.Linkify`. If you have any ideas of how
|
optimal implementation of underlying `android.text.util.Linkify`. If you have any ideas of how
|
||||||
to improve this - PR are welcome!
|
to improve this - PR are welcome!
|
Loading…
x
Reference in New Issue
Block a user