Skip to content

Commit fb0a10b

Browse files
authored
Merge pull request #913 from wordpress-mobile/release/v.1.3.43
Release/v.1.3.43
2 parents 81f0b77 + 74ff130 commit fb0a10b

39 files changed

+642
-204
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Changelog
22

3+
## [1.3.43](https://github.com/wordpress-mobile/AztecEditor-Android/releases/tag/v1.3.43)
4+
### Changed
5+
- Fixed the add image icon in Aztec Toolbar (#908)
6+
7+
## [1.3.42](https://github.com/wordpress-mobile/AztecEditor-Android/releases/tag/v1.3.42)
8+
### Changed
9+
- Update block-based span classes to allow view level alignment rendering (#899)
10+
11+
## [1.3.41](https://github.com/wordpress-mobile/AztecEditor-Android/releases/tag/v1.3.41)
12+
### Changed
13+
- Add option to disable collapsing of whitespaces
14+
315
## [1.3.40](https://github.com/wordpress-mobile/AztecEditor-Android/releases/tag/v1.3.40)
416
### Changed
517
- Adds support to to customise styles for the Aztec Toolbar

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ repositories {
105105
```
106106
```gradle
107107
dependencies {
108-
api ('com.github.wordpress-mobile.WordPress-Aztec-Android:aztec:v1.3.40')
108+
api ('com.github.wordpress-mobile.WordPress-Aztec-Android:aztec:v1.3.43')
109109
}
110110
```
111111

aztec/src/main/java/org/wordpress/aztec/Html.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public static Spanned fromHtml(String source,
154154
Context context,
155155
List<IAztecPlugin> plugins,
156156
List<String> ignoredTags) {
157-
return fromHtml(source, null, context, plugins, ignoredTags);
157+
return fromHtml(source, null, context, plugins, ignoredTags, true);
158158
}
159159

160160
/**
@@ -176,7 +176,8 @@ private static class HtmlParser {
176176
* <p>This uses TagSoup to handle real HTML, including all of the brokenness found in the wild.
177177
*/
178178
public static Spanned fromHtml(String source, TagHandler tagHandler,
179-
Context context, List<IAztecPlugin> plugins, List<String> ignoredTags) {
179+
Context context, List<IAztecPlugin> plugins,
180+
List<String> ignoredTags, boolean shouldIgnoreWhitespace) {
180181

181182
Parser parser = new Parser();
182183
try {
@@ -195,7 +196,13 @@ public static Spanned fromHtml(String source, TagHandler tagHandler,
195196
source = preprocessSource(source, plugins);
196197

197198
HtmlToSpannedConverter converter =
198-
new HtmlToSpannedConverter(source, tagHandler, parser, context, plugins, ignoredTags);
199+
new HtmlToSpannedConverter(source,
200+
tagHandler,
201+
parser,
202+
context,
203+
plugins,
204+
ignoredTags,
205+
shouldIgnoreWhitespace);
199206

200207
return converter.convert();
201208
}
@@ -238,18 +245,21 @@ class HtmlToSpannedConverter implements org.xml.sax.ContentHandler, LexicalHandl
238245
private Html.TagHandler tagHandler;
239246
private Context context;
240247
private List<String> ignoredTags;
248+
private boolean shouldIgnoreWhitespace;
241249

242250
public HtmlToSpannedConverter(
243251
String source, Html.TagHandler tagHandler,
244252
Parser parser,
245-
Context context, List<IAztecPlugin> plugins, List<String> ignoredTags) {
253+
Context context, List<IAztecPlugin> plugins,
254+
List<String> ignoredTags, boolean shouldIgnoreWhitespace) {
246255
this.source = source;
247256
this.plugins = plugins;
248257
this.spannableStringBuilder = new SpannableStringBuilder();
249258
this.tagHandler = tagHandler;
250259
this.reader = parser;
251260
this.context = context;
252261
this.ignoredTags = ignoredTags;
262+
this.shouldIgnoreWhitespace = shouldIgnoreWhitespace;
253263
}
254264

255265
public Spanned convert() {
@@ -718,6 +728,12 @@ public void characters(char ch[], int start, int length) throws SAXException {
718728
char c = ch[i + start];
719729

720730
if (!insidePreTag && !insideCodeTag && c == ' ' || c == '\n') {
731+
732+
if (c == ' ' && !shouldIgnoreWhitespace) {
733+
sb.append(c);
734+
continue;
735+
}
736+
721737
char pred;
722738
int len = sb.length();
723739

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.wordpress.aztec
2+
3+
/**
4+
* With [SPAN_LEVEL] any alignment must be specified at the span level. Importantly, this
5+
* means that the View's gravity will always be ignored in determining the rendering of
6+
* the text's alignment.
7+
*
8+
* With [VIEW_LEVEL] alignment, the rendering of alignment is determined by the View's gravity.
9+
* Note that it is not possible to update the underlying alignment using [AztecText.toggleFormatting]
10+
* when you are using [VIEW_LEVEL] alignment rendering.
11+
*/
12+
enum class AlignmentRendering { SPAN_LEVEL, VIEW_LEVEL }

aztec/src/main/kotlin/org/wordpress/aztec/AztecParser.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ import java.util.ArrayList
5757
import java.util.Collections
5858
import java.util.Comparator
5959

60-
class AztecParser @JvmOverloads constructor(val plugins: List<IAztecPlugin> = listOf(),
60+
class AztecParser @JvmOverloads constructor(private val alignmentRendering: AlignmentRendering,
61+
val plugins: List<IAztecPlugin> = listOf(),
6162
private val ignoredTags: List<String> = listOf("body", "html")) {
6263
/**
6364
* A faster version of fromHtml(), intended for inspecting the span structure only. It doesn't prepare the text for
@@ -68,18 +69,21 @@ class AztecParser @JvmOverloads constructor(val plugins: List<IAztecPlugin> = li
6869
val tidySource = tidy(source)
6970

7071
val spanned = SpannableString(Html.fromHtml(tidySource,
71-
AztecTagHandler(context, plugins), context, plugins, ignoredTags))
72+
AztecTagHandler(context, plugins, alignmentRendering), context, plugins, ignoredTags, true))
7273

7374
postprocessSpans(spanned)
7475

7576
return spanned
7677
}
7778

78-
fun fromHtml(source: String, context: Context, shouldSkipTidying: Boolean = false): Spanned {
79+
fun fromHtml(source: String,
80+
context: Context,
81+
shouldSkipTidying: Boolean = false,
82+
shouldIgnoreWhitespace: Boolean = true): Spanned {
7983
val tidySource = if (shouldSkipTidying) source else tidy(source)
8084

8185
val spanned = SpannableStringBuilder(Html.fromHtml(tidySource,
82-
AztecTagHandler(context, plugins), context, plugins, ignoredTags))
86+
AztecTagHandler(context, plugins, alignmentRendering), context, plugins, ignoredTags, shouldIgnoreWhitespace))
8387

8488
addVisualNewlinesToBlockElements(spanned)
8589
markBlockElementsAsParagraphs(spanned)

aztec/src/main/kotlin/org/wordpress/aztec/AztecTagHandler.kt

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,28 +29,30 @@ import androidx.appcompat.content.res.AppCompatResources
2929
import org.wordpress.aztec.plugins.IAztecPlugin
3030
import org.wordpress.aztec.plugins.html2visual.IHtmlTagHandler
3131
import org.wordpress.aztec.spans.AztecAudioSpan
32-
import org.wordpress.aztec.spans.AztecHeadingSpan
3332
import org.wordpress.aztec.spans.AztecHorizontalRuleSpan
3433
import org.wordpress.aztec.spans.AztecImageSpan
35-
import org.wordpress.aztec.spans.AztecListItemSpan
3634
import org.wordpress.aztec.spans.AztecMediaClickableSpan
3735
import org.wordpress.aztec.spans.AztecMediaSpan
38-
import org.wordpress.aztec.spans.AztecOrderedListSpan
39-
import org.wordpress.aztec.spans.AztecPreformatSpan
40-
import org.wordpress.aztec.spans.AztecQuoteSpan
4136
import org.wordpress.aztec.spans.AztecStrikethroughSpan
42-
import org.wordpress.aztec.spans.AztecUnorderedListSpan
4337
import org.wordpress.aztec.spans.AztecVideoSpan
44-
import org.wordpress.aztec.spans.HiddenHtmlBlock
4538
import org.wordpress.aztec.spans.HiddenHtmlSpan
4639
import org.wordpress.aztec.spans.IAztecAttributedSpan
4740
import org.wordpress.aztec.spans.IAztecNestable
41+
import org.wordpress.aztec.spans.createAztecQuoteSpan
42+
import org.wordpress.aztec.spans.createHeadingSpan
43+
import org.wordpress.aztec.spans.createHiddenHtmlBlockSpan
44+
import org.wordpress.aztec.spans.createHiddenHtmlSpan
45+
import org.wordpress.aztec.spans.createListItemSpan
46+
import org.wordpress.aztec.spans.createOrderedListSpan
4847
import org.wordpress.aztec.spans.createParagraphSpan
48+
import org.wordpress.aztec.spans.createPreformatSpan
49+
import org.wordpress.aztec.spans.createUnorderedListSpan
4950
import org.wordpress.aztec.util.getLast
5051
import org.xml.sax.Attributes
5152
import java.util.ArrayList
5253

53-
class AztecTagHandler(val context: Context, val plugins: List<IAztecPlugin> = ArrayList()) : Html.TagHandler {
54+
class AztecTagHandler(val context: Context, val plugins: List<IAztecPlugin> = ArrayList(), private val alignmentRendering: AlignmentRendering
55+
) : Html.TagHandler {
5456
private val loadingDrawable: Drawable
5557

5658
// Simple LIFO stack to track the html tag nesting for easy reference when we need to handle the ending of a tag
@@ -72,31 +74,35 @@ class AztecTagHandler(val context: Context, val plugins: List<IAztecPlugin> = Ar
7274

7375
when (tag.toLowerCase()) {
7476
LIST_LI -> {
75-
handleElement(output, opening, AztecListItemSpan(nestingLevel, AztecAttributes(attributes)))
77+
val span = createListItemSpan(nestingLevel, alignmentRendering, AztecAttributes(attributes))
78+
handleElement(output, opening, span)
7679
return true
7780
}
7881
STRIKETHROUGH_S, STRIKETHROUGH_STRIKE, STRIKETHROUGH_DEL -> {
7982
handleElement(output, opening, AztecStrikethroughSpan(tag, AztecAttributes(attributes)))
8083
return true
8184
}
8285
SPAN -> {
83-
handleElement(output, opening, HiddenHtmlSpan(tag, AztecAttributes(attributes), nestingLevel))
86+
val span = createHiddenHtmlSpan(tag, AztecAttributes(attributes), nestingLevel, alignmentRendering)
87+
handleElement(output, opening, span)
8488
return true
8589
}
8690
DIV, FIGURE, FIGCAPTION, SECTION -> {
87-
handleElement(output, opening, HiddenHtmlBlock(tag, AztecAttributes(attributes), nestingLevel))
91+
val hiddenHtmlBlockSpan = createHiddenHtmlBlockSpan(tag, alignmentRendering, nestingLevel, AztecAttributes(attributes))
92+
handleElement(output, opening, hiddenHtmlBlockSpan)
8893
return true
8994
}
9095
LIST_UL -> {
91-
handleElement(output, opening, AztecUnorderedListSpan(nestingLevel, AztecAttributes(attributes)))
96+
handleElement(output, opening, createUnorderedListSpan(nestingLevel, alignmentRendering, AztecAttributes(attributes)))
9297
return true
9398
}
9499
LIST_OL -> {
95-
handleElement(output, opening, AztecOrderedListSpan(nestingLevel, AztecAttributes(attributes)))
100+
handleElement(output, opening, createOrderedListSpan(nestingLevel, alignmentRendering, AztecAttributes(attributes)))
96101
return true
97102
}
98103
BLOCKQUOTE -> {
99-
handleElement(output, opening, AztecQuoteSpan(nestingLevel, AztecAttributes(attributes)))
104+
val span = createAztecQuoteSpan(nestingLevel, AztecAttributes(attributes), alignmentRendering)
105+
handleElement(output, opening, span)
100106
return true
101107
}
102108
IMAGE -> {
@@ -118,7 +124,8 @@ class AztecTagHandler(val context: Context, val plugins: List<IAztecPlugin> = Ar
118124
return true
119125
}
120126
PARAGRAPH -> {
121-
handleElement(output, opening, createParagraphSpan(nestingLevel, AztecAttributes(attributes)))
127+
val paragraphSpan = createParagraphSpan(nestingLevel, alignmentRendering, AztecAttributes(attributes))
128+
handleElement(output, opening, paragraphSpan)
122129
return true
123130
}
124131
LINE -> {
@@ -133,12 +140,13 @@ class AztecTagHandler(val context: Context, val plugins: List<IAztecPlugin> = Ar
133140
return true
134141
}
135142
PREFORMAT -> {
136-
handleElement(output, opening, AztecPreformatSpan(nestingLevel, AztecAttributes(attributes)))
143+
val preformatSpan = createPreformatSpan(nestingLevel, alignmentRendering, AztecAttributes(attributes))
144+
handleElement(output, opening, preformatSpan)
137145
return true
138146
}
139147
else -> {
140148
if (tag.length == 2 && Character.toLowerCase(tag[0]) == 'h' && tag[1] >= '1' && tag[1] <= '6') {
141-
handleElement(output, opening, AztecHeadingSpan(nestingLevel, tag, AztecAttributes(attributes)))
149+
handleElement(output, opening, createHeadingSpan(nestingLevel, tag, AztecAttributes(attributes), alignmentRendering))
142150
return true
143151
}
144152
}

aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
152152

153153
val DEFAULT_IMAGE_WIDTH = 800
154154

155+
val DEFAULT_ALIGNMENT_RENDERING = AlignmentRendering.SPAN_LEVEL
156+
155157
var watchersNestingLevel: Int = 0
156158

157159
private fun getPlaceholderDrawableFromResID(context: Context, @DrawableRes drawableId: Int, maxImageWidthForVisualEditor: Int): BitmapDrawable {
@@ -248,7 +250,8 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
248250
var commentsVisible = resources.getBoolean(R.bool.comments_visible)
249251

250252
var isInCalypsoMode = true
251-
var isInGutenbergMode = false
253+
var isInGutenbergMode: Boolean = false
254+
val alignmentRendering: AlignmentRendering
252255

253256
var consumeHistoryEvent: Boolean = false
254257

@@ -334,14 +337,22 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
334337
}
335338

336339
constructor(context: Context) : super(context) {
340+
alignmentRendering = DEFAULT_ALIGNMENT_RENDERING
341+
init(null)
342+
}
343+
344+
constructor(context: Context, alignmentRendering: AlignmentRendering) : super(context) {
345+
this.alignmentRendering = alignmentRendering
337346
init(null)
338347
}
339348

340349
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
350+
alignmentRendering = DEFAULT_ALIGNMENT_RENDERING
341351
init(attrs)
342352
}
343353

344354
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
355+
alignmentRendering = DEFAULT_ALIGNMENT_RENDERING
345356
init(attrs)
346357
}
347358

@@ -416,7 +427,8 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
416427
styles.getColor(R.styleable.AztecText_preformatBackground, 0),
417428
getPreformatBackgroundAlpha(styles),
418429
styles.getColor(R.styleable.AztecText_preformatColor, 0),
419-
verticalParagraphMargin)
430+
verticalParagraphMargin),
431+
alignmentRendering
420432
)
421433

422434
linkFormatter = LinkFormatter(this, LinkFormatter.LinkStyle(styles.getColor(
@@ -591,9 +603,9 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
591603
// will have the chance to run their "beforeTextChanged" and "onTextChanged" with the same string!
592604

593605
BlockElementWatcher(this)
594-
.add(HeadingHandler())
606+
.add(HeadingHandler(alignmentRendering))
595607
.add(ListHandler())
596-
.add(ListItemHandler())
608+
.add(ListItemHandler(alignmentRendering))
597609
.add(QuoteHandler())
598610
.add(PreformatHandler())
599611
.install(this)
@@ -1118,6 +1130,10 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
11181130
return false
11191131
}
11201132

1133+
open fun shouldIgnoreWhitespace(): Boolean {
1134+
return true
1135+
}
1136+
11211137
override fun afterTextChanged(text: Editable) {
11221138
if (isTextChangedListenerDisabled()) {
11231139
subWatcherNestingLevel()
@@ -1164,11 +1180,11 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
11641180

11651181
open fun fromHtml(source: String, isInit: Boolean = true) {
11661182
val builder = SpannableStringBuilder()
1167-
val parser = AztecParser(plugins)
1183+
val parser = AztecParser(alignmentRendering, plugins)
11681184

11691185
var cleanSource = CleaningUtils.cleanNestedBoldTags(source)
11701186
cleanSource = Format.removeSourceEditorFormatting(cleanSource, isInCalypsoMode, isInGutenbergMode)
1171-
builder.append(parser.fromHtml(cleanSource, context, shouldSkipTidying()))
1187+
builder.append(parser.fromHtml(cleanSource, context, shouldSkipTidying(), shouldIgnoreWhitespace()))
11721188

11731189
Format.preProcessSpannedText(builder, isInCalypsoMode)
11741190

@@ -1309,7 +1325,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
13091325
}
13101326

13111327
private fun parseHtml(content: Spannable, withCursorTag: Boolean): String {
1312-
val parser = AztecParser(plugins)
1328+
val parser = AztecParser(alignmentRendering, plugins)
13131329
val output: SpannableStringBuilder
13141330
try {
13151331
output = SpannableStringBuilder(content)
@@ -1555,7 +1571,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
15551571
// Convert selected text to html and add it to clipboard
15561572
fun copy(editable: Editable, start: Int, end: Int) {
15571573
val selectedText = editable.subSequence(start, end)
1558-
val parser = AztecParser(plugins)
1574+
val parser = AztecParser(alignmentRendering, plugins)
15591575
val output = SpannableStringBuilder(selectedText)
15601576

15611577
clearMetaSpans(output)
@@ -1621,7 +1637,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
16211637

16221638
if (clip.itemCount > 0) {
16231639
val textToPaste = if (asPlainText) clip.getItemAt(0).coerceToText(context).toString()
1624-
else clip.getItemAt(0).coerceToHtmlText(AztecParser(plugins))
1640+
else clip.getItemAt(0).coerceToHtmlText(AztecParser(alignmentRendering, plugins))
16251641

16261642
val oldHtml = toPlainHtml().replace("<aztec_cursor>", "")
16271643
val newHtml = oldHtml.replace(Constants.REPLACEMENT_MARKER_STRING, textToPaste + "<" + AztecCursorSpan.AZTEC_CURSOR_TAG + ">")
@@ -1739,7 +1755,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
17391755
val spanStart = text.getSpanStart(unknownHtmlSpan)
17401756

17411757
val textBuilder = SpannableStringBuilder()
1742-
textBuilder.append(AztecParser(plugins).fromHtml(source.getPureHtml(), context).trim())
1758+
textBuilder.append(AztecParser(alignmentRendering, plugins).fromHtml(source.getPureHtml(), context).trim())
17431759
setSelection(spanStart)
17441760

17451761
disableTextChangedListener()

0 commit comments

Comments
 (0)