Skip to content

Commit 4bcc78e

Browse files
authored
Merge pull request #1007 from wordpress-mobile/feature/add-styling-options-to-task-list
Feature/add styling options to task list
2 parents e91ec10 + 5e98273 commit 4bcc78e

File tree

7 files changed

+62
-19
lines changed

7 files changed

+62
-19
lines changed

app/src/main/kotlin/org/wordpress/aztec/demo/MainActivity.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ open class MainActivity : AppCompatActivity(),
9090
private val UNDERLINE = "<u style=\"color:lime\">Underline</u><br>"
9191
private val STRIKETHROUGH = "<s style=\"color:#ff666666\" class=\"test\">Strikethrough</s><br>" // <s> or <strike> or <del>
9292
private val ORDERED = "<ol style=\"color:green\"><li>Ordered</li><li>should have color</li></ol>"
93+
private val TASK_LIST = "<ul type=\"task-list\">\n" +
94+
" <li><input type=\"checkbox\" class=\"task-list-item-checkbox\">Unchecked</li>\n" +
95+
" <li><input type=\"checkbox\" class=\"task-list-item-checkbox\" checked>Checked</li>\n" +
96+
"</ul>"
9397
private val ORDERED_WITH_START = "<h4>Start in 10 List:</h4>" +
9498
"<ol start=\"10\">\n" +
9599
" <li>Ten</li>\n" +
@@ -186,6 +190,7 @@ open class MainActivity : AppCompatActivity(),
186190
ITALIC +
187191
UNDERLINE +
188192
STRIKETHROUGH +
193+
TASK_LIST +
189194
ORDERED +
190195
ORDERED_WITH_START +
191196
ORDERED_REVERSED +

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
314314
var lastPressedXCoord: Int = 0
315315
var lastPressedYCoord: Int = 0
316316

