Skip to content

Commit

Permalink
Merge pull request #851 from wordpress-mobile/issue/1266_allow-paragr…
Browse files Browse the repository at this point in the history
…aph-without-alignment-span

Allow paragraph spans that do not extend AlignmentSpan
  • Loading branch information
mchowning authored Oct 7, 2019
2 parents 20bd6b7 + 2f2a69b commit f4d3dec
Show file tree
Hide file tree
Showing 17 changed files with 107 additions and 74 deletions.
3 changes: 2 additions & 1 deletion aztec/src/main/kotlin/org/wordpress/aztec/AztecParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import org.wordpress.aztec.spans.AztecMediaSpan
import org.wordpress.aztec.spans.AztecURLSpan
import org.wordpress.aztec.spans.AztecVisualLinebreak
import org.wordpress.aztec.spans.CommentSpan
import org.wordpress.aztec.spans.IAztecAlignmentSpan
import org.wordpress.aztec.spans.IAztecBlockSpan
import org.wordpress.aztec.spans.IAztecFullWidthImageSpan
import org.wordpress.aztec.spans.IAztecInlineSpan
Expand Down Expand Up @@ -415,7 +416,7 @@ class AztecParser @JvmOverloads constructor(val plugins: List<IAztecPlugin> = li
private fun withinNestable(out: StringBuilder, text: Spanned, start: Int, end: Int,
nestable: IAztecParagraphStyle, parents: ArrayList<IAztecNestable>?, nestingLevel: Int) {

if (nestable.shouldParseAlignmentToHtml()) {
if (nestable is IAztecAlignmentSpan && nestable.shouldParseAlignmentToHtml()) {
CssStyleFormatter.removeStyleAttribute(nestable.attributes, CssStyleFormatter.CSS_TEXT_ALIGN_ATTRIBUTE)

nestable.align?.let {
Expand Down
4 changes: 2 additions & 2 deletions aztec/src/main/kotlin/org/wordpress/aztec/AztecTagHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import org.wordpress.aztec.spans.HiddenHtmlBlock
import org.wordpress.aztec.spans.HiddenHtmlSpan
import org.wordpress.aztec.spans.IAztecAttributedSpan
import org.wordpress.aztec.spans.IAztecNestable
import org.wordpress.aztec.spans.ParagraphSpan
import org.wordpress.aztec.spans.createParagraphSpan
import org.wordpress.aztec.util.getLast
import org.xml.sax.Attributes
import java.util.ArrayList
Expand Down Expand Up @@ -118,7 +118,7 @@ class AztecTagHandler(val context: Context, val plugins: List<IAztecPlugin> = Ar
return true
}
PARAGRAPH -> {
handleElement(output, opening, ParagraphSpan(nestingLevel, AztecAttributes(attributes)))
handleElement(output, opening, createParagraphSpan(nestingLevel, AztecAttributes(attributes)))
return true
}
LINE -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ import org.wordpress.aztec.spans.AztecOrderedListSpan
import org.wordpress.aztec.spans.AztecPreformatSpan
import org.wordpress.aztec.spans.AztecQuoteSpan
import org.wordpress.aztec.spans.AztecUnorderedListSpan
import org.wordpress.aztec.spans.IAztecAlignmentSpan
import org.wordpress.aztec.spans.IAztecBlockSpan
import org.wordpress.aztec.spans.IAztecCompositeBlockSpan
import org.wordpress.aztec.spans.IAztecLineBlockSpan
import org.wordpress.aztec.spans.IAztecNestable
import org.wordpress.aztec.spans.IAztecParagraphStyle
import org.wordpress.aztec.spans.ParagraphSpan
import org.wordpress.aztec.spans.createParagraphSpan
import org.wordpress.aztec.util.SpanWrapper
import java.util.Arrays

Expand Down Expand Up @@ -279,21 +280,6 @@ class BlockFormatter(editor: AztecText, val listStyle: ListStyle, val quoteStyle
}
}

fun getOuterBlockSpanType(textFormat: ITextFormat): Class<out IAztecBlockSpan> {
when (textFormat) {
AztecTextFormat.FORMAT_ORDERED_LIST -> return AztecOrderedListSpan::class.java
AztecTextFormat.FORMAT_UNORDERED_LIST -> return AztecUnorderedListSpan::class.java
AztecTextFormat.FORMAT_QUOTE -> return AztecQuoteSpan::class.java
AztecTextFormat.FORMAT_HEADING_1,
AztecTextFormat.FORMAT_HEADING_2,
AztecTextFormat.FORMAT_HEADING_3,
AztecTextFormat.FORMAT_HEADING_4,
AztecTextFormat.FORMAT_HEADING_5,
AztecTextFormat.FORMAT_HEADING_6 -> return AztecHeadingSpan::class.java
else -> return ParagraphSpan::class.java
}
}

// TODO: Come up with a better way to init spans and get their classes (all the "make" methods)
fun makeBlock(textFormat: ITextFormat, nestingLevel: Int, attrs: AztecAttributes = AztecAttributes()): List<IAztecBlockSpan> {
when (textFormat) {
Expand All @@ -307,7 +293,7 @@ class BlockFormatter(editor: AztecText, val listStyle: ListStyle, val quoteStyle
AztecTextFormat.FORMAT_HEADING_5,
AztecTextFormat.FORMAT_HEADING_6 -> return Arrays.asList(AztecHeadingSpan(nestingLevel, textFormat, attrs, headerStyle))
AztecTextFormat.FORMAT_PREFORMAT -> return Arrays.asList(AztecPreformatSpan(nestingLevel, attrs, preformatStyle))
else -> return Arrays.asList(ParagraphSpan(nestingLevel, attrs))
else -> return Arrays.asList(createParagraphSpan(nestingLevel, attrs))
}
}

Expand Down Expand Up @@ -335,7 +321,7 @@ class BlockFormatter(editor: AztecText, val listStyle: ListStyle, val quoteStyle
AztecTextFormat.FORMAT_HEADING_5,
AztecTextFormat.FORMAT_HEADING_6 -> makeBlockSpan(AztecHeadingSpan::class.java, textFormat, nestingLevel, attrs)
AztecTextFormat.FORMAT_PREFORMAT -> makeBlockSpan(AztecPreformatSpan::class.java, textFormat, nestingLevel, attrs)
else -> ParagraphSpan(nestingLevel, attrs)
else -> createParagraphSpan(nestingLevel, attrs)
}
}

Expand All @@ -347,7 +333,7 @@ class BlockFormatter(editor: AztecText, val listStyle: ListStyle, val quoteStyle
AztecQuoteSpan::class.java -> AztecQuoteSpan(nestingLevel, attrs, quoteStyle)
AztecHeadingSpan::class.java -> AztecHeadingSpan(nestingLevel, textFormat, attrs, headerStyle)
AztecPreformatSpan::class.java -> AztecPreformatSpan(nestingLevel, attrs, preformatStyle)
else -> ParagraphSpan(nestingLevel, attrs)
else -> createParagraphSpan(nestingLevel, attrs)
}
}

Expand Down Expand Up @@ -509,13 +495,13 @@ class BlockFormatter(editor: AztecText, val listStyle: ListStyle, val quoteStyle

val alignment = getAlignment(textFormat,
editableText.subSequence(boundsOfSelectedText.start until boundsOfSelectedText.endInclusive))
editableText.setSpan(ParagraphSpan(nestingLevel, AztecAttributes(), alignment),
editableText.setSpan(createParagraphSpan(nestingLevel, AztecAttributes(), alignment),
boundsOfSelectedText.start, boundsOfSelectedText.endInclusive, Spanned.SPAN_PARAGRAPH)
}
}

private fun changeAlignment(it: IAztecParagraphStyle, blockElementType: ITextFormat?) {
val wrapper = SpanWrapper<IAztecParagraphStyle>(editableText, it)
private fun changeAlignment(it: IAztecAlignmentSpan, blockElementType: ITextFormat?) {
val wrapper = SpanWrapper(editableText, it)
it.align = getAlignment(blockElementType, editableText.substring(wrapper.start until wrapper.end))

editableText.setSpan(it, wrapper.start, wrapper.end, wrapper.flags)
Expand Down Expand Up @@ -905,10 +891,10 @@ class BlockFormatter(editor: AztecText, val listStyle: ListStyle, val quoteStyle
return getAlignedSpans(textFormat, selStart, selEnd).isNotEmpty()
}

private fun getAlignedSpans(textFormat: ITextFormat?, selStart: Int = selectionStart, selEnd: Int = selectionEnd): List<IAztecParagraphStyle> {
private fun getAlignedSpans(textFormat: ITextFormat?, selStart: Int = selectionStart, selEnd: Int = selectionEnd): List<IAztecAlignmentSpan> {
if (selStart < 0 || selEnd < 0) return emptyList()

return editableText.getSpans(selStart, selEnd, IAztecParagraphStyle::class.java)
return editableText.getSpans(selStart, selEnd, IAztecAlignmentSpan::class.java)
.filter {
textFormat == null || it.align == getAlignment(textFormat,
editableText.substring(editableText.getSpanStart(it) until editableText.getSpanEnd(it)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.text.Layout
import android.text.Spannable
import android.text.style.ForegroundColorSpan
import org.wordpress.aztec.AztecAttributes
import org.wordpress.aztec.spans.IAztecAlignmentSpan
import org.wordpress.aztec.spans.IAztecAttributedSpan
import org.wordpress.aztec.spans.IAztecParagraphStyle
import org.wordpress.aztec.util.ColorConverter
Expand Down Expand Up @@ -47,18 +48,20 @@ class CssStyleFormatter {
}

private fun processAlignment(blockSpan: IAztecParagraphStyle, text: Editable, start: Int, end: Int) {
val alignment = getStyleAttribute(blockSpan.attributes, CSS_TEXT_ALIGN_ATTRIBUTE)
if (!alignment.isBlank()) {
val direction = TextDirectionHeuristicsCompat.FIRSTSTRONG_LTR
val isRtl = direction.isRtl(text, start, end - start)

val align = when (alignment) {
"right" -> if (isRtl) Layout.Alignment.ALIGN_NORMAL else Layout.Alignment.ALIGN_OPPOSITE
"center" -> Layout.Alignment.ALIGN_CENTER
else -> if (!isRtl) Layout.Alignment.ALIGN_NORMAL else Layout.Alignment.ALIGN_OPPOSITE
if (blockSpan is IAztecAlignmentSpan) {
val alignment = getStyleAttribute(blockSpan.attributes, CSS_TEXT_ALIGN_ATTRIBUTE)
if (!alignment.isBlank()) {
val direction = TextDirectionHeuristicsCompat.FIRSTSTRONG_LTR
val isRtl = direction.isRtl(text, start, end - start)

val align = when (alignment) {
"right" -> if (isRtl) Layout.Alignment.ALIGN_NORMAL else Layout.Alignment.ALIGN_OPPOSITE
"center" -> Layout.Alignment.ALIGN_CENTER
else -> if (!isRtl) Layout.Alignment.ALIGN_NORMAL else Layout.Alignment.ALIGN_OPPOSITE
}

blockSpan.align = align
}

blockSpan.align = align
}
}

Expand Down
9 changes: 7 additions & 2 deletions aztec/src/main/kotlin/org/wordpress/aztec/source/Format.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.jsoup.nodes.Document
import org.wordpress.aztec.spans.AztecQuoteSpan
import org.wordpress.aztec.spans.AztecVisualLinebreak
import org.wordpress.aztec.spans.EndOfParagraphMarker
import org.wordpress.aztec.spans.IAztecAlignmentSpan
import org.wordpress.aztec.spans.IAztecParagraphStyle
import org.wordpress.aztec.spans.ParagraphSpan
import org.wordpress.aztec.util.CleaningUtils
Expand Down Expand Up @@ -356,8 +357,12 @@ object Format {

// we don't care about actual ParagraphSpan in calypso that don't have attributes or are empty (paragraphs are made from double newline)
text.getSpans(0, text.length, ParagraphSpan::class.java)
.filter { it.attributes.isEmpty() && it.align == null || text.getSpanStart(it) == text.getSpanEnd(it) - 1 }
.forEach {
.filter {
val hasNoAttributes = it.attributes.isEmpty()
val isAligned = it is IAztecAlignmentSpan && it.align != null
val isEmpty = text.getSpanStart(it) == text.getSpanEnd(it) - 1
(hasNoAttributes && !isAligned) || isEmpty
}.forEach {
text.removeSpan(it)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class AztecHeadingSpan @JvmOverloads constructor(
override var attributes: AztecAttributes,
var headerStyle: BlockFormatter.HeaderStyle = BlockFormatter.HeaderStyle(0),
override var align: Layout.Alignment? = null
) : MetricAffectingSpan(), IAztecLineBlockSpan, LineHeightSpan, UpdateLayout {
) : MetricAffectingSpan(), IAztecAlignmentSpan, IAztecLineBlockSpan, LineHeightSpan, UpdateLayout {
override val TAG: String
get() = heading.tag

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import org.wordpress.aztec.AztecAttributes

class AztecListItemSpan(override var nestingLevel: Int,
override var attributes: AztecAttributes = AztecAttributes(),
override var align: Layout.Alignment? = null) : IAztecCompositeBlockSpan {
override var align: Layout.Alignment? = null
) : IAztecAlignmentSpan, IAztecCompositeBlockSpan {
override val TAG = "li"

override var endBeforeBleed: Int = -1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ import org.wordpress.aztec.Constants

abstract class AztecListSpan(override var nestingLevel: Int,
var verticalPadding: Int = 0,
override var align: Layout.Alignment? = null) : LeadingMarginSpan.Standard(0),
LineHeightSpan, UpdateLayout, IAztecBlockSpan {
override var align: Layout.Alignment? = null
) : LeadingMarginSpan.Standard(0),
LineHeightSpan,
UpdateLayout,
IAztecAlignmentSpan,
IAztecBlockSpan {
override var endBeforeBleed: Int = -1
override var startBeforeCollapse: Int = -1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ class AztecPreformatSpan(
override var attributes: AztecAttributes = AztecAttributes(),
var preformatStyle: BlockFormatter.PreformatStyle = BlockFormatter.PreformatStyle(0, 0f, 0, 0),
override var align: Layout.Alignment? = null
) : IAztecBlockSpan, LeadingMarginSpan, LineBackgroundSpan, LineHeightSpan, TypefaceSpan("monospace") {
) : IAztecAlignmentSpan,
IAztecBlockSpan,
LeadingMarginSpan,
LineBackgroundSpan,
LineHeightSpan,
TypefaceSpan("monospace")
{
override val TAG: String = "pre"

override var endBeforeBleed: Int = -1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,14 @@ class AztecQuoteSpan(
override var nestingLevel: Int,
override var attributes: AztecAttributes = AztecAttributes(),
var quoteStyle: BlockFormatter.QuoteStyle = BlockFormatter.QuoteStyle(0, 0, 0f, 0, 0, 0, 0),
override var align: Layout.Alignment? = null)
: QuoteSpan(), LineBackgroundSpan, IAztecBlockSpan, LineHeightSpan, UpdateLayout {
override var align: Layout.Alignment? = null
) : QuoteSpan(),
LineBackgroundSpan,
IAztecAlignmentSpan,
IAztecBlockSpan,
LineHeightSpan,
UpdateLayout
{

override var endBeforeBleed: Int = -1
override var startBeforeCollapse: Int = -1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package org.wordpress.aztec.spans
import android.text.Layout
import org.wordpress.aztec.AztecAttributes

class HiddenHtmlBlock(tag: String, override var attributes: AztecAttributes = AztecAttributes(),
override var nestingLevel: Int) : IAztecBlockSpan {
class HiddenHtmlBlock(tag: String,
override var attributes: AztecAttributes = AztecAttributes(),
override var nestingLevel: Int) : IAztecAlignmentSpan, IAztecBlockSpan {
override var endBeforeBleed: Int = -1
override var startBeforeCollapse: Int = -1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package org.wordpress.aztec.spans
import android.text.Layout
import org.wordpress.aztec.AztecAttributes

class HiddenHtmlSpan(tag: String, override var attributes: AztecAttributes = AztecAttributes(),
override var nestingLevel: Int) : IAztecParagraphStyle {
class HiddenHtmlSpan(tag: String,
override var attributes: AztecAttributes = AztecAttributes(),
override var nestingLevel: Int) : IAztecAlignmentSpan, IAztecParagraphStyle {
override var align: Layout.Alignment? = null

override val TAG: String = tag
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.wordpress.aztec.spans

import android.text.Layout
import android.text.style.AlignmentSpan

interface IAztecAlignmentSpan : AlignmentSpan {

var align: Layout.Alignment?

override fun getAlignment(): Layout.Alignment = align ?: Layout.Alignment.ALIGN_NORMAL

fun shouldParseAlignmentToHtml(): Boolean = true
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,8 @@
package org.wordpress.aztec.spans

import android.text.Layout
import android.text.style.AlignmentSpan

/**
* Marks spans that are going to be parsed with {@link org.wordpress.aztec.AztecParser#withinHtml()}
* Created in order to distinguish between spans that implement ParagraphStyle for various reasons, but have separate
* parsing logic, like {@link org.wordpress.aztec.spans.AztecHeadingSpan}
**/
interface IAztecParagraphStyle : AlignmentSpan, IAztecSpan, IAztecNestable {

var align: Layout.Alignment?

override fun getAlignment(): Layout.Alignment {
return align ?: Layout.Alignment.ALIGN_NORMAL
}

fun shouldParseAlignmentToHtml(): Boolean {
return true
}
}
interface IAztecParagraphStyle : IAztecSpan, IAztecNestable
31 changes: 26 additions & 5 deletions aztec/src/main/kotlin/org/wordpress/aztec/spans/ParagraphSpan.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,35 @@ package org.wordpress.aztec.spans
import android.text.Layout
import org.wordpress.aztec.AztecAttributes

class ParagraphSpan(
fun createParagraphSpan(nestingLevel: Int,
attributes: AztecAttributes = AztecAttributes(),
align: Layout.Alignment? = null) : IAztecBlockSpan =
if (align == null) {
ParagraphSpan(nestingLevel, attributes)
} else {
ParagraphSpanAligned(align, nestingLevel, attributes)
}

/**
* This class is the same as the {@link ParagraphSpanAligned except it does not implement
* AlignmentSpan (via IAztecAlignmentSpan). This is necessary because IAztecParagraphSpan implements
* AlignmentSpan which has a getAlignment method that returns a non-null Layout.Alignment. Since this
* cannot be null it will always override the view's gravity. By having a class that does not implement
* AlignmentSpan the view's gravity can control.
*/
open class ParagraphSpan(
override var nestingLevel: Int,
override var attributes: AztecAttributes = AztecAttributes(),
override var align: Layout.Alignment? = null
) : IAztecBlockSpan {
override var attributes: AztecAttributes = AztecAttributes()
) : IAztecBlockSpan {

override var TAG: String = "p"

override var endBeforeBleed: Int = -1
override var startBeforeCollapse: Int = -1
}
}

class ParagraphSpanAligned(
override var align: Layout.Alignment?,
nestingLevel: Int,
attributes: AztecAttributes = AztecAttributes()
) : ParagraphSpan(nestingLevel, attributes), IAztecAlignmentSpan
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.wordpress.aztec.plugins.wpcomments.spans

import android.text.Layout
import org.wordpress.aztec.AztecAttributes
import org.wordpress.aztec.spans.IAztecBlockSpan

Expand All @@ -10,7 +9,6 @@ class GutenbergCommentSpan(
override var attributes: AztecAttributes = AztecAttributes()
) : IAztecBlockSpan {
override val TAG: String = "wp:"
override var align: Layout.Alignment? = null
override var startBeforeCollapse: Int = -1
override var endBeforeBleed: Int = -1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.text.style.StyleSpan
import org.wordpress.aztec.AztecAttributes
import org.wordpress.aztec.AztecText
import org.wordpress.aztec.Constants
import org.wordpress.aztec.spans.IAztecAlignmentSpan
import org.wordpress.aztec.spans.IAztecBlockSpan
import org.wordpress.aztec.util.SpanWrapper

Expand All @@ -15,7 +16,7 @@ class CaptionShortcodeSpan @JvmOverloads constructor(override var attributes: Az
override var nestingLevel: Int,
private val aztecText: AztecText? = null,
override var align: Layout.Alignment? = null)
: StyleSpan(Typeface.ITALIC), IAztecBlockSpan {
: StyleSpan(Typeface.ITALIC), IAztecAlignmentSpan, IAztecBlockSpan {

override var endBeforeBleed: Int = -1
override var startBeforeCollapse: Int = -1
Expand Down

0 comments on commit f4d3dec

Please sign in to comment.