Skip to content

Commit

Permalink
Merge pull request #291 from wordpress-mobile/issue/289-multiple-head…
Browse files Browse the repository at this point in the history
…ings

Different headings in consecutive lines
  • Loading branch information
0nko authored Mar 17, 2017
2 parents c8bbee9 + a30168b commit aa7f3f5
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,8 @@ class BlockFormatter(editor: AztecText, val listStyle: ListStyle, val quoteStyle
if (numberOfLines == numberOfLinesWithSpanApplied) {
removeBlockStyle(blockElementType)
} else {
applyBlock(blockElementType, startOfBlock + 1,
(if (endOfBlock == editableText.length) endOfBlock else endOfBlock + 1), nestingLevel)
applyBlock(makeBlockSpan(blockElementType, nestingLevel), startOfBlock + 1,
(if (endOfBlock == editableText.length) endOfBlock else endOfBlock + 1))
}

} else {
Expand All @@ -327,31 +327,39 @@ class BlockFormatter(editor: AztecText, val listStyle: ListStyle, val quoteStyle
val startOfLine = boundsOfSelectedText.start
val endOfLine = boundsOfSelectedText.endInclusive

val spanToApply = getOuterBlockSpanType(blockElementType)
val nestingLevel = AztecNestable.getNestingLevelAt(editableText, start) + 1

val spanToApply = makeBlockSpan(blockElementType, nestingLevel)

var startOfBlock: Int = startOfLine
var endOfBlock: Int = endOfLine


if (startOfLine != 0) {
val spansOnPreviousLine = editableText.getSpans(startOfLine - 1, startOfLine - 1, spanToApply).firstOrNull()
if (spansOnPreviousLine != null) {
val spansOnPreviousLine = editableText.getSpans(startOfLine - 1, startOfLine - 1, spanToApply.javaClass)
.firstOrNull()
// if same span type is found (also check for heading style equality if a heading) extend the start
if (spansOnPreviousLine != null
&& (spansOnPreviousLine !is AztecHeadingSpan
|| spansOnPreviousLine.heading == (spanToApply as AztecHeadingSpan).heading)) {
startOfBlock = editableText.getSpanStart(spansOnPreviousLine)
liftBlock(blockElementType, startOfBlock, endOfBlock)
}
}

if (endOfLine != editableText.length) {
val spanOnNextLine = editableText.getSpans(endOfLine + 1, endOfLine + 1, spanToApply).firstOrNull()
if (spanOnNextLine != null) {
val spanOnNextLine = editableText.getSpans(endOfLine + 1, endOfLine + 1, spanToApply.javaClass)
.firstOrNull()
// if same span type is found (also check for heading style equality if a heading) extend the end
if (spanOnNextLine != null
&& (spanOnNextLine !is AztecHeadingSpan
|| spanOnNextLine.heading == (spanToApply as AztecHeadingSpan).heading)) {
endOfBlock = editableText.getSpanEnd(spanOnNextLine)
liftBlock(blockElementType, startOfBlock, endOfBlock)
}
}

val nestingLevel = AztecNestable.getNestingLevelAt(editableText, start) + 1

applyBlock(blockElementType, startOfBlock, endOfBlock, nestingLevel)
applyBlock(spanToApply, startOfBlock, endOfBlock)

//if the line was empty trigger onSelectionChanged manually to update toolbar buttons status
// if (isEmptyLine) {
Expand All @@ -360,22 +368,17 @@ class BlockFormatter(editor: AztecText, val listStyle: ListStyle, val quoteStyle
}
}

private fun applyBlock(textFormat: TextFormat, start: Int, end: Int, nestingLevel: Int, attrs: String = "") {
when (textFormat) {
TextFormat.FORMAT_ORDERED_LIST -> applyListBlock(AztecOrderedListSpan(nestingLevel, attrs, listStyle), start, end, nestingLevel)
TextFormat.FORMAT_UNORDERED_LIST -> applyListBlock(AztecUnorderedListSpan(nestingLevel, attrs, listStyle), start, end, nestingLevel)
TextFormat.FORMAT_QUOTE -> BlockHandler.set(editableText, AztecQuoteSpan(nestingLevel, attrs, quoteStyle), start, end)
TextFormat.FORMAT_HEADING_1,
TextFormat.FORMAT_HEADING_2,
TextFormat.FORMAT_HEADING_3,
TextFormat.FORMAT_HEADING_4,
TextFormat.FORMAT_HEADING_5,
TextFormat.FORMAT_HEADING_6 -> applyHeadingBlock(AztecHeadingSpan(nestingLevel, textFormat, attrs, headerStyle), start, end, nestingLevel)
else -> editableText.setSpan(ParagraphSpan(nestingLevel, attrs), start, end, Spanned.SPAN_PARAGRAPH)
private fun applyBlock(blockSpan: AztecBlockSpan, start: Int, end: Int) {
when (blockSpan) {
is AztecOrderedListSpan -> applyListBlock(blockSpan, start, end)
is AztecUnorderedListSpan -> applyListBlock(blockSpan, start, end)
is AztecQuoteSpan -> BlockHandler.set(editableText, blockSpan, start, end)
is AztecHeadingSpan -> applyHeadingBlock(blockSpan, start, end)
else -> editableText.setSpan(blockSpan, start, end, Spanned.SPAN_PARAGRAPH)
}
}

private fun applyListBlock(listSpan: AztecListSpan, start: Int, end: Int, nestingLevel: Int) {
private fun applyListBlock(listSpan: AztecListSpan, start: Int, end: Int) {
BlockHandler.set(editableText, listSpan, start, end)

val lines = TextUtils.split(editableText.substring(start, end), "\n")
Expand All @@ -389,23 +392,22 @@ class BlockFormatter(editor: AztecText, val listStyle: ListStyle, val quoteStyle

if (lineLength == 0) continue

ListItemHandler.newListItem(editableText, start + lineStart, start + lineEnd, nestingLevel + 1)
ListItemHandler.newListItem(editableText, start + lineStart, start + lineEnd, listSpan.nestingLevel + 1)
}
}

private fun applyHeadingBlock(headingSpan: AztecHeadingSpan, start: Int, end: Int, nestingLevel: Int) {
private fun applyHeadingBlock(headingSpan: AztecHeadingSpan, start: Int, end: Int) {
val lines = TextUtils.split(editableText.substring(start, end), "\n")
for (i in lines.indices) {
val lineLength = lines[i].length
val splitLength = lines[i].length

val lineStart = (0..i - 1).sumBy { lines[it].length + 1 }
val lineEnd = (lineStart + lineLength).let {
if ((start + it) != editableText.length) it + 1 else it // include the newline or not
}
val lineStart = start + (0..i - 1).sumBy { lines[it].length + 1 }
val lineEnd = Math.min(lineStart + splitLength + 1, end) // +1 to include the newline

val lineLength = lineEnd - lineStart
if (lineLength == 0) continue

HeadingHandler.cloneHeading(editableText, headingSpan, start + lineStart, start + lineEnd)
HeadingHandler.cloneHeading(editableText, headingSpan, lineStart, lineEnd)
}
}

Expand Down
17 changes: 16 additions & 1 deletion aztec/src/test/kotlin/org/wordpress/aztec/HeadingTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,19 @@ class HeadingTest() {
editText.text.delete(l - 1, l)
Assert.assertEquals("<h1></h1>", editText.toHtml())
}
}

@Test
@Throws(Exception::class)
fun addHeading_issue289() {
editText.fromHtml("<h1>Heading 1</h1>")

safeAppend(editText, "\n")

editText.setSelection(safeLength(editText))
editText.toggleFormatting(TextFormat.FORMAT_HEADING_2)
Assert.assertEquals("<h1>Heading 1</h1><h2></h2>", editText.toHtml())

safeAppend(editText, "Heading 2")
Assert.assertEquals("<h1>Heading 1</h1><h2>Heading 2</h2>", editText.toHtml())
}
}

0 comments on commit aa7f3f5

Please sign in to comment.