317+
private lateinit var listItemStyle: BlockFormatter.ListItemStyle
318+
317319
override fun onDraw(canvas: Canvas) {
318320
plugins.filterIsInstance<IOnDrawPlugin>().forEach {
319321
it.onDraw(canvas)
@@ -452,8 +454,14 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
452454
styles.getDimensionPixelSize(R.styleable.AztecText_bulletPadding, 0),
453455
styles.getDimensionPixelSize(R.styleable.AztecText_bulletWidth, 0),
454456
verticalParagraphPadding)
457+
458+
listItemStyle = BlockFormatter.ListItemStyle(
459+
styles.getBoolean(R.styleable.AztecText_taskListStrikethroughChecked, false),
460+
styles.getColor(R.styleable.AztecText_taskListCheckedTextColor, 0))
461+
455462
blockFormatter = BlockFormatter(editor = this,
456463
listStyle = listStyle,
464+
listItemStyle = listItemStyle,
457465
quoteStyle = BlockFormatter.QuoteStyle(
458466
styles.getColor(R.styleable.AztecText_quoteBackground, 0),
459467
styles.getColor(R.styleable.AztecText_quoteColor, 0),
@@ -788,7 +796,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
788796
BlockElementWatcher(this)
789797
.add(HeadingHandler(alignmentRendering))
790798
.add(ListHandler())
791-
.add(ListItemHandler(alignmentRendering))
799+
.add(ListItemHandler(alignmentRendering, listItemStyle))
792800
.add(QuoteHandler())
793801
.add(PreformatHandler())
794802
.install(this)
@@ -1599,6 +1607,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
15991607
editable.getSpans(start, end, EndOfParagraphMarker::class.java).forEach { it.verticalPadding = verticalParagraphPadding }
16001608
editable.getSpans(start, end, AztecURLSpan::class.java).forEach { it.linkStyle = linkFormatter.linkStyle }
16011609
editable.getSpans(start, end, AztecCodeSpan::class.java).forEach { it.codeStyle = inlineFormatter.codeStyle }
1610+
editable.getSpans(start, end, AztecListItemSpan::class.java).forEach { it.listItemStyle = listItemStyle }
16021611

16031612
val imageSpans = editable.getSpans(start, end, AztecImageSpan::class.java)
16041613
imageSpans.forEach {

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import kotlin.reflect.KClass
4444

4545
class BlockFormatter(editor: AztecText,
4646
private val listStyle: ListStyle,
47+
private val listItemStyle: ListItemStyle,
4748
private val quoteStyle: QuoteStyle,
4849
private val headerStyle: HeaderStyles,
4950
private val preformatStyle: PreformatStyle,
@@ -62,6 +63,7 @@ class BlockFormatter(editor: AztecText,
6263

6364
data class QuoteStyle(val quoteBackground: Int, val quoteColor: Int, val quoteTextColor: Int, val quoteBackgroundAlpha: Float, val quoteMargin: Int, val quotePadding: Int, val quoteWidth: Int, val verticalPadding: Int)
6465
data class PreformatStyle(val preformatBackground: Int, val preformatBackgroundAlpha: Float, val preformatColor: Int, val verticalPadding: Int, val leadingMargin: Int, val preformatBorderColor: Int, val preformatBorderRadius: Int, val preformatBorderThickness: Int, val preformatTextSize: Int)
66+
data class ListItemStyle(val strikeThroughCheckedItems: Boolean, val checkedItemsTextColor: Int)
6567
data class HeaderStyles(val verticalPadding: Int, val styles: Map<AztecHeadingSpan.Heading, HeadingStyle>) {
6668
data class HeadingStyle(val fontSize: Int, val fontColor: Int)
6769
}
@@ -452,7 +454,7 @@ class BlockFormatter(editor: AztecText,
452454
return when (textFormat) {
453455
AztecTextFormat.FORMAT_ORDERED_LIST -> listOf(createOrderedListSpan(nestingLevel, alignmentRendering, attrs, listStyle), createListItemSpan(nestingLevel + 1, alignmentRendering))
454456
AztecTextFormat.FORMAT_UNORDERED_LIST -> listOf(createUnorderedListSpan(nestingLevel, alignmentRendering, attrs, listStyle), createListItemSpan(nestingLevel + 1, alignmentRendering))
455-
AztecTextFormat.FORMAT_TASK_LIST -> listOf(createTaskListSpan(nestingLevel, alignmentRendering, attrs, editor.context, listStyle), createListItemSpan(nestingLevel + 1, alignmentRendering))
457+
AztecTextFormat.FORMAT_TASK_LIST -> listOf(createTaskListSpan(nestingLevel, alignmentRendering, attrs, editor.context, listStyle), createListItemSpan(nestingLevel + 1, alignmentRendering, listItemStyle = listItemStyle))
456458
AztecTextFormat.FORMAT_QUOTE -> listOf(createAztecQuoteSpan(nestingLevel, attrs, alignmentRendering, quoteStyle))
457459
AztecTextFormat.FORMAT_HEADING_1,
458460
AztecTextFormat.FORMAT_HEADING_2,
@@ -500,7 +502,7 @@ class BlockFormatter(editor: AztecText,
500502
typeIsAssignableTo(AztecOrderedListSpan::class) -> createOrderedListSpan(nestingLevel, alignmentRendering, attrs, listStyle)
501503
typeIsAssignableTo(AztecUnorderedListSpan::class) -> createUnorderedListSpan(nestingLevel, alignmentRendering, attrs, listStyle)
502504
typeIsAssignableTo(AztecTaskListSpan::class) -> createTaskListSpan(nestingLevel, alignmentRendering, attrs, editor.context, listStyle)
503-
typeIsAssignableTo(AztecListItemSpan::class) -> createListItemSpan(nestingLevel, alignmentRendering, attrs)
505+
typeIsAssignableTo(AztecListItemSpan::class) -> createListItemSpan(nestingLevel, alignmentRendering, attrs, listItemStyle)
504506
typeIsAssignableTo(AztecQuoteSpan::class) -> createAztecQuoteSpan(nestingLevel, attrs, alignmentRendering, quoteStyle)
505507
typeIsAssignableTo(AztecHeadingSpan::class) -> createHeadingSpan(nestingLevel, textFormat, attrs, alignmentRendering, headerStyle)
506508
typeIsAssignableTo(AztecPreformatSpan::class) -> createPreformatSpan(nestingLevel, alignmentRendering, attrs, preformatStyle)
@@ -812,7 +814,7 @@ class BlockFormatter(editor: AztecText,
812814
BlockHandler.set(editableText, listSpan, start, end)
813815
// special case for styling single empty lines
814816
if (end - start == 1 && (editableText[end - 1] == '\n' || editableText[end - 1] == Constants.END_OF_BUFFER_MARKER)) {
815-
ListItemHandler.newListItem(editableText, start, end, listSpan.nestingLevel + 1, alignmentRendering)
817+
ListItemHandler.newListItem(editableText, start, end, listSpan.nestingLevel + 1, alignmentRendering, listItemStyle)
816818
} else {
817819
val listEnd = if (end == editableText.length) end else end - 1
818820
val listContent = editableText.substring(start, listEnd)
@@ -831,7 +833,7 @@ class BlockFormatter(editor: AztecText,
831833
start + lineStart,
832834
start + lineEnd,
833835
listSpan.nestingLevel + 1,
834-
alignmentRendering)
836+
alignmentRendering, listItemStyle)
835837
}
836838
}
837839
}

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package org.wordpress.aztec.handlers
22

33
import android.text.Spannable
44
import org.wordpress.aztec.AlignmentRendering
5+
import org.wordpress.aztec.formatting.BlockFormatter
56
import org.wordpress.aztec.spans.AztecListItemSpan
67
import org.wordpress.aztec.spans.AztecListItemSpan.Companion.CHECKED
78
import org.wordpress.aztec.spans.AztecTaskListSpan
@@ -10,12 +11,13 @@ import org.wordpress.aztec.spans.createListItemSpan
1011
import org.wordpress.aztec.watchers.TextDeleter
1112

1213
class ListItemHandler(
13-
val alignmentRendering: AlignmentRendering
14+
val alignmentRendering: AlignmentRendering,
15+
val listItemStyle: BlockFormatter.ListItemStyle
1416
) : BlockHandler<AztecListItemSpan>(AztecListItemSpan::class.java) {
1517

1618
override fun handleNewlineAtStartOfBlock() {
1719
// newline added at start of bullet so, add a new bullet
18-
newListItem(text, newlineIndex, newlineIndex + 1, block.span.nestingLevel, alignmentRendering)
20+
newListItem(text, newlineIndex, newlineIndex + 1, block.span.nestingLevel, alignmentRendering, listItemStyle)
1921

2022
// push current bullet forward
2123
block.start = newlineIndex + 1
@@ -58,7 +60,7 @@ class ListItemHandler(
5860
newListItemStart = newlineIndex
5961
}
6062

61-
newListItem(text, newListItemStart, block.end, block.span.nestingLevel, alignmentRendering)
63+
newListItem(text, newListItemStart, block.end, block.span.nestingLevel, alignmentRendering, listItemStyle)
6264
block.end = newListItemStart
6365
}
6466

@@ -69,7 +71,7 @@ class ListItemHandler(
6971
}
7072

7173
// attach a new bullet around the end-of-text marker
72-
newListItem(text, markerIndex, markerIndex + 1, block.span.nestingLevel, alignmentRendering)
74+
newListItem(text, markerIndex, markerIndex + 1, block.span.nestingLevel, alignmentRendering, listItemStyle)
7375

7476
// the current list item has bled over to the marker so, let's adjust its range to just before the marker.
7577
// There's a newline there hopefully :)
@@ -82,10 +84,11 @@ class ListItemHandler(
8284
start: Int,
8385
end: Int,
8486
nestingLevel: Int,
85-
alignmentRendering: AlignmentRendering
87+
alignmentRendering: AlignmentRendering,
88+
listItemStyle: BlockFormatter.ListItemStyle
8689
) {
8790
val isInTaskList = !text.getSpans(start, end, AztecTaskListSpan::class.java).isNullOrEmpty()
88-
set(text, createListItemSpan(nestingLevel, alignmentRendering).apply {
91+
set(text, createListItemSpan(nestingLevel, alignmentRendering, listItemStyle = listItemStyle).apply {
8992
if (isInTaskList) {
9093
this.attributes.setValue(CHECKED, "false")
9194
}

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

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
package org.wordpress.aztec.spans
22

33
import android.text.Layout
4+
import android.text.TextPaint
5+
import android.text.style.CharacterStyle
46
import org.wordpress.aztec.AlignmentRendering
57
import org.wordpress.aztec.AztecAttributes
68
import org.wordpress.aztec.ITextFormat
9+
import org.wordpress.aztec.formatting.BlockFormatter
710
import java.lang.StringBuilder
811

912
fun createListItemSpan(nestingLevel: Int,
1013
alignmentRendering: AlignmentRendering,
11-
attributes: AztecAttributes = AztecAttributes()) : IAztecBlockSpan =
12-
when (alignmentRendering) {
13-
AlignmentRendering.SPAN_LEVEL -> AztecListItemSpanAligned(nestingLevel, attributes, null)
14-
AlignmentRendering.VIEW_LEVEL -> AztecListItemSpan(nestingLevel, attributes)
15-
}
14+
attributes: AztecAttributes = AztecAttributes(),
15+
listItemStyle: BlockFormatter.ListItemStyle = BlockFormatter.ListItemStyle(false, 0)): IAztecBlockSpan = when (alignmentRendering) {
16+
AlignmentRendering.SPAN_LEVEL -> AztecListItemSpanAligned(nestingLevel, attributes, null, listItemStyle)
17+
AlignmentRendering.VIEW_LEVEL -> AztecListItemSpan(nestingLevel, attributes, listItemStyle)
18+
}
1619

1720
/**
1821
* We need to have two classes for handling alignment at either the Span-level (ListItemSpanAligned)
@@ -24,7 +27,9 @@ fun createListItemSpan(nestingLevel: Int,
2427
*/
2528
open class AztecListItemSpan(
2629
override var nestingLevel: Int,
27-
override var attributes: AztecAttributes) : IAztecCompositeBlockSpan {
30+
override var attributes: AztecAttributes,
31+
var listItemStyle: BlockFormatter.ListItemStyle = BlockFormatter.ListItemStyle(
32+
false, 0)) : CharacterStyle(), IAztecCompositeBlockSpan {
2833
fun toggleCheck() {
2934
if (attributes.getValue(CHECKED) == "true") {
3035
attributes.setValue(CHECKED, "false")
@@ -74,13 +79,27 @@ open class AztecListItemSpan(
7479

7580
override var endBeforeBleed: Int = -1
7681
override var startBeforeCollapse: Int = -1
82+
7783
companion object {
7884
const val CHECKED = "checked"
7985
}
86+
87+
override fun updateDrawState(tp: TextPaint) {
88+
val isChecked = attributes.getValue(CHECKED) == "true"
89+
90+
if (listItemStyle.strikeThroughCheckedItems) {
91+
tp.isStrikeThruText = isChecked
92+
}
93+
94+
if (listItemStyle.checkedItemsTextColor != 0 && isChecked) {
95+
tp.color = listItemStyle.checkedItemsTextColor
96+
}
97+
}
8098
}
8199

82100
class AztecListItemSpanAligned(
83101
nestingLevel: Int,
84102
attributes: AztecAttributes,
85-
override var align: Layout.Alignment?
86-
) : AztecListItemSpan(nestingLevel, attributes), IAztecAlignmentSpan
103+
override var align: Layout.Alignment?,
104+
listItemStyle: BlockFormatter.ListItemStyle = BlockFormatter.ListItemStyle(false, 0)
105+
) : AztecListItemSpan(nestingLevel, attributes, listItemStyle), IAztecAlignmentSpan

aztec/src/main/res/values/attrs.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
<attr name="headingFourFontColor" format="reference|color" />
5757
<attr name="headingFiveFontColor" format="reference|color" />
5858
<attr name="headingSixFontColor" format="reference|color" />
59+
<attr name="taskListStrikethroughChecked" format="reference|boolean" />
60+
<attr name="taskListCheckedTextColor" format="reference|color" />
5961
</declare-styleable>
6062

6163
<declare-styleable name="AztecToolbar">

aztec/src/main/res/values/styles.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
<item name="bulletMargin">@dimen/bullet_margin</item>
3131
<item name="bulletPadding">@dimen/bullet_padding</item>
3232
<item name="bulletWidth">@dimen/bullet_width</item>
33+
<!-- Task list -->
34+
<item name="taskListCheckedTextColor">@android:color/darker_gray</item>
35+
<item name="taskListStrikethroughChecked">true</item>
3336
<!-- Code -->
3437
<item name="codeBackground">@color/code_background</item>
3538
<item name="codeBackgroundAlpha">75%</item>

0 commit comments

Comments
 (0)