Skip to content

Commit

Permalink
Merge pull request #200 from noties/v4.2.2
Browse files Browse the repository at this point in the history
V4.2.2
  • Loading branch information
noties committed Feb 26, 2020
2 parents c939c0f + 047ff86 commit 8d3f0e9
Show file tree
Hide file tree
Showing 11 changed files with 357 additions and 17 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

# 4.2.2
* Fixed `AsyncDrawable` display when it has placeholder with empty bounds ([#189])
* Fixed `syntax-highlight` where code input is empty string ([#192])
* Add `appendFactory`/`prependFactory` in `MarkwonSpansFactory.Builder` for more explicit `SpanFactory` ordering ([#193])

[#189]: https://github.com/noties/Markwon/issues/189
[#192]: https://github.com/noties/Markwon/issues/192
[#193]: https://github.com/noties/Markwon/issues/193

# 4.2.1
* Fix SpannableBuilder `subSequence` method
* Introduce Nougat check in `BulletListItemSpan` to position bullet (for bullets to be
Expand Down
23 changes: 22 additions & 1 deletion docs/docs/v4/core/spans-factory.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ builder.setFactory(Link.class, new SpanFactory() {

---

Since <Badge text="3.0.1" /> you can _add_ multiple `SpanFactory` for a single node:
:::warning
Deprecated in <Badge text="4.2.2" type="error" vertical="middle" />. Use `appendFactory` or `prependFactory` for
more explicit factories ordering. `addFactories` behaves like new `prependFactory` method.
:::

Since <Badge text="3.0.1" /><Badge text="4.2.2" type="error" /> you can _add_ multiple `SpanFactory` for a single node:

```java
final Markwon markwon = Markwon.builder(context)
Expand All @@ -81,6 +86,22 @@ final Markwon markwon = Markwon.builder(context)
.build();
```

## appendFactory/prependFactory <Badge text="4.2.2" />

* use `appendFactory` if you wish to add a factory **after** original (can be used to post-process original factory)
* use `prependFactory` if you wish to add a factory **before** original (original factory will be applied after this one)

```java
@Override
public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {
// `RemoveUnderlineSpan` will be added AFTER original, thus it will remove underline applied by original
builder.appendFactory(Link.class, (configuration, props) -> new RemoveUnderlineSpan());

// will be added BEFORE origin (origin can override this)
builder.prependFactory(Link.class, (configuration, props) -> new AbsoluteSizeSpan(48, true));
}
```

---

If you wish to inspect existing factory you can use:
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ android.enableJetifier=true
android.enableBuildCache=true
android.buildCacheDir=build/pre-dex-cache

VERSION_NAME=4.2.1
VERSION_NAME=4.2.2

GROUP=io.noties.markwon
POM_DESCRIPTION=Markwon markdown for Android
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,34 @@ interface Builder {
* {@link SpanFactory} with the specified one.
*
* @since 3.0.1
* @deprecated 4.2.2 consider using {@link #appendFactory(Class, SpanFactory)} or
* {@link #prependFactory(Class, SpanFactory)} methods for more explicit factory ordering.
* `addFactory` behaved like {@link #prependFactory(Class, SpanFactory)}, so
* this method call can be replaced with it
*/
@NonNull
@Deprecated
<N extends Node> Builder addFactory(@NonNull Class<N> node, @NonNull SpanFactory factory);

/**
* Append a factory to existing one (or make the first one for specified node). Specified factory
* will be called <strong>after</strong> original (if present) factory. Can be used to
* <em>change</em> behavior or original span factory.
*
* @since 4.2.2
*/
@NonNull
<N extends Node> Builder appendFactory(@NonNull Class<N> node, @NonNull SpanFactory factory);

/**
* Prepend a factory to existing one (or make the first one for specified node). Specified factory
* will be called <string>before</string> original (if present) factory.
*
* @since 4.2.2
*/
@NonNull
<N extends Node> Builder prependFactory(@NonNull Class<N> node, @NonNull SpanFactory factory);

/**
* Can be useful when <em>enhancing</em> an already defined SpanFactory with another one.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,32 @@ public <N extends Node> Builder setFactory(@NonNull Class<N> node, @Nullable Spa

@NonNull
@Override
@Deprecated
public <N extends Node> Builder addFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {
return prependFactory(node, factory);
}

@NonNull
@Override
public <N extends Node> Builder appendFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {
final SpanFactory existing = factories.get(node);
if (existing == null) {
factories.put(node, factory);
} else {
if (existing instanceof CompositeSpanFactory) {
((CompositeSpanFactory) existing).factories.add(0, factory);
} else {
final CompositeSpanFactory compositeSpanFactory =
new CompositeSpanFactory(factory, existing);
factories.put(node, compositeSpanFactory);
}
}
return this;
}

@NonNull
@Override
public <N extends Node> Builder prependFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {
// if there is no factory registered for this node -> just add it
final SpanFactory existing = factories.get(node);
if (existing == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,20 +164,44 @@ public void setCallback2(@Nullable Callback cb) {
@SuppressWarnings("WeakerAccess")
protected void setPlaceholderResult(@NonNull Drawable placeholder) {
// okay, if placeholder has bounds -> use it, otherwise use original imageSize
// it's important to NOT pass to imageSizeResolver when placeholder has bounds
// this is done, so actual result and placeholder can have _different_
// bounds. Assume image is loaded with HTML and has ImageSize width=100%,
// so, even if placeholder has exact bounds, it will still be scaled up.

// this condition should not be true for placeholder (at least for now)
// (right now this method is always called from constructor)
if (result != null) {
// but it is, unregister current result
result.setCallback(null);
}

final Rect rect = placeholder.getBounds();

if (rect.isEmpty()) {
// if bounds are empty -> just use placeholder as a regular result
DrawableUtils.applyIntrinsicBounds(placeholder);
// check for intrinsic bounds
final Rect intrinsic = DrawableUtils.intrinsicBounds(placeholder);
if (intrinsic.isEmpty()) {
// @since 4.2.2
// if intrinsic bounds are empty, use _any_ non-empty bounds,
// they must be non-empty so when result is obtained - proper invalidation will occur
// (0, 0, 1, 0) is still considered empty
placeholder.setBounds(0, 0, 1, 1);
} else {
// use them
placeholder.setBounds(intrinsic);
}

// it is very important (if we have a placeholder) to set own bounds to it (and they must not be empty
// otherwise result won't be rendered)
// @since 4.2.2
setBounds(placeholder.getBounds());
setResult(placeholder);

} else {

// this condition should not be true for placeholder (at least for now)
if (result != null) {
// but it is, unregister current result
result.setCallback(null);
}
// this method is not the same as above, as we do not want to trigger image-size-resolver
// in case when placeholder has exact bounds

// placeholder has bounds specified -> use them until we have real result
this.result = placeholder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public void composite_span_factory() {
}

@Test
@Deprecated
public void builder_add_factory() {
// here is what we should validate:
// * if we call addFactory and there is none already -> supplied factory
Expand Down Expand Up @@ -146,4 +147,74 @@ public void builder_add_factory() {
assertEquals(compositeSpanFactory, builder.getFactory(node));
assertEquals(Arrays.asList(first, second, third), compositeSpanFactory.factories);
}

@Test
public void builder_prepend_factory() {
// here is what we should validate:
// * if we call prependFactory and there is none already -> supplied factory
// * if there is
// * * if not composite -> make composite
// * * if composite -> add to it

final MarkwonSpansFactoryImpl.BuilderImpl builder = new MarkwonSpansFactoryImpl.BuilderImpl();

final SpanFactory first = mock(SpanFactory.class);
final SpanFactory second = mock(SpanFactory.class);
final SpanFactory third = mock(SpanFactory.class);

final Class<Node> node = Node.class;

// assert none yet
assertNull(builder.getFactory(node));

// add first, none yet -> it should be added without modifications
builder.prependFactory(node, first);
assertEquals(first, builder.getFactory(node));

// add second -> composite factory will be created
builder.prependFactory(node, second);
final MarkwonSpansFactoryImpl.CompositeSpanFactory compositeSpanFactory =
(MarkwonSpansFactoryImpl.CompositeSpanFactory) builder.getFactory(node);
assertNotNull(compositeSpanFactory);
assertEquals(Arrays.asList(first, second), compositeSpanFactory.factories);

builder.prependFactory(node, third);
assertEquals(compositeSpanFactory, builder.getFactory(node));
assertEquals(Arrays.asList(first, second, third), compositeSpanFactory.factories);
}

@Test
public void builder_append_factory() {
// here is what we should validate:
// * if we call appendFactory and there is none already -> supplied factory
// * if there is
// * * if not composite -> make composite
// * * if composite -> add to it

final MarkwonSpansFactoryImpl.BuilderImpl builder = new MarkwonSpansFactoryImpl.BuilderImpl();

final SpanFactory first = mock(SpanFactory.class);
final SpanFactory second = mock(SpanFactory.class);
final SpanFactory third = mock(SpanFactory.class);

final Class<Node> node = Node.class;

// assert none yet
assertNull(builder.getFactory(node));

// add first, none yet -> it should be added without modifications
builder.appendFactory(node, first);
assertEquals(first, builder.getFactory(node));

// add second -> composite factory will be created
builder.appendFactory(node, second);
final MarkwonSpansFactoryImpl.CompositeSpanFactory compositeSpanFactory =
(MarkwonSpansFactoryImpl.CompositeSpanFactory) builder.getFactory(node);
assertNotNull(compositeSpanFactory);
assertEquals(Arrays.asList(second, first), compositeSpanFactory.factories);

builder.appendFactory(node, third);
assertEquals(compositeSpanFactory, builder.getFactory(node));
assertEquals(Arrays.asList(third, second, first), compositeSpanFactory.factories);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,18 @@ public <N extends Node> MarkwonSpansFactory.Builder addFactory(@NonNull Class<N>
throw new RuntimeException();
}

@NonNull
@Override
public <N extends Node> MarkwonSpansFactory.Builder appendFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {
throw new RuntimeException();
}

@NonNull
@Override
public <N extends Node> MarkwonSpansFactory.Builder prependFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {
throw new RuntimeException();
}

@Nullable
@Override
public <N extends Node> SpanFactory getFactory(@NonNull Class<N> node) {
Expand Down

0 comments on commit 8d3f0e9

Please sign in to comment.