Skip to content

Commit

Permalink
Merge pull request #1073 from wordpress-mobile/fix/mark-style-issues
Browse files Browse the repository at this point in the history
Improve Mark formatting
  • Loading branch information
geriux committed Mar 21, 2024
2 parents e204002 + 2f73564 commit 6e9814f
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 13 deletions.
1 change: 1 addition & 0 deletions aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,7 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown
AztecTextFormat.FORMAT_CODE -> inlineFormatter.toggle(textFormat)
AztecTextFormat.FORMAT_BOLD,
AztecTextFormat.FORMAT_STRONG -> inlineFormatter.toggleAny(ToolbarAction.BOLD.textFormats)
AztecTextFormat.FORMAT_MARK -> inlineFormatter.toggle(textFormat)
AztecTextFormat.FORMAT_UNORDERED_LIST -> blockFormatter.toggleUnorderedList()
AztecTextFormat.FORMAT_TASK_LIST -> blockFormatter.toggleTaskList()
AztecTextFormat.FORMAT_ORDERED_LIST -> blockFormatter.toggleOrderedList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import org.wordpress.aztec.watchers.TextChangedEvent
class InlineFormatter(editor: AztecText, val codeStyle: CodeStyle, private val highlightStyle: HighlightStyle) : AztecFormatter(editor) {

var backgroundSpanColor: Int? = null
var markStyleColor: String? = null

data class CodeStyle(val codeBackground: Int, val codeBackgroundAlpha: Float, val codeColor: Int)
data class HighlightStyle(@ColorRes val color: Int)
Expand Down Expand Up @@ -107,12 +108,8 @@ class InlineFormatter(editor: AztecText, val codeStyle: CodeStyle, private val h
applyInlineStyle(item, textChangedEvent.inputStart, textChangedEvent.inputEnd)
}
AztecTextFormat.FORMAT_MARK -> {
// For cases of an empty mark tag, either at the beginning of the text or in between
if (textChangedEvent.inputStart == 0 && textChangedEvent.inputEnd == 1) {
applyMarkInlineStyle(textChangedEvent.inputStart, textChangedEvent.inputEnd)
} else {
applyInlineStyle(item, textChangedEvent.inputStart, textChangedEvent.inputEnd)
}
applyInlineStyle(item, textChangedEvent.inputStart, textChangedEvent.inputEnd)
applyAfterMarkInlineStyle(textChangedEvent.inputStart, textChangedEvent.inputEnd)
}
else -> {
// do nothing
Expand All @@ -128,6 +125,16 @@ class InlineFormatter(editor: AztecText, val codeStyle: CodeStyle, private val h
val newStart = if (start > end) end else start
// if there is END_OF_BUFFER_MARKER at the end of or range, extend the range to include it

// Clear Mark formatting styles
if (!editor.selectedStyles.contains(AztecTextFormat.FORMAT_MARK) && start >= 1 && end > 1 ) {
val previousMarkSpan = editableText.getSpans(start - 1, start, MarkSpan::class.java)
val markSpan = editableText.getSpans(start, end, MarkSpan::class.java)
if (markSpan.isNotEmpty() || previousMarkSpan.isNotEmpty()) {
removeInlineCssStyle(start, end)
return
}
}

// remove lingering empty spans when removing characters
if (start > end) {
editableText.getSpans(newStart, end, IAztecInlineSpan::class.java)
Expand Down Expand Up @@ -250,10 +257,40 @@ class InlineFormatter(editor: AztecText, val codeStyle: CodeStyle, private val h
}
}

private fun applyMarkInlineStyle(start: Int = selectionStart, end: Int = selectionEnd) {
val previousSpans = editableText.getSpans(start, end, MarkSpan::class.java)
previousSpans.forEach {
it.applyInlineStyleAttributes(editableText, start, end)
private fun applyAfterMarkInlineStyle(start: Int = selectionStart, end: Int = selectionEnd) {
// If there's no new mark style color to update, it skips applying the style updates.
if (markStyleColor == null) {
return
}

val spans = editableText.getSpans(start, end, MarkSpan::class.java)
spans.forEach { span ->
if (span != null) {
val color = span.getTextColor()
val currentSpanStart = editableText.getSpanStart(span)
val currentSpanEnd = editableText.getSpanEnd(span)

if (end < currentSpanEnd) {
markStyleColor = null
return
}

if (!color.equals(markStyleColor, ignoreCase = true)) {
editableText.removeSpan(span)
editableText.setSpan(
MarkSpan(AztecAttributes(), color),
currentSpanStart,
start,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
editableText.setSpan(
MarkSpan(AztecAttributes(), markStyleColor),
start,
end,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
}
}
}

Expand Down Expand Up @@ -444,7 +481,7 @@ class InlineFormatter(editor: AztecText, val codeStyle: CodeStyle, private val h
AztecTextFormat.FORMAT_HIGHLIGHT -> {
HighlightSpan.create(context = editor.context, defaultStyle = highlightStyle)
}
AztecTextFormat.FORMAT_MARK -> MarkSpan()
AztecTextFormat.FORMAT_MARK -> MarkSpan(AztecAttributes(), markStyleColor)
else -> AztecStyleSpan(Typeface.NORMAL)
}
}
Expand Down
25 changes: 25 additions & 0 deletions aztec/src/main/kotlin/org/wordpress/aztec/plugins/MarkPlugin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.wordpress.aztec.plugins

import android.text.SpannableStringBuilder
import org.wordpress.aztec.plugins.visual2html.ISpanPreprocessor
import org.wordpress.aztec.source.CssStyleFormatter
import org.wordpress.aztec.spans.MarkSpan

class MarkPlugin : ISpanPreprocessor {

override fun beforeSpansProcessed(spannable: SpannableStringBuilder) {
spannable.getSpans(0, spannable.length, MarkSpan::class.java).forEach {
if (!CssStyleFormatter.containsStyleAttribute(it.attributes, CssStyleFormatter.CSS_BACKGROUND_COLOR_ATTRIBUTE)) {
CssStyleFormatter.addStyleAttribute(it.attributes, CssStyleFormatter.CSS_BACKGROUND_COLOR_ATTRIBUTE, "rgba(0, 0, 0, 0)")
}

if (!CssStyleFormatter.containsStyleAttribute(it.attributes, CssStyleFormatter.CSS_COLOR_ATTRIBUTE)) {
CssStyleFormatter.addStyleAttribute(it.attributes, CssStyleFormatter.CSS_COLOR_ATTRIBUTE, it.getTextColor())
}

if (!it.attributes.hasAttribute("class")) {
it.attributes.setValue("class", "has-inline-color")
}
}
}
}
37 changes: 35 additions & 2 deletions aztec/src/main/kotlin/org/wordpress/aztec/spans/MarkSpan.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,45 @@
package org.wordpress.aztec.spans

import android.graphics.Color
import android.text.TextPaint
import android.text.style.CharacterStyle
import org.wordpress.aztec.AztecAttributes
import org.wordpress.aztec.source.CssStyleFormatter

class MarkSpan(override var attributes: AztecAttributes = AztecAttributes()) : CharacterStyle(), IAztecInlineSpan {
class MarkSpan : CharacterStyle, IAztecInlineSpan {
override var TAG = "mark"

override fun updateDrawState(tp: TextPaint?) {
override var attributes: AztecAttributes = AztecAttributes()
private val textColorValue: Int?

constructor(attributes: AztecAttributes = AztecAttributes()) : super() {
this.attributes = attributes

val color = CssStyleFormatter.getStyleAttribute(attributes,
CssStyleFormatter.CSS_COLOR_ATTRIBUTE)
textColorValue = if (color.isNotEmpty()) {
Color.parseColor(color)
} else {
null
}
}

constructor(attributes: AztecAttributes = AztecAttributes(), colorString: String?) : super() {
this.attributes = attributes

textColorValue = if (colorString != null) {
Color.parseColor(colorString)
} else {
null
}
}

override fun updateDrawState(tp: TextPaint) {
textColorValue?.let { tp.color = it }
}

fun getTextColor(): String {
val currentColor = textColorValue ?: 0
return String.format("#%06X", 0xFFFFFF and currentColor)
}
}

0 comments on commit 6e9814f

Please sign in to comment.