Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Mark formatting #1073

Merged
merged 13 commits into from
Mar 21, 2024
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 @@ -40,6 +40,7 @@ class InlineFormatter(editor: AztecText, val codeStyle: CodeStyle, private val h

data class CodeStyle(val codeBackground: Int, val codeBackgroundAlpha: Float, val codeColor: Int)
data class HighlightStyle(@ColorRes val color: Int)
var markStyleColor: String? = null
geriux marked this conversation as resolved.
Show resolved Hide resolved

fun toggle(textFormat: ITextFormat) {
if (!containsInlineStyle(textFormat)) {
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 Down Expand Up @@ -250,10 +247,33 @@ 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)

editableText.removeSpan(span)
editableText.setSpan(
MarkSpan(AztecAttributes(), color),
currentSpanStart,
start,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
geriux marked this conversation as resolved.
Show resolved Hide resolved
editableText.setSpan(
MarkSpan(AztecAttributes(), markStyleColor),
start,
end,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
geriux marked this conversation as resolved.
Show resolved Hide resolved
markStyleColor = null
}
}
}

Expand Down Expand Up @@ -444,7 +464,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")
}
}
}
}
32 changes: 30 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,40 @@
package org.wordpress.aztec.spans

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

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()
var textColor: Int? = null
geriux marked this conversation as resolved.
Show resolved Hide resolved

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

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

if (colorString != null) {
textColor = Color.parseColor(colorString)
}
geriux marked this conversation as resolved.
Show resolved Hide resolved
}

override fun updateDrawState(tp: TextPaint) {
configureTextPaint(tp)
}

private fun configureTextPaint(tp: TextPaint) {
if (textColor != null) {
tp.color = textColor as Int
}
geriux marked this conversation as resolved.
Show resolved Hide resolved
}

fun getTextColor(): String {
geriux marked this conversation as resolved.
Show resolved Hide resolved
val currentColor = textColor ?: 0
return String.format("#%06X", 0xFFFFFF and currentColor)
}
}