Skip to content

Commit 7701b32

Browse files
committed
Use AlignmentApproach with list spans
1 parent d2d8a5d commit 7701b32

File tree

8 files changed

+122
-33
lines changed

8 files changed

+122
-33
lines changed

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,21 @@ import org.wordpress.aztec.plugins.html2visual.IHtmlTagHandler
3131
import org.wordpress.aztec.spans.AztecAudioSpan
3232
import org.wordpress.aztec.spans.AztecHorizontalRuleSpan
3333
import org.wordpress.aztec.spans.AztecImageSpan
34-
import org.wordpress.aztec.spans.AztecListItemSpan
3534
import org.wordpress.aztec.spans.AztecMediaClickableSpan
3635
import org.wordpress.aztec.spans.AztecMediaSpan
37-
import org.wordpress.aztec.spans.AztecOrderedListSpan
38-
import org.wordpress.aztec.spans.AztecQuoteSpan
3936
import org.wordpress.aztec.spans.AztecStrikethroughSpan
40-
import org.wordpress.aztec.spans.AztecUnorderedListSpan
4137
import org.wordpress.aztec.spans.AztecVideoSpan
4238
import org.wordpress.aztec.spans.HiddenHtmlSpan
4339
import org.wordpress.aztec.spans.IAztecAttributedSpan
4440
import org.wordpress.aztec.spans.IAztecNestable
4541
import org.wordpress.aztec.spans.createAztecQuoteSpan
4642
import org.wordpress.aztec.spans.createHeadingSpan
4743
import org.wordpress.aztec.spans.createHiddenHtmlBlockSpan
44+
import org.wordpress.aztec.spans.createListItemSpan
45+
import org.wordpress.aztec.spans.createOrderedListSpan
4846
import org.wordpress.aztec.spans.createParagraphSpan
4947
import org.wordpress.aztec.spans.createPreformatSpan
48+
import org.wordpress.aztec.spans.createUnorderedListSpan
5049
import org.wordpress.aztec.util.getLast
5150
import org.xml.sax.Attributes
5251
import java.util.ArrayList
@@ -74,7 +73,8 @@ class AztecTagHandler(val context: Context, val plugins: List<IAztecPlugin> = Ar
7473

7574
when (tag.toLowerCase()) {
7675
LIST_LI -> {
77-
handleElement(output, opening, AztecListItemSpan(nestingLevel, AztecAttributes(attributes)))
76+
val span = createListItemSpan(nestingLevel, alignmentApproach, AztecAttributes(attributes))
77+
handleElement(output, opening, span)
7878
return true
7979
}
8080
STRIKETHROUGH_S, STRIKETHROUGH_STRIKE, STRIKETHROUGH_DEL -> {
@@ -91,11 +91,11 @@ class AztecTagHandler(val context: Context, val plugins: List<IAztecPlugin> = Ar
9191
return true
9292
}
9393
LIST_UL -> {
94-
handleElement(output, opening, AztecUnorderedListSpan(nestingLevel, AztecAttributes(attributes)))
94+
handleElement(output, opening, createUnorderedListSpan(nestingLevel, alignmentApproach, AztecAttributes(attributes)))
9595
return true
9696
}
9797
LIST_OL -> {
98-
handleElement(output, opening, AztecOrderedListSpan(nestingLevel, AztecAttributes(attributes)))
98+
handleElement(output, opening, createOrderedListSpan(nestingLevel, alignmentApproach, AztecAttributes(attributes)))
9999
return true
100100
}
101101
BLOCKQUOTE -> {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
605605
BlockElementWatcher(this)
606606
.add(HeadingHandler(alignmentApproach))
607607
.add(ListHandler())
608-
.add(ListItemHandler())
608+
.add(ListItemHandler(alignmentApproach))
609609
.add(QuoteHandler())
610610
.add(PreformatHandler())
611611
.install(this)

aztec/src/main/kotlin/org/wordpress/aztec/formatting/BlockFormatter.kt

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ import org.wordpress.aztec.spans.IAztecNestable
2929
import org.wordpress.aztec.spans.ParagraphSpan
3030
import org.wordpress.aztec.spans.createAztecQuoteSpan
3131
import org.wordpress.aztec.spans.createHeadingSpan
32+
import org.wordpress.aztec.spans.createListItemSpan
33+
import org.wordpress.aztec.spans.createOrderedListSpan
3234
import org.wordpress.aztec.spans.createParagraphSpan
3335
import org.wordpress.aztec.spans.createPreformatSpan
36+
import org.wordpress.aztec.spans.createUnorderedListSpan
3437
import org.wordpress.aztec.util.SpanWrapper
3538
import java.util.Arrays
3639
import kotlin.reflect.KClass
@@ -251,7 +254,7 @@ class BlockFormatter(editor: AztecText,
251254
// when removing style from multiple selected lines, if the last selected line is empty
252255
// or at the end of editor the selection wont include the trailing newline/EOB marker
253256
// that will leave us with orphan <li> tag, so we need to shift index to the right
254-
val hasLingeringEmptyListItem = spanType.isAssignableFrom(AztecListItemSpan::class.java)
257+
val hasLingeringEmptyListItem = AztecListItemSpan::class.java.isAssignableFrom(spanType)
255258
&& editableText.length > end
256259
&& (editableText[end] == '\n' || editableText[end] == Constants.END_OF_BUFFER_MARKER)
257260

@@ -294,8 +297,8 @@ class BlockFormatter(editor: AztecText,
294297
// TODO: Come up with a better way to init spans and get their classes (all the "make" methods)
295298
fun makeBlock(textFormat: ITextFormat, nestingLevel: Int, attrs: AztecAttributes = AztecAttributes()): List<IAztecBlockSpan> {
296299
when (textFormat) {
297-
AztecTextFormat.FORMAT_ORDERED_LIST -> return Arrays.asList(AztecOrderedListSpan(nestingLevel, attrs, listStyle), AztecListItemSpan(nestingLevel + 1))
298-
AztecTextFormat.FORMAT_UNORDERED_LIST -> return Arrays.asList(AztecUnorderedListSpan(nestingLevel, attrs, listStyle), AztecListItemSpan(nestingLevel + 1))
300+
AztecTextFormat.FORMAT_ORDERED_LIST -> return Arrays.asList(createOrderedListSpan(nestingLevel, alignmentApproach, attrs, listStyle), createListItemSpan(nestingLevel + 1, alignmentApproach))
301+
AztecTextFormat.FORMAT_UNORDERED_LIST -> return Arrays.asList(createUnorderedListSpan(nestingLevel, alignmentApproach, attrs, listStyle), createListItemSpan(nestingLevel + 1, alignmentApproach))
299302
AztecTextFormat.FORMAT_QUOTE -> return Arrays.asList(createAztecQuoteSpan(nestingLevel, attrs, alignmentApproach, quoteStyle))
300303
AztecTextFormat.FORMAT_HEADING_1,
301304
AztecTextFormat.FORMAT_HEADING_2,
@@ -339,9 +342,9 @@ class BlockFormatter(editor: AztecText,
339342
private fun <T : KClass<out IAztecBlockSpan>> makeBlockSpan(type: T, textFormat: ITextFormat, nestingLevel: Int, attrs: AztecAttributes = AztecAttributes()): IAztecBlockSpan {
340343
val typeIsAssignableTo = { clazz: KClass<out Any> -> clazz.java.isAssignableFrom(type.java) }
341344
return when {
342-
typeIsAssignableTo(AztecOrderedListSpan::class) -> AztecOrderedListSpan(nestingLevel, attrs, listStyle)
343-
typeIsAssignableTo(AztecUnorderedListSpan::class) -> AztecUnorderedListSpan(nestingLevel, attrs, listStyle)
344-
typeIsAssignableTo(AztecListItemSpan::class) -> AztecListItemSpan(nestingLevel, attrs)
345+
typeIsAssignableTo(AztecOrderedListSpan::class) -> createOrderedListSpan(nestingLevel, alignmentApproach, attrs, listStyle)
346+
typeIsAssignableTo(AztecUnorderedListSpan::class) -> createUnorderedListSpan(nestingLevel, alignmentApproach, attrs, listStyle)
347+
typeIsAssignableTo(AztecListItemSpan::class) -> createListItemSpan(nestingLevel, alignmentApproach, attrs)
345348
typeIsAssignableTo(AztecQuoteSpan::class) -> createAztecQuoteSpan(nestingLevel, attrs, alignmentApproach, quoteStyle)
346349
typeIsAssignableTo(AztecHeadingSpan::class) -> createHeadingSpan(nestingLevel, textFormat, attrs, alignmentApproach, headerStyle)
347350
typeIsAssignableTo(AztecPreformatSpan::class) -> createPreformatSpan(nestingLevel, alignmentApproach, attrs, preformatStyle)
@@ -651,7 +654,7 @@ class BlockFormatter(editor: AztecText,
651654
BlockHandler.set(editableText, listSpan, start, end)
652655
// special case for styling single empty lines
653656
if (end - start == 1 && (editableText[end - 1] == '\n' || editableText[end - 1] == Constants.END_OF_BUFFER_MARKER)) {
654-
ListItemHandler.newListItem(editableText, start, end, listSpan.nestingLevel + 1)
657+
ListItemHandler.newListItem(editableText, start, end, listSpan.nestingLevel + 1, alignmentApproach)
655658
} else {
656659
val listEnd = if (end == editableText.length) end else end - 1
657660
val listContent = editableText.substring(start, listEnd)
@@ -666,7 +669,12 @@ class BlockFormatter(editor: AztecText,
666669
if ((start + it) != editableText.length) it + 1 else it // include the newline or not
667670
}
668671

669-
ListItemHandler.newListItem(editableText, start + lineStart, start + lineEnd, listSpan.nestingLevel + 1)
672+
ListItemHandler.newListItem(
673+
editableText,
674+
start + lineStart,
675+
start + lineEnd,
676+
listSpan.nestingLevel + 1,
677+
alignmentApproach)
670678
}
671679
}
672680
}

aztec/src/main/kotlin/org/wordpress/aztec/handlers/ListItemHandler.kt

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
package org.wordpress.aztec.handlers
22

33
import android.text.Spannable
4+
import org.wordpress.aztec.AlignmentApproach
45
import org.wordpress.aztec.spans.AztecListItemSpan
56
import org.wordpress.aztec.spans.IAztecNestable
7+
import org.wordpress.aztec.spans.createListItemSpan
68
import org.wordpress.aztec.watchers.TextDeleter
79

8-
class ListItemHandler : BlockHandler<AztecListItemSpan>(AztecListItemSpan::class.java) {
10+
class ListItemHandler(
11+
val alignmentApproach: AlignmentApproach
12+
) : BlockHandler<AztecListItemSpan>(AztecListItemSpan::class.java) {
913

1014
override fun handleNewlineAtStartOfBlock() {
1115
// newline added at start of bullet so, add a new bullet
12-
newListItem(text, newlineIndex, newlineIndex + 1, block.span.nestingLevel)
16+
newListItem(text, newlineIndex, newlineIndex + 1, block.span.nestingLevel, alignmentApproach)
1317

1418
// push current bullet forward
1519
block.start = newlineIndex + 1
@@ -51,7 +55,7 @@ class ListItemHandler : BlockHandler<AztecListItemSpan>(AztecListItemSpan::class
5155
newListItemStart = newlineIndex
5256
}
5357

54-
newListItem(text, newListItemStart, block.end, block.span.nestingLevel)
58+
newListItem(text, newListItemStart, block.end, block.span.nestingLevel, alignmentApproach)
5559
block.end = newListItemStart
5660
}
5761

@@ -62,16 +66,22 @@ class ListItemHandler : BlockHandler<AztecListItemSpan>(AztecListItemSpan::class
6266
}
6367

6468
// attach a new bullet around the end-of-text marker
65-
newListItem(text, markerIndex, markerIndex + 1, block.span.nestingLevel)
69+
newListItem(text, markerIndex, markerIndex + 1, block.span.nestingLevel, alignmentApproach)
6670

6771
// the current list item has bled over to the marker so, let's adjust its range to just before the marker.
6872
// There's a newline there hopefully :)
6973
block.end = markerIndex
7074
}
7175

7276
companion object {
73-
fun newListItem(text: Spannable, start: Int, end: Int, nestingLevel: Int) {
74-
set(text, AztecListItemSpan(nestingLevel), start, end)
77+
fun newListItem(
78+
text: Spannable,
79+
start: Int,
80+
end: Int,
81+
nestingLevel: Int,
82+
alignmentApproach: AlignmentApproach
83+
) {
84+
set(text, createListItemSpan(nestingLevel, alignmentApproach), start, end)
7585
}
7686
}
7787
}
Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,36 @@
11
package org.wordpress.aztec.spans
22

33
import android.text.Layout
4+
import org.wordpress.aztec.AlignmentApproach
45
import org.wordpress.aztec.AztecAttributes
56

6-
class AztecListItemSpan(override var nestingLevel: Int,
7-
override var attributes: AztecAttributes = AztecAttributes(),
8-
override var align: Layout.Alignment? = null
9-
) : IAztecAlignmentSpan, IAztecCompositeBlockSpan {
7+
fun createListItemSpan(nestingLevel: Int,
8+
alignmentApproach: AlignmentApproach,
9+
attributes: AztecAttributes = AztecAttributes()) : IAztecBlockSpan =
10+
when (alignmentApproach) {
11+
AlignmentApproach.SPAN_LEVEL -> AztecListItemSpanAligned(nestingLevel, attributes, null)
12+
AlignmentApproach.VIEW_LEVEL -> AztecListItemSpan(nestingLevel, attributes)
13+
}
14+
15+
/**
16+
* We need to have two classes for handling alignment at either the Span-level (ListItemSpanAligned)
17+
* or the View-level (ListItemSpan). IAztecAlignment implements AlignmentSpan, which has a
18+
* getAlignment method that returns a non-null Layout.Alignment. The Android system checks for
19+
* AlignmentSpans and, if present, overrides the view's gravity with their value. Having a class
20+
* that does not implement AlignmentSpan allows the view's gravity to control. These classes should
21+
* be created using the createListItemSpan(...) methods.
22+
*/
23+
open class AztecListItemSpan(
24+
override var nestingLevel: Int,
25+
override var attributes: AztecAttributes) : IAztecCompositeBlockSpan {
1026
override val TAG = "li"
1127

1228
override var endBeforeBleed: Int = -1
1329
override var startBeforeCollapse: Int = -1
1430
}
31+
32+
class AztecListItemSpanAligned(
33+
nestingLevel: Int,
34+
attributes: AztecAttributes,
35+
override var align: Layout.Alignment?
36+
) : AztecListItemSpan(nestingLevel, attributes), IAztecAlignmentSpan

aztec/src/main/kotlin/org/wordpress/aztec/spans/AztecListSpan.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
package org.wordpress.aztec.spans
22

33
import android.graphics.Paint
4-
import android.text.Layout
54
import android.text.Spanned
65
import android.text.style.LeadingMarginSpan
76
import android.text.style.LineHeightSpan
87
import android.text.style.UpdateLayout
98
import org.wordpress.aztec.Constants
109

1110
abstract class AztecListSpan(override var nestingLevel: Int,
12-
var verticalPadding: Int = 0,
13-
override var align: Layout.Alignment? = null
14-
) : LeadingMarginSpan.Standard(0),
11+
var verticalPadding: Int = 0
12+
) : LeadingMarginSpan.Standard(0),
1513
LineHeightSpan,
1614
UpdateLayout,
17-
IAztecAlignmentSpan,
1815
IAztecBlockSpan {
1916
override var endBeforeBleed: Int = -1
2017
override var startBeforeCollapse: Int = -1

aztec/src/main/kotlin/org/wordpress/aztec/spans/AztecOrderedListSpan.kt

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,36 @@ import android.graphics.Canvas
2121
import android.graphics.Paint
2222
import android.text.Layout
2323
import android.text.Spanned
24+
import org.wordpress.aztec.AlignmentApproach
2425
import org.wordpress.aztec.AztecAttributes
2526
import org.wordpress.aztec.formatting.BlockFormatter
2627

27-
class AztecOrderedListSpan(
28+
fun createOrderedListSpan(
29+
nestingLevel: Int,
30+
alignmentApproach: AlignmentApproach,
31+
attributes: AztecAttributes = AztecAttributes(),
32+
listStyle: BlockFormatter.ListStyle = BlockFormatter.ListStyle(0, 0, 0, 0, 0)
33+
) = when (alignmentApproach) {
34+
AlignmentApproach.SPAN_LEVEL -> AztecOrderedListSpanAligned(nestingLevel, attributes, listStyle, null)
35+
AlignmentApproach.VIEW_LEVEL -> AztecOrderedListSpan(nestingLevel, attributes, listStyle)
36+
}
37+
38+
/**
39+
* We need to have two classes for handling alignment at either the Span-level (AztecOrderedListSpanAligned)
40+
* or the View-level (AztecOrderedListSpan). IAztecAlignment implements AlignmentSpan, which has a
41+
* getAlignment method that returns a non-null Layout.Alignment. The Android system checks for
42+
* AlignmentSpans and, if present, overrides the view's gravity with their value. Having a class
43+
* that does not implement AlignmentSpan allows the view's gravity to control. These classes should
44+
* be created using the createOrderedListSpan(...) methods.
45+
*/
46+
class AztecOrderedListSpanAligned(
47+
nestingLevel: Int,
48+
attributes: AztecAttributes = AztecAttributes(),
49+
listStyle: BlockFormatter.ListStyle = BlockFormatter.ListStyle(0, 0, 0, 0, 0),
50+
override var align: Layout.Alignment?
51+
) : AztecOrderedListSpan(nestingLevel, attributes, listStyle), IAztecAlignmentSpan
52+
53+
open class AztecOrderedListSpan(
2854
override var nestingLevel: Int,
2955
override var attributes: AztecAttributes = AztecAttributes(),
3056
var listStyle: BlockFormatter.ListStyle = BlockFormatter.ListStyle(0, 0, 0, 0, 0)

aztec/src/main/kotlin/org/wordpress/aztec/spans/AztecUnorderedListSpan.kt

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,36 @@ import android.graphics.Canvas
2121
import android.graphics.Paint
2222
import android.text.Layout
2323
import android.text.Spanned
24+
import org.wordpress.aztec.AlignmentApproach
2425
import org.wordpress.aztec.AztecAttributes
2526
import org.wordpress.aztec.formatting.BlockFormatter
2627

27-
class AztecUnorderedListSpan(
28+
fun createUnorderedListSpan(
29+
nestingLevel: Int,
30+
alignmentApproach: AlignmentApproach,
31+
attributes: AztecAttributes = AztecAttributes(),
32+
listStyle: BlockFormatter.ListStyle = BlockFormatter.ListStyle(0, 0, 0, 0, 0)
33+
) = when (alignmentApproach) {
34+
AlignmentApproach.SPAN_LEVEL -> AztecUnorderedListSpanAligned(nestingLevel, attributes, listStyle, null)
35+
AlignmentApproach.VIEW_LEVEL -> AztecUnorderedListSpan(nestingLevel, attributes, listStyle)
36+
}
37+
38+
/**
39+
* We need to have two classes for handling alignment at either the Span-level (AztecUnorderedListSpanAligned)
40+
* or the View-level (AztecUnorderedListSpan). IAztecAlignment implements AlignmentSpan, which has a
41+
* getAlignment method that returns a non-null Layout.Alignment. The Android system checks for
42+
* AlignmentSpans and, if present, overrides the view's gravity with their value. Having a class
43+
* that does not implement AlignmentSpan allows the view's gravity to control. These classes should
44+
* be created using the createUnorderedListSpan(...) methods.
45+
*/
46+
class AztecUnorderedListSpanAligned(
47+
nestingLevel: Int,
48+
attributes: AztecAttributes = AztecAttributes(),
49+
listStyle: BlockFormatter.ListStyle = BlockFormatter.ListStyle(0, 0, 0, 0, 0),
50+
override var align: Layout.Alignment?
51+
) : AztecUnorderedListSpan(nestingLevel, attributes, listStyle), IAztecAlignmentSpan
52+
53+
open class AztecUnorderedListSpan(
2854
override var nestingLevel: Int,
2955
override var attributes: AztecAttributes = AztecAttributes(),
3056
var listStyle: BlockFormatter.ListStyle = BlockFormatter.ListStyle(0, 0, 0, 0, 0)

0 commit comments

Comments
 (0)